package org.herac.tuxguitar.gui.actions.note;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.TypedEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Spinner;
import org.herac.tuxguitar.gui.TuxGuitar;
import org.herac.tuxguitar.gui.actions.Action;
import org.herac.tuxguitar.gui.actions.ActionLock;
import org.herac.tuxguitar.gui.editors.tab.Caret;
import org.herac.tuxguitar.gui.undo.undoables.track.UndoableTrackGeneric;
import org.herac.tuxguitar.gui.util.DialogUtils;
import org.herac.tuxguitar.gui.util.MessageDialog;
import org.herac.tuxguitar.song.models.TGBeat;
import org.herac.tuxguitar.song.models.TGDivisionType;
import org.herac.tuxguitar.song.models.TGDuration;
import org.herac.tuxguitar.song.models.TGMeasure;
import org.herac.tuxguitar.song.models.TGTrack;
import org.herac.tuxguitar.util.TGSynchronizer;
public class MoveBeatsCustomAction extends Action {
protected static class ComboItem {
private String label;
private Object value;
public ComboItem(String label, Object value) {
this.label = label;
this.value = value;
}
public String getLabel() {
return this.label;
}
public Object getValue() {
return this.value;
}
}
private static final ComboItem[] MOVE_DIRECTIONS = new ComboItem[] {
new ComboItem(TuxGuitar
.getProperty("beat.move-custom.dialog.direction.right"), new Integer(
1)),
new ComboItem(TuxGuitar
.getProperty("beat.move-custom.dialog.direction.left"), new Integer(
-1)), };
private static final ComboItem[] MOVE_DURATION_DIVISIONS = new ComboItem[] {
new ComboItem(
TuxGuitar
.getProperty("beat.move-custom.dialog.duration.division-type.normal"),
new int[] { 1, 1 }), new ComboItem("3", new int[] { 3, 2 }),
new ComboItem("5", new int[] { 5, 4 }),
new ComboItem("6", new int[] { 6, 4 }),
new ComboItem("7", new int[] { 7, 4 }),
new ComboItem("9", new int[] { 9, 8 }),
new ComboItem("10", new int[] { 10, 8 }),
new ComboItem("11", new int[] { 11, 8 }),
new ComboItem("12", new int[] { 12, 8 }), };
private static final ComboItem[] MOVE_DURATION_TYPES = new ComboItem[] {
new ComboItem(TuxGuitar
.getProperty("beat.move-custom.dialog.duration.type.normal"),
new boolean[] { false, false }),
new ComboItem(TuxGuitar.getProperty("duration.dotted"), new boolean[] {
true, false }),
new ComboItem(TuxGuitar.getProperty("duration.doubledotted"),
new boolean[] { false, true }), };
private static final ComboItem[] MOVE_DURATIONS = new ComboItem[] {
new ComboItem(TuxGuitar.getProperty("duration.whole"), new Integer(
TGDuration.WHOLE)),
new ComboItem(TuxGuitar.getProperty("duration.half"), new Integer(
TGDuration.HALF)),
new ComboItem(TuxGuitar.getProperty("duration.quarter"), new Integer(
TGDuration.QUARTER)),
new ComboItem(TuxGuitar.getProperty("duration.eighth"), new Integer(
TGDuration.EIGHTH)),
new ComboItem(TuxGuitar.getProperty("duration.sixteenth"), new Integer(
TGDuration.SIXTEENTH)),
new ComboItem(TuxGuitar.getProperty("duration.thirtysecond"),
new Integer(TGDuration.THIRTY_SECOND)),
new ComboItem(TuxGuitar.getProperty("duration.sixtyfourth"), new Integer(
TGDuration.SIXTY_FOURTH)), };
public static final String NAME = "action.beat.general.move-custom";
public MoveBeatsCustomAction() {
super(NAME, AUTO_LOCK | AUTO_UNLOCK | AUTO_UPDATE | DISABLE_ON_PLAYING
| KEY_BINDING_AVAILABLE);
}
@Override
protected int execute(TypedEvent e) {
this.showDialog(getEditor().getTablature().getShell());
return 0;
}
protected GridData getButtonData() {
GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
data.minimumWidth = 80;
data.minimumHeight = 25;
return data;
}
protected int getDirection(int index) {
if (index >= 0 && index < MOVE_DIRECTIONS.length) {
return ((Integer) MOVE_DIRECTIONS[index].getValue()).intValue();
}
return 0;
}
protected long getDuration1(int index, int count) {
if (count > 0 && index >= 0 && index < MOVE_DURATIONS.length) {
TGDuration duration = new TGDuration();
duration
.setValue(((Integer) MOVE_DURATIONS[index].getValue()).intValue());
duration.setDotted(false);
duration.setDoubleDotted(false);
duration.setDivision(TGDivisionType.NORMAL);
return (duration.getTime() * count);
}
return 0;
}
protected long getDuration2(int index, int indexType, int indexDivision,
int count) {
if (count > 0 && index >= 0 && index < MOVE_DURATIONS.length) {
if (indexType >= 0 && indexType < MOVE_DURATION_TYPES.length
&& indexDivision >= 0
&& indexDivision < MOVE_DURATION_DIVISIONS.length) {
TGDuration duration = new TGDuration();
duration.setValue(((Integer) MOVE_DURATIONS[index].getValue())
.intValue());
duration.setDotted(((boolean[]) MOVE_DURATION_TYPES[indexType]
.getValue())[0]);
duration.setDoubleDotted(((boolean[]) MOVE_DURATION_TYPES[indexType]
.getValue())[1]);
final int enters = ((int[]) MOVE_DURATION_DIVISIONS[indexDivision]
.getValue())[0];
final int times = ((int[]) MOVE_DURATION_DIVISIONS[indexDivision]
.getValue())[1];
duration.setDivision(new TGDivisionType(enters, times));
return (duration.getTime() * count);
}
}
return 0;
}
protected int moveBeats(long theMove) {
Caret caret = getEditor().getTablature().getCaret();
TGBeat beat = caret.getSelectedBeat();
TGMeasure measure = caret.getMeasure();
TGTrack track = caret.getTrack();
if (beat != null && measure != null && track != null) {
// comienza el undoable
UndoableTrackGeneric undoable = UndoableTrackGeneric.startUndo(track);
getSongManager().getTrackManager().moveTrackBeats(track,
measure.getStart(), beat.getStart(), theMove);
// termia el undoable
addUndoableEdit(undoable.endUndo(track));
TuxGuitar.instance().getFileHistory().setUnsavedFile();
updateTablature();
}
return 0;
}
protected void showDialog(Shell shell) {
final Shell dialog = DialogUtils.newDialog(shell, SWT.DIALOG_TRIM
| SWT.APPLICATION_MODAL);
dialog.setLayout(new GridLayout());
dialog.setText(TuxGuitar.getProperty("beat.move-custom.dialog.title"));
// -------direction-------------------------------------
Group direction = new Group(dialog, SWT.SHADOW_ETCHED_IN);
direction.setLayout(new GridLayout(2, false));
direction.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
direction.setText(TuxGuitar
.getProperty("beat.move-custom.dialog.direction-tip"));
Label directionLabel = new Label(direction, SWT.RIGHT);
directionLabel.setText(TuxGuitar
.getProperty("beat.move-custom.dialog.direction")
+ ":");
final Combo directionCombo = new Combo(direction, SWT.DROP_DOWN
| SWT.READ_ONLY);
for (int i = 0; i < MOVE_DIRECTIONS.length; i++) {
directionCombo.add(MOVE_DIRECTIONS[i].getLabel());
}
directionCombo.select(0);
directionCombo.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
// -------move 1------------------------------------------
final List<Control> move1Controls = new ArrayList<Control>();
Group move1 = new Group(dialog, SWT.SHADOW_ETCHED_IN);
move1.setLayout(new GridLayout(2, false));
move1.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
move1.setText(TuxGuitar.getProperty("beat.move-custom.dialog.move-1.tip"));
Label count1Label = new Label(move1, SWT.RIGHT);
count1Label.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, true, true));
count1Label.setText(TuxGuitar.getProperty("beat.move-custom.dialog.count")
+ ":");
final Spinner count1Spinner = new Spinner(move1, SWT.BORDER);
count1Spinner.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
count1Spinner.setMinimum(0);
count1Spinner.setMaximum(100);
count1Spinner.setIncrement(1);
count1Spinner.setSelection(0);
count1Spinner.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
updateControls(count1Spinner.getSelection(), move1Controls);
}
});
Label duration1Label = new Label(move1, SWT.RIGHT);
duration1Label
.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, true, true));
duration1Label.setText(TuxGuitar
.getProperty("beat.move-custom.dialog.duration")
+ ":");
move1Controls.add(duration1Label);
final Combo duration1Combo = new Combo(move1, SWT.DROP_DOWN | SWT.READ_ONLY);
duration1Combo.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
for (int i = 0; i < MOVE_DURATIONS.length; i++) {
duration1Combo.add(MOVE_DURATIONS[i].getLabel());
}
duration1Combo.select(0);
move1Controls.add(duration1Combo);
updateControls(0, move1Controls);
// -------move 2------------------------------------------
final List<Control> move2Controls = new ArrayList<Control>();
Group move2 = new Group(dialog, SWT.SHADOW_ETCHED_IN);
move2.setLayout(new GridLayout(2, false));
move2.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
move2.setText(TuxGuitar.getProperty("beat.move-custom.dialog.move-2.tip"));
Label count2Label = new Label(move2, SWT.RIGHT);
count2Label.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, true, true));
count2Label.setText(TuxGuitar.getProperty("beat.move-custom.dialog.count")
+ ":");
final Spinner count2Spinner = new Spinner(move2, SWT.BORDER);
count2Spinner.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
count2Spinner.setSelection(0);
count2Spinner.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
updateControls(count2Spinner.getSelection(), move2Controls);
}
});
Label duration2Label = new Label(move2, SWT.RIGHT);
duration2Label
.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, true, true));
duration2Label.setText(TuxGuitar
.getProperty("beat.move-custom.dialog.duration")
+ ":");
move2Controls.add(duration2Label);
final Combo duration2Combo = new Combo(move2, SWT.DROP_DOWN | SWT.READ_ONLY);
duration2Combo.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
for (int i = 0; i < MOVE_DURATIONS.length; i++) {
duration2Combo.add(MOVE_DURATIONS[i].getLabel());
}
duration2Combo.select(2);
move2Controls.add(duration2Combo);
Label type2Label = new Label(move2, SWT.RIGHT);
type2Label.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, true, true));
type2Label.setText(TuxGuitar
.getProperty("beat.move-custom.dialog.duration.type")
+ ":");
move2Controls.add(type2Label);
final Combo type2Combo = new Combo(move2, SWT.DROP_DOWN | SWT.READ_ONLY);
type2Combo.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
for (int i = 0; i < MOVE_DURATION_TYPES.length; i++) {
type2Combo.add(MOVE_DURATION_TYPES[i].getLabel());
}
type2Combo.select(0);
move2Controls.add(type2Combo);
Label division2Label = new Label(move2, SWT.RIGHT);
division2Label
.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, true, true));
division2Label.setText(TuxGuitar
.getProperty("beat.move-custom.dialog.duration.division-type")
+ ":");
move2Controls.add(division2Label);
final Combo division2Combo = new Combo(move2, SWT.DROP_DOWN | SWT.READ_ONLY);
division2Combo.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
for (int i = 0; i < MOVE_DURATION_DIVISIONS.length; i++) {
division2Combo.add(MOVE_DURATION_DIVISIONS[i].getLabel());
}
division2Combo.select(0);
move2Controls.add(division2Combo);
updateControls(0, move2Controls);
// ------------------BUTTONS--------------------------
Composite buttons = new Composite(dialog, SWT.NONE);
buttons.setLayout(new GridLayout(2, false));
buttons.setLayoutData(new GridData(SWT.RIGHT, SWT.FILL, true, true));
final Button buttonOK = new Button(buttons, SWT.PUSH);
buttonOK.setText(TuxGuitar.getProperty("ok"));
buttonOK.setLayoutData(getButtonData());
buttonOK.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent arg0) {
final int directionValue = getDirection(directionCombo
.getSelectionIndex());
final long duration1 = getDuration1(duration1Combo.getSelectionIndex(),
count1Spinner.getSelection());
final long duration2 = getDuration2(duration2Combo.getSelectionIndex(),
type2Combo.getSelectionIndex(), division2Combo.getSelectionIndex(),
count2Spinner.getSelection());
final long duration = ((duration1 + duration2) * directionValue);
dialog.dispose();
try {
TGSynchronizer.instance().runLater(new TGSynchronizer.TGRunnable() {
public void run() throws Throwable {
ActionLock.lock();
TuxGuitar.instance().loadCursor(SWT.CURSOR_WAIT);
moveBeats(duration);
TuxGuitar.instance().updateCache(true);
TuxGuitar.instance().loadCursor(SWT.CURSOR_ARROW);
ActionLock.unlock();
}
});
} catch (Throwable throwable) {
MessageDialog.errorMessage(throwable);
}
}
});
Button buttonCancel = new Button(buttons, SWT.PUSH);
buttonCancel.setText(TuxGuitar.getProperty("cancel"));
buttonCancel.setLayoutData(getButtonData());
buttonCancel.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent arg0) {
dialog.dispose();
}
});
dialog.setDefaultButton(buttonOK);
DialogUtils.openDialog(dialog, DialogUtils.OPEN_STYLE_CENTER
| DialogUtils.OPEN_STYLE_PACK | DialogUtils.OPEN_STYLE_WAIT);
}
protected void updateControls(int count, List<Control> controls) {
for (final Control control : controls) {
control.setEnabled(count > 0);
}
}
}