From ce3eb7165aeaa1e1dcc264c1277cddd21290b3ed Mon Sep 17 00:00:00 2001 From: Matt Jenkins Date: Fri, 17 Jan 2020 12:31:25 +0000 Subject: [PATCH] Added book/chapter/phrase notes area tabs --- .../audiobookrecorder/AudiobookRecorder.java | 207 ++++++++++++++---- src/uk/co/majenko/audiobookrecorder/Book.java | 4 +- .../audiobookrecorder/BookTreeNode.java | 20 ++ .../co/majenko/audiobookrecorder/Chapter.java | 19 +- .../majenko/audiobookrecorder/Sentence.java | 28 ++- 5 files changed, 229 insertions(+), 49 deletions(-) create mode 100644 src/uk/co/majenko/audiobookrecorder/BookTreeNode.java diff --git a/src/uk/co/majenko/audiobookrecorder/AudiobookRecorder.java b/src/uk/co/majenko/audiobookrecorder/AudiobookRecorder.java index 1c7d981..76b2335 100644 --- a/src/uk/co/majenko/audiobookrecorder/AudiobookRecorder.java +++ b/src/uk/co/majenko/audiobookrecorder/AudiobookRecorder.java @@ -3,6 +3,7 @@ package uk.co.majenko.audiobookrecorder; import javax.sound.sampled.*; import javax.swing.*; import javax.swing.event.*; +import javax.swing.text.*; import java.awt.*; import java.awt.event.*; import java.nio.file.*; @@ -40,7 +41,7 @@ import org.w3c.dom.Element; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeEvent; -public class AudiobookRecorder extends JFrame { +public class AudiobookRecorder extends JFrame implements DocumentListener { // Settings - tweakable @@ -106,8 +107,17 @@ public class AudiobookRecorder extends JFrame { public Waveform sampleWaveform; JScrollBar sampleScroll; JSplitPane mainSplit; - JTextArea notesArea; - JScrollPane notesScroll; + + JTabbedPane notesTabs; + + JTextArea bookNotesArea; + JScrollPane bookNotesScroll; + + JTextArea chapterNotesArea; + JScrollPane chapterNotesScroll; + + JTextArea sentenceNotesArea; + JScrollPane sentenceNotesScroll; JSpinner postSentenceGap; JSpinner gainPercent; @@ -641,10 +651,9 @@ public class AudiobookRecorder extends JFrame { centralPanel.getActionMap().put("startRecord", new AbstractAction() { public void actionPerformed(ActionEvent e) { if (!getLock()) return; - if (getFocusOwner() == notesArea) { - freeLock(); - return; - } + if (getFocusOwner() == bookNotesArea) { freeLock(); return; } + if (getFocusOwner() == chapterNotesArea) { freeLock(); return; } + if (getFocusOwner() == sentenceNotesArea) { freeLock(); return; } if (bookTree.isEditing()) { freeLock(); return; @@ -660,10 +669,9 @@ public class AudiobookRecorder extends JFrame { centralPanel.getActionMap().put("startRecordShort", new AbstractAction() { public void actionPerformed(ActionEvent e) { if (!getLock()) return; - if (getFocusOwner() == notesArea) { - freeLock(); - return; - } + if (getFocusOwner() == bookNotesArea) { freeLock(); return; } + if (getFocusOwner() == chapterNotesArea) { freeLock(); return; } + if (getFocusOwner() == sentenceNotesArea) { freeLock(); return; } if (bookTree.isEditing()) { freeLock(); return; @@ -679,10 +687,9 @@ public class AudiobookRecorder extends JFrame { centralPanel.getActionMap().put("startRecordNewPara", new AbstractAction() { public void actionPerformed(ActionEvent e) { if (!getLock()) return; - if (getFocusOwner() == notesArea) { - freeLock(); - return; - } + if (getFocusOwner() == bookNotesArea) { freeLock(); return; } + if (getFocusOwner() == chapterNotesArea) { freeLock(); return; } + if (getFocusOwner() == sentenceNotesArea) { freeLock(); return; } if (bookTree.isEditing()) { freeLock(); return; @@ -698,10 +705,9 @@ public class AudiobookRecorder extends JFrame { centralPanel.getActionMap().put("startRecordNewSection", new AbstractAction() { public void actionPerformed(ActionEvent e) { if (!getLock()) return; - if (getFocusOwner() == notesArea) { - freeLock(); - return; - } + if (getFocusOwner() == bookNotesArea) { freeLock(); return; } + if (getFocusOwner() == chapterNotesArea) { freeLock(); return; } + if (getFocusOwner() == sentenceNotesArea) { freeLock(); return; } if (bookTree.isEditing()) { freeLock(); return; @@ -717,10 +723,9 @@ public class AudiobookRecorder extends JFrame { centralPanel.getActionMap().put("startRerecord", new AbstractAction() { public void actionPerformed(ActionEvent e) { if (!getLock()) return; - if (getFocusOwner() == notesArea) { - freeLock(); - return; - } + if (getFocusOwner() == bookNotesArea) { freeLock(); return; } + if (getFocusOwner() == chapterNotesArea) { freeLock(); return; } + if (getFocusOwner() == sentenceNotesArea) { freeLock(); return; } if (bookTree.isEditing()) { freeLock(); return; @@ -735,9 +740,9 @@ public class AudiobookRecorder extends JFrame { }); centralPanel.getActionMap().put("stopRecord", new AbstractAction() { public void actionPerformed(ActionEvent e) { - if (getFocusOwner() == notesArea) { - return; - } + if (getFocusOwner() == bookNotesArea) { return; } + if (getFocusOwner() == chapterNotesArea) { return; } + if (getFocusOwner() == sentenceNotesArea) { return; } if (bookTree.isEditing()) return; stopLock(); stopRecording(); @@ -746,9 +751,9 @@ public class AudiobookRecorder extends JFrame { }); centralPanel.getActionMap().put("deleteLast", new AbstractAction() { public void actionPerformed(ActionEvent e) { - if (getFocusOwner() == notesArea) { - return; - } + if (getFocusOwner() == bookNotesArea) { return; } + if (getFocusOwner() == chapterNotesArea) { return; } + if (getFocusOwner() == sentenceNotesArea) { return; } if (bookTree.isEditing()) return; deleteLastRecording(); } @@ -756,9 +761,9 @@ public class AudiobookRecorder extends JFrame { centralPanel.getActionMap().put("startStopPlayback", new AbstractAction() { public void actionPerformed(ActionEvent e) { - if (getFocusOwner() == notesArea) { - return; - } + if (getFocusOwner() == bookNotesArea) { return; } + if (getFocusOwner() == chapterNotesArea) { return; } + if (getFocusOwner() == sentenceNotesArea) { return; } if (bookTree.isEditing()) return; if (playing == null) { playSelectedSentence(); @@ -770,9 +775,9 @@ public class AudiobookRecorder extends JFrame { centralPanel.getActionMap().put("startPlaybackFrom", new AbstractAction() { public void actionPerformed(ActionEvent e) { - if (getFocusOwner() == notesArea) { - return; - } + if (getFocusOwner() == bookNotesArea) { return; } + if (getFocusOwner() == chapterNotesArea) { return; } + if (getFocusOwner() == sentenceNotesArea) { return; } if (bookTree.isEditing()) return; if (playing == null) { playFromSelectedSentence(); @@ -782,12 +787,30 @@ public class AudiobookRecorder extends JFrame { mainScroll = new JScrollPane(); - notesArea = new JTextArea(); - notesArea.setFont(new Font("Monospaced", Font.PLAIN, 10)); - notesScroll = new JScrollPane(); - notesScroll.setViewportView(notesArea); + bookNotesArea = new JTextArea(); + bookNotesArea.setFont(new Font("Monospaced", Font.PLAIN, 10)); + bookNotesScroll = new JScrollPane(); + bookNotesScroll.setViewportView(bookNotesArea); - mainSplit = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, mainScroll, notesScroll); + chapterNotesArea = new JTextArea(); + chapterNotesArea.setFont(new Font("Monospaced", Font.PLAIN, 10)); + chapterNotesArea.getDocument().addDocumentListener(this); + chapterNotesScroll = new JScrollPane(); + chapterNotesScroll.setViewportView(chapterNotesArea); + + sentenceNotesArea = new JTextArea(); + sentenceNotesArea.setFont(new Font("Monospaced", Font.PLAIN, 10)); + sentenceNotesArea.getDocument().addDocumentListener(this); + sentenceNotesScroll = new JScrollPane(); + sentenceNotesScroll.setViewportView(sentenceNotesArea); + + notesTabs = new JTabbedPane(); + + notesTabs.add("Book", bookNotesScroll); + notesTabs.add("Chapter", chapterNotesScroll); + notesTabs.add("Phrase", sentenceNotesScroll); + + mainSplit = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, mainScroll, notesTabs); centralPanel.add(mainSplit, BorderLayout.CENTER); mainSplit.addPropertyChangeListener(new PropertyChangeListener() { @@ -2011,6 +2034,11 @@ public class AudiobookRecorder extends JFrame { bookTree.addTreeSelectionListener(new TreeSelectionListener() { public void valueChanged(TreeSelectionEvent e) { DefaultMutableTreeNode n = (DefaultMutableTreeNode)bookTree.getLastSelectedPathComponent(); + if (n instanceof BookTreeNode) { + BookTreeNode btn = (BookTreeNode)n; + btn.onSelect(); + } + if (n instanceof Sentence) { Sentence s = (Sentence)n; selectedSentence = s; @@ -2178,6 +2206,11 @@ public class AudiobookRecorder extends JFrame { bookTree.addTreeSelectionListener(new TreeSelectionListener() { public void valueChanged(TreeSelectionEvent e) { DefaultMutableTreeNode n = (DefaultMutableTreeNode)bookTree.getLastSelectedPathComponent(); + if (n instanceof BookTreeNode) { + BookTreeNode btn = (BookTreeNode)n; + btn.onSelect(); + } + if (n instanceof Sentence) { Sentence s = (Sentence)n; selectedSentence = s; @@ -3729,12 +3762,28 @@ public class AudiobookRecorder extends JFrame { System.err.println("Effects Enabled: " + b); } - public void setNotes(String text) { - notesArea.setText(text); + public void setBookNotes(String text) { + bookNotesArea.setText(text); } - public String getNotes() { - return notesArea.getText(); + public void setChapterNotes(String text) { + chapterNotesArea.setText(text); + } + + public void setSentenceNotes(String text) { + sentenceNotesArea.setText(text); + } + + public String getBookNotes() { + return bookNotesArea.getText(); + } + + public String getChapterNotes() { + return chapterNotesArea.getText(); + } + + public String getSentenceNotes() { + return sentenceNotesArea.getText(); } public void openManuscript() { @@ -3766,4 +3815,74 @@ public class AudiobookRecorder extends JFrame { } } + //* DocumentListener + + public void changedUpdate(DocumentEvent e) { + javax.swing.text.Document doc = e.getDocument(); + if (doc == chapterNotesArea.getDocument()) { + DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode)bookTree.getLastSelectedPathComponent(); + if (selectedNode instanceof Sentence) { + selectedNode = (DefaultMutableTreeNode)selectedNode.getParent(); + } + if (! (selectedNode instanceof Chapter)) { + return; + } + Chapter c = (Chapter)selectedNode; + c.setNotes(chapterNotesArea.getText()); + } else if (doc == sentenceNotesArea.getDocument()) { + DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode)bookTree.getLastSelectedPathComponent(); + if (! (selectedNode instanceof Sentence)) { + return; + } + Sentence s = (Sentence)selectedNode; + s.setNotes(sentenceNotesArea.getText()); + } + } + + public void removeUpdate(DocumentEvent e) { + javax.swing.text.Document doc = e.getDocument(); + if (doc == chapterNotesArea.getDocument()) { + DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode)bookTree.getLastSelectedPathComponent(); + if (selectedNode instanceof Sentence) { + selectedNode = (DefaultMutableTreeNode)selectedNode.getParent(); + } + if (! (selectedNode instanceof Chapter)) { + return; + } + Chapter c = (Chapter)selectedNode; + c.setNotes(chapterNotesArea.getText()); + } else if (doc == sentenceNotesArea.getDocument()) { + DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode)bookTree.getLastSelectedPathComponent(); + if (! (selectedNode instanceof Sentence)) { + return; + } + Sentence s = (Sentence)selectedNode; + s.setNotes(sentenceNotesArea.getText()); + } + } + + public void insertUpdate(DocumentEvent e) { + javax.swing.text.Document doc = e.getDocument(); + if (doc == chapterNotesArea.getDocument()) { + DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode)bookTree.getLastSelectedPathComponent(); + if (selectedNode instanceof Sentence) { + selectedNode = (DefaultMutableTreeNode)selectedNode.getParent(); + } + if (! (selectedNode instanceof Chapter)) { + return; + } + Chapter c = (Chapter)selectedNode; + c.setNotes(chapterNotesArea.getText()); + } else if (doc == sentenceNotesArea.getDocument()) { + DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode)bookTree.getLastSelectedPathComponent(); + if (! (selectedNode instanceof Sentence)) { + return; + } + Sentence s = (Sentence)selectedNode; + s.setNotes(sentenceNotesArea.getText()); + } + } + + // DocumentListener *// + } diff --git a/src/uk/co/majenko/audiobookrecorder/Book.java b/src/uk/co/majenko/audiobookrecorder/Book.java index 485cade..31433ff 100644 --- a/src/uk/co/majenko/audiobookrecorder/Book.java +++ b/src/uk/co/majenko/audiobookrecorder/Book.java @@ -66,7 +66,7 @@ public class Book extends DefaultMutableTreeNode { ACX = getTextNode(root, "acx"); manuscript = getTextNode(root, "manuscript"); - AudiobookRecorder.window.setNotes(getTextNode(root, "notes")); + AudiobookRecorder.window.setBookNotes(getTextNode(root, "notes")); Element settings = getNode(root, "settings"); Element audioSettings = getNode(settings, "audio"); @@ -306,7 +306,7 @@ public class Book extends DefaultMutableTreeNode { root.appendChild(makeTextNode(doc, "acx", ACX)); root.appendChild(makeTextNode(doc, "manuscript", manuscript)); - root.appendChild(makeTextNode(doc, "notes", AudiobookRecorder.window.getNotes())); + root.appendChild(makeTextNode(doc, "notes", AudiobookRecorder.window.getBookNotes())); Element settingsNode = doc.createElement("settings"); root.appendChild(settingsNode); diff --git a/src/uk/co/majenko/audiobookrecorder/BookTreeNode.java b/src/uk/co/majenko/audiobookrecorder/BookTreeNode.java new file mode 100644 index 0000000..1f42ecd --- /dev/null +++ b/src/uk/co/majenko/audiobookrecorder/BookTreeNode.java @@ -0,0 +1,20 @@ +package uk.co.majenko.audiobookrecorder; + +import javax.swing.tree.DefaultMutableTreeNode; + +public abstract class BookTreeNode extends DefaultMutableTreeNode { + + public BookTreeNode(String t) { + super(t); + } + + public BookTreeNode() { + super(""); + } + + public abstract void setNotes(String t); + public abstract String getNotes(); + + public abstract void onSelect(); +} + diff --git a/src/uk/co/majenko/audiobookrecorder/Chapter.java b/src/uk/co/majenko/audiobookrecorder/Chapter.java index 42ebd99..298d44e 100644 --- a/src/uk/co/majenko/audiobookrecorder/Chapter.java +++ b/src/uk/co/majenko/audiobookrecorder/Chapter.java @@ -26,7 +26,7 @@ import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.w3c.dom.Text; -public class Chapter extends DefaultMutableTreeNode { +public class Chapter extends BookTreeNode { String name; String id; @@ -34,6 +34,8 @@ public class Chapter extends DefaultMutableTreeNode { int preGap; int postGap; + String notes; + public Chapter(String i, String chaptername) { super(chaptername); @@ -49,6 +51,8 @@ public class Chapter extends DefaultMutableTreeNode { id = root.getAttribute("id"); preGap = Utils.s2i(Book.getTextNode(root, "pre-gap")); postGap = Utils.s2i(Book.getTextNode(root, "post-gap")); + + notes = Book.getTextNode(root, "notes"); Element sentencesNode = Book.getNode(root, "sentences"); NodeList sentences = sentencesNode.getElementsByTagName("sentence"); @@ -284,6 +288,7 @@ public class Chapter extends DefaultMutableTreeNode { chapterNode.appendChild(Book.makeTextNode(doc, "name", name)); chapterNode.appendChild(Book.makeTextNode(doc, "pre-gap", preGap)); chapterNode.appendChild(Book.makeTextNode(doc, "post-gap", postGap)); + chapterNode.appendChild(Book.makeTextNode(doc, "notes", notes)); Element sentencesNode = doc.createElement("sentences"); chapterNode.appendChild(sentencesNode); @@ -299,4 +304,16 @@ public class Chapter extends DefaultMutableTreeNode { return chapterNode; } + public String getNotes() { + return notes; + } + + public void setNotes(String t) { + notes = t; + } + + public void onSelect() { + AudiobookRecorder.window.setChapterNotes(notes); + } + } diff --git a/src/uk/co/majenko/audiobookrecorder/Sentence.java b/src/uk/co/majenko/audiobookrecorder/Sentence.java index e31c352..e081cc8 100644 --- a/src/uk/co/majenko/audiobookrecorder/Sentence.java +++ b/src/uk/co/majenko/audiobookrecorder/Sentence.java @@ -41,10 +41,11 @@ import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Text; -public class Sentence extends DefaultMutableTreeNode implements Cacheable { +public class Sentence extends BookTreeNode implements Cacheable { String text; String id; + String notes; int postGap; int startOffset = 0; int endOffset = 0; @@ -179,6 +180,7 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable { super(""); id = root.getAttribute("id"); text = Book.getTextNode(root, "text"); + notes = Book.getTextNode(root, "notes"); setUserObject(text); setPostGap(Utils.s2i(Book.getTextNode(root, "post-gap"))); setStartOffset(Utils.s2i(Book.getTextNode(root, "start-offset"))); @@ -348,7 +350,7 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable { intens = null; samples = null; processed = true; - + AudiobookRecorder.window.bookTreeModel.reload(this); } public void autoTrimSamplePeak() { @@ -405,6 +407,7 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable { if (endOffset >= samples.length) endOffset = samples.length-1; updateCrossings(useRaw); processed = true; + AudiobookRecorder.window.bookTreeModel.reload(this); } public String getId() { @@ -414,6 +417,7 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable { public void setText(String t) { overrideText = null; text = t; + AudiobookRecorder.window.bookTreeModel.reload(this); } public String getText() { @@ -461,6 +465,7 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable { if (o instanceof String) { String so = (String)o; text = so; + AudiobookRecorder.window.bookTreeModel.reload(this); } } @@ -520,6 +525,7 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable { if (startOffset != o) { startOffset = o; crossStartOffset = -1; + AudiobookRecorder.window.bookTreeModel.reload(this); } } @@ -535,6 +541,7 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable { if (endOffset != o) { endOffset = o; crossEndOffset = -1; + AudiobookRecorder.window.bookTreeModel.reload(this); } } @@ -615,6 +622,7 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable { public void setLocked(boolean l) { locked = l; + AudiobookRecorder.window.bookTreeModel.reload(this); } public boolean isLocked() { @@ -717,6 +725,7 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable { public void setAttentionFlag(boolean f) { attention = f; + AudiobookRecorder.window.bookTreeModel.reload(this); } public boolean getAttentionFlag() { @@ -1316,6 +1325,7 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable { CacheManager.removeFromCache(this); } effectChain = key; + AudiobookRecorder.window.bookTreeModel.reload(this); } public String getEffectChain() { @@ -1342,6 +1352,7 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable { } } postGapType = t; + AudiobookRecorder.window.bookTreeModel.reload(this); } public void resetPostGap() { @@ -1410,6 +1421,7 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable { sentenceNode.appendChild(Book.makeTextNode(doc, "gaptype", getPostGapType())); sentenceNode.appendChild(Book.makeTextNode(doc, "samples", getSampleSize())); sentenceNode.appendChild(Book.makeTextNode(doc, "processed", isProcessed())); + sentenceNode.appendChild(Book.makeTextNode(doc, "notes", getNotes())); return sentenceNode; } @@ -1419,7 +1431,19 @@ public class Sentence extends DefaultMutableTreeNode implements Cacheable { public void setProcessed(boolean p) { processed = p; + AudiobookRecorder.window.bookTreeModel.reload(this); } + public void setNotes(String n) { + notes = n; + } + + public String getNotes() { + return notes; + } + + public void onSelect() { + AudiobookRecorder.window.setSentenceNotes(notes); + } }