diff --git a/properties/appResource.properties b/properties/appResource.properties index 924c9ae9..7d56ba12 100644 --- a/properties/appResource.properties +++ b/properties/appResource.properties @@ -18,6 +18,7 @@ error.needDls=DLS file is required error.read=Failed to read error.nofile=File not found error.invalid_file=Invalid file format +fail.saveFile=Failed to save ####### message ####### message.throw=Change up to now will be destroyed, OK? diff --git a/properties/appResource_ja.properties b/properties/appResource_ja.properties index b903eade..fb80547e 100644 --- a/properties/appResource_ja.properties +++ b/properties/appResource_ja.properties @@ -17,6 +17,7 @@ error.needDls=DLSファイルが必要です error.read=読み込みに失敗しました error.nofile=指定されたファイルがありません error.invalid_file=ファイル形式が不正です +fail.saveFile=ファイルの保存に失敗しました ####### message ####### message.throw=いままでの変更が破棄されますが、よろしいですか? diff --git a/src/fourthline/mabiicco/ActionDispatcher.java b/src/fourthline/mabiicco/ActionDispatcher.java index 34631fe7..395d8511 100644 --- a/src/fourthline/mabiicco/ActionDispatcher.java +++ b/src/fourthline/mabiicco/ActionDispatcher.java @@ -29,6 +29,7 @@ import fourthline.mabiicco.ui.MainFrame; import fourthline.mabiicco.ui.editor.MMLTranspose; import fourthline.mmlTools.MMLScore; +import fourthline.mmlTools.UndefinedTickException; import fourthline.mmlTools.parser.IMMLFileParser; import fourthline.mmlTools.parser.MMLFile; import fourthline.mmlTools.parser.MMLParseException; @@ -182,7 +183,7 @@ private void initializeActionMap() { actionMap.put(ADD_MEASURE, mmlSeqView::addMeasure); actionMap.put(REMOVE_MEASURE, mmlSeqView::removeMeasure); actionMap.put(NOTE_PROPERTY, editState::noteProperty); - actionMap.put(TRANSPOSE, () -> new MMLTranspose().execute(mainFrame, mmlSeqView)); + actionMap.put(TRANSPOSE, () -> new MMLTranspose(mmlSeqView.getFileState()).execute(mainFrame, mmlSeqView)); actionMap.put(ABOUT, () -> new About().show(mainFrame)); actionMap.put(MIDI_EXPORT, this::midiExportAction); actionMap.put(FILE_IMPORT, this::fileImportAction); @@ -261,15 +262,24 @@ public void reloadMMLFileAction() { } } - private void saveMMLFile(File file) { + /** + * @param file + * @return 保存に成功した場合は true, 失敗した場合は false を返す. + */ + private boolean saveMMLFile(File file) { try { + // generateできないデータは保存させない. + mmlSeqView.getMMLScore().generateAll(); FileOutputStream outputStream = new FileOutputStream(file); mmlSeqView.getMMLScore().writeToOutputStream(outputStream); mainFrame.setTitleAndFileName(file.getName()); fileState.setOriginalBase(); notifyUpdateFileState(); MabiIccoProperties.getInstance().setRecentFile(file.getPath()); - } catch (Exception e) {} + } catch (UndefinedTickException | IOException e) { + return false; + } + return true; } private void newMMLFileAction() { @@ -351,8 +361,11 @@ private boolean showDialogSaveFile() { saveFileChooser.setFileFilter(mmiFilter); File file = showSaveDialog(saveFileChooser, "mmi"); if (file != null) { - saveMMLFile(file); - openedFile = file; + if (saveMMLFile(file)) { + openedFile = file; + } else { + JOptionPane.showMessageDialog(mainFrame, AppResource.appText("fail.saveFile"), "ERROR", JOptionPane.ERROR_MESSAGE); + } return true; } return false; diff --git a/src/fourthline/mabiicco/IFileState.java b/src/fourthline/mabiicco/IFileState.java index edadee12..ed93f79a 100644 --- a/src/fourthline/mabiicco/IFileState.java +++ b/src/fourthline/mabiicco/IFileState.java @@ -9,6 +9,7 @@ public interface IFileState { public boolean canUndo(); public boolean canRedo(); public void saveState(); + public void revertState(); public void setOriginalBase(); public void setFileStateObserver(IFileStateObserver observer); diff --git a/src/fourthline/mabiicco/ui/ColumnPanel.java b/src/fourthline/mabiicco/ui/ColumnPanel.java index f411d223..fc8cb0bb 100644 --- a/src/fourthline/mabiicco/ui/ColumnPanel.java +++ b/src/fourthline/mabiicco/ui/ColumnPanel.java @@ -20,6 +20,7 @@ import javax.swing.JPopupMenu; import javax.swing.SwingUtilities; +import fourthline.mabiicco.IFileState; import fourthline.mabiicco.MabiIccoProperties; import fourthline.mabiicco.midi.MabiDLS; import fourthline.mabiicco.ui.editor.IEditAlign; @@ -46,7 +47,7 @@ public final class ColumnPanel extends JPanel implements MouseListener, MouseMot private final JPopupMenu popupMenu = new JPopupMenu(); private final ArrayList markerEditor = new ArrayList<>(); - public ColumnPanel(PianoRollView pianoRollView, IMMLManager mmlManager, IEditAlign editAlign) { + public ColumnPanel(PianoRollView pianoRollView, IMMLManager mmlManager, IEditAlign editAlign, IFileState fileState) { super(); this.pianoRollView = pianoRollView; this.mmlManager = mmlManager; @@ -54,8 +55,8 @@ public ColumnPanel(PianoRollView pianoRollView, IMMLManager mmlManager, IEditAli addMouseListener(this); addMouseMotionListener(this); - markerEditor.add( new MMLTempoEditor(mmlManager, editAlign) ); - markerEditor.add( new MarkerEditor(mmlManager, editAlign) ); + markerEditor.add( new MMLTempoEditor(mmlManager, editAlign, fileState) ); + markerEditor.add( new MarkerEditor(mmlManager, editAlign, fileState) ); // popupMenu に各MenuItemを登録する. markerEditor.forEach(t -> t.getMenuItems().forEach(popupMenu::add)); diff --git a/src/fourthline/mabiicco/ui/MMLSeqView.java b/src/fourthline/mabiicco/ui/MMLSeqView.java index 70aed48a..35047ed7 100644 --- a/src/fourthline/mabiicco/ui/MMLSeqView.java +++ b/src/fourthline/mabiicco/ui/MMLSeqView.java @@ -88,9 +88,9 @@ public MMLSeqView() { panel.add(tabbedPane, BorderLayout.SOUTH); // create mml editor - editor = new MMLEditor(keyboardView, pianoRollView, this); + editor = new MMLEditor(keyboardView, pianoRollView, this, undoEdit); pianoRollView.addMouseInputListener(editor); - columnView = new ColumnPanel(pianoRollView, this, editor); + columnView = new ColumnPanel(pianoRollView, this, editor, undoEdit); scrollPane.setRowHeaderView(keyboardView); scrollPane.setColumnHeaderView(columnView); diff --git a/src/fourthline/mabiicco/ui/editor/AbstractMarkerEditor.java b/src/fourthline/mabiicco/ui/editor/AbstractMarkerEditor.java index ac875e4d..d64695fc 100644 --- a/src/fourthline/mabiicco/ui/editor/AbstractMarkerEditor.java +++ b/src/fourthline/mabiicco/ui/editor/AbstractMarkerEditor.java @@ -12,8 +12,10 @@ import javax.swing.JMenuItem; import fourthline.mabiicco.AppResource; +import fourthline.mabiicco.IFileState; import fourthline.mabiicco.ui.IMMLManager; import fourthline.mmlTools.MMLEvent; +import fourthline.mmlTools.UndefinedTickException; /** * Marker (for MMLEvent) Editor @@ -37,18 +39,20 @@ public abstract class AbstractMarkerEditor implements IMarke protected final String deleteCommand; private final IEditAlign editAlign; + private final IFileState fileState; protected final IMMLManager mmlManager; protected T targetEvent; protected int targetTick; - public AbstractMarkerEditor(String suffix, IMMLManager mmlManager, IEditAlign editAlign) { + public AbstractMarkerEditor(String suffix, IMMLManager mmlManager, IEditAlign editAlign, IFileState fileState) { this.suffix = suffix; this.insertCommand = "insert_" + suffix; this.editCommand = "edit_" + suffix; this.deleteCommand = "delete_" + suffix; this.mmlManager = mmlManager; this.editAlign = editAlign; + this.fileState = fileState; insertMenu = newMenuItem(AppResource.appText("edit."+insertCommand)); insertMenu.setActionCommand(insertCommand); @@ -99,8 +103,8 @@ private T getTempoEventOnTick(int baseTick, int delta) { } @Override - public void actionPerformed(ActionEvent e) { - String actionCommand = e.getActionCommand(); + public void actionPerformed(ActionEvent event) { + String actionCommand = event.getActionCommand(); if (actionCommand.equals(insertCommand)) { insertAction(); } else if (actionCommand.equals(editCommand)) { @@ -108,7 +112,12 @@ public void actionPerformed(ActionEvent e) { } else if (actionCommand.equals(deleteCommand)) { deleteAction(); } - + + try { + mmlManager.getMMLScore().generateAll(); + } catch (UndefinedTickException e) { + fileState.revertState(); + } mmlManager.updateActivePart(); } diff --git a/src/fourthline/mabiicco/ui/editor/MMLEditor.java b/src/fourthline/mabiicco/ui/editor/MMLEditor.java index 485d6a31..e938a8c5 100644 --- a/src/fourthline/mabiicco/ui/editor/MMLEditor.java +++ b/src/fourthline/mabiicco/ui/editor/MMLEditor.java @@ -22,6 +22,7 @@ import fourthline.mabiicco.AppResource; import fourthline.mabiicco.IEditState; import fourthline.mabiicco.IEditStateObserver; +import fourthline.mabiicco.IFileState; import fourthline.mabiicco.midi.MabiDLS; import fourthline.mabiicco.ui.IMMLManager; import fourthline.mabiicco.ui.KeyboardView; @@ -54,6 +55,7 @@ public final class MMLEditor implements MouseInputListener, IEditState, IEditCon private final PianoRollView pianoRollView; private final KeyboardView keyboardView; private final IMMLManager mmlManager; + private final IFileState fileState; private final JPopupMenu popupMenu = new JPopupMenu(); @@ -86,10 +88,11 @@ public static NoteAlign[] createAlignList() { return list.toArray(new NoteAlign[list.size()]); } - public MMLEditor(KeyboardView keyboard, PianoRollView pianoRoll, IMMLManager mmlManager) { + public MMLEditor(KeyboardView keyboard, PianoRollView pianoRoll, IMMLManager mmlManager, IFileState fileState) { this.keyboardView = keyboard; this.pianoRollView = pianoRoll; this.mmlManager = mmlManager; + this.fileState = fileState; pianoRoll.setSelectNote(selectedNote); @@ -168,6 +171,19 @@ private void selectMultipleNote(MMLNoteEvent noteEvent1, MMLNoteEvent noteEvent2 } } + /** + * 編集結果をMML文字列に反映させる. 失敗時はREVERT. + */ + private void mmlGenerate() { + try { + mmlManager.getMMLScore().generateAll(); + } catch (UndefinedTickException e) { + System.out.println("REVERT: " + e.getMessage()); + fileState.revertState(); + } + mmlManager.updateActivePart(); + } + /** * @param point nullのときはクリアする. */ @@ -281,7 +297,7 @@ public void applyEditNote(boolean select) { if (!select) { selectNote(null); } - mmlManager.updateActivePart(); + mmlGenerate(); keyboardView.offNote(); } @@ -460,7 +476,7 @@ public void paste(long startTick) { } editObserver.notifyUpdateEditState(); - mmlManager.updateActivePart(); + mmlGenerate(); } @Override @@ -473,7 +489,7 @@ public void selectedCut() { selectNote(null); editObserver.notifyUpdateEditState(); - mmlManager.updateActivePart(); + mmlGenerate(); } @Override @@ -494,7 +510,7 @@ public void selectedDelete() { selectNote(null); editObserver.notifyUpdateEditState(); - mmlManager.updateActivePart(); + mmlGenerate(); } @Override @@ -504,7 +520,7 @@ public void noteProperty() { } new MMLNotePropertyPanel(selectedNote.toArray(new MMLNoteEvent[selectedNote.size()]), editEventList).showDialog(); - mmlManager.updateActivePart(); + mmlGenerate(); } public void changePart(MMLEventList from, MMLEventList to, boolean useSelectedNoteList, ChangePartAction action) { diff --git a/src/fourthline/mabiicco/ui/editor/MMLScoreUndoEdit.java b/src/fourthline/mabiicco/ui/editor/MMLScoreUndoEdit.java index 61890da8..5a7aca67 100644 --- a/src/fourthline/mabiicco/ui/editor/MMLScoreUndoEdit.java +++ b/src/fourthline/mabiicco/ui/editor/MMLScoreUndoEdit.java @@ -62,6 +62,12 @@ public void saveState() { System.out.println("saveState() "+undoState.size()); } + @Override + public void revertState() { + MMLScore score = mmlManager.getMMLScore(); + score.putObjectState(undoState.lastElement()); + } + @Override public void undo() throws CannotUndoException { super.undo(); diff --git a/src/fourthline/mabiicco/ui/editor/MMLTempoEditor.java b/src/fourthline/mabiicco/ui/editor/MMLTempoEditor.java index ffcd0cb9..785e4570 100644 --- a/src/fourthline/mabiicco/ui/editor/MMLTempoEditor.java +++ b/src/fourthline/mabiicco/ui/editor/MMLTempoEditor.java @@ -14,6 +14,7 @@ import javax.swing.SpinnerNumberModel; import fourthline.mabiicco.AppResource; +import fourthline.mabiicco.IFileState; import fourthline.mabiicco.ui.IMMLManager; import fourthline.mmlTools.MMLTempoEvent; @@ -27,8 +28,8 @@ */ public final class MMLTempoEditor extends AbstractMarkerEditor { - public MMLTempoEditor(IMMLManager mmlManager, IEditAlign editAlign) { - super("tempo", mmlManager, editAlign); + public MMLTempoEditor(IMMLManager mmlManager, IEditAlign editAlign, IFileState fileState) { + super("tempo", mmlManager, editAlign, fileState); } private int showTempoInputDialog(String title, int tempo) { diff --git a/src/fourthline/mabiicco/ui/editor/MMLTranspose.java b/src/fourthline/mabiicco/ui/editor/MMLTranspose.java index 8fc0e85d..cf5498fe 100644 --- a/src/fourthline/mabiicco/ui/editor/MMLTranspose.java +++ b/src/fourthline/mabiicco/ui/editor/MMLTranspose.java @@ -14,14 +14,22 @@ import javax.swing.SpinnerNumberModel; import fourthline.mabiicco.AppResource; +import fourthline.mabiicco.IFileState; import fourthline.mabiicco.midi.InstType; import fourthline.mabiicco.midi.MabiDLS; import fourthline.mabiicco.ui.IMMLManager; import fourthline.mmlTools.MMLEventList; import fourthline.mmlTools.MMLNoteEvent; import fourthline.mmlTools.MMLTrack; +import fourthline.mmlTools.UndefinedTickException; public final class MMLTranspose { + private final IFileState fileState; + + public MMLTranspose(IFileState fileState) { + this.fileState = fileState; + } + public void execute(Frame parentFrame, IMMLManager mmlManager) { int transpose = showTransposeDialog(parentFrame); if (transpose == 0) { @@ -41,6 +49,11 @@ public void execute(Frame parentFrame, IMMLManager mmlManager) { } } + try { + mmlManager.getMMLScore().generateAll(); + } catch (UndefinedTickException e) { + fileState.revertState(); + } mmlManager.updateActivePart(); } diff --git a/src/fourthline/mabiicco/ui/editor/MarkerEditor.java b/src/fourthline/mabiicco/ui/editor/MarkerEditor.java index 658a1924..25555bf7 100644 --- a/src/fourthline/mabiicco/ui/editor/MarkerEditor.java +++ b/src/fourthline/mabiicco/ui/editor/MarkerEditor.java @@ -13,6 +13,7 @@ import javax.swing.JTextField; import fourthline.mabiicco.AppResource; +import fourthline.mabiicco.IFileState; import fourthline.mabiicco.ui.IMMLManager; import fourthline.mmlTools.Marker; @@ -27,8 +28,8 @@ */ public final class MarkerEditor extends AbstractMarkerEditor { - public MarkerEditor(IMMLManager mmlManager, IEditAlign editAlign) { - super("marker", mmlManager, editAlign); + public MarkerEditor(IMMLManager mmlManager, IEditAlign editAlign, IFileState fileState) { + super("marker", mmlManager, editAlign, fileState); } private String showTextInputDialog(String title, String text) { diff --git a/src/fourthline/mmlTools/MMLEvent.java b/src/fourthline/mmlTools/MMLEvent.java index cd043e96..a0cf6288 100644 --- a/src/fourthline/mmlTools/MMLEvent.java +++ b/src/fourthline/mmlTools/MMLEvent.java @@ -30,5 +30,5 @@ public int getTickOffset() { public abstract String toString(); - public abstract String toMMLString(); + public abstract String toMMLString() throws UndefinedTickException; } diff --git a/src/fourthline/mmlTools/MMLEventList.java b/src/fourthline/mmlTools/MMLEventList.java index 678c59a6..2e37e87a 100644 --- a/src/fourthline/mmlTools/MMLEventList.java +++ b/src/fourthline/mmlTools/MMLEventList.java @@ -205,15 +205,16 @@ public void deleteMMLEvent(MMLEvent deleteItem) { noteList.remove(deleteItem); } - public String toMMLString() { + public String toMMLString() throws UndefinedTickException { return toMMLString(false, 0, true); } - public String toMMLString(boolean withTempo, boolean mabiTempo) { + public String toMMLString(boolean withTempo, boolean mabiTempo) throws UndefinedTickException { return toMMLString(withTempo, 0, mabiTempo); } - private MMLNoteEvent insertTempoMML(StringBuilder sb, MMLNoteEvent prevNoteEvent, MMLTempoEvent tempoEvent, boolean mabiTempo) { + private MMLNoteEvent insertTempoMML(StringBuilder sb, MMLNoteEvent prevNoteEvent, MMLTempoEvent tempoEvent, boolean mabiTempo) + throws UndefinedTickException { if (prevNoteEvent.getEndTick() != tempoEvent.getTickOffset()) { int tickLength = tempoEvent.getTickOffset() - prevNoteEvent.getEndTick(); int tickOffset = prevNoteEvent.getEndTick(); @@ -225,12 +226,12 @@ private MMLNoteEvent insertTempoMML(StringBuilder sb, MMLNoteEvent prevNoteEvent if (prevNoteEvent.getVelocity() != 0) { sb.append("v0"); } - sb.append(ticks.toString()); + sb.append(ticks.toMMLText()); prevNoteEvent = new MMLNoteEvent(note, tickLength, tickOffset, 0); } else { MMLTicks ticks = new MMLTicks("r", tickLength, false); prevNoteEvent = new MMLNoteEvent(prevNoteEvent.getNote(), tickLength, tickOffset, prevNoteEvent.getVelocity()); - sb.append(ticks.toString()); + sb.append(ticks.toMMLText()); } } sb.append(tempoEvent.toMMLString()); @@ -245,7 +246,8 @@ private MMLNoteEvent insertTempoMML(StringBuilder sb, MMLNoteEvent prevNoteEvent * @param totalTick 最大tick長. これに満たない場合は、末尾を休符分で埋めます. * @return */ - public String toMMLString(boolean withTempo, int totalTick, boolean mabiTempo) { + public String toMMLString(boolean withTempo, int totalTick, boolean mabiTempo) + throws UndefinedTickException { // テンポ Iterator tempoIterator = null; MMLTempoEvent tempoEvent = null; diff --git a/src/fourthline/mmlTools/MMLNoteEvent.java b/src/fourthline/mmlTools/MMLNoteEvent.java index 8b0cf513..948e5f0c 100644 --- a/src/fourthline/mmlTools/MMLNoteEvent.java +++ b/src/fourthline/mmlTools/MMLNoteEvent.java @@ -93,17 +93,17 @@ private String getNoteName() { } @Override - public String toMMLString() { + public String toMMLString() throws UndefinedTickException { String noteName = getNoteName(); MMLTicks mmlTick = new MMLTicks(noteName, tick); if (isTuningNote) { - return mmlTick.toStringByL64(); + return mmlTick.toMMLTextByL64(); } else { - return mmlTick.toString(); + return mmlTick.toMMLText(); } } - public String toMMLString(MMLNoteEvent prevNoteEvent) { + public String toMMLString(MMLNoteEvent prevNoteEvent) throws UndefinedTickException { StringBuilder sb = new StringBuilder(); // 前のノートとの差を見て、休符を挿入する. @@ -122,11 +122,11 @@ public String toMMLString(MMLNoteEvent prevNoteEvent) { * @param prevNoteEvent * @return */ - private String createMMLSpaceString(MMLNoteEvent prevNoteEvent) { + private String createMMLSpaceString(MMLNoteEvent prevNoteEvent) throws UndefinedTickException { int noteSpaceTick = getTickOffset() - prevNoteEvent.getEndTick(); if ( noteSpaceTick > 0 ) { MMLTicks mmlTick = new MMLTicks("r", noteSpaceTick, false); - return mmlTick.toString(); + return mmlTick.toMMLText(); } return ""; diff --git a/src/fourthline/mmlTools/MMLScore.java b/src/fourthline/mmlTools/MMLScore.java index fbd99c7f..b096eb7a 100644 --- a/src/fourthline/mmlTools/MMLScore.java +++ b/src/fourthline/mmlTools/MMLScore.java @@ -298,6 +298,11 @@ public MMLScore parse(InputStream istream) throws MMLParseException { parseMarker(section.getContents()); } } + try { + generateAll(); + } catch (UndefinedTickException e) { + throw new MMLParseException(e.getMessage()); + } return this; } @@ -334,7 +339,7 @@ private void parseMarker(String contents) { } } - public MMLScore generateAll() { + public MMLScore generateAll() throws UndefinedTickException { for (MMLTrack track : trackList) { track.generate(); } diff --git a/src/fourthline/mmlTools/MMLTrack.java b/src/fourthline/mmlTools/MMLTrack.java index 6fec0e14..5f0f3f56 100644 --- a/src/fourthline/mmlTools/MMLTrack.java +++ b/src/fourthline/mmlTools/MMLTrack.java @@ -69,7 +69,7 @@ public boolean isEmpty() { public String getOriginalMML() { return originalMML.getMML(); } - + public String getMabiMML() { return mabiMML.getMML(); } @@ -167,13 +167,13 @@ public long getMaxTickLength() { return max; } - public MMLTrack generate() { + public MMLTrack generate() throws UndefinedTickException { originalMML.setMMLText(getMMLStrings(false, false)); mabiMML.setMMLText(getMMLStrings(true, true)); return this; } - - private String[] getMMLStrings(boolean tailFix, boolean mabiTempo) { + + private String[] getMMLStrings(boolean tailFix, boolean mabiTempo) throws UndefinedTickException { int count = mmlParts.size(); String mml[] = new String[count]; int totalTick = (int)this.getMaxTickLength(); @@ -201,18 +201,18 @@ private String[] getMMLStrings(boolean tailFix, boolean mabiTempo) { return mml; } - private String tailFix(String s) { + private String tailFix(String s) throws UndefinedTickException { long totalTick = this.getMaxTickLength(); double playTime = getPlayTime(); double mmlTime = getMabinogiTime(); int tick = (int)(totalTick - new MMLEventList(s).getTickLength()); if (playTime > mmlTime) { // スキルが演奏の途中で止まるのを防ぎます. - s += new MMLTicks("r", tick, false).toString(); + s += new MMLTicks("r", tick, false).toMMLText(); } else if (playTime < mmlTime) { // 演奏が終ってスキルが止まらないのを防ぎます. if (tick > 0) { - s += new MMLTicks("r", tick, false).toString() + "v0c64"; + s += new MMLTicks("r", tick, false).toMMLText() + "v0c64"; } s += MMLTempoEvent.getMaxTempoEvent(globalTempoList).toMMLString(); } diff --git a/src/fourthline/mmlTools/core/MMLTicks.java b/src/fourthline/mmlTools/core/MMLTicks.java index d4ffcd69..f76f3870 100644 --- a/src/fourthline/mmlTools/core/MMLTicks.java +++ b/src/fourthline/mmlTools/core/MMLTicks.java @@ -232,74 +232,64 @@ private String mmlNotePart(String phoneticString) { /** * noteNameとtickをMMLの文字列に変換します. * needTieがtrueのときは、'&'による連結を行います. + * @throws UndefinedTickException */ - public String toString() { - try { - int remTick = tick; - StringBuilder sb = new StringBuilder(); + public String toMMLText() throws UndefinedTickException { + int remTick = tick; + StringBuilder sb = new StringBuilder(); - // "1." - int mTick = getTick("1."); - int tick1 = getTick("1"); - while (remTick > (tick1*2)) { - sb.append( mmlNotePart("1.") ); - remTick -= mTick; - } + // "1." + int mTick = getTick("1."); + int tick1 = getTick("1"); + while (remTick > (tick1*2)) { + sb.append( mmlNotePart("1.") ); + remTick -= mTick; + } - // 1~64の分割 - for (int base = 1; base <= 64; base *= 2) { - int baseTick = getTick(""+base); - if (tickInvTable.containsKey(remTick)) { - sb.append( mmlNotePart(tickInvTable.get(remTick)) ); - remTick = 0; - break; - } - while (remTick >= baseTick) { - sb.append( mmlNotePart(""+base) ); - remTick -= baseTick; - } - } - if (remTick > 0) { - sb.append( mmlNotePart(tickInvTable.get(minimumTick())) ); + // 1~64の分割 + for (int base = 1; base <= 64; base *= 2) { + int baseTick = getTick(""+base); + if (tickInvTable.containsKey(remTick)) { + sb.append( mmlNotePart(tickInvTable.get(remTick)) ); + remTick = 0; + break; } - - if (needTie) { - return sb.substring(1); - } else { - return sb.toString(); + while (remTick >= baseTick) { + sb.append( mmlNotePart(""+base) ); + remTick -= baseTick; } - } catch (UndefinedTickException e) { - e.printStackTrace(); + } + if (remTick > 0) { + throw new UndefinedTickException(remTick + "/" + tick); } - return null; + if (needTie) { + return sb.substring(1); + } else { + return sb.toString(); + } } /** * L64を使って変換します. (調律用) * @return + * @throws UndefinedTickException */ - public String toStringByL64() { - try { - int remTick = tick; - StringBuilder sb = new StringBuilder(); - - int base = 64; - int baseTick = getTick(""+base); - while (remTick >= baseTick) { - sb.append( mmlNotePart(""+base) ); - remTick -= baseTick; - } + public String toMMLTextByL64() throws UndefinedTickException { + int remTick = tick; + StringBuilder sb = new StringBuilder(); - if (needTie) { - return sb.substring(1); - } else { - return sb.toString(); - } - } catch (UndefinedTickException e) { - e.printStackTrace(); + int base = 64; + int baseTick = getTick(""+base); + while (remTick >= baseTick) { + sb.append( mmlNotePart(""+base) ); + remTick -= baseTick; } - return null; + if (needTie) { + return sb.substring(1); + } else { + return sb.toString(); + } } } diff --git a/test/fourthline/mmlTools/MMLEventListTest.java b/test/fourthline/mmlTools/MMLEventListTest.java index 76f6215a..79a8ee4f 100644 --- a/test/fourthline/mmlTools/MMLEventListTest.java +++ b/test/fourthline/mmlTools/MMLEventListTest.java @@ -222,7 +222,7 @@ public void testSearchPrevNoteOnTickOffset() throws UndefinedTickException { } @Test - public void testToMMLString_0() { + public void testToMMLString_0() throws UndefinedTickException { MMLEventList eventList = new MMLEventList("ara"); String mml = eventList.toMMLString(); @@ -233,9 +233,10 @@ public void testToMMLString_0() { /** * オクターブ変化を付けたMMLの双方向変換のテスト. + * @throws UndefinedTickException */ @Test - public void testToMMLString_1() { + public void testToMMLString_1() throws UndefinedTickException { MMLEventList eventList = new MMLEventList("cdef-gab>cdef+gab+ globalTempoList = new ArrayList(); String expectMML = "c8t150&c8d4"; @@ -289,9 +293,10 @@ public void testToMMLString_4() { /** * tempo, velocity を含むMML. (テンポ指定が最終ノートより後方にある) + * @throws UndefinedTickException */ @Test - public void testToMMLString_5() { + public void testToMMLString_5() throws UndefinedTickException { MMLEventList eventList = new MMLEventList("c4d4"); String expectMML = "c4d4v0c1.c1.t150"; List globalTempoList = new ArrayList(); @@ -306,9 +311,10 @@ public void testToMMLString_5() { /** * tempo, velocity を含むMML. (rTn式) + * @throws UndefinedTickException */ @Test - public void testToMMLString_7() { + public void testToMMLString_7() throws UndefinedTickException { MMLEventList eventList = new MMLEventList("c1r1t150c1"); String expectMML = "c1v0c1t150v8c1"; @@ -320,9 +326,10 @@ public void testToMMLString_7() { /** * tempo, velocity を含むMML. (r前のv) + * @throws UndefinedTickException */ @Test - public void testToMMLString_8() { + public void testToMMLString_8() throws UndefinedTickException { MMLEventList eventList = new MMLEventList("v12rc"); String expectMML = "v12r4c4"; @@ -334,9 +341,10 @@ public void testToMMLString_8() { /** * 調律符の判定テスト. + * @throws UndefinedTickException */ @Test - public void testTuningNote() { + public void testTuningNote() throws UndefinedTickException { MMLEventList eventList = new MMLEventList("c64&c64&c64&c64"); String expectMML = "c64&c64&c64&c64"; @@ -372,9 +380,10 @@ public void testBottomOctave() { /** * テンポ+休符のテスト. + * @throws UndefinedTickException */ @Test - public void testTempoAndR() { + public void testTempoAndR() throws UndefinedTickException { MMLEventList eventList = new MMLEventList("v12t110rt60rt90c"); String expectMML = "t110v0c4t60c4t90v12c4"; @@ -512,9 +521,10 @@ public void testAlignmentEndTick3() { /** * swap + * @throws UndefinedTickException */ @Test - public void testSwap0() { + public void testSwap0() throws UndefinedTickException { MMLEventList eventList1 = new MMLEventList("rcrc"); MMLEventList eventList2 = new MMLEventList("r.c2"); @@ -532,9 +542,10 @@ public void testSwap0() { /** * move + * @throws UndefinedTickException */ @Test - public void testMove0() { + public void testMove0() throws UndefinedTickException { MMLEventList eventList1 = new MMLEventList("rcrc"); MMLEventList eventList2 = new MMLEventList("r.c2"); @@ -551,9 +562,10 @@ public void testMove0() { /** * copy + * @throws UndefinedTickException */ @Test - public void testCopy0() { + public void testCopy0() throws UndefinedTickException { MMLEventList eventList1 = new MMLEventList("rcrc"); MMLEventList eventList2 = new MMLEventList("r.c2"); diff --git a/test/fourthline/mmlTools/MMLNoteEventTest.java b/test/fourthline/mmlTools/MMLNoteEventTest.java index da79b466..599c68c8 100644 --- a/test/fourthline/mmlTools/MMLNoteEventTest.java +++ b/test/fourthline/mmlTools/MMLNoteEventTest.java @@ -51,7 +51,7 @@ public void testDecreaseOctave() { } @Test - public void testTuningNote() { + public void testTuningNote() throws UndefinedTickException { MMLEventList eventList = new MMLEventList("c1"); String expected = "c64&c64&c64&c64&c64&c64&c64&c64&c64&c64&c64&c64&c64&c64&c64&c64&c64&c64&c64&c64&c64&c64&c64&c64&c64&c64&c64&c64&c64&c64&c64&c64&c64&c64&c64&c64&c64&c64&c64&c64&c64&c64&c64&c64&c64&c64&c64&c64&c64&c64&c64&c64&c64&c64&c64&c64&c64&c64&c64&c64&c64&c64&c64&c64"; MMLNoteEvent noteEvent = eventList.getMMLNoteEventList().get(0); diff --git a/test/fourthline/mmlTools/MMLScoreTest.java b/test/fourthline/mmlTools/MMLScoreTest.java index 42b54c44..cef68c13 100644 --- a/test/fourthline/mmlTools/MMLScoreTest.java +++ b/test/fourthline/mmlTools/MMLScoreTest.java @@ -60,7 +60,7 @@ private void checkMMLFileOutput(MMLScore score, String expectFileName, String ex } @Test - public void testMMLFileFormat0() { + public void testMMLFileFormat0() throws UndefinedTickException { MMLScore score = new MMLScore(); MMLTrack track = new MMLTrack().setMML("MML@aaa,bbb,ccc,dd1;"); track.setTrackName("track1"); @@ -73,7 +73,7 @@ public void testMMLFileFormat0() { } @Test - public void testMMLFileFormat1() { + public void testMMLFileFormat1() throws UndefinedTickException { MMLScore score = new MMLScore(); MMLTrack track1 = new MMLTrack().setMML("MML@at150aa1,bbb,ccc,dd1;"); track1.setTrackName("track1"); @@ -93,7 +93,7 @@ public void testMMLFileFormat1() { } @Test - public void testMMLFileFormat_r0() { + public void testMMLFileFormat_r0() throws UndefinedTickException { MMLScore score = new MMLScore(); MMLTrack track = new MMLTrack().setMML("MML@r1t180c8;"); track.setTrackName("track1"); @@ -105,7 +105,7 @@ public void testMMLFileFormat_r0() { } @Test - public void testMMLFileFormat_r1() { + public void testMMLFileFormat_r1() throws UndefinedTickException { MMLScore score = new MMLScore(); MMLTrack track1 = new MMLTrack().setMML("MML@r1>f+1t120&f+1;"); track1.setTrackName("track1"); diff --git a/test/fourthline/mmlTools/MMLTrackTest.java b/test/fourthline/mmlTools/MMLTrackTest.java index 29d25f08..daa5810c 100644 --- a/test/fourthline/mmlTools/MMLTrackTest.java +++ b/test/fourthline/mmlTools/MMLTrackTest.java @@ -18,9 +18,10 @@ public class MMLTrackTest { /** * Test method for {@link fourthline.mmlTools.MMLTrack#getMMLStrings()}. + * @throws UndefinedTickException */ @Test - public void testGetMMLStrings() { + public void testGetMMLStrings() throws UndefinedTickException { MMLTrack track = new MMLTrack().setMML("MML@aaa,bbb,ccc,ddd;"); String expect[] = { "a8t150&a8aa", // melodyパートのみテンポ指定. @@ -130,10 +131,11 @@ public void testPlayingLong2MML() throws Exception { } /** - * テンポを跨ぐ場合の分割Tick-Undefined(最小Tick近似) + * テンポを跨ぐ場合の分割Tick-Undefined(最小Tick近似) = Exception + * @throws UndefinedTickException */ - @Test - public void testGeneric00() { + @Test(expected=UndefinedTickException.class) + public void testGeneric00() throws UndefinedTickException { String mml = "MML@ggt150gg,rr8r16.a24aa;"; String expectMML = "MML@ggt150ggr64,rr8r16.a32&a64aa,;"; diff --git a/test/fourthline/mmlTools/parser/MMLFileTest.java b/test/fourthline/mmlTools/parser/MMLFileTest.java index 80c8f7ac..ce89514d 100644 --- a/test/fourthline/mmlTools/parser/MMLFileTest.java +++ b/test/fourthline/mmlTools/parser/MMLFileTest.java @@ -19,6 +19,7 @@ import fourthline.mabiicco.midi.MabiDLS; import fourthline.mmlTools.MMLScore; import fourthline.mmlTools.MMLScoreTest; +import fourthline.mmlTools.UndefinedTickException; public class MMLFileTest extends FileSelect { @@ -50,7 +51,7 @@ public final void testParse() { InputStream inputStream = fileSelect("sample2.mmi"); MMLScoreTest.checkMMLScoreWriteToOutputStream(score.generateAll(), inputStream); - } catch (MMLParseException | IOException e) { + } catch (MMLParseException | UndefinedTickException | IOException e) { fail(e.getMessage()); } }