diff options
Diffstat (limited to 'cmpcj/src/de')
17 files changed, 407 insertions, 124 deletions
diff --git a/cmpcj/src/de/schwarzrot/control/app/CMPCJ.java b/cmpcj/src/de/schwarzrot/control/app/CMPCJ.java index 9dc2158..c138d96 100644 --- a/cmpcj/src/de/schwarzrot/control/app/CMPCJ.java +++ b/cmpcj/src/de/schwarzrot/control/app/CMPCJ.java @@ -40,6 +40,7 @@ import java.beans.PropertyChangeListener; import java.io.BufferedReader; import java.io.File; import java.io.InputStreamReader; +import java.net.NoRouteToHostException; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Comparator; @@ -67,6 +68,7 @@ import javax.swing.UIManager; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreeModel; +import javax.swing.tree.TreePath; import bibliothek.gui.dock.common.CControl; import bibliothek.gui.dock.common.CGrid; import bibliothek.gui.dock.common.theme.ThemeMap; @@ -92,6 +94,8 @@ import de.schwarzrot.base.util.MessageBundle; import de.schwarzrot.base.util.SuccessHandler; import de.schwarzrot.control.client.CMPClient; import de.schwarzrot.control.client.MediaClientExecutor; +import de.schwarzrot.control.config.CMPUIDark; +import de.schwarzrot.control.config.CMPUIDefaults; import de.schwarzrot.control.config.ConfigDialog; import de.schwarzrot.control.config.ConfigFactory; import de.schwarzrot.control.dnd.ListSelectionSourceTransferHandler; @@ -102,21 +106,25 @@ import de.schwarzrot.control.support.SelectedMedia; import de.schwarzrot.control.support.TreeCellEditor; import de.schwarzrot.control.support.TreeSelectionFilter; import de.schwarzrot.control.table.MediaTableFormat; -import de.schwarzrot.media.domain.AbstractMediaNode; import de.schwarzrot.media.domain.Config; import de.schwarzrot.media.domain.Genre; import de.schwarzrot.media.domain.Media; import de.schwarzrot.media.domain.MediaServer; import de.schwarzrot.media.domain.PlayerDefinition; +import de.schwarzrot.media.service.AbstractMediaChangeCommand; +import de.schwarzrot.media.service.CreateMediaCommand; import de.schwarzrot.media.service.DataManager; import de.schwarzrot.media.service.MediaExecutor; +import de.schwarzrot.media.service.RemoveMediaCommand; import de.schwarzrot.media.util.ListLoader; import de.schwarzrot.media.util.MedialistParser; public class CMPCJ extends WindowAdapter implements PropertyChangeListener, SuccessHandler, - ListEventListener<AbstractMediaNode>, MediaClientExecutor { + ListEventListener<AbstractMediaChangeCommand>, MediaClientExecutor { private static final String PREFFERRED_LOOK_N_FEEL = "Nimbus"; //$NON-NLS-1$ + // private static final String PREFFERRED_LOOK_N_FEEL = "CDE/Motif"; //$NON-NLS-1$ + // private static final String PREFFERRED_LOOK_N_FEEL = "GTK+"; //$NON-NLS-1$ private static final String USER_HOME = "user.home"; //$NON-NLS-1$ private static final String DOCKING_CONFIG = "srdocking.conf"; //$NON-NLS-1$ enum Commands { @@ -126,7 +134,7 @@ public class CMPCJ extends WindowAdapter implements PropertyChangeListener, Succ public CMPCJ(String[] args, ConfigFactory configFactory) { nodeCache = new HashMap<File, DefaultMutableTreeNode>(); - changes = new BasicEventList<AbstractMediaNode>(); + changes = new BasicEventList<AbstractMediaChangeCommand>(); rootNode = new DefaultMutableTreeNode(setupServices(args, configFactory)); changes.addListEventListener(this); } @@ -136,16 +144,19 @@ public class CMPCJ extends WindowAdapter implements PropertyChangeListener, Succ @SuppressWarnings("unchecked") ActionManager<Commands> am = ApplicationServiceProvider.getService(ActionManager.class); MessageBundle mb = ApplicationServiceProvider.getService(MessageBundle.class); + UIDefaults theme = ApplicationServiceProvider.getService(UIDefaults.class); mediaList = new SortedList<Media>(GlazedListsSwing.swingThreadProxyList(new BasicEventList<Media>())); try { String lookNFeel = UIManager.getSystemLookAndFeelClassName(); for (UIManager.LookAndFeelInfo lfi : UIManager.getInstalledLookAndFeels()) { + // System.out.println("installed look and feel: " + lfi.getName()); if (PREFFERRED_LOOK_N_FEEL.equals(lfi.getName())) lookNFeel = lfi.getClassName(); } UIManager.setLookAndFeel(lookNFeel); + theme.apply(); } catch (Exception e) { System.err.println(mb.getMessage(CMPMessageBundle.MCC_6)); } @@ -239,11 +250,20 @@ public class CMPCJ extends WindowAdapter implements PropertyChangeListener, Succ @Override public void handleFailure(Throwable t) { - // loading list from server failed ... - if (t instanceof UnknownHostException) { - //TODO: tell the user ... + if (t.getCause() != null) { + MessageBundle mb = ApplicationServiceProvider.getService(MessageBundle.class); + Throwable rt = t.getCause(); + + // loading list from server failed ... + if (rt instanceof UnknownHostException) { + JOptionPane.showMessageDialog(frame, mb.getMessage(CMPMessageBundle.MCC_1), + mb.getMessage(CMPMessageBundle.MCC_2), JOptionPane.ERROR_MESSAGE); + } else if (rt instanceof NoRouteToHostException) { + JOptionPane.showMessageDialog(frame, mb.getMessage(CMPMessageBundle.MCC_3), + mb.getMessage(CMPMessageBundle.MCC_2), JOptionPane.ERROR_MESSAGE); + } } - t.printStackTrace(); + t.printStackTrace(System.err); tree.updateUI(); updateServerActions(false); } @@ -258,7 +278,7 @@ public class CMPCJ extends WindowAdapter implements PropertyChangeListener, Succ @Override - public void listChanged(ListEvent<AbstractMediaNode> arg0) { + public void listChanged(ListEvent<AbstractMediaChangeCommand> e) { // get rid of changes made by user @SuppressWarnings("unchecked") ActionManager<Commands> am = ApplicationServiceProvider.getService(ActionManager.class); @@ -334,6 +354,7 @@ public class CMPCJ extends WindowAdapter implements PropertyChangeListener, Succ protected JComponent createMediaTableView() { MessageBundle mb = ApplicationServiceProvider.getService(MessageBundle.class); + UIDefaults theme = ApplicationServiceProvider.getService(UIDefaults.class); JTextField filterEdit = new JTextField(30); mediaTypeSelector = new MediaTypeSelector(mediaList); FilterList<Media> typeFilteredMedias = new FilterList<Media>(mediaList, mediaTypeSelector); @@ -352,6 +373,8 @@ public class CMPCJ extends WindowAdapter implements PropertyChangeListener, Succ mediaJTable.setTransferHandler(new ListSelectionSourceTransferHandler(selectionModel)); mediaJTable.setSelectionModel(selectionModel); mediaJTable.addMouseListener(new MediaExecutor(mediaJTable, textFilteredMedias, this)); + mediaJTable.setSelectionBackground(theme.getColor("Table[Enabled+Selected].textBackground")); + mediaJTable.setSelectionForeground(theme.getColor("Table[Enabled+Selected].textForeground")); @SuppressWarnings({ "rawtypes", "unused" }) TableComparatorChooser tableSorter = TableComparatorChooser.install(mediaJTable, mediaList, TableComparatorChooser.MULTIPLE_COLUMN_MOUSE_WITH_UNDO); @@ -406,7 +429,7 @@ public class CMPCJ extends WindowAdapter implements PropertyChangeListener, Succ mWindow.add(cdGenreTree.createMenuItem()); mWindow.add(cdMediaTypes.createMenuItem()); mWindow.add(cdProperties.createMenuItem()); - //TODO: not yet + //XXX: not yet // mHelp.add(new JMenuItem(getAction(Commands.HelpHelp))); // mHelp.add(new JSeparator()); mHelp.add(new JMenuItem(am.getAction(Commands.HelpAbout))); @@ -423,6 +446,7 @@ public class CMPCJ extends WindowAdapter implements PropertyChangeListener, Succ propertyList = GlazedLists.eventList(selectedMedia.getMedia().getProperties().entrySet()); else propertyList = new BasicEventList<Map.Entry<String, Object>>(); + UIDefaults theme = ApplicationServiceProvider.getService(UIDefaults.class); SortedList<Map.Entry<String, Object>> psl = new SortedList<Map.Entry<String, Object>>(propertyList, new Comparator<Map.Entry<String, Object>>() { @Override @@ -443,6 +467,9 @@ public class CMPCJ extends WindowAdapter implements PropertyChangeListener, Succ if (cw > 0) propertyTable.getColumnModel().getColumn(i).setMaxWidth(cw); } + propertyTable.setSelectionBackground(theme.getColor("Table[Enabled+Selected].textBackground")); + propertyTable.setSelectionForeground(theme.getColor("Table[Enabled+Selected].textForeground")); + return psp; } @@ -510,12 +537,30 @@ public class CMPCJ extends WindowAdapter implements PropertyChangeListener, Succ // respond to tree action protected void doCreateGenre() { + TreePath selectionPath = tree.getSelectionPath(); + + if (selectionPath == null) + return; MessageBundle mb = ApplicationServiceProvider.getService(MessageBundle.class); + DefaultMutableTreeNode node = (DefaultMutableTreeNode) selectionPath.getLastPathComponent(); + DefaultMutableTreeNode parent = (DefaultMutableTreeNode) node.getParent(); + Genre parentGenre = (Genre) parent.getUserObject(); + String name = (String) JOptionPane.showInputDialog(frame, mb.getMessage("create.genre.prompt"), + mb.getMessage("create.genre.title"), JOptionPane.PLAIN_MESSAGE, null, null, "new"); - System.out.println(mb.getMessage(CMPMessageBundle.MCC_17)); + if (name == null) + return; + if (name.contains(File.pathSeparator)) { + System.err.println("NO - name may not contain path separator!"); + return; + } + System.out.println("name for new genre: " + name); + Genre newGenre = new Genre(parentGenre, new File(parentGenre.getRealPath(), name)); - //TODO: ask user for genre name and create node and cache entries + node = new DefaultMutableTreeNode(newGenre); + parent.add(node); tree.updateUI(); + changes.add(new CreateMediaCommand(newGenre)); }; @@ -543,11 +588,24 @@ public class CMPCJ extends WindowAdapter implements PropertyChangeListener, Succ Genre g = (Genre) node.getUserObject(); if (g.getMediaList().size() > 0 || g.getChildren().size() > 0) { - //TODO: ask user and/or pop some warning + Object[] options = { "Yes", "No" }; + int n = JOptionPane.showOptionDialog(frame, mb.getMessage(CMPMessageBundle.MCC_9), + mb.getMessage(CMPMessageBundle.MCC_8), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, + null, options, options[1]); + + System.err.println("node to delete has children! - really delete?!?"); + + if (n == 0) { + ((DefaultMutableTreeNode) node.getParent()).remove(node); + removeGenre(g); + tree.updateUI(); + changes.add(new RemoveMediaCommand(g)); + } } else { nodeCache.remove(g.getRealPath()); ((DefaultMutableTreeNode) node.getParent()).remove(node); tree.updateUI(); + changes.add(new RemoveMediaCommand(g)); } } @@ -579,6 +637,23 @@ public class CMPCJ extends WindowAdapter implements PropertyChangeListener, Succ } + protected void removeGenre(Genre g) { + nodeCache.remove(g.getRealPath()); + if (g.getMediaList() != null && g.getMediaList().size() > 0) { + mediaList.getReadWriteLock().writeLock().lock(); + for (Media m : g.getMediaList()) { + mediaList.remove(m); + } + mediaList.getReadWriteLock().writeLock().unlock(); + } + if (g.getChildren() != null && g.getChildren().size() > 0) { + for (Genre child : g.getChildren()) { + removeGenre(child); + } + } + } + + protected void restoreAppStatus() { Config config = ApplicationServiceProvider.getService(Config.class); @@ -670,7 +745,9 @@ public class CMPCJ extends WindowAdapter implements PropertyChangeListener, Succ protected Genre setupServices(String[] args, ConfigFactory configFactory) { MessageBundle mb = new CMPMessageBundle(); configDirectory = configFactory.getConfigDirectory(); - ApplicationServiceProvider.registerService(Config.class, configFactory.getConfig()); + Config cfg = configFactory.getConfig(); + + ApplicationServiceProvider.registerService(Config.class, cfg); ApplicationServiceProvider.registerService(ConfigFactory.class, configFactory); ApplicationServiceProvider.registerService(MessageBundle.class, mb); if (args.length > 0) { @@ -687,6 +764,8 @@ public class CMPCJ extends WindowAdapter implements PropertyChangeListener, Succ ApplicationServiceProvider.registerService(DataManager.class, new DataManager(input, nodeCache)); ApplicationServiceProvider.registerService(ImageFactory.class, new ImageFactory()); ApplicationServiceProvider.registerService(MedialistParser.class, new MedialistParser()); + ApplicationServiceProvider.registerService(UIDefaults.class, cfg.isUseDarkStyle() ? new CMPUIDark() + : new CMPUIDefaults()); File base = new File("/"); //$NON-NLS-1$ Genre root = new Genre(base); @@ -723,7 +802,7 @@ public class CMPCJ extends WindowAdapter implements PropertyChangeListener, Succ private DefaultMutableTreeNode rootNode; private SortedList<Media> mediaList; private SelectedMedia selectedMedia; - private EventList<AbstractMediaNode> changes; + private EventList<AbstractMediaChangeCommand> changes; private Map<File, DefaultMutableTreeNode> nodeCache; private EventList<Map.Entry<String, Object>> propertyList; private MediaTypeSelector mediaTypeSelector; diff --git a/cmpcj/src/de/schwarzrot/control/app/CMPMessageBundle.java b/cmpcj/src/de/schwarzrot/control/app/CMPMessageBundle.java index 33c4854..a4db7cb 100644 --- a/cmpcj/src/de/schwarzrot/control/app/CMPMessageBundle.java +++ b/cmpcj/src/de/schwarzrot/control/app/CMPMessageBundle.java @@ -1,25 +1,25 @@ /** * ======================== legal notice ====================== * - * File: MCCMessageBundle.java - * Created: 13. June 2012, 04:57 - * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> - * Project: cmpc - a java frontend (client) part of compound media player - * uses external players to play the media + * File: MCCMessageBundle.java Created: 13. June 2012, 04:57 Author: <a + * href="mailto:geronimo013@gmx.de">Geronimo</a> Project: cmpc - a java frontend + * (client) part of compound media player uses external players to play the + * media * * CMP - compound media player * - * is a client/server mediaplayer intended to play any media from any workstation - * without the need to export or mount shares. cmps is an easy to use backend - * with a (ready to use) HTML-interface. Additionally the backend supports - * authentication via HTTP-digest authorization. - * cmpc is a client with vdr-like osd-menues. + * is a client/server mediaplayer intended to play any media from any + * workstation without the need to export or mount shares. cmps is an easy to + * use backend with a (ready to use) HTML-interface. Additionally the backend + * supports authentication via HTTP-digest authorization. cmpc is a client with + * vdr-like osd-menues. * - * Copyright (c) 2012 Reinhard Mantey, some rights reserved! - * published under Creative Commons by-sa - * For details see http://creativecommons.org/licenses/by-sa/3.0/ + * Copyright (c) 2012 Reinhard Mantey, some rights reserved! published under + * Creative Commons by-sa For details see + * http://creativecommons.org/licenses/by-sa/3.0/ * - * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp + * The cmp project's homepage is at + * http://projects.vdr-developer.org/projects/cmp * * -------------------------------------------------------------- */ @@ -33,6 +33,15 @@ import de.schwarzrot.base.util.MessageBundle; public class CMPMessageBundle implements MessageBundle { public static final String MCC_0 = "MCC_0"; + public static final String MCC_1 = "MCC_1"; + public static final String MCC_2 = "MCC_2"; + public static final String MCC_3 = "MCC_3"; + public static final String MCC_4 = "MCC_4"; + public static final String MCC_5 = "MCC_5"; + public static final String MCC_6 = "MCC_6"; + public static final String MCC_7 = "MCC_7"; + public static final String MCC_8 = "MCC_8"; + public static final String MCC_9 = "MCC_9"; public static final String MCC_12 = "MCC_12"; public static final String MCC_13 = "MCC_13"; public static final String MCC_14 = "MCC_14"; @@ -48,10 +57,6 @@ public class CMPMessageBundle implements MessageBundle { public static final String MCC_31 = "MCC_31"; public static final String MCC_33 = "MCC_33"; public static final String MCC_35 = "MCC_35"; - public static final String MCC_4 = "MCC_4"; - public static final String MCC_5 = "MCC_5"; - public static final String MCC_6 = "MCC_6"; - public static final String MCC_7 = "MCC_7"; public static final String PTF_0 = "PTF_0"; public static final String PTF_1 = "PTF_1"; public static final String MTF_0 = "MTF_0"; diff --git a/cmpcj/src/de/schwarzrot/control/app/UIDefaults.java b/cmpcj/src/de/schwarzrot/control/app/UIDefaults.java new file mode 100644 index 0000000..7ecd0c9 --- /dev/null +++ b/cmpcj/src/de/schwarzrot/control/app/UIDefaults.java @@ -0,0 +1,12 @@ +package de.schwarzrot.control.app; + + +import java.awt.Color; + + +public interface UIDefaults { + public void apply(); + + + public Color getColor(String key); +}
\ No newline at end of file diff --git a/cmpcj/src/de/schwarzrot/control/client/CMPClient.java b/cmpcj/src/de/schwarzrot/control/client/CMPClient.java index 38c6ccb..8d8196e 100644 --- a/cmpcj/src/de/schwarzrot/control/client/CMPClient.java +++ b/cmpcj/src/de/schwarzrot/control/client/CMPClient.java @@ -1,25 +1,25 @@ /** * ======================== legal notice ====================== * - * File: CMPClient.java - * Created: 13. June 2012, 04:57 - * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> - * Project: cmpc - a java frontend (client) part of compound media player - * uses external players to play the media + * File: CMPClient.java Created: 13. June 2012, 04:57 Author: <a + * href="mailto:geronimo013@gmx.de">Geronimo</a> Project: cmpc - a java frontend + * (client) part of compound media player uses external players to play the + * media * * CMP - compound media player * - * is a client/server mediaplayer intended to play any media from any workstation - * without the need to export or mount shares. cmps is an easy to use backend - * with a (ready to use) HTML-interface. Additionally the backend supports - * authentication via HTTP-digest authorization. - * cmpc is a client with vdr-like osd-menues. + * is a client/server mediaplayer intended to play any media from any + * workstation without the need to export or mount shares. cmps is an easy to + * use backend with a (ready to use) HTML-interface. Additionally the backend + * supports authentication via HTTP-digest authorization. cmpc is a client with + * vdr-like osd-menues. * - * Copyright (c) 2012 Reinhard Mantey, some rights reserved! - * published under Creative Commons by-sa - * For details see http://creativecommons.org/licenses/by-sa/3.0/ + * Copyright (c) 2012 Reinhard Mantey, some rights reserved! published under + * Creative Commons by-sa For details see + * http://creativecommons.org/licenses/by-sa/3.0/ * - * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp + * The cmp project's homepage is at + * http://projects.vdr-developer.org/projects/cmp * * -------------------------------------------------------------- */ @@ -27,16 +27,17 @@ package de.schwarzrot.control.client; import java.net.ConnectException; +import java.net.NoRouteToHostException; import java.net.URL; import java.net.URLConnection; import java.net.UnknownHostException; import java.util.Date; import ca.odell.glazedlists.EventList; import de.schwarzrot.base.util.ApplicationServiceProvider; -import de.schwarzrot.media.domain.AbstractMediaNode; import de.schwarzrot.media.domain.Media; import de.schwarzrot.media.domain.MediaServer; import de.schwarzrot.media.domain.PlayList; +import de.schwarzrot.media.service.AbstractMediaChangeCommand; import de.schwarzrot.media.util.ElementConsumer; import de.schwarzrot.media.util.ListLoader; import de.schwarzrot.media.util.MedialistParser; @@ -101,6 +102,8 @@ public class CMPClient implements ListLoader<Media> { System.out.println("processing of first playlist-part took " + (end.getTime() - start.getTime()) + " ms."); } catch (UnknownHostException uhe) { throw new RuntimeException("failed to connect to " + server.getHostName(), uhe); + } catch (NoRouteToHostException nre) { + throw new RuntimeException("failed to connect to " + server.getHostName(), nre); } catch (ConnectException ce) { throw new RuntimeException("connection failure with " + server.getHostName(), ce); } catch (Throwable t) { @@ -156,13 +159,13 @@ public class CMPClient implements ListLoader<Media> { } - public void transmitChanges(EventList<AbstractMediaNode> changes) { - for (AbstractMediaNode n : changes) { - System.out.println("geƤnderter Eintrag: " + n.getClass().getSimpleName() + " - " + n.getName()); //$NON-NLS-1$ - System.out.println("\tverschieben von " + n.getOriginalPath().getAbsolutePath() + " nach " - + n.getRealPath().getAbsolutePath()); + public void transmitChanges(EventList<AbstractMediaChangeCommand> changes) { + for (AbstractMediaChangeCommand cc : changes) { + System.out.println("got change command of type: " + cc.getCommandType()); + System.out.println("\toriginal was: " + cc.getMediaNode().getOriginalPath().getAbsolutePath() + "\tnew: " + + cc.getMediaNode().getRealPath().getAbsolutePath()); - //TODO: really create jobs for changes, so backend can participate on work + //TODO: transform and send to server } } diff --git a/cmpcj/src/de/schwarzrot/control/config/CMPUIDark.java b/cmpcj/src/de/schwarzrot/control/config/CMPUIDark.java new file mode 100644 index 0000000..237980d --- /dev/null +++ b/cmpcj/src/de/schwarzrot/control/config/CMPUIDark.java @@ -0,0 +1,53 @@ +package de.schwarzrot.control.config; + + +import java.awt.Color; +import java.util.HashMap; +import java.util.Map; +import javax.swing.UIManager; +import de.schwarzrot.control.app.UIDefaults; + + +public class CMPUIDark implements UIDefaults { + private static final Color DarkBlue; + private static final Map<String, Color> theme; + + + public void apply() { + for (String key : theme.keySet()) + UIManager.put(key, theme.get(key)); + } + + + public Color getColor(String key) { + if (theme.containsKey(key)) + return theme.get(key); + Object rv = UIManager.get(key); + + if (rv instanceof Color) + return (Color) rv; + return Color.GRAY; + } + + static { + DarkBlue = new Color(0, 0, 50); + theme = new HashMap<String, Color>(); + + theme.put("control", Color.BLACK); // Dialog, Panel, defaults + theme.put("nimbusBase", Color.BLUE); + theme.put("nimbusBlueGrey", Color.DARK_GRAY); + theme.put("nimbusBorder", Color.BLACK); + theme.put("nimbusFocus", Color.CYAN); + theme.put("nimbusLightBackground", Color.BLACK); // Tree, Textfield + theme.put("Table.alternateRowColor", DarkBlue); + theme.put("Table[Enabled+Selected].textForeground", Color.CYAN); + theme.put("Tree.selectionForeground", Color.CYAN); // Tree selected Text + theme.put("info", Color.BLUE); // info background + theme.put("text", Color.WHITE); // inactive dockable tabs foreground (includes textForeground, menuText, infoText) + theme.put("menu", Color.DARK_GRAY); // inactive dockable tabs background + theme.put("nimbusSelectionBackground", Color.BLUE); + theme.put("nimbusSelection", Color.BLUE); // active dockable tabs background + theme.put("menuText", Color.YELLOW); // inactive dockable tabs foreground + theme.put("textForeground", Color.WHITE); // standard Text + } +} diff --git a/cmpcj/src/de/schwarzrot/control/config/CMPUIDefaults.java b/cmpcj/src/de/schwarzrot/control/config/CMPUIDefaults.java new file mode 100644 index 0000000..6c6ed3f --- /dev/null +++ b/cmpcj/src/de/schwarzrot/control/config/CMPUIDefaults.java @@ -0,0 +1,36 @@ +package de.schwarzrot.control.config; + + +import java.awt.Color; +import java.util.HashMap; +import java.util.Map; +import javax.swing.UIManager; +import de.schwarzrot.control.app.UIDefaults; + + +public class CMPUIDefaults implements UIDefaults { + private static final Map<String, Color> theme; + + + @Override + public void apply() { + for (String key : theme.keySet()) + UIManager.put(key, theme.get(key)); + } + + + @Override + public Color getColor(String key) { + if (theme.containsKey(key)) + return theme.get(key); + Object rv = UIManager.get(key); + + if (rv instanceof Color) + return (Color) rv; + return Color.GRAY; + } + + static { + theme = new HashMap<String, Color>(); + } +} diff --git a/cmpcj/src/de/schwarzrot/control/config/ConfigDialog.java b/cmpcj/src/de/schwarzrot/control/config/ConfigDialog.java index 32bd808..0f28610 100644 --- a/cmpcj/src/de/schwarzrot/control/config/ConfigDialog.java +++ b/cmpcj/src/de/schwarzrot/control/config/ConfigDialog.java @@ -30,13 +30,14 @@ import java.awt.Dimension; import java.awt.Window; import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; import java.util.ArrayList; import java.util.List; import java.util.Map; import javax.swing.AbstractAction; import javax.swing.JComponent; import javax.swing.JScrollPane; -import javax.swing.JTabbedPane; import javax.swing.JTable; import javax.swing.KeyStroke; import javax.swing.ListSelectionModel; @@ -53,6 +54,7 @@ import ca.odell.glazedlists.swing.DefaultEventTableModel; import de.schwarzrot.base.dock.BasicDockable; import de.schwarzrot.base.util.AbstractDialog; import de.schwarzrot.base.util.ApplicationServiceProvider; +import de.schwarzrot.control.app.UIDefaults; import de.schwarzrot.control.table.PlayerDefinitionTableFormat; import de.schwarzrot.control.table.ServerDefinitionTableFormat; import de.schwarzrot.media.domain.AbstractMediaNode; @@ -69,13 +71,22 @@ public class ConfigDialog extends AbstractDialog implements WindowProvider { event.forbid(); } } + private class WindowListener extends WindowAdapter { + @Override + public void windowOpened(WindowEvent e) { + System.out.println("window opened ..."); + servers.toFront(); + } + } public ConfigDialog(Window parent) { super(parent, true, DialogMode.CANCEL_APPROVE, Orientation.Right); config = ApplicationServiceProvider.getService(Config.class); listeners = new ArrayList<WindowProviderListener>(); + theme = ApplicationServiceProvider.getService(UIDefaults.class); setFixedSize(new Dimension(520, 320)); + this.addWindowListener(new WindowListener()); } @@ -86,16 +97,6 @@ public class ConfigDialog extends AbstractDialog implements WindowProvider { } - public JComponent create_Old_ContentPane() { - JTabbedPane rv = new JTabbedPane(); - - rv.addTab("server", createServerTable()); - rv.addTab("player", createPlayerTable()); - - return rv; - } - - @Override public JComponent createContentPane() { CControl docking = new CControl(this); @@ -104,10 +105,10 @@ public class ConfigDialog extends AbstractDialog implements WindowProvider { docking.setTheme(ThemeMap.KEY_ECLIPSE_THEME); docking.getController().getRelocator() .addVetoableDockRelocatorListener(new TabbedVetoableDockRelocatorListener()); - BasicDockable servers = new BasicDockable("servers", msgBundle.getMessage(getClass().getSimpleName() - + ".servers"), createServerTable()); BasicDockable players = new BasicDockable("players", msgBundle.getMessage(getClass().getSimpleName() + ".players"), createPlayerTable()); + servers = new BasicDockable("servers", msgBundle.getMessage(getClass().getSimpleName() + ".servers"), + createServerTable()); servers.setMinimizable(false); servers.setExternalizable(false); @@ -115,8 +116,9 @@ public class ConfigDialog extends AbstractDialog implements WindowProvider { players.setMinimizable(false); players.setExternalizable(false); players.setMaximizable(false); - grid.add(0, 0, 1, 1, players); grid.add(0, 0, 1, 1, servers); + grid.add(0, 0, 1, 1, players); + grid.select(0, 0, 1, 1, servers); docking.getContentArea().deploy(grid); return docking.getContentArea(); @@ -162,6 +164,8 @@ public class ConfigDialog extends AbstractDialog implements WindowProvider { } } playerTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + playerTable.setSelectionBackground(theme.getColor("Table[Enabled+Selected].textBackground")); + playerTable.setSelectionForeground(theme.getColor("Table[Enabled+Selected].textForeground")); return playerTableScrollPane; } @@ -201,6 +205,8 @@ public class ConfigDialog extends AbstractDialog implements WindowProvider { }); serverTable.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_INSERT, 0), "createServerDefinition"); serverTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + serverTable.setSelectionBackground(theme.getColor("Table[Enabled+Selected].textBackground")); + serverTable.setSelectionForeground(theme.getColor("Table[Enabled+Selected].textForeground")); return serverTableScrollPane; } @@ -223,5 +229,7 @@ public class ConfigDialog extends AbstractDialog implements WindowProvider { private EventList<MediaServer> serverDefinitions; private EventList<PlayerDefinition> playerDefinitions; private List<WindowProviderListener> listeners; + private BasicDockable servers; + private UIDefaults theme; private Config config; } diff --git a/cmpcj/src/de/schwarzrot/control/config/ConfigFactory.java b/cmpcj/src/de/schwarzrot/control/config/ConfigFactory.java index edf438a..eb53b4f 100644 --- a/cmpcj/src/de/schwarzrot/control/config/ConfigFactory.java +++ b/cmpcj/src/de/schwarzrot/control/config/ConfigFactory.java @@ -120,6 +120,9 @@ public class ConfigFactory { } } } + } else if (key.compareToIgnoreCase("style") == 0) { + if (value.compareToIgnoreCase("dark") == 0) + rv.setUseDarkStyle(true); } else if (key.compareToIgnoreCase("size") == 0) { String[] parts = value.split("\\s*x\\s*"); diff --git a/cmpcj/src/de/schwarzrot/control/dnd/TreeSourceAndDestTransferHandler.java b/cmpcj/src/de/schwarzrot/control/dnd/TreeSourceAndDestTransferHandler.java index 4c481f2..c61d943 100644 --- a/cmpcj/src/de/schwarzrot/control/dnd/TreeSourceAndDestTransferHandler.java +++ b/cmpcj/src/de/schwarzrot/control/dnd/TreeSourceAndDestTransferHandler.java @@ -37,9 +37,10 @@ import javax.swing.TransferHandler; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.TreePath; import ca.odell.glazedlists.EventList; -import de.schwarzrot.media.domain.AbstractMediaNode; import de.schwarzrot.media.domain.Genre; import de.schwarzrot.media.domain.Media; +import de.schwarzrot.media.service.AbstractMediaChangeCommand; +import de.schwarzrot.media.service.ChangeMediaCommand; public class TreeSourceAndDestTransferHandler extends TransferHandler { @@ -47,7 +48,7 @@ public class TreeSourceAndDestTransferHandler extends TransferHandler { public TreeSourceAndDestTransferHandler(JTree tree, Map<File, DefaultMutableTreeNode> cache, - EventList<AbstractMediaNode> changes) { + EventList<AbstractMediaChangeCommand> changes) { this.tree = tree; nodeCache = cache; this.changes = changes; @@ -123,7 +124,7 @@ public class TreeSourceAndDestTransferHandler extends TransferHandler { refreshNodeCache(); if (!changes.contains(transfer)) { changes.getReadWriteLock().writeLock().lock(); - changes.add(transfer); + changes.add(new ChangeMediaCommand(transfer)); changes.getReadWriteLock().writeLock().unlock(); } } catch (Throwable t) { @@ -178,11 +179,22 @@ public class TreeSourceAndDestTransferHandler extends TransferHandler { if (transferMedia != null) { transferMedia.setParent(targetGenre); if (!changes.contains(transferMedia)) { - changes.getReadWriteLock().writeLock().lock(); - changes.add(transferMedia); - changes.getReadWriteLock().writeLock().unlock(); + try { + changes.getReadWriteLock().writeLock().lock(); + changes.add(new ChangeMediaCommand(transferMedia)); + changes.getReadWriteLock().writeLock().unlock(); + } catch (Throwable t) { + t.printStackTrace(); + } } + } else { + System.err.println("transfer media not found in genre medialist!"); } + } else { + if (targetGenre == null) + System.err.println("failed to determine target genre!"); + if (node == null) + System.err.println("failed to determine source parent node of " + mediaPath.getAbsolutePath()); } } @@ -195,6 +207,6 @@ public class TreeSourceAndDestTransferHandler extends TransferHandler { } private JTree tree; - private EventList<AbstractMediaNode> changes; + private EventList<AbstractMediaChangeCommand> changes; private Map<File, DefaultMutableTreeNode> nodeCache; } diff --git a/cmpcj/src/de/schwarzrot/control/support/SelectedMedia.java b/cmpcj/src/de/schwarzrot/control/support/SelectedMedia.java index efde378..1ab15de 100644 --- a/cmpcj/src/de/schwarzrot/control/support/SelectedMedia.java +++ b/cmpcj/src/de/schwarzrot/control/support/SelectedMedia.java @@ -1,25 +1,25 @@ /** * ======================== legal notice ====================== * - * File: SelectedMedia.java - * Created: 13. June 2012, 04:57 - * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> - * Project: cmpc - a java frontend (client) part of compound media player - * uses external players to play the media + * File: SelectedMedia.java Created: 13. June 2012, 04:57 Author: <a + * href="mailto:geronimo013@gmx.de">Geronimo</a> Project: cmpc - a java frontend + * (client) part of compound media player uses external players to play the + * media * * CMP - compound media player * - * is a client/server mediaplayer intended to play any media from any workstation - * without the need to export or mount shares. cmps is an easy to use backend - * with a (ready to use) HTML-interface. Additionally the backend supports - * authentication via HTTP-digest authorization. - * cmpc is a client with vdr-like osd-menues. + * is a client/server mediaplayer intended to play any media from any + * workstation without the need to export or mount shares. cmps is an easy to + * use backend with a (ready to use) HTML-interface. Additionally the backend + * supports authentication via HTTP-digest authorization. cmpc is a client with + * vdr-like osd-menues. * - * Copyright (c) 2012 Reinhard Mantey, some rights reserved! - * published under Creative Commons by-sa - * For details see http://creativecommons.org/licenses/by-sa/3.0/ + * Copyright (c) 2012 Reinhard Mantey, some rights reserved! published under + * Creative Commons by-sa For details see + * http://creativecommons.org/licenses/by-sa/3.0/ * - * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp + * The cmp project's homepage is at + * http://projects.vdr-developer.org/projects/cmp * * -------------------------------------------------------------- */ @@ -75,7 +75,10 @@ public class SelectedMedia implements ListSelectionListener { if (sm.isSelectionEmpty()) return; - pcs.firePropertyChange(MEDIA_PROPERTY, this.media, this.media = mediaList.get(sm.getLeadSelectionIndex())); + int i = sm.getLeadSelectionIndex(); + + if (i > 0) + pcs.firePropertyChange(MEDIA_PROPERTY, this.media, this.media = mediaList.get(i)); } } diff --git a/cmpcj/src/de/schwarzrot/control/support/TreeCellEditor.java b/cmpcj/src/de/schwarzrot/control/support/TreeCellEditor.java index b436207..6935249 100644 --- a/cmpcj/src/de/schwarzrot/control/support/TreeCellEditor.java +++ b/cmpcj/src/de/schwarzrot/control/support/TreeCellEditor.java @@ -8,12 +8,13 @@ import javax.swing.event.ChangeEvent; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeCellEditor; import javax.swing.tree.DefaultTreeCellRenderer; -import de.schwarzrot.media.domain.AbstractMediaNode; import de.schwarzrot.media.domain.Genre; +import de.schwarzrot.media.service.AbstractMediaChangeCommand; +import de.schwarzrot.media.service.ChangeMediaCommand; public class TreeCellEditor extends DefaultTreeCellEditor implements CellEditorListener { - public TreeCellEditor(JTree tree, List<AbstractMediaNode> changes) { + public TreeCellEditor(JTree tree, List<AbstractMediaChangeCommand> changes) { super(tree, (DefaultTreeCellRenderer) tree.getCellRenderer()); this.changes = changes; addCellEditorListener(this); @@ -33,7 +34,7 @@ public class TreeCellEditor extends DefaultTreeCellEditor implements CellEditorL genre.setName((String) editedValue); if (!changes.contains(genre)) - changes.add(genre); + changes.add(new ChangeMediaCommand(genre)); } @@ -48,5 +49,5 @@ public class TreeCellEditor extends DefaultTreeCellEditor implements CellEditorL private Object editedValue; private DefaultMutableTreeNode editedNode; - private List<AbstractMediaNode> changes; + private List<AbstractMediaChangeCommand> changes; } diff --git a/cmpcj/src/de/schwarzrot/media/domain/Config.java b/cmpcj/src/de/schwarzrot/media/domain/Config.java index d273972..826ad55 100644 --- a/cmpcj/src/de/schwarzrot/media/domain/Config.java +++ b/cmpcj/src/de/schwarzrot/media/domain/Config.java @@ -1,25 +1,25 @@ /** * ======================== legal notice ====================== * - * File: Config.java - * Created: 13. June 2012, 04:57 - * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> - * Project: cmpc - a java frontend (client) part of compound media player - * uses external players to play the media + * File: Config.java Created: 13. June 2012, 04:57 Author: <a + * href="mailto:geronimo013@gmx.de">Geronimo</a> Project: cmpc - a java frontend + * (client) part of compound media player uses external players to play the + * media * * CMP - compound media player * - * is a client/server mediaplayer intended to play any media from any workstation - * without the need to export or mount shares. cmps is an easy to use backend - * with a (ready to use) HTML-interface. Additionally the backend supports - * authentication via HTTP-digest authorization. - * cmpc is a client with vdr-like osd-menues. + * is a client/server mediaplayer intended to play any media from any + * workstation without the need to export or mount shares. cmps is an easy to + * use backend with a (ready to use) HTML-interface. Additionally the backend + * supports authentication via HTTP-digest authorization. cmpc is a client with + * vdr-like osd-menues. * - * Copyright (c) 2012 Reinhard Mantey, some rights reserved! - * published under Creative Commons by-sa - * For details see http://creativecommons.org/licenses/by-sa/3.0/ + * Copyright (c) 2012 Reinhard Mantey, some rights reserved! published under + * Creative Commons by-sa For details see + * http://creativecommons.org/licenses/by-sa/3.0/ * - * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp + * The cmp project's homepage is at + * http://projects.vdr-developer.org/projects/cmp * * -------------------------------------------------------------- */ @@ -79,6 +79,11 @@ public class Config { } + public boolean isUseDarkStyle() { + return useDarkStyle; + } + + public void putPlayer(Media.SupportedMediaType type, PlayerDefinition pd) { playerMap.put(type, pd); } @@ -118,9 +123,15 @@ public class Config { this.posY = posY; } + + public void setUseDarkStyle(boolean useDarkStyle) { + this.useDarkStyle = useDarkStyle; + } + private List<MediaServer> knownServers; private Map<Media.SupportedMediaType, PlayerDefinition> playerMap; private boolean debug; + private boolean useDarkStyle; private int posX; private int posY; private int mainWidth; diff --git a/cmpcj/src/de/schwarzrot/media/service/AbstractMediaChangeCommand.java b/cmpcj/src/de/schwarzrot/media/service/AbstractMediaChangeCommand.java new file mode 100644 index 0000000..de6bf8d --- /dev/null +++ b/cmpcj/src/de/schwarzrot/media/service/AbstractMediaChangeCommand.java @@ -0,0 +1,25 @@ +package de.schwarzrot.media.service; + + +import de.schwarzrot.media.domain.AbstractMediaNode; + + +public abstract class AbstractMediaChangeCommand { + protected AbstractMediaChangeCommand(AbstractMediaNode media, String type) { + mediaNode = media; + commandType = type; + } + + + public String getCommandType() { + return commandType; + } + + + public AbstractMediaNode getMediaNode() { + return mediaNode; + } + + private AbstractMediaNode mediaNode; + private String commandType; +} diff --git a/cmpcj/src/de/schwarzrot/media/service/ChangeMediaCommand.java b/cmpcj/src/de/schwarzrot/media/service/ChangeMediaCommand.java new file mode 100644 index 0000000..da23f8b --- /dev/null +++ b/cmpcj/src/de/schwarzrot/media/service/ChangeMediaCommand.java @@ -0,0 +1,11 @@ +package de.schwarzrot.media.service; + + +import de.schwarzrot.media.domain.AbstractMediaNode; + + +public class ChangeMediaCommand extends AbstractMediaChangeCommand { + public ChangeMediaCommand(AbstractMediaNode mediaNode) { + super(mediaNode, "M"); + } +} diff --git a/cmpcj/src/de/schwarzrot/media/service/CreateMediaCommand.java b/cmpcj/src/de/schwarzrot/media/service/CreateMediaCommand.java new file mode 100644 index 0000000..745d2ce --- /dev/null +++ b/cmpcj/src/de/schwarzrot/media/service/CreateMediaCommand.java @@ -0,0 +1,11 @@ +package de.schwarzrot.media.service; + + +import de.schwarzrot.media.domain.AbstractMediaNode; + + +public class CreateMediaCommand extends AbstractMediaChangeCommand { + public CreateMediaCommand(AbstractMediaNode mediaNode) { + super(mediaNode, "C"); + } +} diff --git a/cmpcj/src/de/schwarzrot/media/service/MediaFactory.java b/cmpcj/src/de/schwarzrot/media/service/MediaFactory.java index ff31822..3ee711d 100644 --- a/cmpcj/src/de/schwarzrot/media/service/MediaFactory.java +++ b/cmpcj/src/de/schwarzrot/media/service/MediaFactory.java @@ -1,25 +1,25 @@ /** * ======================== legal notice ====================== * - * File: MediaFactory.java - * Created: 13. June 2012, 04:57 - * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> - * Project: cmpc - a java frontend (client) part of compound media player - * uses external players to play the media + * File: MediaFactory.java Created: 13. June 2012, 04:57 Author: <a + * href="mailto:geronimo013@gmx.de">Geronimo</a> Project: cmpc - a java frontend + * (client) part of compound media player uses external players to play the + * media * * CMP - compound media player * - * is a client/server mediaplayer intended to play any media from any workstation - * without the need to export or mount shares. cmps is an easy to use backend - * with a (ready to use) HTML-interface. Additionally the backend supports - * authentication via HTTP-digest authorization. - * cmpc is a client with vdr-like osd-menues. + * is a client/server mediaplayer intended to play any media from any + * workstation without the need to export or mount shares. cmps is an easy to + * use backend with a (ready to use) HTML-interface. Additionally the backend + * supports authentication via HTTP-digest authorization. cmpc is a client with + * vdr-like osd-menues. * - * Copyright (c) 2012 Reinhard Mantey, some rights reserved! - * published under Creative Commons by-sa - * For details see http://creativecommons.org/licenses/by-sa/3.0/ + * Copyright (c) 2012 Reinhard Mantey, some rights reserved! published under + * Creative Commons by-sa For details see + * http://creativecommons.org/licenses/by-sa/3.0/ * - * The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp + * The cmp project's homepage is at + * http://projects.vdr-developer.org/projects/cmp * * -------------------------------------------------------------- */ @@ -50,10 +50,9 @@ public class MediaFactory { } - //TODO: - // here we can't rely on file system information. + //XXX: here we can't rely on file system information. // may be we got files from remote system ... - // so instead to use lookahead for multifile movies, we need to go back + // so instead of using lookahead for multifile movies, we need to go back // from keyfiles public Media createMedia(File mayBeMedia) { if (!mayBeMedia.getAbsolutePath().startsWith(prefix)) diff --git a/cmpcj/src/de/schwarzrot/media/service/RemoveMediaCommand.java b/cmpcj/src/de/schwarzrot/media/service/RemoveMediaCommand.java new file mode 100644 index 0000000..a4f0854 --- /dev/null +++ b/cmpcj/src/de/schwarzrot/media/service/RemoveMediaCommand.java @@ -0,0 +1,11 @@ +package de.schwarzrot.media.service; + + +import de.schwarzrot.media.domain.AbstractMediaNode; + + +public class RemoveMediaCommand extends AbstractMediaChangeCommand { + public RemoveMediaCommand(AbstractMediaNode mediaNode) { + super(mediaNode, "R"); + } +} |