/* 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.screen.livetv; import java.awt.AWTKeyStroke; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.Frame; import java.awt.KeyboardFocusManager; import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.awt.image.BufferedImage; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.File; import java.io.IOException; import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Set; import javax.swing.JLayeredPane; import javax.swing.KeyStroke; import javax.swing.SwingConstants; import javax.swing.SwingUtilities; import javax.swing.Timer; import org.jflicks.job.JobContainer; import org.jflicks.job.JobEvent; import org.jflicks.job.JobListener; import org.jflicks.job.JobManager; import org.jflicks.mvc.View; import org.jflicks.nms.NMS; import org.jflicks.nms.NMSUtil; import org.jflicks.player.Bookmark; import org.jflicks.player.Player; import org.jflicks.transfer.Transfer; import org.jflicks.tv.Airing; import org.jflicks.tv.Channel; import org.jflicks.tv.LiveTV; import org.jflicks.tv.Recording; import org.jflicks.tv.RecordingRule; import org.jflicks.tv.Show; import org.jflicks.tv.ShowAiring; import org.jflicks.ui.view.fe.AddRuleJob; import org.jflicks.ui.view.fe.ButtonPanel; import org.jflicks.ui.view.fe.ChannelInfoWindow; import org.jflicks.ui.view.fe.Dialog; import org.jflicks.ui.view.fe.FrontEndView; import org.jflicks.ui.view.fe.GridGuidePanel; import org.jflicks.ui.view.fe.GuideJob; import org.jflicks.ui.view.fe.NMSProperty; import org.jflicks.ui.view.fe.RecordingInfoWindow; import org.jflicks.ui.view.fe.RecordingRulePanel; import org.jflicks.ui.view.fe.RecordingRuleProperty; import org.jflicks.ui.view.fe.ShowDetailPanel; import org.jflicks.ui.view.fe.screen.PlayerScreen; import org.jflicks.ui.view.fe.screen.ScreenEvent; import org.jflicks.util.Busy; import org.jflicks.util.LogUtil; import org.jflicks.util.Util; import org.jdesktop.swingx.JXLabel; import org.jdesktop.swingx.JXPanel; import org.jdesktop.swingx.painter.MattePainter; /** * This class supports Videos in a front end UI on a TV. * * @author Doug Barnum * @version 1.0 */ public abstract class BaseLiveTVScreen extends PlayerScreen implements NMSProperty, RecordingRuleProperty, PropertyChangeListener, JobListener { public abstract void startPlayer(LiveTV ltv); public abstract void changeChannel(LiveTV l, Channel c); public abstract LiveTV openSession(NMS n, String number); private static final int ALL_CHANNELS = 1; private static final int FAVORITE_CHANNELS = 2; private static final String ALL_CHANNELS_TEXT = "All Channels"; private static final String FAVORITE_CHANNELS_TEXT = "Favorite Channels"; private static final String ADD_FAVORITE = "Add to Favorites"; private static final String SWITCH_TO_FAVORITE = "Switch to Favorites"; private static final String REMOVE_FAVORITE = "Remove from Favorites"; private static final String SWITCH_FROM_FAVORITE = "Switch from Favorites"; private static final String CHANGE_CHANNEL = "Change Channel"; private static final String SCHEDULE = "Schedule"; private NMS[] nms; private LiveTV liveTV; private Timer startTimer; private Channel nextChannel; private JobContainer guideJobContainer; private HashMap<Channel, ShowAiring[]> guideMap; private RecordingRule[] recordingRules; private RecordingInfoWindow recordingInfoWindow; private ChannelInfoWindow channelInfoWindow; private long watchingStartTime; private Rectangle guideRectangle; private boolean guideMode; private JXPanel waitPanel; private GridGuidePanel gridGuidePanel; private ShowDetailPanel showDetailPanel; private ShowAiring selectedShowAiring; private RecordingRulePanel recordingRulePanel; private int channelState; private JXLabel channelLabel; private Channel lastChannel; private ArrayList<String> favoriteChannelList; private Channel[] allChannels; /** * Simple empty constructor. */ public BaseLiveTVScreen() { setFavoriteChannelList(new ArrayList<String>()); BufferedImage bi = getImageByName("Live_TV"); setDefaultBackgroundImage(bi); setFocusable(true); requestFocus(); setChannelState(ALL_CHANNELS); setChannelLabel(new JXLabel(ALL_CHANNELS_TEXT)); RecordingRulePanel rrp = new RecordingRulePanel(); HashSet<AWTKeyStroke> set = new HashSet<AWTKeyStroke>(rrp.getFocusTraversalKeys( KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS)); set.clear(); set.add(KeyStroke.getKeyStroke("DOWN")); rrp.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, set); set = new HashSet<AWTKeyStroke>(rrp.getFocusTraversalKeys( KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS)); set.clear(); set.add(KeyStroke.getKeyStroke("UP")); rrp.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, set); setRecordingRulePanel(rrp); } /** * {@inheritDoc} */ public RecordingRule[] getRecordingRules() { RecordingRule[] result = null; if (recordingRules != null) { result = Arrays.copyOf(recordingRules, recordingRules.length); } return (result); } /** * {@inheritDoc} */ public void setRecordingRules(RecordingRule[] array) { if (array != null) { recordingRules = Arrays.copyOf(array, array.length); } else { recordingRules = null; } } public Frame getFrame() { return (Util.findFrame(this)); } private ArrayList<String> getFavoriteChannelList() { return (favoriteChannelList); } private void setFavoriteChannelList(ArrayList<String> l) { favoriteChannelList = l; } private Channel[] getAllChannels() { return (allChannels); } private void setAllChannels(Channel[] array) { allChannels = array; } public Channel getLastChannel() { return (lastChannel); } public void setLastChannel(Channel c) { lastChannel = c; } private int getChannelState() { return (channelState); } private void setChannelState(int i) { channelState = i; } private boolean isGuideMode() { return (guideMode); } private void setGuideMode(boolean b) { guideMode = b; } private Rectangle getGuideRectangle() { return (guideRectangle); } private void setGuideRectangle(Rectangle r) { guideRectangle = r; } public LiveTV getLiveTV() { return (liveTV); } public void setLiveTV(LiveTV l) { liveTV = l; } public Channel getNextChannel() { return (nextChannel); } public void setNextChannel(Channel c) { nextChannel = c; } private JobContainer getGuideJobContainer() { return (guideJobContainer); } private void setGuideJobContainer(JobContainer c) { guideJobContainer = c; } private HashMap<Channel, ShowAiring[]> getGuideMap() { return (guideMap); } private void setGuideMap(HashMap<Channel, ShowAiring[]> m) { guideMap = m; LogUtil.log(LogUtil.INFO, "Guide is done..."); GridGuidePanel ggp = getGridGuidePanel(); if (ggp != null) { ggp.setGuideMap(guideMap); } } public RecordingInfoWindow getRecordingInfoWindow() { return (recordingInfoWindow); } private void setRecordingInfoWindow(RecordingInfoWindow w) { recordingInfoWindow = w; } public ChannelInfoWindow getChannelInfoWindow() { return (channelInfoWindow); } private void setChannelInfoWindow(ChannelInfoWindow w) { channelInfoWindow = w; } public GridGuidePanel getGridGuidePanel() { return (gridGuidePanel); } private void setGridGuidePanel(GridGuidePanel p) { gridGuidePanel = p; } public ShowDetailPanel getShowDetailPanel() { return (showDetailPanel); } private void setShowDetailPanel(ShowDetailPanel p) { showDetailPanel = p; } public JXLabel getChannelLabel() { return (channelLabel); } private void setChannelLabel(JXLabel l) { channelLabel = l; } public long getWatchingStartTime() { return (watchingStartTime); } public void setWatchingStartTime(long l) { watchingStartTime = l; } public JXPanel getWaitPanel() { return (waitPanel); } private void setWaitPanel(JXPanel p) { waitPanel = p; } public RecordingRulePanel getRecordingRulePanel() { return (recordingRulePanel); } private void setRecordingRulePanel(RecordingRulePanel p) { recordingRulePanel = p; } public ShowAiring getSelectedShowAiring() { return (selectedShowAiring); } private void setSelectedShowAiring(ShowAiring sa) { selectedShowAiring = sa; } /** * {@inheritDoc} */ public NMS[] getNMS() { NMS[] result = null; if (nms != null) { result = Arrays.copyOf(nms, nms.length); } return (result); } /** * {@inheritDoc} */ public void setNMS(NMS[] array) { if (array != null) { nms = Arrays.copyOf(array, array.length); } else { nms = null; } } /** * {@inheritDoc} */ public void performLayout(Dimension d) { JLayeredPane pane = getLayeredPane(); if ((d != null) && (pane != null)) { float alpha = (float) getPanelAlpha(); int width = (int) d.getWidth(); int height = (int) d.getHeight(); int wspan = (int) (width * 0.03); int listwidth = (width - (2 * wspan)); int halflistwidth = (width - (3 * wspan)) / 2; int onethirdlistwidth = (width - (3 * wspan)) / 3; int twothirdlistwidth = onethirdlistwidth * 2; int hspan = (int) (height * 0.03); int listheight = (int) ((height - (2 * hspan)) / 1.5); int detailwidth = (int) (width * 0.63); int detailheight = (height - (3 * hspan)) - listheight; FrontEndView fev = (FrontEndView) getView(); RecordingInfoWindow w = new RecordingInfoWindow(fev.getPosition(), 8, getInfoColor(), getPanelColor(), (float) getPanelAlpha(), getSmallFont(), getMediumFont()); w.setImageCache(getImageCache()); w.setPlayer(getPlayer()); w.setVisible(false); setRecordingInfoWindow(w); ChannelInfoWindow cw = new ChannelInfoWindow(fev.getPosition(), 8, getInfoColor(), getPanelColor(), (float) getPanelAlpha(), getSmallFont(), getMediumFont()); cw.setVisible(false); setChannelInfoWindow(cw); JXPanel panel = new JXPanel(new BorderLayout()); JXLabel l = new JXLabel("Tuning channel, please wait..."); l.setHorizontalTextPosition(SwingConstants.CENTER); l.setHorizontalAlignment(SwingConstants.CENTER); l.setFont(getLargeFont()); panel.add(l, BorderLayout.CENTER); MattePainter p = new MattePainter(Color.BLACK); panel.setBackgroundPainter(p); panel.setBounds(0, 0, (int) d.getWidth(), (int) d.getHeight()); setWaitPanel(panel); GridGuidePanel ggp = new GridGuidePanel(); ggp.addPropertyChangeListener("SelectedShowAiring", this); setGridGuidePanel(ggp); ShowDetailPanel sdp = new ShowDetailPanel(); sdp.setBounds(wspan, hspan + listheight + hspan, detailwidth, detailheight); setShowDetailPanel(sdp); JXLabel label = getChannelLabel(); label.setFont(ggp.getLargeFont()); label.setForeground(ggp.getInfoColor()); label.setHorizontalTextPosition(SwingConstants.CENTER); label.setHorizontalAlignment(SwingConstants.RIGHT); Dimension ldim = label.getPreferredSize(); int labelHeight = (int) ldim.getHeight(); label.setBounds(wspan, hspan, listwidth, labelHeight); ggp.setBounds(wspan, hspan + labelHeight, listwidth, listheight - labelHeight); Rectangle fevrec = fev.getPosition(); int subx = wspan + detailwidth + wspan; subx += (int) fevrec.getX(); int suby = hspan + hspan + listheight; suby += (int) fevrec.getY(); int subw = detailheight * 16 / 9; int subh = detailheight; setGuideRectangle(new Rectangle(subx, suby, subw, subh)); setDefaultBackgroundImage( Util.resize(getDefaultBackgroundImage(), width, height)); } } private void updateLayout(boolean wait) { JLayeredPane pane = getLayeredPane(); if (pane != null) { pane.removeAll(); if (wait) { pane.add(getWaitPanel(), Integer.valueOf(100)); } else { if (isGuideMode()) { pane.add(getChannelLabel(), Integer.valueOf(110)); pane.add(getGridGuidePanel(), Integer.valueOf(100)); pane.add(getShowDetailPanel(), Integer.valueOf(100)); } else { pane.add(getWaitPanel(), Integer.valueOf(100)); } } repaint(); } } /** * Override so we can start up the player. * * @param b When true we are ready to start the player. */ public void setVisible(boolean b) { super.setVisible(b); if (b) { // We are being shown so let's read the local channel favorite // text file in case it's been changed since last time we were // here. Each entry is a line that came from a Channel.toString() // call. Since we can dynamically change them here we will read // them into an ArrayList<String>. When this screen ends we // will need to write out the current state in case other screens // need the same info. File here = new File ("."); ArrayList<String> favlist = getFavoriteChannelList(); if (favlist != null) { favlist.clear(); String[] cnames = Util.readTextFile(new File(here, "fav-chan.txt")); if ((cnames != null) && (cnames.length > 0)) { for (int i = 0; i < cnames.length; i++) { favlist.add(cnames[i]); } Collections.sort(favlist); } } // Try to find the last channel. String lastChannelNumber = null; String[] lastText = Util.readTextFile(new File(here, "last-chan.txt")); if ((lastText != null) && (lastText.length > 0)) { lastChannelNumber = lastText[0]; } NMS[] array = getNMS(); if ((array != null) && (array.length > 0)) { NMS n = null; // Just use the first one we find.... for (int i = 0; i < array.length; i++) { if (array[i].supportsLiveTV()) { n = array[i]; break; } } if (n != null) { setWatchingStartTime(System.currentTimeMillis()); LiveTV l = openSession(n, lastChannelNumber); LogUtil.log(LogUtil.DEBUG, "Called start livetv: " + l); if (l != null) { LogUtil.log(LogUtil.DEBUG, "livetv: " + l.getMessage()); if (l.getMessageType() == LiveTV.MESSAGE_TYPE_NONE) { GuideJob gjob = new GuideJob(n, l.getChannels()); gjob.addJobListener(this); JobContainer jc = JobManager.getJobContainer(gjob); setGuideJobContainer(jc); jc.start(); setLiveTV(l); updateInfoWindow(); controlKeyboard(false); final LiveTV fl = l; Runnable doRun = new Runnable() { public void run() { LogUtil.log(LogUtil.DEBUG, "Starting player..."); startPlayer(fl); } }; SwingUtilities.invokeLater(doRun); updateLayout(true); } else { n.closeSession(l); setLiveTV(null); setDone(true); } } else { setDone(true); } } else { setDone(true); } } else { setDone(true); } } } /** * {@inheritDoc} */ public Bookmark createBookmark() { Bookmark result = null; return (result); } /** * {@inheritDoc} */ public String getBookmarkId() { String result = null; return (result); } /** * {@inheritDoc} */ public void info() { if (isGuideMode()) { if (!isPopupEnabled()) { GridGuidePanel ggp = getGridGuidePanel(); if (ggp != null) { ArrayList<String> blist = new ArrayList<String>(); if (ggp.isOn(getSelectedShowAiring())) { blist.add(CHANGE_CHANNEL); } else { blist.add(SCHEDULE); } if (getChannelState() == ALL_CHANNELS) { blist.add(SWITCH_TO_FAVORITE); blist.add(ADD_FAVORITE); } else { blist.add(SWITCH_FROM_FAVORITE); blist.add(REMOVE_FAVORITE); } blist.add(CANCEL); popup(blist.toArray(new String[blist.size()])); } } } else { RecordingInfoWindow w = getRecordingInfoWindow(); if (w != null) { w.setVisible(!w.isVisible()); } } } /** * {@inheritDoc} */ @Override public void save() { Player p = getPlayer(); if (p != null) { p.stop(); } close(); } /** * {@inheritDoc} */ public void guide() { Player p = getPlayer(); Rectangle r = getGuideRectangle(); if ((p != null) && (p.isPlaying()) && (r != null)) { if (!isGuideMode()) { RecordingInfoWindow w = getRecordingInfoWindow(); if (w != null) { w.setVisible(false); } ChannelInfoWindow cw = getChannelInfoWindow(); if (cw != null) { cw.setVisible(false); } setGuideMode(true); LiveTV l = getLiveTV(); GridGuidePanel ggp = getGridGuidePanel(); if ((l != null) && (ggp != null)) { Channel c = l.getCurrentChannel(); if (c != null) { ggp.setCurrentChannel(c); } } LogUtil.log(LogUtil.DEBUG, "About to resize to little"); p.setSize(r); //requestFocus(); updateLayout(false); } else { setGuideMode(false); LogUtil.log(LogUtil.DEBUG, "About to resize to big"); p.setSize(p.getRectangle()); updateLayout(true); } } } /** * {@inheritDoc} */ public void pageup() { GridGuidePanel ggp = getGridGuidePanel(); if (ggp != null) { ggp.pageUp(); } } /** * {@inheritDoc} */ public void pagedown() { GridGuidePanel ggp = getGridGuidePanel(); if (ggp != null) { ggp.pageDown(); } } /** * {@inheritDoc} */ public void close() { controlKeyboard(true); RecordingInfoWindow w = getRecordingInfoWindow(); if (w != null) { w.setVisible(false); } ChannelInfoWindow cw = getChannelInfoWindow(); if (cw != null) { cw.setVisible(false); } LiveTV l = getLiveTV(); if (l != null) { NMS n = NMSUtil.select(getNMS(), l.getHostPort()); if (n != null) { LogUtil.log(LogUtil.DEBUG, "calling stop..."); n.closeSession(l); setLiveTV(null); setNextChannel(null); JobContainer jc = getGuideJobContainer(); if (jc != null) { jc.stop(); setGuideJobContainer(null); } } } File here = new File ("."); ArrayList<String> favlist = getFavoriteChannelList(); if (favlist != null) { StringBuilder sb = new StringBuilder(""); for (int i = 0; i < favlist.size(); i++) { sb.append(favlist.get(i)); sb.append("\n"); } try { Util.writeTextFile(new File(here, "fav-chan.txt"), sb.toString()); } catch (IOException ex) { } } Channel lc = getLastChannel(); if (lc != null) { try { Util.writeTextFile(new File(here, "last-chan.txt"), lc.getNumber() + "\n"); } catch (IOException ex) { } } setGuideMode(false); setDone(true); } /** * {@inheritDoc} */ public void rewind() { Player p = getPlayer(); if (p != null) { p.seek(-8); } } /** * {@inheritDoc} */ public void forward() { Player p = getPlayer(); if (p != null) { int left = leftToGo(p, getMarkTime()); LogUtil.log(LogUtil.DEBUG, "left to go: " + left); if (left > 30) { p.seek(30); } } } /** * {@inheritDoc} */ public void skipforward() { } /** * {@inheritDoc} */ public void skipbackward() { } /** * {@inheritDoc} */ public void up() { if (!isGuideMode()) { computeNextChannelUp(); LogUtil.log(LogUtil.DEBUG, "Up: " + getNextChannel()); ChannelInfoWindow cw = getChannelInfoWindow(); Channel c = getNextChannel(); HashMap<Channel, ShowAiring[]> m = getGuideMap(); if ((c != null) && (m != null) && (cw != null)) { cw.setChannel(c); cw.setShowAiring(currentShowAiring(m.get(c))); cw.setVisible(true); } } else { if (isPopupEnabled()) { ButtonPanel bp = getPlayButtonPanel(); if (bp != null) { bp.moveUp(); } } else { GridGuidePanel ggp = getGridGuidePanel(); if (ggp != null) { ggp.up(); } } } } /** * {@inheritDoc} */ public void down() { if (!isGuideMode()) { computeNextChannelDown(); LogUtil.log(LogUtil.DEBUG, "Down: " + getNextChannel()); ChannelInfoWindow cw = getChannelInfoWindow(); Channel c = getNextChannel(); HashMap<Channel, ShowAiring[]> m = getGuideMap(); if ((c != null) && (m != null) && (cw != null)) { cw.setChannel(c); cw.setShowAiring(currentShowAiring(m.get(c))); cw.setVisible(true); } } else { if (isPopupEnabled()) { ButtonPanel bp = getPlayButtonPanel(); if (bp != null) { bp.moveDown(); } } else { GridGuidePanel ggp = getGridGuidePanel(); if (ggp != null) { ggp.down(); } } } } /** * {@inheritDoc} */ public void left() { if (!isGuideMode()) { Player p = getPlayer(); if (p != null) { p.seek(-8); } } else { if (isPopupEnabled()) { } else { GridGuidePanel ggp = getGridGuidePanel(); if (ggp != null) { ggp.left(); } } } } /** * {@inheritDoc} */ public void right() { if (!isGuideMode()) { Player p = getPlayer(); if (p != null) { int left = leftToGo(p, getMarkTime()); LogUtil.log(LogUtil.DEBUG, "left to go: " + left); if (left > 30) { p.seek(30); } } } else { if (isPopupEnabled()) { } else { GridGuidePanel ggp = getGridGuidePanel(); if (ggp != null) { ggp.right(); } } } } /** * {@inheritDoc} */ public void enter() { if (!isGuideMode()) { changeChannel(getLiveTV(), getNextChannel()); } else { if (!isPopupEnabled()) { handleGuideEnter(); } else { // We got this event because the player has focus. So // as a hack we call actionPerformed so we do the right // thing. Cheesy. String val = getPlayButtonPanel().getSelectedButton(); actionPerformed(new ActionEvent(this, 1, val)); } } } /** * Listen for the Player being "done". This signifies the video finished * by coming to the end. * * @param event A given PropertyChangeEvent. */ public void propertyChange(PropertyChangeEvent event) { LogUtil.log(LogUtil.DEBUG, "propertyChange: " + event.getPropertyName()); if ((event.getSource() == getPlayer()) && (!isDone())) { // If we get this property update, then it means the video // finished playing on it's own. setBlocking(false); Boolean bobj = (Boolean) event.getNewValue(); if (bobj.booleanValue()) { getPlayer().removePropertyChangeListener(this); LogUtil.log(LogUtil.DEBUG, "we are stopping because mplayer says so"); close(); LogUtil.log(LogUtil.DEBUG, "about to request focus"); requestFocus(); } } else if (event.getPropertyName().equals("SelectedShowAiring")) { ShowDetailPanel sdp = getShowDetailPanel(); if (sdp != null) { ShowAiring sa = (ShowAiring) event.getNewValue(); sdp.setShowAiring(sa); setSelectedShowAiring(sa); } } } private void handleFavorite() { GridGuidePanel ggp = getGridGuidePanel(); ArrayList<String> favlist = getFavoriteChannelList(); if ((ggp != null) && (favlist != null)) { Channel chan = ggp.getSelectedChannel(); if (chan != null) { String text = chan.toString(); if (getChannelState() == ALL_CHANNELS) { if (!favlist.contains(text)) { favlist.add(text); Collections.sort(favlist); } } else if (getChannelState() == FAVORITE_CHANNELS) { if (favlist.contains(text)) { favlist.remove(text); Collections.sort(favlist); applyChannels(); } } } } } public void editRule(NMS n, RecordingRulePanel p, RecordingRule rr) { if ((n != null) && (p != null) && (rr != null)) { p.setNMS(n); p.setRecordingRule(rr); p.setFrame(getFrame()); Dialog.showPanel(getFrame(), p, p.getOkButton(), p.getCancelButton()); if (p.isAccept()) { rr = p.getRecordingRule(); AddRuleJob arj = new AddRuleJob(n, rr); Busy busy = new Busy(getLayeredPane(), arj); busy.addJobListener(this); busy.execute(); } else { requestFocus(); } } } /** * We need to listen for events from the "play popup dialog". * * @param event A given event. */ public void actionPerformed(ActionEvent event) { if (isGuideMode()) { ButtonPanel pbp = getPlayButtonPanel(); if (pbp != null) { if (CHANGE_CHANNEL.equals(pbp.getSelectedButton())) { GridGuidePanel ggp = getGridGuidePanel(); if (ggp != null) { setGuideMode(false); updateLayout(true); changeChannel(getLiveTV(), ggp.getSelectedChannel()); } } else if (ADD_FAVORITE.equals(pbp.getSelectedButton())) { handleFavorite(); } else if (REMOVE_FAVORITE.equals(pbp.getSelectedButton())) { handleFavorite(); } else if (SWITCH_TO_FAVORITE.equals(pbp.getSelectedButton())) { setChannelState(FAVORITE_CHANNELS); applyChannels(); } else if (SWITCH_FROM_FAVORITE.equals( pbp.getSelectedButton())) { setChannelState(ALL_CHANNELS); applyChannels(); } else if (SCHEDULE.equals(pbp.getSelectedButton())) { ShowAiring sa = getSelectedShowAiring(); RecordingRulePanel rrp = getRecordingRulePanel(); if ((sa != null) && (rrp != null)) { NMS n = NMSUtil.select(getNMS(), sa.getHostPort()); if (n != null) { Show show = sa.getShow(); Airing airing = sa.getAiring(); if ((show != null) && (airing != null)) { RecordingRule rr = getRecordingRule(sa); if (rr == null) { rr = new RecordingRule(); rr.setShowAiring(sa); rr.setType(RecordingRule.SERIES_TYPE); rr.setName(show.getTitle()); rr.setShowId(show.getId()); rr.setSeriesId(show.getSeriesId()); rr.setChannelId(airing.getChannelId()); rr.setListingId(airing.getListingId()); rr.setDuration(airing.getDuration()); rr.setPriority( RecordingRule.NORMAL_PRIORITY); rr.setTasks(n.getTasks()); } editRule(n, rrp, rr); } } } } unpopup(); } } fireScreenEvent(ScreenEvent.USER_INPUT); } /** * {@inheritDoc} */ @SuppressWarnings("unchecked") public void jobUpdate(JobEvent event) { if (event.getType() == JobEvent.COMPLETE) { Serializable s = event.getState(); if (s instanceof HashMap<?, ?>) { HashMap<Channel, ShowAiring[]> map = (HashMap<Channel, ShowAiring[]>) s; setGuideMap(map); updateInfoWindow(); setGuideJobContainer(null); Set<Channel> set = map.keySet(); if (set.size() > 0) { Channel[] chans = set.toArray(new Channel[set.size()]); Arrays.sort(chans); setAllChannels(chans); applyChannels(); } } } } private void computeNextChannelUp() { LiveTV l = getLiveTV(); if (l != null) { Channel[] array = l.getChannels(); if (array != null) { Channel current = getNextChannel(); if (current == null) { setNextChannel(l.getCurrentChannel()); } else { int index = 0; for (int i = 0; i < array.length; i++) { if (array[i].equals(current)) { index = i; break; } } index--; if (index < 0) { index = array.length - 1; } setNextChannel(array[index]); } } } } private void computeNextChannelDown() { LiveTV l = getLiveTV(); if (l != null) { Channel[] array = l.getChannels(); if (array != null) { Channel current = getNextChannel(); if (current == null) { setNextChannel(l.getCurrentChannel()); } else { int index = 0; for (int i = 0; i < array.length; i++) { if (array[i].equals(current)) { index = i; break; } } index++; if (index == array.length) { index = 0; } setNextChannel(array[index]); } } } } public void updateInfoWindow() { LiveTV l = getLiveTV(); if (l != null) { Channel c = l.getCurrentChannel(); HashMap<Channel, ShowAiring[]> m = getGuideMap(); RecordingInfoWindow w = getRecordingInfoWindow(); if ((c != null) && (m != null) && (w != null)) { ShowAiring[] array = m.get(c); Recording r = new Recording(currentShowAiring(array)); r.setCurrentlyRecording(true); r.setRealStart(getWatchingStartTime()); w.setRecording(r); } } } private ShowAiring currentShowAiring(ShowAiring[] array) { ShowAiring result = null; if (array != null) { if (array.length > 0) { for (int i = 0; i < array.length; i++) { if (!array[i].isOver()) { result = array[i]; break; } } } } return (result); } private ShowAiring[] computeShowAirings(ShowAiring[] array) { ShowAiring[] result = array; if (array != null) { if (array.length > 0) { int skip = 0; for (int i = 0; i < array.length; i++) { if (!array[i].isOver()) { skip = i; break; } } if (skip > 0) { result = Arrays.copyOfRange(array, skip, array.length); } } } return (result); } private Channel[] filterByFavorite(Channel[] array) { Channel[] result = null; ArrayList<String> favlist = getFavoriteChannelList(); if ((array != null) && (favlist != null)) { ArrayList<Channel> filter = new ArrayList<Channel>(); for (int i = 0; i < favlist.size(); i++) { String tmp = favlist.get(i); if (tmp != null) { for (int j = 0; j < array.length; j++) { if (tmp.equals(array[j].toString())) { filter.add(array[j]); break; } } } } if (filter.size() > 0) { Collections.sort(filter); result = filter.toArray(new Channel[filter.size()]); } } return (result); } private void applyChannels() { GridGuidePanel ggp = getGridGuidePanel(); Channel[] carray = getAllChannels(); JXLabel l = getChannelLabel(); if ((ggp != null) && (carray != null) && (l != null)) { if (getChannelState() == ALL_CHANNELS) { ggp.setChannels(carray); l.setText(ALL_CHANNELS_TEXT); } else if (getChannelState() == FAVORITE_CHANNELS) { Channel[] only = filterByFavorite(carray); if (only != null) { ggp.setChannels(only); l.setText(FAVORITE_CHANNELS_TEXT); } else { setChannelState(ALL_CHANNELS); } } } } private void handleGuideEnter() { GridGuidePanel ggp = getGridGuidePanel(); if (ggp != null) { Channel chan = ggp.getSelectedChannel(); if (chan != null) { ArrayList<String> blist = new ArrayList<String>(); ShowAiring sa = getSelectedShowAiring(); if (sa != null) { if (ggp.isOn(sa)) { blist.add(CHANGE_CHANNEL); } else { blist.add(SCHEDULE); } } blist.add(CANCEL); popup(blist.toArray(new String[blist.size()])); } } } private RecordingRule getRecordingRule(ShowAiring sa) { RecordingRule result = null; if (sa != null) { NMS n = NMSUtil.select(getNMS(), sa.getHostPort()); Show show = sa.getShow(); Airing airing = sa.getAiring(); if ((n != null) && (show != null) && (airing != null)) { int cid = airing.getChannelId(); String seriesId = show.getSeriesId(); RecordingRule[] rules = n.getRecordingRules(); if ((seriesId != null) && (rules != null)) { for (int i = 0; i < rules.length; i++) { ShowAiring rrsa = rules[i].getShowAiring(); if (rrsa != null) { // We have a rule that is a ONCE recording. It // is only our rule to edit if the two ShowAiring // instances are the same. if (rrsa.equals(sa)) { result = rules[i]; break; } } else { if ((cid == rules[i].getChannelId()) && (seriesId.equals(rules[i].getSeriesId()))) { result = rules[i]; break; } } } } } } return (result); } }