aboutsummaryrefslogtreecommitdiff
path: root/src/uk/org/ury/frontend/modules
diff options
context:
space:
mode:
Diffstat (limited to 'src/uk/org/ury/frontend/modules')
-rw-r--r--src/uk/org/ury/frontend/modules/library/LibraryTableModel.java184
-rw-r--r--src/uk/org/ury/frontend/modules/library/LibraryViewer.java159
-rw-r--r--src/uk/org/ury/frontend/modules/library/LibraryViewer.properties22
-rw-r--r--src/uk/org/ury/frontend/modules/library/LibraryViewerPanel.java219
-rw-r--r--src/uk/org/ury/frontend/modules/library/library_viewer_gui.xml32
-rw-r--r--src/uk/org/ury/frontend/modules/menu/DemoMenu.java64
-rw-r--r--src/uk/org/ury/frontend/modules/menu/DemoMenuPanel.java68
-rw-r--r--src/uk/org/ury/frontend/modules/show/ChannelPanel.java84
-rw-r--r--src/uk/org/ury/frontend/modules/show/ShowViewer.java118
-rw-r--r--src/uk/org/ury/frontend/modules/show/ShowViewerPanel.java133
-rw-r--r--src/uk/org/ury/frontend/modules/show/TrackBin.java56
-rw-r--r--src/uk/org/ury/frontend/modules/show/channel_panel.xml36
-rw-r--r--src/uk/org/ury/frontend/modules/show/show_viewer_gui.xml43
-rw-r--r--src/uk/org/ury/frontend/modules/show/show_viewer_gui_old.xml46
-rw-r--r--src/uk/org/ury/frontend/modules/show/show_viewer_gui_panels.xml43
-rw-r--r--src/uk/org/ury/frontend/modules/show/track_bin.xml10
16 files changed, 1317 insertions, 0 deletions
diff --git a/src/uk/org/ury/frontend/modules/library/LibraryTableModel.java b/src/uk/org/ury/frontend/modules/library/LibraryTableModel.java
new file mode 100644
index 0000000..334eb8b
--- /dev/null
+++ b/src/uk/org/ury/frontend/modules/library/LibraryTableModel.java
@@ -0,0 +1,184 @@
+/**
+ *
+ */
+package uk.org.ury.frontend.modules.library;
+
+import java.util.List;
+
+import javax.swing.table.AbstractTableModel;
+
+import uk.org.ury.backend.database.exceptions.MissingPropertyException;
+import uk.org.ury.common.library.item.LibraryItem;
+import uk.org.ury.common.library.item.LibraryItemProperty;
+
+
+/**
+ * A table model for the library viewer.
+ *
+ * @author Matt Windsor
+ */
+
+public class LibraryTableModel extends AbstractTableModel
+{
+
+ /**
+ *
+ */
+
+ private static final long serialVersionUID = -1744980619128903509L;
+
+ private List<LibraryItem> data;
+
+
+ /**
+ * Construct a new table model.
+ *
+ * @param data The list of data on which the model will be based.
+ */
+
+ public
+ LibraryTableModel (List<LibraryItem> data)
+ {
+ this.data = data;
+ }
+
+
+ /* (non-Javadoc)
+ * @see javax.swing.table.TableModel#getColumnCount()
+ */
+
+ @Override
+ public int
+ getColumnCount ()
+ {
+ return 6;
+ }
+
+
+ /* (non-Javadoc)
+ * @see javax.swing.table.TableModel#getRowCount()
+ */
+
+ @Override
+ public int
+ getRowCount ()
+ {
+ return data.size ();
+ }
+
+
+ /**
+ * @param c The column whose class should be investigated.
+ *
+ * @return the column class of column c.
+ */
+
+ @Override
+ public Class<?>
+ getColumnClass (int c)
+ {
+ return getValueAt (0, c).getClass ();
+ }
+
+
+ /* (non-Javadoc)
+ * @see javax.swing.table.TableModel#getValueAt(int, int)
+ */
+
+ @Override
+ public Object
+ getValueAt (int rowIndex, int columnIndex)
+ {
+ LibraryItem li = data.get (rowIndex);
+
+ try
+ {
+ String[] columnData = {li.get (LibraryItemProperty.TITLE),
+ li.get (LibraryItemProperty.ARTIST),
+ li.get (LibraryItemProperty.ALBUM)};
+
+ switch (columnIndex)
+ {
+ default: // Title, artist, album, unknown
+
+ if (columnIndex >= columnData.length)
+ return "Unknown";
+ else
+ return columnData[columnIndex];
+
+ case 3: // Medium
+
+ // TODO: Make this less kludge-y
+
+ String mediumString = li.get (LibraryItemProperty.MEDIUM);
+
+ if (mediumString.equals ("c"))
+ return "Compact Disc";
+ else if (mediumString.equals ("7"))
+ return "7\" Vinyl";
+ else if (mediumString.equals ("2"))
+ return "12\" Vinyl";
+ else
+ return "Unrecognised";
+
+ case 4: // Clean?
+
+ // Return true if marked true, false if marked false or unknown etc.
+
+ String cleanString = li.get (LibraryItemProperty.IS_CLEAN);
+
+ // TODO: Nicer way of showing this
+
+ if (cleanString.equals ("y"))
+ return "Yes";
+ else if (cleanString.equals ("n"))
+ return "No";
+ else
+ return "???";
+
+ case 5: // isDigitised
+
+ // Return true if marked true, false if marked false or unknown etc.
+
+ String digitisedString = li.get (LibraryItemProperty.IS_DIGITISED);
+
+ if (digitisedString.equals ("t"))
+ return true;
+ else
+ return false;
+ }
+ }
+ catch (MissingPropertyException e)
+ {
+ return "Unknown";
+ }
+ }
+
+
+ /* (non-Javadoc)
+ * @see javax.swing.table.TableModel#getColumnName(int, int)
+ */
+
+ @Override
+ public String
+ getColumnName (int index)
+ {
+ switch (index)
+ {
+ case 0:
+ return "Title";
+ case 1:
+ return "Artist";
+ case 2:
+ return "Album";
+ case 3:
+ return "Medium";
+ case 4:
+ return "Clean?";
+ case 5:
+ return "On system?";
+ default:
+ return "ERROR";
+ }
+ }
+}
diff --git a/src/uk/org/ury/frontend/modules/library/LibraryViewer.java b/src/uk/org/ury/frontend/modules/library/LibraryViewer.java
new file mode 100644
index 0000000..c4a3630
--- /dev/null
+++ b/src/uk/org/ury/frontend/modules/library/LibraryViewer.java
@@ -0,0 +1,159 @@
+/*
+ * LibraryViewer.java
+ * ------------------
+ *
+ * Part of the URY Frontend Platform
+ *
+ * V0.00 2011/03/20
+ *
+ * (C) 2011 URY Computing
+ */
+
+package uk.org.ury.frontend.modules.library;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import uk.org.ury.common.library.exceptions.EmptySearchException;
+import uk.org.ury.common.library.item.LibraryItem;
+import uk.org.ury.common.library.item.LibraryItemProperty;
+import uk.org.ury.common.protocol.Directive;
+import uk.org.ury.common.protocol.ProtocolUtils;
+import uk.org.ury.common.protocol.exceptions.DecodeFailureException;
+import uk.org.ury.common.protocol.exceptions.InvalidMessageException;
+import uk.org.ury.frontend.AbstractFrontendModule;
+import uk.org.ury.frontend.FrontendMaster;
+import uk.org.ury.frontend.FrontendModulePanel;
+import uk.org.ury.frontend.client.Client;
+import uk.org.ury.frontend.exceptions.UICreationFailureException;
+
+/**
+ * Module for investigating the track library.
+ *
+ * The <code>LibraryViewer</code> and its corresponding user
+ * interface, <code>LibraryViewerPanel</code>, provide a
+ * user interface for querying the server's library services
+ * for track information.
+ *
+ * Subclasses of this module provide editing features for
+ * the track library.
+ *
+ * @author Matt Windsor
+ */
+public class LibraryViewer extends AbstractFrontendModule {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -2782366476480563739L;
+ private List<LibraryItem> libraryList;
+ private LibraryViewerPanel panel;
+
+ /**
+ * Constructs a new LibraryViewer as a frontend object.
+ */
+ public LibraryViewer() {
+ libraryList = new ArrayList<LibraryItem>();
+ panel = null;
+ }
+
+ /**
+ * Runs the library viewer frontend.
+ */
+ @Override
+ public FrontendModulePanel runFrontend(FrontendMaster master) {
+ try {
+ panel = new LibraryViewerPanel(this, master);
+ } catch (UICreationFailureException e) {
+ master.fatalError(e.getMessage());
+ }
+
+ return panel;
+ }
+
+ /**
+ * Does a library search.
+ *
+ * This will update the library list to reflect the results of the search.
+ *
+ * @param search
+ * The string fragment to use in searches. Cannot be empty or
+ * null.
+ *
+ * @throws EmptySearchException
+ * if the search string is empty or null (from
+ * LibraryUtils.search).
+ *
+ * @throws InvalidMessageException
+ * if the response from the server is invalid.
+ */
+ public void doSearch(String search) throws EmptySearchException,
+ InvalidMessageException {
+ // TODO: fan out?
+
+ if (search == null || search == "")
+ throw new EmptySearchException();
+
+ Client cl = new Client();
+ Map<?, ?> response = null;
+ libraryList.clear();
+
+ try {
+ response = cl
+ .get("/library/tracks?search="
+ + search);
+ } catch (DecodeFailureException e) {
+ throw new InvalidMessageException(e.getMessage());
+ }
+
+ /*
+ * Check to see if this is Map<String, ?> by looking for the status,
+ * which should always be in a valid response.
+ */
+
+ if (ProtocolUtils.responseIsOK(response) == false)
+ throw new InvalidMessageException(
+ (String) response.get(Directive.REASON.toString()));
+
+ // Should contain a list of items, even if there are no items.
+ if (response.containsKey(Directive.ITEMS.toString()) == false)
+ throw new InvalidMessageException("No item set returned.");
+
+ if ((response.get(Directive.ITEMS.toString()) instanceof List<?>) == false)
+ throw new InvalidMessageException("Malformed item list.");
+
+ for (Object obj : (List<?>) response.get(Directive.ITEMS.toString())) {
+ Map<LibraryItemProperty, String> properties = new HashMap<LibraryItemProperty, String>();
+
+ if (obj instanceof Map<?, ?> == false)
+ throw new InvalidMessageException("Malformed item.");
+
+ Set<?> keySet = ((Map<?, ?>) obj).keySet();
+
+ // Check to make sure this item has only String-String mappings.
+ for (Object key : keySet) {
+ if ((key instanceof String && ((Map<?, ?>) obj).get(key) instanceof String) == false)
+ throw new InvalidMessageException("Not a valid property.");
+ else if (LibraryItemProperty.valueOf((String) key) == null)
+ throw new InvalidMessageException("Property type " + key
+ + " not recognised.");
+ else
+ properties.put(LibraryItemProperty.valueOf((String) key),
+ (String) ((Map<?, ?>) obj).get(key));
+
+ }
+
+ libraryList.add(new LibraryItem(properties));
+ }
+ }
+
+ /**
+ * @return the current library list.
+ */
+
+ public List<LibraryItem> getLibraryList() {
+ return libraryList;
+ }
+}
diff --git a/src/uk/org/ury/frontend/modules/library/LibraryViewer.properties b/src/uk/org/ury/frontend/modules/library/LibraryViewer.properties
new file mode 100644
index 0000000..bb88988
--- /dev/null
+++ b/src/uk/org/ury/frontend/modules/library/LibraryViewer.properties
@@ -0,0 +1,22 @@
+// Module name
+MODULE_NAME = Library Viewer Demo
+
+// Search errors
+// 1st parameter: search term, 2nd parameter: failure reason etc.
+ERR_UNKNOWN = Unknown error.
+ERR_SEARCH_FAILED = Search for '%1$s' failed: %2$s
+ERR_EMPTY_SEARCH = Please type in a search term.
+ERR_NO_RESULTS = Sorry, but no results were found for '%1$s'.
+
+// Search messages
+// 1st parameter: search term
+MSG_SEARCHING = Searching for '%1$s', please wait...
+
+// Labels
+LBL_SEARCHFOR = Search for:
+
+// Buttons
+BTN_SEARCH = Start Search
+
+// Hint
+HINT = To narrow your search, type part or all of the record title or artist into the box above. \ No newline at end of file
diff --git a/src/uk/org/ury/frontend/modules/library/LibraryViewerPanel.java b/src/uk/org/ury/frontend/modules/library/LibraryViewerPanel.java
new file mode 100644
index 0000000..37c134a
--- /dev/null
+++ b/src/uk/org/ury/frontend/modules/library/LibraryViewerPanel.java
@@ -0,0 +1,219 @@
+/*
+ * LibraryViewerPanel.java
+ * -----------------------
+ *
+ * Part of the URY Frontend Platform
+ *
+ * V0.00 2011/03/20
+ *
+ * (C) 2011 URY Computing
+ */
+
+package uk.org.ury.frontend.modules.library;
+
+import java.util.ResourceBundle;
+import java.util.concurrent.ExecutionException;
+
+import javax.swing.JButton;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
+import javax.swing.JTextField;
+import javax.swing.SwingWorker;
+
+import uk.org.ury.common.library.exceptions.EmptySearchException;
+import uk.org.ury.common.protocol.exceptions.InvalidMessageException;
+import uk.org.ury.frontend.FrontendMaster;
+import uk.org.ury.frontend.FrontendModulePanel;
+import uk.org.ury.frontend.HintField;
+import uk.org.ury.frontend.exceptions.UICreationFailureException;
+
+/**
+ * Frontend panel providing access to an underlying library viewer.
+ *
+ * @author Matt Windsor
+ * @author Nathan Lasseter
+ */
+public class LibraryViewerPanel extends FrontendModulePanel {
+ /**
+ *
+ */
+ private static final long serialVersionUID = -2441616418398056712L;
+
+ /* Panel widgets exposed by the SwiXML user interface. */
+
+ private JTable resultsTable;
+ private JScrollPane resultsPane;
+
+ private JPanel messagePanel;
+ private JLabel messageLabel;
+
+ private JPanel searchingPanel;
+ private JLabel searchingLabel;
+
+ private JTextField searchField;
+ private JButton searchButton;
+ private JLabel searchForLabel;
+
+ private HintField hint;
+
+ /*
+ * This contains the last search failure message, for use in letting the
+ * user know what happened.
+ */
+
+ private String searchFailureMessage;
+
+ // Resource bundle.
+
+ private ResourceBundle rb;
+
+ /**
+ * Construct a new LibraryViewerPanel.
+ *
+ * @param viewer
+ * The LibraryViewer controlling this LibraryViewerPanel.
+ *
+ * @param master
+ * The FrontendMaster driving the frontend.
+ *
+ * @throws UICreationFailureException
+ * if the UI creation fails.
+ */
+
+ public LibraryViewerPanel(LibraryViewer viewer, FrontendMaster master)
+ throws UICreationFailureException {
+ /*
+ * The UI implementation is contained in library_viewer_gui.xml.
+ *
+ * See this file for more details.
+ */
+ super(viewer, "library_viewer_gui.xml", master);
+
+ // Fill in locale-specific data.
+ rb = ResourceBundle
+ .getBundle("uk.org.ury.frontend.modules.library.LibraryViewer");
+
+ searchFailureMessage = rb.getString("ERR_UNKNOWN");
+
+ searchingLabel.setText(rb.getString("MSG_SEARCHING"));
+ searchForLabel.setText(rb.getString("LBL_SEARCHFOR"));
+ searchButton.setText(rb.getString("BTN_SEARCH"));
+ hint.setText(rb.getString("HINT"));
+
+ // Fine-tune table
+ resultsTable.setAutoCreateRowSorter(true);
+ }
+
+ /**
+ * @return the name of the panel.
+ *
+ * @see uk.org.ury.frontend.FrontendModulePanel#getModuleName()
+ */
+ @Override
+ public String getModuleName() {
+ return rb.getString("MODULE_NAME");
+ }
+
+ /**
+ * Action method for performing a search, bound by the UI XML manifest to
+ * the search field and button.
+ */
+ public void search() {
+ /*
+ * We can't let the user search while another search is going on, but
+ * it's not good to let the search "freeze" the UI.
+ *
+ * Hence the search function disables all sensitive parts of the
+ * interface and launches a search as a background process.
+ *
+ * We also swap the results table or no-results panel out for a panel
+ * that says "Searching...", in the interests of user-friendliness.
+ */
+ searchField.setEnabled(false);
+ searchButton.setEnabled(false);
+ resultsPane.setVisible(false);
+ messagePanel.setVisible(false);
+ searchingPanel.setVisible(true);
+ searchingLabel.setText(String.format(rb.getString("MSG_SEARCHING"),
+ searchField.getText()));
+
+ final LibraryViewer master = (LibraryViewer) getModule();
+
+ SwingWorker<Boolean, Void> worker = new SwingWorker<Boolean, Void>() {
+ private String searchTerm = "";
+
+ /**
+ * Perform a task in a separate thread from event-dispatch.
+ *
+ * In this case, perform a search.
+ *
+ * @return whether or not the search was successful.
+ */
+ @Override
+ public Boolean doInBackground() {
+ searchTerm = searchField.getText();
+
+ try {
+ master.doSearch(searchTerm);
+ } catch (InvalidMessageException e) {
+ searchFailureMessage = String.format(
+ rb.getString("ERR_SEARCH_FAILED"), searchTerm,
+ e.getMessage());
+ return false;
+ } catch (EmptySearchException e) {
+ searchFailureMessage = rb.getString("ERR_EMPTY_SEARCH");
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Perform post-search cleanup and finalisation.
+ */
+ @Override
+ public void done() {
+ // Figure out whether or not the search succeeded.
+ boolean hasSucceeded = false;
+
+ try {
+ hasSucceeded = this.get();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ } catch (ExecutionException e) {
+ searchFailureMessage = String.format(
+ rb.getString("ERR_SEARCH_FAILED"), searchTerm,
+ e.getMessage());
+ }
+
+ /*
+ * Re-enable widgets and swap panels according to whether or not
+ * results were found.
+ */
+ searchField.setEnabled(true);
+ searchButton.setEnabled(true);
+ searchingPanel.setVisible(false);
+
+ if (hasSucceeded == false) {
+ messageLabel.setText(searchFailureMessage);
+ messagePanel.setVisible(true);
+ } else if (master.getLibraryList().size() == 0) {
+ messageLabel.setText(String.format(
+ rb.getString("ERR_NO_RESULTS"), searchTerm));
+ messagePanel.setVisible(true);
+ } else {
+ // Force table update with new results.
+ resultsTable.setModel(new LibraryTableModel(master
+ .getLibraryList()));
+
+ messagePanel.setVisible(false);
+ resultsPane.setVisible(true);
+ }
+ }
+ };
+
+ worker.execute();
+ }
+}
diff --git a/src/uk/org/ury/frontend/modules/library/library_viewer_gui.xml b/src/uk/org/ury/frontend/modules/library/library_viewer_gui.xml
new file mode 100644
index 0000000..ce30a1d
--- /dev/null
+++ b/src/uk/org/ury/frontend/modules/library/library_viewer_gui.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<panel layout="BorderLayout">
+ <hbox constraints="BorderLayout.NORTH" border="EmptyBorder(5,5,5,5)">
+ <label id="searchForLabel" labelfor="searchField" displayedmnemonic="VK_F" />
+ <hbox border="EmptyBorder(0,5,0,5)">
+ <textfield id="searchField" mnemonic="VK_F" action="search" />
+ </hbox>
+ <button id="searchButton" mnemonic="VK_S" action="search" />
+ </hbox>
+
+ <hbox constraints="BorderLayout.CENTER" border="EmptyBorder(0,5,0,5)">
+ <scrollpane id="resultsPane" constraints="BorderLayout.CENTER">
+ <table id="resultsTable" />
+ </scrollpane>
+ <panel id="searchingPanel" constraints="BorderLayout.CENTER" visible="false"
+ layout="BorderLayout">
+ <label id="searchingLabel"
+ constraints="BorderLayout.CENTER" horizontalalignment="CENTER" />
+ <progressbar id="searchingProgressBar" indeterminate="true"
+ constraints="BorderLayout.SOUTH" />
+ </panel>
+ <panel id="messagePanel" constraints="BorderLayout.CENTER" visible="false"
+ layout="BorderLayout">
+ <label id="messageLabel" text="You shouldn't see this."
+ constraints="BorderLayout.CENTER" horizontalalignment="CENTER" />
+ </panel>
+ </hbox>
+
+ <hbox constraints="BorderLayout.SOUTH" border="EmptyBorder(5,5,5,5)">
+ <hint id="hint" />
+ </hbox>
+</panel>
diff --git a/src/uk/org/ury/frontend/modules/menu/DemoMenu.java b/src/uk/org/ury/frontend/modules/menu/DemoMenu.java
new file mode 100644
index 0000000..2210ef8
--- /dev/null
+++ b/src/uk/org/ury/frontend/modules/menu/DemoMenu.java
@@ -0,0 +1,64 @@
+package uk.org.ury.frontend.modules.menu;
+
+import uk.org.ury.frontend.AbstractFrontendModule;
+import uk.org.ury.frontend.FrontendMaster;
+import uk.org.ury.frontend.FrontendModulePanel;
+import uk.org.ury.frontend.exceptions.LoadFailureException;
+
+
+/**
+ * Application frontend, for testing early-stage frontend code.
+ *
+ * @author Matt Windsor
+ *
+ */
+
+public class DemoMenu extends AbstractFrontendModule
+{
+ /**
+ *
+ */
+ private static final long serialVersionUID = -5264235507636809476L;
+ private FrontendMaster master;
+
+
+ /**
+ *
+ */
+
+ public void
+ loadModule (String module)
+ {
+ try
+ {
+ master.loadModule (module, "testrig.DemoControlPanel");
+ }
+ catch (LoadFailureException e)
+ {
+ master.fatalError (e.getMessage ());
+ }
+ }
+
+
+ /**
+ * Run the demo menu, creating a user interface.
+ */
+
+ public void
+ run ()
+ {
+
+ }
+
+
+ /**
+ * Run the demo menu in frontend mode.
+ */
+
+ @Override
+ public FrontendModulePanel
+ runFrontend (FrontendMaster master)
+ {
+ return new DemoMenuPanel (master);
+ }
+}
diff --git a/src/uk/org/ury/frontend/modules/menu/DemoMenuPanel.java b/src/uk/org/ury/frontend/modules/menu/DemoMenuPanel.java
new file mode 100644
index 0000000..3520f2a
--- /dev/null
+++ b/src/uk/org/ury/frontend/modules/menu/DemoMenuPanel.java
@@ -0,0 +1,68 @@
+package uk.org.ury.frontend.modules.menu;
+
+import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.JButton;
+
+import uk.org.ury.frontend.FrontendMaster;
+import uk.org.ury.frontend.FrontendModulePanel;
+import uk.org.ury.frontend.exceptions.LoadFailureException;
+
+public class DemoMenuPanel extends FrontendModulePanel {
+ /**
+ *
+ */
+ private static final long serialVersionUID = 5268978856289909262L;
+
+ /**
+ * Construct a new DemoMenuPanel.
+ *
+ * @param inMaster
+ * The new frontend master of the panel, if any.
+ */
+ public DemoMenuPanel(FrontendMaster inMaster) {
+ super(null, inMaster);
+
+ setLayout(new GridLayout(2, 1));
+
+ JButton lb = new JButton("Library Viewer Demo");
+ JButton sb = new JButton("Show Viewer Demo");
+
+ lb.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent arg0) {
+ try {
+ master.loadModule("library.LibraryViewer",
+ "menu.DemoControlPanel");
+ } catch (LoadFailureException e) {
+ master.fatalError(e.getMessage());
+ }
+ }
+ });
+
+ sb.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent arg0) {
+ try {
+ master.loadModule("show.ShowViewer",
+ "menu.DemoControlPanel");
+ } catch (LoadFailureException e) {
+ master.fatalError(e.getMessage());
+ }
+ }
+ });
+
+ add(lb);
+ add(sb);
+ }
+
+ /**
+ * @return the name of the module.
+ */
+ @Override
+ public String getModuleName() {
+ return "Demo Menu";
+ }
+}
diff --git a/src/uk/org/ury/frontend/modules/show/ChannelPanel.java b/src/uk/org/ury/frontend/modules/show/ChannelPanel.java
new file mode 100644
index 0000000..150f1bc
--- /dev/null
+++ b/src/uk/org/ury/frontend/modules/show/ChannelPanel.java
@@ -0,0 +1,84 @@
+/**
+ *
+ */
+package uk.org.ury.frontend.modules.show;
+
+import java.awt.event.KeyEvent;
+
+import javax.swing.JButton;
+import javax.swing.JLabel;
+import javax.swing.JList;
+
+import uk.org.ury.common.show.ShowChannel;
+import uk.org.ury.frontend.FrontendPanel;
+import uk.org.ury.frontend.exceptions.UICreationFailureException;
+
+
+/**
+ * A panel displaying channel information.
+ *
+ * @author Matt Windsor.
+ */
+
+public class ChannelPanel extends FrontendPanel
+{
+ /**
+ *
+ */
+ private static final long serialVersionUID = 897125684384350966L;
+
+
+ /* Components created and exposed by the XML engine. */
+
+ private JLabel channelName;
+ private JList itemList;
+ private JButton playButton;
+ private JButton pauseButton;
+ private JButton stopButton;
+
+
+ /**
+ * Construct a new ChannelPanel.
+ *
+ * This constructor reads the channel panel layout from the
+ * XML manifest "channel_panel.xml" in the same directory as
+ * this class file.
+ *
+ * @param number The number of the channel.
+ *
+ * @param channel The channel whose data the ChannelPanel is viewing.
+ *
+ * @throws UICreationFailureException if the UI creation fails.
+ */
+
+ public
+ ChannelPanel (int number, ShowChannel channel)
+ throws UICreationFailureException
+ {
+ super ("channel_panel.xml", null);
+
+
+ // Tweak buttons to add function key mnemonics, if function keys are available.
+
+ if (number <= 3)
+ {
+ int base = (number - 1) * 4;
+
+ playButton.setText ("Play (F" + (base + 1) + ")");
+ playButton.setMnemonic (KeyEvent.VK_F1 + (base ));
+ playButton.setDisplayedMnemonicIndex (7);
+
+ pauseButton.setText ("Stop (F" + (base + 2) + ")");
+ pauseButton.setMnemonic (KeyEvent.VK_F2 + (base ));
+ pauseButton.setDisplayedMnemonicIndex (7);
+
+ stopButton.setText ("Pause (F" + (base + 3) + ")");
+ stopButton.setMnemonic (KeyEvent.VK_F3 + (base ));
+ stopButton.setDisplayedMnemonicIndex (8);
+ }
+
+ // Test stuff
+ itemList.setModel (channel);
+ channelName.setText ("Channel " + number);
+ }
+}
diff --git a/src/uk/org/ury/frontend/modules/show/ShowViewer.java b/src/uk/org/ury/frontend/modules/show/ShowViewer.java
new file mode 100644
index 0000000..641ee3a
--- /dev/null
+++ b/src/uk/org/ury/frontend/modules/show/ShowViewer.java
@@ -0,0 +1,118 @@
+/*
+ * ShowViewer.java
+ * ---------------
+ *
+ * Part of the URY Frontend Platform
+ *
+ * V0.00 2011/03/20
+ *
+ * (C) 2011 URY Computing
+ */
+
+package uk.org.ury.frontend.modules.show;
+
+import java.util.List;
+
+import uk.org.ury.backend.config.ConfigReader;
+import uk.org.ury.backend.database.DatabaseDriver;
+import uk.org.ury.backend.database.UserClass;
+import uk.org.ury.backend.database.exceptions.MissingCredentialsException;
+import uk.org.ury.backend.database.exceptions.QueryFailureException;
+import uk.org.ury.common.show.ShowChannel;
+import uk.org.ury.common.show.ShowUtils;
+import uk.org.ury.common.show.item.ShowItem;
+import uk.org.ury.frontend.AbstractFrontendModule;
+import uk.org.ury.frontend.FrontendMaster;
+import uk.org.ury.frontend.FrontendModulePanel;
+import uk.org.ury.frontend.exceptions.UICreationFailureException;
+
+/**
+ * Frontend module for viewing show details.
+ *
+ * This serves as the base for the show playout and editor classes, but can be
+ * used stand-alone as an (admittedly rather pointless) module.
+ *
+ * @author Matt Windsor
+ *
+ */
+public class ShowViewer extends AbstractFrontendModule {
+ /**
+ *
+ */
+
+ private static final long serialVersionUID = -2782366476480563739L;
+ private DatabaseDriver dd;
+ private ShowChannel[] channels;
+ private ShowViewerPanel panel;
+ private ConfigReader config;
+
+ /**
+ * Construct a new ShowViewer as a frontend object.
+ */
+ public ShowViewer() {
+ channels = new ShowChannel[ShowUtils.NUM_CHANNELS];
+ }
+
+ /**
+ * Run the library viewer frontend.
+ */
+ @Override
+ public FrontendModulePanel runFrontend(FrontendMaster master) {
+ dd = null;
+ config = null;
+
+ try {
+ config = new ConfigReader(master.getResourceDirectory()
+ + "conf.xml");
+ } catch (MissingCredentialsException e) {
+ System.out.println(e);
+ }
+
+ try {
+ dd = new DatabaseDriver(config, UserClass.READ_ONLY);
+ } catch (MissingCredentialsException e) {
+ // TODO: Privilege de-escalation
+ master.fatalError(e.getMessage());
+ } catch (Exception f) {
+ master.fatalError(f.getMessage());
+ }
+
+ for (int i = 0; i < channels.length; i++) {
+ channels[i] = new ShowChannel();
+
+ try {
+ for (ShowItem item : ShowUtils.getChannelList(dd, 4696, i)) {
+ channels[i].add(item);
+ }
+ } catch (QueryFailureException e) {
+ master.fatalError(e.getMessage());
+ }
+ }
+
+ try {
+ panel = new ShowViewerPanel(this, master);
+ } catch (UICreationFailureException e) {
+ master.fatalError(e.getMessage());
+ }
+
+ return panel;
+ }
+
+ /**
+ * @return the channel array.
+ */
+ public ShowChannel[] getChannels() {
+ // TODO Auto-generated method stub
+ return channels;
+ }
+
+ /**
+ * @return the list of bin names.
+ *
+ * @throws QueryFailureException
+ * if the underlying database query fails.
+ */
+ public List<String> getBins() throws QueryFailureException {
+ return ShowUtils.getPublicFolders(dd);
+ }
+}
diff --git a/src/uk/org/ury/frontend/modules/show/ShowViewerPanel.java b/src/uk/org/ury/frontend/modules/show/ShowViewerPanel.java
new file mode 100644
index 0000000..c4eb6e2
--- /dev/null
+++ b/src/uk/org/ury/frontend/modules/show/ShowViewerPanel.java
@@ -0,0 +1,133 @@
+/**
+ *
+ */
+package uk.org.ury.frontend.modules.show;
+
+import java.awt.GridLayout;
+import java.util.List;
+
+import javax.swing.JPanel;
+
+import uk.org.ury.backend.database.exceptions.QueryFailureException;
+import uk.org.ury.common.show.ShowChannel;
+import uk.org.ury.frontend.FrontendMaster;
+import uk.org.ury.frontend.FrontendModulePanel;
+import uk.org.ury.frontend.exceptions.LoadFailureException;
+import uk.org.ury.frontend.exceptions.UICreationFailureException;
+
+
+/**
+ * Frontend panel providing access to an underlying show viewer.
+ *
+ * The various show user interfaces (show editor, playout etc.)
+ * are derived from this.
+ *
+ * @author Matt Windsor, Nathan Lasseter
+ */
+
+public class ShowViewerPanel extends FrontendModulePanel
+{
+ /**
+ *
+ */
+ private static final long serialVersionUID = -2441616418398056712L;
+
+
+ /* Panel widgets exposed by the SwiXML user interface. */
+
+ private JPanel channelGroupPanel;
+ private JPanel binGroupPanel;
+
+
+ /**
+ * Construct a new ShowViewerPanel.
+ *
+ * The panel will interface with the given show viewer and is
+ * expected to be placed as a sub-component in the given
+ * FrontendMaster.
+ *
+ * @param viewer The ShowViewer controlling this LibraryViewerPanel.
+ *
+ * @param master The FrontendMaster driving the frontend.
+ *
+ * @throws UICreationFailureException if the UI creation fails.
+ */
+
+ public
+ ShowViewerPanel (ShowViewer viewer, FrontendMaster master)
+ throws UICreationFailureException
+ {
+ super (viewer, "show_viewer_gui.xml", master);
+
+ int channelNumber = 1;
+ ChannelPanel cp;
+
+ for (ShowChannel channel : viewer.getChannels ())
+ {
+ cp = new ChannelPanel (channelNumber, channel);
+
+ channelGroupPanel.add (cp);
+ channelNumber++;
+ }
+
+ channelGroupPanel.setLayout (new GridLayout (1, channelNumber - 1));
+
+
+ // TEST
+ List<String> binNames = null;
+
+ try
+ {
+ binNames = viewer.getBins ();
+ }
+ catch (QueryFailureException e)
+ {
+ master.fatalError (e.getMessage ());
+ }
+
+ TrackBin tb;
+
+ for (String name : binNames)
+ {
+ tb = new TrackBin (name);
+
+ binGroupPanel.add (tb);
+ }
+
+ binGroupPanel.setLayout (new GridLayout (1, binNames.size ()));
+ }
+
+
+ /**
+ * @return the name of the panel.
+ *
+ * @see uk.org.ury.frontend.FrontendModulePanel#getModuleName()
+ */
+
+ @Override
+ public String
+ getModuleName ()
+ {
+ return "Show Viewer Demo";
+ }
+
+
+ /**
+ * Initialise the library viewer for the purposes of adding tracks
+ * and/or browsing the library.
+ */
+
+ public void
+ search ()
+ {
+ try
+ {
+ master.loadModule ("library.LibraryViewer",
+ "show.LibraryControlPanel");
+ }
+ catch (LoadFailureException e)
+ {
+ master.fatalError (e.getMessage ());
+ }
+ }
+}
diff --git a/src/uk/org/ury/frontend/modules/show/TrackBin.java b/src/uk/org/ury/frontend/modules/show/TrackBin.java
new file mode 100644
index 0000000..96b67f4
--- /dev/null
+++ b/src/uk/org/ury/frontend/modules/show/TrackBin.java
@@ -0,0 +1,56 @@
+/**
+ *
+ */
+package uk.org.ury.frontend.modules.show;
+
+import javax.swing.JLabel;
+
+import uk.org.ury.frontend.FrontendPanel;
+import uk.org.ury.frontend.exceptions.UICreationFailureException;
+
+
+/**
+ * A panel displaying track bin contents.
+ *
+ * @author Matt Windsor.
+ */
+
+public class TrackBin extends FrontendPanel
+{
+ /**
+ *
+ */
+ private static final long serialVersionUID = -5414923374901972511L;
+
+
+ /* Components created and exposed by the XML engine. */
+
+ private JLabel binName;
+
+
+ /**
+ * Construct a new TrackBin.
+ *
+ * This constructor reads the channel panel layout from the
+ * XML manifest "track_bin.xml" in the same directory as
+ * this class file.
+ *
+ * TODO: add track list into constructor
+ *
+ * @param name The name of the bin.
+ *
+ * @throws UICreationFailureException if the UI creation fails.
+ */
+
+ public
+ TrackBin (String name)
+ throws UICreationFailureException
+ {
+ super ("track_bin.xml", null);
+
+ // Tweak name.
+
+ binName.setText (name);
+
+ }
+}
diff --git a/src/uk/org/ury/frontend/modules/show/channel_panel.xml b/src/uk/org/ury/frontend/modules/show/channel_panel.xml
new file mode 100644
index 0000000..bf576ce
--- /dev/null
+++ b/src/uk/org/ury/frontend/modules/show/channel_panel.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<panel border="EmptyBorder(5,5,5,5)" layout="BorderLayout">
+ <subbanner id="channelName" text="Channel x"
+ constraints="BorderLayout.NORTH" />
+ <vbox constraints="BorderLayout.CENTER">
+ <scrollpane id="itemScroller" constraints="BorderLayout.CENTER">
+ <list id="itemList" visiblerowcount="1" />
+ </scrollpane>
+ </vbox>
+ <vbox constraints="BorderLayout.SOUTH">
+ <panel layout="GridLayout(1,3)">
+ <button id="playButton" text="Play" />
+ <button id="pauseButton" text="Pause" />
+ <button id="stopButton" text="Stop" />
+ </panel>
+ <panel layout="GridLayout(3, 1)">
+ <label text="Name of track" />
+ <hbox border="EtchedBorder">
+ <label text="Duration chart" />
+ </hbox>
+ <hbox>
+ <glue />
+ <hbox border="EmptyBorder(5,5,5,5)">
+ <label text="Elapsed: " />
+ <label text="0:00:00" font="Verdana-BOLD-14" />
+ </hbox>
+ <glue />
+ <hbox border="EmptyBorder(5,5,5,5)">
+ <label text="Remaining: " />
+ <label text="0:00:00" font="Verdana-BOLD-14" />
+ </hbox>
+ <glue />
+ </hbox>
+ </panel>
+ </vbox>
+</panel> \ No newline at end of file
diff --git a/src/uk/org/ury/frontend/modules/show/show_viewer_gui.xml b/src/uk/org/ury/frontend/modules/show/show_viewer_gui.xml
new file mode 100644
index 0000000..90b8cb5
--- /dev/null
+++ b/src/uk/org/ury/frontend/modules/show/show_viewer_gui.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<panel layout="BorderLayout">
+ <hbox constraints="BorderLayout.NORTH" border="EmptyBorder(5,5,5,5)">
+ <button id="loadButton" text="Load Show or Template..." mnemonic="VK_L"
+ action="load" />
+ <button id="searchButton" text="Search Record Library" mnemonic="VK_S"
+ action="search" />
+ <glue />
+ <button id="helpButton" text="Help..." mnemonic="VK_H"
+ action="help" />
+ <button id="feedbackButton" text="Feedback..." mnemonic="VK_F"
+ action="feedback" />
+ </hbox>
+
+ <panel layout="BorderLayout" constraints="BorderLayout.CENTER">
+ <panel layout="BorderLayout" constraints="BorderLayout.NORTH">
+ <subbanner text="Useful Tracks"
+ constraints="BorderLayout.NORTH" />
+ <scrollpane id="binScrollPane"
+ constraints="BorderLayout.CENTER">
+ <panel id="binGroupPanel" />
+ </scrollpane>
+ </panel>
+ <panel layout="BorderLayout" constraints="BorderLayout.CENTER">
+ <subbanner text="Sound Channels"
+ constraints="BorderLayout.NORTH" />
+ <scrollpane id="channelScrollPane"
+ constraints="BorderLayout.CENTER">
+ <panel id="channelGroupPanel" />
+ </scrollpane>
+ </panel>
+ <panel layout="BorderLayout" constraints="BorderLayout.SOUTH">
+ <subbanner text="Quick Notes"
+ constraints="BorderLayout.NORTH" />
+ <textarea id="noteArea" border="LoweredBevelBorder"
+ text="Type quick notes here..." rows="3" />
+ </panel>
+ </panel>
+
+ <hbox constraints="BorderLayout.SOUTH" border="EmptyBorder(5,5,5,5)">
+ <hint text="For help, click the Help button." />
+ </hbox>
+</panel>
diff --git a/src/uk/org/ury/frontend/modules/show/show_viewer_gui_old.xml b/src/uk/org/ury/frontend/modules/show/show_viewer_gui_old.xml
new file mode 100644
index 0000000..d11e579
--- /dev/null
+++ b/src/uk/org/ury/frontend/modules/show/show_viewer_gui_old.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<panel layout="BorderLayout">
+ <hbox constraints="BorderLayout.NORTH" border="EmptyBorder(5,5,5,5)">
+ <button id="loadButton" text="Load Show or Template..." mnemonic="VK_L"
+ action="load" />
+ <button id="searchButton" text="Search Record Library" mnemonic="VK_S"
+ action="search" />
+ <glue />
+ <button id="helpButton" text="Help..." mnemonic="VK_H"
+ action="help" />
+ <button id="feedbackButton" text="Feedback..." mnemonic="VK_F"
+ action="feedback" />
+ </hbox>
+
+ <splitpane constraints="BorderLayout.CENTER" border="EmptyBorder(0,5,0,5)"
+ id="mainSplit" orientation="0">
+ <splitpane orientation="0" id="binSplit">
+ <panel layout="BorderLayout">
+ <subbanner text="Useful Tracks"
+ constraints="BorderLayout.NORTH" />
+ <scrollpane id="binScrollPane"
+ constraints="BorderLayout.CENTER">
+ <panel id="binGroupPanel" />
+ </scrollpane>
+ </panel>
+ <panel layout="BorderLayout">
+ <subbanner text="Sound Channels"
+ constraints="BorderLayout.NORTH" />
+ <scrollpane id="channelScrollPane"
+ constraints="BorderLayout.CENTER">
+ <panel id="channelGroupPanel" />
+ </scrollpane>
+ </panel>
+ </splitpane>
+ <panel layout="BorderLayout">
+ <subbanner text="Quick Notes"
+ constraints="BorderLayout.NORTH" />
+ <textarea id="noteArea" border="LoweredBevelBorder"
+ text="Type quick notes here..." rows="3" />
+ </panel>
+ </splitpane>
+
+ <hbox constraints="BorderLayout.SOUTH" border="EmptyBorder(5,5,5,5)">
+ <hint text="For help, click the Help button." />
+ </hbox>
+</panel>
diff --git a/src/uk/org/ury/frontend/modules/show/show_viewer_gui_panels.xml b/src/uk/org/ury/frontend/modules/show/show_viewer_gui_panels.xml
new file mode 100644
index 0000000..eda711b
--- /dev/null
+++ b/src/uk/org/ury/frontend/modules/show/show_viewer_gui_panels.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<panel layout="BorderLayout">
+ <hbox constraints="BorderLayout.NORTH" border="EmptyBorder(5,5,5,5)">
+ <button id="loadButton" text="Load Show or Template..." mnemonic="VK_L"
+ action="load" />
+ <button id="searchButton" text="Search Record Library" mnemonic="VK_S"
+ action="search" />
+ <glue />
+ <button id="helpButton" text="Help..." mnemonic="VK_H"
+ action="help" />
+ <button id="feedbackButton" text="Feedback..." mnemonic="VK_F"
+ action="feedback" />
+ </hbox>
+
+ <panel constraints="BorderLayout.CENTER" layout="BorderLayout>
+ <panel layout="BorderLayout" constraints="BorderLayout.NORTH">
+ <subbanner text="Useful Tracks"
+ constraints="BorderLayout.NORTH" />
+ <scrollpane id="binScrollPane"
+ constraints="BorderLayout.CENTER">
+ <panel id="binGroupPanel" />
+ </scrollpane>
+ </panel>
+ <panel layout="BorderLayout" constraints="BorderLayout.CENTER">
+ <subbanner text="Sound Channels"
+ constraints="BorderLayout.NORTH" />
+ <scrollpane id="channelScrollPane"
+ constraints="BorderLayout.CENTER">
+ <panel id="channelGroupPanel" />
+ </scrollpane>
+ </panel>
+ <panel layout="BorderLayout" constraints="BorderLayout.SOUTH">
+ <subbanner text="Quick Notes"
+ constraints="BorderLayout.NORTH" />
+ <textarea id="noteArea" border="LoweredBevelBorder"
+ text="Type quick notes here..." rows="3" />
+ </panel>
+ </panel>
+
+ <hbox constraints="BorderLayout.SOUTH" border="EmptyBorder(5,5,5,5)">
+ <hint text="For help, click the Help button." />
+ </hbox>
+</panel>
diff --git a/src/uk/org/ury/frontend/modules/show/track_bin.xml b/src/uk/org/ury/frontend/modules/show/track_bin.xml
new file mode 100644
index 0000000..d1ff9da
--- /dev/null
+++ b/src/uk/org/ury/frontend/modules/show/track_bin.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<panel border="EmptyBorder(5,5,5,5)" layout="BorderLayout">
+ <subbanner id="binName" text="Bin"
+ constraints="BorderLayout.NORTH" />
+ <vbox>
+ <scrollpane id="itemScroller">
+ <list id="itemList" visiblerowcount="5" />
+ </scrollpane>
+ </vbox>
+</panel> \ No newline at end of file