]> ruin.nu Git - moosique.git/commitdiff
Implemented editing functions - biggie!
authorEinar Pehrson <einarp@itstud.chalmers.se>
Mon, 19 May 2003 00:08:36 +0000 (00:08 +0000)
committerEinar Pehrson <einarp@itstud.chalmers.se>
Mon, 19 May 2003 00:08:36 +0000 (00:08 +0000)
Fixed bug in octave changes.

MooDialog.java
MooGUI.java
MooKeyboard.java
MooMenu.java
MooNote.java
MooNoteElement.java
MooTrackTitle.java
MooTrackView.java
Moosique.java
To Do.txt
midi/test3.mid

index 8eb2b8c61fd43c4d5641fb5f111c062560c09cf4..e4f3b0fdb0a6790c7e4556a9433acf37fe61579f 100644 (file)
@@ -26,7 +26,8 @@ public class MooDialog extends JDialog {
                                MANUAL = 6,
                                INSERT_MEASURE = 7,
                                DELETE_MEASURE = 8,
-                               SET_TEMPO = 9;
+                               SET_TEMPO = 9,
+                               PREFERENCES = 10;
        
        /**
         * Constructor of the dialogs.
@@ -49,6 +50,7 @@ public class MooDialog extends JDialog {
                        case INSERT_MEASURE:    makeInsertMeasureDialog(pane); break;
                        case DELETE_MEASURE:    makeDeleteMeasureDialog(pane); break;
                        case SET_TEMPO:         makeSetTempoDialog(pane); break;
+                       case PREFERENCES:       makePrefsDialog(pane); break;
                }
         }
        
@@ -437,6 +439,25 @@ public class MooDialog extends JDialog {
                setVisible(true);
        }
 
+       private void makePrefsDialog(Container pane) {
+               /*              
+               MidiDevice.Info[] devInfo = MidiSystem.getMidiDeviceInfo();
+               for (int i = 0; i < devInfo.length; i++) {
+                       if (MidiSystem.getMidiDevice(devInfo[i]) instanceof Sequencer) {
+                       
+                       } else if (MidiSystem.getMidiDevice(devInfo[i]) instanceof Synthesizer) {
+                       
+                       }
+               }
+               String[] seqNames, synthNames;
+               JPanel pane = (JPanel) this.getContentPane();
+               pane.add(new JLabel("Sequencer"));
+               JComboBox seqBox = new JComboBox(seqNames);
+               pane.add(new JLabel("Synthesizer"));
+               JComboBox synthBox = new JComboBox(synthNames);
+               */
+       }
+
        private MooNote note;
        private JOptionPane optionPane;
        private JTextField pitch;
index 43c553a5d0f11336cb3a1a25f56e5733124ce8b3..490026440350483e48b0f7bfd0aac2a4ab8afeba 100644 (file)
@@ -76,8 +76,8 @@ public class MooGUI extends JFrame {
                                }
                        }};
                am.put("Play", playAction);
-               am.put("Change octave up", createOctaveAction(1));
-               am.put("Change octave down", createOctaveAction(-1));
+               am.put("Change octave up", createOctaveAction(true));
+               am.put("Change octave down", createOctaveAction(false));
 
                InputMap im = getRootPane().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
                KeyStroke playKey = KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0);
@@ -143,12 +143,12 @@ public class MooGUI extends JFrame {
 
        /**
         * Creates an action for a specific octave.
-        * @param octave The octave we want an action for.
+        * @param increase      true for increase, false for decrease
         */
-       private Action createOctaveAction(final int octave) {
+       private Action createOctaveAction(final boolean increase) {
                Action octaveAction = new AbstractAction() {
                        public void actionPerformed(ActionEvent ae) {
-                               MooKeyboard.setOctave(octave);
+                               MooKeyboard.setRelativeOctave(increase);
                        }};
                return octaveAction;
        }
index 5581172e6d10792cbe5d6cbbae30c10b88ce492e..ef4785e67c5081e343983c06d411800dab2e1d1c 100644 (file)
@@ -64,11 +64,24 @@ public class MooKeyboard extends KeyAdapter {
         * @param n     the octave to start at
         */
        public static void setOctave(int n) {
-               if ((startNote == 0 && n == -1) || (startNote == 108 && n == 1)) return;
-               startNote += n*12;
+               startNote = n * 12;
                makeKeyboardMapping();
        }
 
+       /**
+        * Increases or decreases the octave of the lower part of the keyboard (default = 4)
+        * @param increase      true for increase, false for decrease
+        */
+       public static void setRelativeOctave(boolean increase) {
+               if (increase) {
+                       if (startNote == 108) return;
+                       setOctave((startNote/12) + 1);
+               } else {
+                       if (startNote == 0) return;
+                       setOctave((startNote/12) - 1);
+               }
+       }
+
        /** Maps keycodes (array indices) to MIDI note numbers using the following layout:
         *
         *  2 3   5 6 7   9 0   =>  # #   # # #   # #
index 9abc407a9a4222b2a83305737958725c992807b8..d2acd204a49cc932a30679b9e93eadb7a497570c 100644 (file)
@@ -152,7 +152,7 @@ public class MooMenu extends JMenuBar implements ActionListener {
                Sequence seq;
                
                if(command == "New") {
-                       Moosique.clearSequence();
+                       if (!Moosique.promptOnUnsavedChanges()) Moosique.clearSequence();
                } else if (command == "Open...") {
                        // Shows a file chooser. If shown previously, starts in the current directory.
                        if (directory != null) {
index 78e1564064161aac20851980d249eb97771efaf5..023de207da3aa053ffafff81f2febabe076ea996 100644 (file)
@@ -7,19 +7,10 @@ import javax.sound.midi.*;
  * @author  Einar Pehrson
  */
  
-public class MooNote extends MidiEvent {
+public class MooNote extends MidiEvent implements Cloneable {
 
-       protected MidiEvent noteOffEvent;
-       protected ShortMessage noteOnMsg, noteOffMsg;
-
-       /** 
-        * Creates a MooNote from the given NoteOn event in the current track.
-        * @param noteOnEvent   the NoteOn event of the note
-        */
-       public MooNote (MidiEvent noteOnEvent) {
-               super(noteOnEvent.getMessage(), noteOnEvent.getTick());
-               noteOnMsg = (ShortMessage)getMessage();
-       }
+       private MidiEvent noteOffEvent;
+       private ShortMessage noteOnMsg, noteOffMsg;
 
        /** 
         * Creates a MooNote from the given NoteOn event in the current track and creates a reference to
@@ -60,7 +51,7 @@ public class MooNote extends MidiEvent {
        public void setChannel(int channel) {
                try {
                        noteOnMsg.setMessage(noteOnMsg.getCommand(), (byte)channel, noteOnMsg.getData1(), noteOnMsg.getData2());
-                       if(hasNoteOffEvent()) noteOffMsg.setMessage(noteOffMsg.getCommand(), (byte)channel, noteOffMsg.getData1(), noteOffMsg.getData2());
+                       noteOffMsg.setMessage(noteOffMsg.getCommand(), (byte)channel, noteOffMsg.getData1(), noteOffMsg.getData2());
                } catch (InvalidMidiDataException e) {}
        }
 
@@ -71,18 +62,10 @@ public class MooNote extends MidiEvent {
        public void setPitch(int pitch) {
                try {
                        noteOnMsg.setMessage(noteOnMsg.getCommand(), noteOnMsg.getChannel(), (byte)pitch, noteOnMsg.getData2());
-                       if(hasNoteOffEvent()) noteOffMsg.setMessage(noteOffMsg.getCommand(), noteOffMsg.getChannel(), (byte)pitch, noteOffMsg.getData2());
+                       noteOffMsg.setMessage(noteOffMsg.getCommand(), noteOffMsg.getChannel(), (byte)pitch, noteOffMsg.getData2());
                } catch (InvalidMidiDataException e) {}
        }
 
-       /** 
-        * Transposes the current note the given number of halftones.
-        * @param halftones             the number of halftones to transpose - positive for up, negative for down
-        */
-       public void transpose(int halftones) {
-               setPitch(getPitch() + halftones);
-       }
-
        /** 
         * Sets the velocity of the current note.
         * @param vel   the velocity of the note (0-127)
@@ -90,7 +73,7 @@ public class MooNote extends MidiEvent {
        public void setVelocity(int vel) {
                try {
                        noteOnMsg.setMessage(noteOnMsg.getCommand(), noteOnMsg.getChannel(), noteOnMsg.getData1(), (byte)vel);
-                       if(hasNoteOffEvent()) noteOffMsg.setMessage(noteOffMsg.getCommand(), noteOffMsg.getChannel(), noteOffMsg.getData1(), noteOffMsg.getData2());
+                       noteOffMsg.setMessage(noteOffMsg.getCommand(), noteOffMsg.getChannel(), noteOffMsg.getData1(), noteOffMsg.getData2());
                } catch (InvalidMidiDataException e) {}
        }
 
@@ -99,7 +82,7 @@ public class MooNote extends MidiEvent {
         * @param n     the duration of the note in ticks (96 per beat)
         */
        public void setDuration(int ticks) {
-               if (hasNoteOffEvent()) noteOffEvent.setTick(getTick() + ticks);
+               noteOffEvent.setTick(getTick() + ticks);
        }
 
        /** 
@@ -107,10 +90,18 @@ public class MooNote extends MidiEvent {
         * @param tick  the timestamp of the note in ticks (96 per beat)
         */
        public void setTick(long tick) {
-               if (hasNoteOffEvent()) noteOffEvent.setTick(tick + getDuration());
+               noteOffEvent.setTick(tick + getDuration());
                super.setTick(tick);
        }
 
+       /** 
+        * Transposes the current note the given number of halftones.
+        * @param halftones     the number of halftones to transpose - positive for up, negative for down
+        */
+       public void transpose(int halftones) {
+               setPitch(getPitch() + halftones);
+       }
+
        /** 
         * Returns the channel of the current note.
         * @return the channel of the note (1-16)
@@ -140,33 +131,34 @@ public class MooNote extends MidiEvent {
         * @return the duration of the note (in ticks)
         */
        public int getDuration() {
-               if (!hasNoteOffEvent()) return 0;
                return (int)(noteOffEvent.getTick() - getTick());
        }
 
-       /** 
-        * Returns whether the NoteOff event was found.
-        * @return      the note off MidiEvent
-        */
-       public boolean hasNoteOffEvent() {
-               return noteOffEvent != null;
-       }
-
        /**
         * Adds this note (both noteOn and noteOffEvents) to a track.
         * @param track the track it'll be added to.
         */
-       public void addTo(Track track){
+       public void addTo(Track track) {
                track.add(this);
-               if (hasNoteOffEvent()) track.add(noteOffEvent);
+               track.add(noteOffEvent);
        }
        
        /**
         * Removes this note (both noteOn and noteOffEvents) from a track.
         * @param track the track it'll be removed from.
         */
-       public void removeFrom(Track track){
+       public void removeFrom(Track track) {
                track.remove(this);
-               if (hasNoteOffEvent()) track.remove(noteOffEvent);
+               track.remove(noteOffEvent);
+       }
+
+       /**
+        * Returns a clone of this note.
+        */
+       public Object clone() {
+               return new MooNote(
+                       new MidiEvent((ShortMessage)getMessage().clone(), getTick()), 
+                       new MidiEvent((ShortMessage)noteOffEvent.getMessage().clone(), noteOffEvent.getTick())
+               );
        }
 }
index 67555fcf5ccc80c45c85c7512b7ae69f1928ccd3..886a1111be40c3056cd2a8078e0c34b994612520 100644 (file)
@@ -87,6 +87,15 @@ public class MooNoteElement extends JPanel {
                repaint();
        }
 
+       /** 
+        * Transposes the current note element the given number of halftones.
+        * @param halftones     the number of halftones to transpose - positive for up, negative for down
+        */
+       public void transpose(int halftones) {
+               note.transpose(halftones);
+               update();
+       }
+
        /**
         * Draws the string that shows the note's properties.
         * @param g     The Graphics object used to draw the strings.
@@ -155,11 +164,12 @@ public class MooNoteElement extends JPanel {
        }
 
        /**
-        * layout this changed elemnt
+        * Layout this changed elemnt.
         */
        protected void newLayout(){
                mtv.layoutElement(this,true);
        }
+
        /**
         * Listener that checks the mouse actions on this element.
         */
@@ -232,11 +242,9 @@ public class MooNoteElement extends JPanel {
                        } else if (source == popupRemove) {
                                remove();
                        } else if (source == popupTranspOctUp) {
-                               note.transpose(12);
-                               update();
+                               transpose(12);
                        } else if (source == popupTranspOctDown) {
-                               note.transpose(-12);
-                               update();
+                               transpose(-12);
                        }
                }
        }
index f2bed14e37b919130e2c6abda153bdc113aed64c..979aed2139208e234f4124871b34b955fe536aef 100644 (file)
@@ -25,6 +25,16 @@ public class MooTrackTitle extends JPanel {
        private String trackName = "";
        private int channel = 0;
 
+       /** 
+        * Creates the title bar for an empty track, and therefore an initial channel is required.
+        * @param aTrack the track that this tracktitle is operating on.
+        * @param chan  the initial channel
+        */
+       public MooTrackTitle (Track aTrack, int chan) {
+               this(aTrack);
+               channel = chan;
+       }
+
        /** 
         * Creates the title bar.
         * @param aTrack the track that this tracktitle is operating on.
index f2afcaae2be4e18373b97a3250d4cfe5ce7b29e0..bf3590aedc59e2f25663b367beb3f85aef0763cd 100644 (file)
@@ -19,11 +19,10 @@ public class MooTrackView extends JPanel {
 
        private JPopupMenu popup, selPopup;
        private JMenu selPopupTranspUp, selPopupTranspDown;
-       private JMenuItem popupAdd;
-       private JMenuItem selPopupRemove, selPopupTranspUpOct, selPopupTranspDownOct;
+       private JMenuItem popupAdd, popupPaste;
+       private JMenuItem selPopupCopy, selPopupCut, selPopupRemove, selPopupTranspUpOct, selPopupTranspDownOct;
 
-       private ArrayList rects;
-       private ArrayList selected;
+       private ArrayList coords, selection, copyBuffer; 
        private Insets insets;
        private int ticksPerSixteenth, popupY = 0;
        protected static int viewLength = 0;
@@ -39,8 +38,17 @@ public class MooTrackView extends JPanel {
                super(true);
                this.track = track;
                this.title = title;
+
+               // Creates instance variables
                insets = getInsets();
-               selected = new ArrayList();
+               coords = new ArrayList(track.size() / 2);
+               selection = new ArrayList();
+               copyBuffer = new ArrayList();
+
+               // Creates temporary variables
+               MidiEvent note;
+               MooNoteElement elem;
+               extraHeight = Toolkit.getDefaultToolkit().getScreenSize().height - 150;
 
                // Configures panel
                setBackground(Color.white);
@@ -48,12 +56,6 @@ public class MooTrackView extends JPanel {
                setLayout(null);
                setPreferredSize(new Dimension(VIEW_WIDTH, 140 * NOTE_HEIGHT));
 
-               // Creates temporary variables
-               MidiEvent note;
-               MooNoteElement elem;
-               rects = new ArrayList(track.size() / 2);
-               extraHeight = Toolkit.getDefaultToolkit().getScreenSize().height - 150;
-
                // Places note elements
                for (int i = 0; i < track.size(); i++) {
                        note = track.get(i);
@@ -74,9 +76,18 @@ public class MooTrackView extends JPanel {
                popupAdd = new JMenuItem("Add note...");
                popupAdd.addActionListener(pList);
                popup.add(popupAdd);
+               popupPaste = new JMenuItem("Paste");
+               popupPaste.addActionListener(pList);
+               popup.add(popupPaste);
 
                // Creates selection pop-up menu.
                selPopup = new JPopupMenu();
+               selPopupCopy = new JMenuItem("Copy selection");
+               selPopupCopy.addActionListener(pList);
+               selPopup.add(selPopupCopy);
+               selPopupCut = new JMenuItem("Cut selection");
+               selPopupCut.addActionListener(pList);
+               selPopup.add(selPopupCut);
                selPopupRemove = new JMenuItem("Remove selection");
                selPopupRemove.addActionListener(pList);
                selPopup.add(selPopupRemove);
@@ -106,10 +117,10 @@ public class MooTrackView extends JPanel {
                Rectangle r = new Rectangle();
                if (old){
                        r = elem.getBounds(r);
-                       for (Iterator i = rects.iterator(); i.hasNext();){
+                       for (Iterator i = coords.iterator(); i.hasNext();){
                                Object ob = i.next();
                                if (r.equals(ob)){
-                                       rects.remove(ob);
+                                       coords.remove(ob);
                                        break;
                                }
                        }
@@ -130,12 +141,15 @@ public class MooTrackView extends JPanel {
                // Places the element in the appropriate place.
                while(isOccupied(r)) r.translate(NOTE_WIDTH, 0);
                elem.setBounds(r);
-               rects.add(r);
+               coords.add(r);
                if (viewLength < (y + height)){
                        viewLength = y + height;
                        if(old)setPreferredSize(new Dimension(VIEW_WIDTH, viewLength + extraHeight));
                }
-               if(old)repaint();
+               if (old) {
+                       validate();
+                       repaint();
+               }
        }
 
        /** 
@@ -159,7 +173,7 @@ public class MooTrackView extends JPanel {
         * @return true if the position is occupied.
         */
        private boolean isOccupied(Rectangle r) {
-               Iterator it = rects.iterator();
+               Iterator it = coords.iterator();
                while (it.hasNext()) {
                        if(r.intersects((Rectangle)it.next())) return true;
                }
@@ -177,6 +191,7 @@ public class MooTrackView extends JPanel {
                layoutElement(elem, false);
                setPreferredSize(new Dimension(VIEW_WIDTH, viewLength + extraHeight));
                Moosique.setEdited();
+               validate();
                repaint();
        }
 
@@ -184,7 +199,7 @@ public class MooTrackView extends JPanel {
         * Adds a standard note to this track.
         */
        private void addStandardNote() {
-               int row =  (popupY - insets.top) / NOTE_HEIGHT;
+               int row = (popupY - insets.top) / NOTE_HEIGHT;
                long timestamp = (long)(ticksPerSixteenth * row);
                addNote(new MooNote(title.getChannel(), 60, 100, timestamp, Moosique.getSequence().getResolution() / 4));
        }
@@ -198,34 +213,37 @@ public class MooTrackView extends JPanel {
                remove(elem);
                Rectangle r = new Rectangle();
                r = elem.getBounds(r);
-               rects.remove(r);
+               coords.remove(r);
                Moosique.setEdited();
+               validate();
                repaint();
        }
 
        /**
-        * Deselects all notes.
+        * Selects the given note
+        * @param the note to select
         */
        public void selectNote(MooNoteElement elem) {
-               selected.add(elem);
+               selection.add(elem);
        }
 
        /**
-        * Deselects all notes.
+        * Deselects the given note
+        * @param the note to deselect
         */
        public void deselectNote(MooNoteElement elem) {
-               selected.remove(selected.indexOf(elem));
+               selection.remove(selection.indexOf(elem));
        }
 
        /**
         * Deselects all notes.
         */
        public void deselectAllNotes() {
-               Iterator it = selected.iterator();
+               Iterator it = selection.iterator();
                while(it.hasNext()) {
                        ((MooNoteElement)it.next()).deselect();
                }
-               selected.clear();
+               selection.clear();
        }
 
        /**
@@ -233,7 +251,7 @@ public class MooTrackView extends JPanel {
         * @return if the given element is the only selected one
         */
        public boolean isTheOnlySelected(MooNoteElement elem) {
-               Iterator it = selected.iterator();
+               Iterator it = selection.iterator();
                while(it.hasNext()) {
                        if (!it.next().equals(elem)) return false;
                }
@@ -241,27 +259,74 @@ public class MooTrackView extends JPanel {
        }
 
        /**
-        * Shows a popup-menu with options for the current selection of note elements.
-        * @param c     the component over which to display the menu
-        * @param x     the x-coordinate in which to display the menu
-        * @param y     the y-coordinate in which to display the menu
+        * Copies the current selection.
         */
-       public void showSelectionPopup(Component c, int x, int y) {
-               selPopup.show(c, x, y);
+       public void copySelectedNotes() {
+               copyBuffer = new ArrayList(selection.size());
+               Iterator it = selection.iterator();
+               while(it.hasNext()) {
+                       copyBuffer.add(((MooNoteElement)it.next()).getNote().clone());
+               }
+               Collections.sort(copyBuffer, new Moosique.NoteComparator());
+       }
+
+       /**
+        * Cuts the current selection.
+        */
+       public void cutSelectedNotes() {
+               copySelectedNotes();
+               removeSelectedNotes();
+       }
+
+       /**
+        * Pastes the current copy buffer at the given timestamp.
+        */
+       public void pasteCopiedNotes() {
+               int row = (popupY - insets.top) / NOTE_HEIGHT;
+               long timestamp = (long)(ticksPerSixteenth * row);
+               if (copyBuffer.size() > 0) {
+                       long startTime = ((MooNote)copyBuffer.get(0)).getTick();
+                       Iterator it = copyBuffer.iterator();
+                       while(it.hasNext()) {
+                               MooNote mn = (MooNote)((MooNote)it.next()).clone();
+                               mn.setTick(mn.getTick() - startTime + timestamp);
+                               addNote(mn);
+                       }
+               }
+       }
+
+       /**
+        * Removes the current selection.
+        */
+       public void removeSelectedNotes() {
+               Iterator it = selection.iterator();
+               while(it.hasNext()) {
+                       removeNote((MooNoteElement)it.next());
+               }
+               selection.clear();
        }
 
        /**
         * Transposes all selected notes the given number of halftones.
         */
        private void transposeSelectedNotes(int halftones) {
-               Iterator it = selected.iterator();
+               Iterator it = selection.iterator();
                while(it.hasNext()) {
                        MooNoteElement elem = (MooNoteElement)it.next();
-                       elem.getNote().transpose(halftones);
-                       elem.update();
+                       elem.transpose(halftones);
                }
        }
 
+       /**
+        * Shows a popup-menu with options for the current selection of note elements.
+        * @param c     the component over which to display the menu
+        * @param x     the x-coordinate in which to display the menu
+        * @param y     the y-coordinate in which to display the menu
+        */
+       public void showSelectionPopup(Component c, int x, int y) {
+               selPopup.show(c, x, y);
+       }
+
        /**
         * Draws the grid that is on the background.
         * @param g The Graphics object used to draw the grid.
@@ -336,14 +401,18 @@ public class MooTrackView extends JPanel {
        class PopupListener implements ActionListener {
                public void actionPerformed(ActionEvent e) {
                        Object source = e.getSource();
+                       // Handling panel popup actions.
                        if (source == popupAdd) {
                                addStandardNote();
+                       } else if (source == popupPaste) {
+                               pasteCopiedNotes();
+                       // Handling selection popup actions.
+                       } else if (source == selPopupCopy) {
+                               copySelectedNotes();
+                       } else if (source == selPopupCut) {
+                               cutSelectedNotes();
                        } else if (source == selPopupRemove) {
-                               Iterator it = selected.iterator();
-                               while(it.hasNext()) {
-                                       removeNote((MooNoteElement)it.next());
-                               }
-                               selected.clear();
+                               removeSelectedNotes();
                        } else if (source == selPopupTranspUpOct) {
                                transposeSelectedNotes(12);
                        } else if (source == selPopupTranspDownOct) {
index 5cf7af5b814f6c6eb07dcab4755d1bd894223f21..42b3637cf21db7d67b6a3659f279741723b987e3 100644 (file)
@@ -527,11 +527,7 @@ public class Moosique {
                        if (noteOns.size() == 0) emptyTracks.add(tracks[i]);
                        
                        // Sorts the note lists by tick position.
-                       Comparator c = new Comparator() {
-                               public int compare(Object o1, Object o2) {
-                                       return (int)(((MidiEvent)o1).getTick() - ((MidiEvent)o2).getTick());
-                               }
-                       };
+                       Comparator c = new NoteComparator();
                        Collections.sort(noteOns, c);
                        Collections.sort(noteOffs, c);
 
@@ -559,7 +555,7 @@ public class Moosique {
                                if (off != null) {
                                        tracks[i].add(new MooNote(on, off));
                                } else {
-                                       tracks[i].add(new MooNote(on));
+                                       tracks[i].add(new MooNote(on, new MidiEvent((ShortMessage)on.getMessage().clone(), on.getTick() + 48)));
                                }
                                iOn.remove();
                        }
@@ -572,6 +568,20 @@ public class Moosique {
                return true;
        }
 
+       /** 
+        * Prompts the user .
+        */
+       public static boolean promptOnUnsavedChanges() {
+               if (!isEdited) return false;
+               int exitOption = JOptionPane.showConfirmDialog(gui,
+                       "The current sequence has been edited, but not saved.\nDo you wish to continue anyway?",
+                       "File not saved - continue?", 
+                       JOptionPane.OK_CANCEL_OPTION, 
+                       JOptionPane.WARNING_MESSAGE);
+               if (exitOption == JOptionPane.CANCEL_OPTION || exitOption == JOptionPane.CLOSED_OPTION) return true;
+               return false;
+       }
+
        /** 
         * Saves the current sequence to the previously given filename.
         */
@@ -591,6 +601,7 @@ public class Moosique {
                try {
                        MidiSystem.write(seq, 1, new File(file));
                        filename = file;
+                       isEdited = false;
                        gui.setStatus("Saved " + file);
                        return true;
                } catch (IOException e) {
@@ -603,16 +614,20 @@ public class Moosique {
         * Releases all reserved devices and exits the program.
         */
        public static void quit() {
-               if (isEdited && gui != null) {
-                       int exitOption = JOptionPane.showConfirmDialog(gui,
-                               "The current sequence has been edited, but not saved.\nDo you wish to quit anyway?",
-                               "File not saved - really quit?", 
-                               JOptionPane.OK_CANCEL_OPTION, 
-                               JOptionPane.WARNING_MESSAGE);
-                       if (exitOption == JOptionPane.CANCEL_OPTION || exitOption == JOptionPane.CLOSED_OPTION) return;
+               if (gui != null) {
+                       if (promptOnUnsavedChanges()) return;
                }
                if (sequencer.isOpen()) sequencer.close();
                if (synthesizer.isOpen()) synthesizer.close();
                System.exit(0);
        }
+       
+       /** 
+        * A Comparator for sorting lists of MidiEvents.
+        */
+       public static class NoteComparator implements Comparator {
+               public int compare(Object o1, Object o2) {
+                       return (int)(((MidiEvent)o1).getTick() - ((MidiEvent)o2).getTick());
+               }
+       }
 }
index dedc490e5f26d01447b60af34c7bedcfbc4ff151..321bd186d2e55c1e1b2f099d06aebc8e3d9189c0 100644 (file)
--- a/To Do.txt
+++ b/To Do.txt
@@ -1,4 +1,24 @@
 
+\f
+jar cmf manif Moosique.jar *.class
+manif: Main-Class: Moosique
+
+\f
+Presentation
+
+EDIT-huset vån 2 ES52
+Onsdag 19/5 10-12
+
+TID    PRESENTATION    OPPOSITION
+11:00  Group 03        Vi
+11:30  Vi              Group 11 
+
+\f
+Varför ritar den ut de tomma spåren i en ny fil? Rätt, men hur?
+Lägg till redigeringsfunktionerna i menyn. Metoderna flyttas till MooView?
+Fixa kanalnummer 1,2,10 i nya filer.
+Kopiera/flytta spår, möjligt?
+
 \f
 IO
 x Implementera ljudlös körning med -m.
@@ -28,7 +48,6 @@ x Textf
 
 MooTrackView
 
-x Fixa markera, kopiera, klipp ut och klistra in.
 x Highlighta noter som spelas? (Enligt kravspec.)
 x Ändra längden på MooNoteElement (JPanel).
        Känn av klick på panelens gräns, MouseMotionListener känner av när ny ruta nås.
index 460b3bccb457379dcb5ae3e7a80966fcadfcc702..7f093dd832a05dc38f4d6082caff37ec457de34e 100644 (file)
Binary files a/midi/test3.mid and b/midi/test3.mid differ