/*
This file is part of JFLICKS.
JFLICKS is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
JFLICKS is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with JFLICKS. If not, see <http://www.gnu.org/licenses/>.
*/
package org.jflicks.ui.view.fe;
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
import javax.imageio.ImageIO;
import javax.swing.AbstractAction;
import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JWindow;
import javax.swing.KeyStroke;
import javax.swing.Timer;
import org.jflicks.nms.NMS;
import org.jflicks.nms.NMSConstants;
import org.jflicks.nms.NMSUtil;
import org.jflicks.nms.Video;
import org.jflicks.photomanager.Photo;
import org.jflicks.photomanager.Tag;
import org.jflicks.rc.RC;
import org.jflicks.rc.RCProperty;
import org.jflicks.tv.Recording;
import org.jflicks.tv.RecordingRule;
import org.jflicks.tv.Upcoming;
import org.jflicks.ui.view.JFlicksView;
import org.jflicks.ui.view.fe.screen.ExecuteScreen;
import org.jflicks.ui.view.fe.screen.Screen;
import org.jflicks.ui.view.fe.screen.ScreenEvent;
import org.jflicks.ui.view.fe.screen.ScreenListener;
import org.jflicks.util.LogUtil;
import org.jflicks.util.Util;
import org.jdesktop.core.animation.timing.Animator;
import org.jdesktop.core.animation.timing.PropertySetter;
import org.jdesktop.core.animation.timing.TimingTarget;
import org.jdesktop.core.animation.timing.TimingTargetAdapter;
import org.jdesktop.swingx.JXFrame;
import org.jdesktop.swingx.JXPanel;
import org.jdesktop.swingx.graphics.GraphicsUtilities;
/**
* A base class that full Views can extend.
*
* @author Doug Barnum
* @version 1.0
*/
public class FrontEndView extends JFlicksView implements ActionListener,
PropertyChangeListener, RCProperty, ScreenListener {
private JXFrame frame;
private JXPanel panel;
private TextImagePanel textIconPanel;
private ArrayList<Screen> screenList;
private NMS[] nms;
private RC rc;
private Cursor noCursor;
private boolean hideMouse;
private int pathCount;
private ArrayList<String> fromPathList;
private ArrayList<String> toPathList;
private Rectangle positionRectangle;
private Timer activityTimer;
private ActivityActionListener activityActionListener;
private JWindow blankWindow;
private long lastActivityMillis;
/**
* Default constructor.
*/
public FrontEndView() {
setScreenList(new ArrayList<Screen>());
setPathCount(-1);
setFromPathList(new ArrayList<String>());
setToPathList(new ArrayList<String>());
setLastActivityMillis(System.currentTimeMillis());
ActivityActionListener aal = new ActivityActionListener();
setActivityActionListener(aal);
Timer t = new Timer(60000, aal);
setActivityTimer(t);
t.start();
}
/**
* {@inheritDoc}
*/
public RC getRC() {
return (rc);
}
/**
* {@inheritDoc}
*/
public void setRC(RC r) {
rc = r;
if (rc != null) {
rc.setKeyboardControl(true);
rc.setEventControl(true);
}
}
private NMS[] getNMS() {
return (nms);
}
private void setNMS(NMS[] array) {
nms = array;
}
private Cursor getNoCursor() {
return (noCursor);
}
private void setNoCursor(Cursor c) {
noCursor = c;
}
private JXPanel getPanel() {
return (panel);
}
private void setPanel(JXPanel p) {
panel = p;
}
private TextImagePanel getTextImagePanel() {
return (textIconPanel);
}
private void setTextImagePanel(TextImagePanel p) {
textIconPanel = p;
}
private ArrayList<Screen> getScreenList() {
return (screenList);
}
private void setScreenList(ArrayList<Screen> l) {
screenList = l;
}
private ActivityActionListener getActivityActionListener() {
return (activityActionListener);
}
private void setActivityActionListener(ActivityActionListener aal) {
activityActionListener = aal;
}
private Timer getActivityTimer() {
return (activityTimer);
}
private void setActivityTimer(Timer t) {
activityTimer = t;
}
private long getLastActivityMillis() {
return (lastActivityMillis);
}
private void setLastActivityMillis(long l) {
lastActivityMillis = l;
}
private boolean isBlanked() {
boolean result = false;
if (blankWindow != null) {
result = blankWindow.isVisible();
}
return (result);
}
private void setBlanked(boolean b) {
if (blankWindow != null) {
blankWindow.setVisible(b);
}
}
/**
* We keep track of screens that are available to us.
*
* @param s A given screen.
*/
public void addScreen(Screen s) {
ArrayList<Screen> l = getScreenList();
if ((l != null) && (s != null)) {
s.setView(this);
l.add(s);
Collections.sort(l);
}
}
/**
* We keep track of screens that are available to us.
*
* @param s A given screen.
*/
public void removeScreen(Screen s) {
ArrayList<Screen> l = getScreenList();
if ((l != null) && (s != null)) {
l.remove(s);
}
}
private Screen[] getScreens() {
Screen[] result = null;
ArrayList<Screen> l = getScreenList();
if ((l != null) && (l.size() > 0)) {
result = l.toArray(new Screen[l.size()]);
}
return (result);
}
private ArrayList<String> getFromPathList() {
return (fromPathList);
}
private void setFromPathList(ArrayList<String> l) {
fromPathList = l;
}
private ArrayList<String> getToPathList() {
return (toPathList);
}
private void setToPathList(ArrayList<String> l) {
toPathList = l;
}
private int getPathCount() {
if (pathCount == -1) {
// First time here. Lets check the Properties just once if
// path transforms even exist. This will save parsing Strings
// a tremendous amount og times. First thing set it to zero.
pathCount = 0;
Properties p = getProperties();
if (p != null) {
pathCount = Util.str2int(p.getProperty("pathCount"), 0);
if (pathCount > 0) {
// It's easier to process the paths if we put them in
// associative lists. So lets do that now.
ArrayList<String> fl = getFromPathList();
ArrayList<String> tl = getToPathList();
if ((fl != null) && (tl != null)) {
fl.clear();
tl.clear();
for (int i = 0; i < pathCount; i++) {
String from = p.getProperty("pathFrom" + i);
String to = p.getProperty("pathTo" + i);
if ((from != null) && (to != null)) {
fl.add(from);
tl.add(to);
}
}
// Reset the pathCount to the actual pairs we found.
pathCount = fl.size();
}
}
}
}
return (pathCount);
}
private void setPathCount(int i) {
pathCount = i;
}
/**
* Convenience method available to Screens to transform any path
* to something else that is available to this client. Path
* transformations are defined in jflicks.properties in the install
* directory.
*
* @param path Transform the given path to something else.
* @return A proper path for this client.
*/
public String transformPath(String path) {
String result = path;
if (path != null) {
int pcount = getPathCount();
if (pcount > 0) {
ArrayList<String> fl = getFromPathList();
ArrayList<String> tl = getToPathList();
if ((fl != null) && (tl != null)) {
for (int i = 0; i < fl.size(); i++) {
String from = fl.get(i);
if (path.startsWith(from)) {
// We are done. Set out result.
int length = from.length();
result = tl.get(i) + path.substring(length);
if (Util.isWindows()) {
result = result.replace("/", "\\");
}
break;
}
}
}
}
}
return (result);
}
private void transformRecording(Recording r) {
if (r != null) {
if (getPathCount() > 0) {
r.setPath(transformPath(r.getPath()));
}
}
}
private void transformRecordings(Recording[] array) {
if ((array != null) && (array.length > 0)) {
if (getPathCount() > 0) {
// We have paths to check. We can't be sure actually
// anything will change but we have to check.
for (int i = 0; i < array.length; i++) {
array[i].setPath(transformPath(array[i].getPath()));
}
}
}
}
private void transformPhotos(Photo[] array) {
if ((array != null) && (array.length > 0)) {
if (getPathCount() > 0) {
// We have paths to check. We can't be sure actually
// anything will change but we have to check.
for (int i = 0; i < array.length; i++) {
array[i].setPath(transformPath(array[i].getPath()));
}
}
}
}
private void transformVideos(Video[] array) {
if ((array != null) && (array.length > 0)) {
if (getPathCount() > 0) {
// We have paths to check. We can't be sure actually
// anything will change but we have to check.
for (int i = 0; i < array.length; i++) {
array[i].setPath(transformPath(array[i].getPath()));
}
}
}
}
private NMS[] filterNMS(NMS[] array) {
// By default don't filter anything...
NMS[] result = array;
if (array != null) {
Properties p = getProperties();
if (p != null) {
String groups = p.getProperty("groups");
if (groups != null) {
// We only filter if groups is set to something...
String[] garray = groups.split(",");
if ((garray != null) && (garray.length > 0)) {
ArrayList<NMS> list = new ArrayList<NMS>();
for (int i = 0; i < garray.length; i++) {
for (int j = 0; j < array.length; j++) {
String gn = array[j].getGroupName();
if (garray[i].equals(gn)) {
if (!list.contains(array[j])) {
list.add(array[j]);
}
}
}
}
if (list.size() > 0) {
result = list.toArray(new NMS[list.size()]);
} else {
result = null;
}
}
}
}
}
return (result);
}
/**
* {@inheritDoc}
*/
public void modelPropertyChange(PropertyChangeEvent event) {
String name = event.getPropertyName();
if (name != null) {
if (name.equals("NMS")) {
NMS[] array = (NMS[]) event.getNewValue();
array = filterNMS(array);
setNMS(array);
}
}
}
/**
* Determine the size of the desktop but retuen a subset of it if the user
* has defined a size in the application's properties file.
*
* @return A Rectangle instance.
*/
public Rectangle getPosition() {
if (positionRectangle == null) {
Toolkit tk = Toolkit.getDefaultToolkit();
Dimension d = tk.getScreenSize();
int x = 0;
int y = 0;
int width = (int) d.getWidth();
int height = (int) d.getHeight();
Properties p = getProperties();
if (p != null) {
x = Util.str2int(p.getProperty("x"), x);
y = Util.str2int(p.getProperty("y"), y);
width = Util.str2int(p.getProperty("width"), width);
height = Util.str2int(p.getProperty("height"), height);
}
positionRectangle = new Rectangle(x, y, width, height);
} else {
// We have been here before. We want to change positionRectangle
// if the user has dragged it off somewhere. We only worry
// about this when undecorated is false.
if (!isUndecorated()) {
positionRectangle = frame.getBounds();
}
}
return (positionRectangle);
}
private boolean isBlankingEnabled() {
boolean result = false;
Properties p = getProperties();
if (p != null) {
result = Util.str2boolean(p.getProperty("blankingenabled"), result);
}
return (result);
}
private int getMaxInactivity() {
int result = 3;
Properties p = getProperties();
if (p != null) {
result = Util.str2int(p.getProperty("maxinactivity"), result);
}
return (result);
}
private long getMaxInactivityMillis() {
long mins = (long) getMaxInactivity();
return (mins * 60 * 1000);
}
private boolean isUndecorated() {
boolean result = true;
Properties p = getProperties();
if (p != null) {
result = Util.str2boolean(p.getProperty("undecorated"), result);
}
return (result);
}
private boolean isEffects() {
boolean result = true;
Properties p = getProperties();
if (p != null) {
result = Util.str2boolean(p.getProperty("effects"), result);
}
return (result);
}
/**
* {@inheritDoc}
*/
public JFrame getFrame() {
if (frame == null) {
Toolkit t = Toolkit.getDefaultToolkit();
if (t != null) {
Dimension d = t.getBestCursorSize(1, 1);
if (d != null) {
int w = (int) d.getWidth();
int h = (int) d.getHeight();
if ((w != 0) && (h != 0)) {
setNoCursor(t.createCustomCursor(
new BufferedImage(w, h,
BufferedImage.TYPE_INT_ARGB),
new Point(0, 0), "NO_CURSOR"));
} else {
setNoCursor(null);
}
}
}
Rectangle position = getPosition();
int x = (int) position.getX();
int y = (int) position.getY();
int width = (int) position.getWidth();
int height = (int) position.getHeight();
frame = new JXFrame();
frame.setTitle("jflicks media system TV UI");
frame.setUndecorated(isUndecorated());
frame.setResizable(false);
frame.setBounds(x, y, width, height);
blankWindow = new JWindow(frame);
blankWindow.setBounds(x, y, width, height);
JXPanel bwpanel = new JXPanel();
bwpanel.setBackground(Color.BLACK);
bwpanel.setBounds(0, 0, width, height);
bwpanel.setFocusable(false);
blankWindow.getLayeredPane().add(bwpanel);
blankWindow.getContentPane().setCursor(getNoCursor());
JXPanel cards = new JXPanel(new CardLayout());
cards.setBackground(Color.BLACK);
setPanel(cards);
// This assumes we get all screens before we get here to
// build our Frame. Probably a bad assumption but this is
// what we will do for now...
Screen[] array = getScreens();
if (array != null) {
ArrayList<TextImage> list = new ArrayList<TextImage>();
for (int i = 0; i < array.length; i++) {
array[i].setEffects(isEffects());
array[i].setDone(true);
array[i].addScreenListener(this);
array[i].addPropertyChangeListener("Done", this);
String title = array[i].getTitle();
cards.add(title, array[i]);
BufferedImage bufcap = GraphicsUtilities.toCompatibleImage(
array[i].getDefaultBackgroundImage());
TextImage ti = new TextImage(title, bufcap);
list.add(ti);
if (array[i] instanceof ExecuteScreen) {
ExecuteScreen escreen = (ExecuteScreen) array[i];
String[] commands = escreen.getCommands();
if (commands != null) {
for (int j = 0; j < commands.length; j++) {
TextImage cti = new TextImage(commands[j], ti);
list.add(cti);
}
}
}
if (array[i] instanceof ParameterProperty) {
LogUtil.log(LogUtil.WARNING, "Now getting parameter - screen.");
ParameterProperty pp = (ParameterProperty) array[i];
String[] parameters = pp.getParameters();
if (parameters != null) {
for (int j = 0; j < parameters.length; j++) {
TextImage pti =
new TextImage(parameters[j], ti);
list.add(pti);
}
}
}
}
TextImage[] tiarray =
list.toArray(new TextImage[list.size()]);
TextImagePanel tip =
new TextImagePanel(tiarray, getLogoImage());
tip.setEffects(isEffects());
cards.add(tip, "main");
tip.addActionListener(this);
tip.setBounds(0, 0, width, height);
setTextImagePanel(tip);
EscapeAction escapeAction = new EscapeAction();
InputMap map =
tip.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
map.put(KeyStroke.getKeyStroke("ESCAPE"), "escape");
tip.getActionMap().put("escape", escapeAction);
}
CardLayout cl = (CardLayout) cards.getLayout();
cl.show(cards, "main");
setLastActivityMillis(System.currentTimeMillis());
frame.setLayout(new BorderLayout());
frame.add(cards, BorderLayout.CENTER);
setHideMouse(true);
}
return (frame);
}
/**
* This method will re-layout our application. This needs to be called
* when the user has changed their theme or other display property.
*/
public void restartUI() {
JXPanel p = getPanel();
if (p != null) {
Screen[] array = getScreens();
if (array != null) {
for (int i = 0; i < array.length; i++) {
array[i].restartUI();
}
}
TextImagePanel tip = getTextImagePanel();
if (tip != null) {
TextImage[] tiarray = tip.getTextImages();
if (tiarray != null) {
for (int i = 0; i < tiarray.length; i++) {
reset(tiarray[i]);
}
}
tip.restartUI();
}
}
}
private void reset(TextImage ti) {
Screen[] array = getScreens();
if ((ti != null) && (array != null)) {
for (int i = 0; i < array.length; i++) {
String s = ti.getText();
if (s != null) {
if (s.equals(array[i].getTitle())) {
ti.setImage(array[i].getDefaultBackgroundImage());
break;
}
}
}
}
}
/**
* Screens may want access to the defined logo. They can get it
* here and display it however they choose.
*
* @return A BufferedImage instance if such a logo exists.
*/
public BufferedImage getLogoImage() {
BufferedImage result = null;
try {
result = ImageIO.read(getClass().getResource("logo.png"));
result = GraphicsUtilities.toCompatibleImage(result);
} catch (IOException ex) {
}
return (result);
}
/**
* {@inheritDoc}
*/
public void messageReceived(String s) {
NMS[] array = getNMS();
if ((s != null) && (array != null)) {
Screen[] sarray = getScreens();
if (sarray != null) {
if (s.startsWith(NMSConstants.MESSAGE_RECORDING_UPDATE)) {
String rid = s.substring(s.indexOf(":") + 1);
rid = rid.trim();
for (int i = 0; i < array.length; i++) {
Recording r = array[i].getRecordingById(rid);
if (r != null) {
for (int j = 0; j < sarray.length; j++) {
if (sarray[j] instanceof RecordingProperty) {
RecordingProperty rp =
(RecordingProperty) sarray[j];
transformRecording(r);
rp.updateRecording(r);
}
}
}
}
} else if ((s.startsWith(NMSConstants.MESSAGE_RECORDING_ADDED))
|| (s.startsWith(NMSConstants.MESSAGE_RECORDING_REMOVED))) {
for (int i = 0; i < sarray.length; i++) {
if (sarray[i] instanceof RecordingProperty) {
applyRecordings((RecordingProperty) sarray[i]);
}
}
} else if (s.startsWith(NMSConstants.MESSAGE_SCHEDULE_UPDATE)) {
for (int i = 0; i < sarray.length; i++) {
if (sarray[i] instanceof UpcomingProperty) {
applyUpcomings((UpcomingProperty) sarray[i]);
}
}
} else if (s.startsWith(NMSConstants.MESSAGE_RULE_UPDATE)) {
for (int i = 0; i < sarray.length; i++) {
if (sarray[i] instanceof RecordingRuleProperty) {
applyRecordingRules(
(RecordingRuleProperty) sarray[i]);
}
}
}
}
}
}
/**
* We listen for button clicks (or enter keys) that trigger the display
* of a screen.
*
* @param event A given ActionEvent instance.
*/
public void actionPerformed(ActionEvent event) {
String title = event.getActionCommand();
JXPanel p = getPanel();
if ((title != null) && (p != null)) {
Screen[] array = getScreens();
for (int i = 0; i < array.length; i++) {
if (title.startsWith(array[i].getTitle())) {
if (array[i] instanceof ParameterProperty) {
ParameterProperty pp = (ParameterProperty) array[i];
String s = title.substring(title.indexOf(":") + 1);
if (s != null) {
pp.setSelectedParameter(s);
}
}
if (array[i] instanceof PhotoTagProperty) {
applyPhotoTag((PhotoTagProperty) array[i]);
}
if (array[i] instanceof RecordingProperty) {
applyRecordings((RecordingProperty) array[i]);
}
if (array[i] instanceof NMSProperty) {
applyNMS((NMSProperty) array[i]);
}
if (array[i] instanceof VideoProperty) {
applyVideos((VideoProperty) array[i]);
}
if (array[i] instanceof UpcomingProperty) {
applyUpcomings((UpcomingProperty) array[i]);
}
if (array[i] instanceof RecordingRuleProperty) {
applyRecordingRules((RecordingRuleProperty) array[i]);
}
// See if it's a screen that just executes a script.
// if so do it, otherwise update the current screen.
if (array[i] instanceof ExecuteScreen) {
ExecuteScreen escreen = (ExecuteScreen) array[i];
String s = title.substring(title.indexOf(":") + 1);
if (s != null) {
escreen.execute(s);
}
} else {
array[i].setDone(false);
CardLayout cl = (CardLayout) p.getLayout();
int index = title.indexOf(":");
if (index != -1) {
title = title.substring(0, index);
}
TextImagePanel tip = getTextImagePanel();
if (isEffects()) {
TimingTarget tt = PropertySetter.getTarget(tip,
"alpha", Float.valueOf(1.0f),
Float.valueOf(0.0f));
Animator fadeout =
new Animator.Builder().setDuration(125,
TimeUnit.MILLISECONDS).addTarget(tt).build();
fadeout.addTarget(
new TripScreenFadeIn(p, title, array[i]));
fadeout.start();
} else {
array[i].setAlpha(1.0f);
cl.show(panel, title);
setLastActivityMillis(System.currentTimeMillis());
}
break;
}
}
}
}
setLastActivityMillis(System.currentTimeMillis());
if (isBlanked()) {
setBlanked(false);
}
}
private void applyPhotoTag(PhotoTagProperty ptp) {
if (ptp != null) {
NMS[] array = getNMS();
if ((array != null) && (array.length > 0)) {
if (array.length == 1) {
Tag root = array[0].getRootTag();
if (root != null) {
Tag[] tarray = root.toArray();
if (tarray != null) {
tarray[0].dump();
tarray = Arrays.copyOfRange(tarray, 1,
tarray.length);
ptp.setTags(tarray);
} else {
ptp.setTags(null);
}
} else {
ptp.setTags(null);
}
Photo[] parray = array[0].getPhotos();
if (parray != null) {
transformPhotos(parray);
ptp.setPhotos(parray);
} else {
ptp.setPhotos(null);
}
} else {
// We have to merge from multiple NMS.
ArrayList<Tag> tlist = new ArrayList<Tag>();
for (int i = 0; i < array.length; i++) {
Tag root = array[i].getRootTag();
if (root != null) {
Tag[] tarray = root.toArray();
if (tarray != null) {
tarray = Arrays.copyOfRange(tarray, 1,
tarray.length - 1);
Collections.addAll(tlist, tarray);
}
}
}
ptp.setTags(tlist.toArray(new Tag[tlist.size()]));
ArrayList<Photo> plist = new ArrayList<Photo>();
for (int i = 0; i < array.length; i++) {
Photo[] picts = array[i].getPhotos();
if (picts != null) {
Collections.addAll(plist, picts);
}
}
Photo[] parray = plist.toArray(new Photo[plist.size()]);
transformPhotos(parray);
ptp.setPhotos(parray);
}
}
}
}
private void applyRecordings(RecordingProperty rp) {
if (rp != null) {
NMS[] array = getNMS();
if ((array != null) && (array.length > 0)) {
LogUtil.log(LogUtil.DEBUG, "NMS count: " + array.length);
if (array.length == 1) {
Recording[] recs = array[0].getRecordings();
transformRecordings(recs);
rp.setRecordings(recs);
} else {
// We have to merge from multiple NMS.
ArrayList<Recording> list = new ArrayList<Recording>();
for (int i = 0; i < array.length; i++) {
Recording[] recs = array[i].getRecordings();
LogUtil.log(LogUtil.DEBUG, "recs from NMS : " + i);
if (recs != null) {
LogUtil.log(LogUtil.DEBUG, "recs from NMS : " + recs.length);
Collections.addAll(list, recs);
}
}
Recording[] recs = list.toArray(new Recording[list.size()]);
if (recs != null) {
Arrays.sort(recs);
}
transformRecordings(recs);
rp.setRecordings(recs);
}
}
}
}
private void applyNMS(NMSProperty np) {
if (np != null) {
np.setNMS(getNMS());
}
}
private void applyVideos(VideoProperty vp) {
if (vp != null) {
NMS[] array = getNMS();
if ((array != null) && (array.length > 0)) {
if (array.length == 1) {
Video[] vids = array[0].getVideos();
transformVideos(vids);
vp.setVideos(vids);
} else {
// We have to merge from multiple NMS.
ArrayList<Video> list = new ArrayList<Video>();
for (int i = 0; i < array.length; i++) {
Video[] vids = array[i].getVideos();
if (vids != null) {
Collections.addAll(list, vids);
}
}
Video[] vids = list.toArray(new Video[list.size()]);
transformVideos(vids);
vp.setVideos(vids);
}
}
}
}
private void applyUpcomings(UpcomingProperty up) {
if (up != null) {
NMS[] array = getNMS();
if ((array != null) && (array.length > 0)) {
if (array.length == 1) {
up.setUpcomings(array[0].getUpcomings());
} else {
// We have to merge from multiple NMS.
ArrayList<Upcoming> list = new ArrayList<Upcoming>();
for (int i = 0; i < array.length; i++) {
Upcoming[] ups = array[i].getUpcomings();
if (ups != null) {
Collections.addAll(list, ups);
}
}
Upcoming[] upa = list.toArray(new Upcoming[list.size()]);
if (upa != null) {
Arrays.sort(upa);
}
up.setUpcomings(upa);
}
}
}
}
private void applyRecordingRules(RecordingRuleProperty rrp) {
if (rrp != null) {
NMS[] array = getNMS();
if ((array != null) && (array.length > 0)) {
if (array.length == 1) {
rrp.setRecordingRules(array[0].getRecordingRules());
} else {
// We have to merge from multiple NMS.
ArrayList<RecordingRule> list =
new ArrayList<RecordingRule>();
for (int i = 0; i < array.length; i++) {
RecordingRule[] rrs = array[i].getRecordingRules();
if (rrs != null) {
Collections.addAll(list, rrs);
}
}
rrp.setRecordingRules(list.toArray(
new RecordingRule[list.size()]));
}
}
}
}
/**
* We need to listen for when screens are done so the main
* UI component is displayed.
*
* @param event A given PropertyChangeEvent instance.
*/
public void propertyChange(PropertyChangeEvent event) {
Screen screen = (Screen) event.getSource();
if (screen.isDone()) {
// Set back to the main UI.
JXPanel p = getPanel();
if (p != null) {
CardLayout cl = (CardLayout) (p.getLayout());
TextImagePanel tip = getTextImagePanel();
if (isEffects()) {
TimingTarget tt = PropertySetter.getTarget(tip,
"alpha", Float.valueOf(1.0f), Float.valueOf(0.0f));
Animator fadeout = new Animator.Builder().setDuration(
125, TimeUnit.MILLISECONDS).addTarget(tt).build();
fadeout.addTarget(new TripMainFadeIn(p));
fadeout.start();
} else {
tip.setAlpha(1.0f);
cl.show(p, "main");
setLastActivityMillis(System.currentTimeMillis());
}
p.requestFocus();
}
}
}
/**
* {@inheritDoc}
*/
public void screenUpdate(ScreenEvent event) {
NMS[] array = getNMS();
boolean allow = false;
switch (event.getType()) {
default:
break;
case ScreenEvent.DELETE_RECORDING_ALLOW_RERECORDING:
allow = true;
// fall-thru
case ScreenEvent.DELETE_RECORDING:
if (array != null) {
Recording todelete = event.getRecording();
if (todelete != null) {
LogUtil.log(LogUtil.DEBUG, "whence: " + todelete.getHostPort());
NMS from = NMSUtil.select(array, todelete.getHostPort());
if (from != null) {
from.removeRecording(todelete, allow);
}
if (event.getSource() instanceof RecordingProperty) {
RecordingProperty rp =
(RecordingProperty) event.getSource();
applyRecordings(rp);
}
}
}
break;
case ScreenEvent.STOP_RECORDING:
if (array != null) {
Recording tostop = event.getRecording();
if (tostop != null) {
NMS from = NMSUtil.select(array, tostop.getHostPort());
if (from != null) {
from.stopRecording(tostop);
}
}
}
break;
case ScreenEvent.USER_INPUT:
setLastActivityMillis(System.currentTimeMillis());
if (isBlanked()) {
setBlanked(false);
}
break;
}
}
class EscapeAction extends AbstractAction {
public EscapeAction() {
}
public void actionPerformed(ActionEvent e) {
TextImagePanel tip = getTextImagePanel();
if (tip != null) {
if (tip.isPopup()) {
tip.deactivatePopup();
} else {
exitAction(true);
}
} else {
exitAction(true);
}
}
}
private boolean isHideMouse() {
return (hideMouse);
}
private void setHideMouse(boolean b) {
hideMouse = b;
if (frame != null) {
if (hideMouse) {
frame.getContentPane().setCursor(getNoCursor());
} else {
frame.getContentPane().setCursor(Cursor.getDefaultCursor());
}
}
}
private class TripScreenFadeIn extends TimingTargetAdapter {
private JXPanel panel;
private String title;
private Screen screen;
public TripScreenFadeIn(JXPanel p, String t, Screen s) {
panel = p;
title = t;
screen = s;
}
public void end(Animator source) {
CardLayout cl = (CardLayout) panel.getLayout();
screen.setAlpha(0.0f);
cl.show(panel, title);
setLastActivityMillis(System.currentTimeMillis());
TimingTarget tt = PropertySetter.getTarget(screen,
"alpha", Float.valueOf(0.0f), Float.valueOf(1.0f));
Animator fadein = new Animator.Builder().setDuration(
125, TimeUnit.MILLISECONDS).addTarget(tt).build();
fadein.start();
}
}
private class TripMainFadeIn extends TimingTargetAdapter {
private JXPanel panel;
public TripMainFadeIn(JXPanel p) {
panel = p;
}
public void end(Animator source) {
CardLayout cl = (CardLayout) panel.getLayout();
TextImagePanel p = getTextImagePanel();
p.setAlpha(0.0f);
cl.show(panel, "main");
setLastActivityMillis(System.currentTimeMillis());
TimingTarget tt = PropertySetter.getTarget(p,
"alpha", Float.valueOf(0.0f), Float.valueOf(1.0f));
Animator fadein = new Animator.Builder().setDuration(
125, TimeUnit.MILLISECONDS).addTarget(tt).build();
fadein.start();
}
}
class ActivityActionListener implements ActionListener {
public ActivityActionListener() {
}
public void actionPerformed(ActionEvent event) {
if (isBlankingEnabled()) {
if (!isBlanked()) {
// We do not ever unblank here so no need to do
// anything unless the screen is active.
long last = getLastActivityMillis();
Screen[] all = getScreens();
if ((all != null) && (all.length > 0)) {
for (int i = 0; i < all.length; i++) {
long tmp = all[i].getLastActivityMillis();
if (tmp > last) {
last = tmp;
}
}
}
setLastActivityMillis(last);
long max = getMaxInactivityMillis();
long now = System.currentTimeMillis();
long inactivity = now - last;
if (inactivity > max) {
setBlanked(true);
}
}
}
}
}
}