Package captureplugin

Source Code of captureplugin.CapturePlugin

/*
* CapturePlugin by Andreas Hessel (Vidrec@gmx.de), Bodo Tasche
*
* This program 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 2
* of the License, or (at your option) any later version.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*
* CVS information:
*  $RCSfile$
*   $Source$
*     $Date: 2011-02-26 16:29:44 +0100 (Sat, 26 Feb 2011) $
*   $Author: bananeweizen $
* $Revision: 6925 $
*/
package captureplugin;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.Properties;
import java.util.Vector;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.filechooser.FileFilter;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;

import org.apache.commons.lang.StringUtils;

import util.ui.Localizer;
import util.ui.UIThreadRunner;
import util.ui.UiUtilities;
import captureplugin.drivers.DeviceIf;
import devplugin.ActionMenu;
import devplugin.PluginInfo;
import devplugin.PluginTreeNode;
import devplugin.Program;
import devplugin.ProgramFieldType;
import devplugin.ProgramReceiveTarget;
import devplugin.SettingsTab;
import devplugin.ThemeIcon;
import devplugin.Version;

/**
* Plugin to send the TV-Data to an external program
*
* @author Andreas Hessel, Bodo Tasche
*/
public class CapturePlugin extends devplugin.Plugin {
  private static final Version mVersion = new Version(3,00);

    /**
     * Translator
     */
    private static final Localizer mLocalizer = Localizer.getLocalizerFor(CapturePlugin.class);

    /**
     * mData that stores the Settings
     */
    private CapturePluginData mConfig = new CapturePluginData();

    /**
     * Current Marked Programs
     */
    private Vector<Program> mMarkedPrograms = new Vector<Program>();

    /**
     * The Singleton
     */
    private static CapturePlugin mInstance = null;

    private boolean mAllowedToShowDialog = false;
    private boolean mNeedsUpdate = false;

    private Properties mSettings;

    /**
     * Root-Node for the Program-Tree
     */
    private PluginTreeNode mRootNode = new PluginTreeNode(this, false);
    private static final String RECORD = "##record";
    private static final String REMOVE = "##remove";

    private PluginInfo mPluginInfo;

    /**
     * Creates the Plugin
     */
    public CapturePlugin() {
        mInstance = this;
    }

    /**
     * Returns this Instance
     *
     * @return Instance
     */
    public static CapturePlugin getInstance() {
        return mInstance;
    }

    /**
     * Called by the host-application during start-up. Implement this method to
     * load any objects from the file system.
     *
     * @see #writeData(ObjectOutputStream)
     */
    public void readData(ObjectInputStream in) throws IOException, ClassNotFoundException {
        mConfig = new CapturePluginData();
        mConfig.readData(in, this);
        updateMarkedPrograms();
    }

    /**
     * Counterpart to loadData. Called when the application shuts down.
     * Implement this method to store any objects to the file system.
     *
     * @see #readData(ObjectInputStream)
     */
    public void writeData(ObjectOutputStream out) throws IOException {
        mConfig.writeData(out);
    }

    /**
     * Called by the host-application during start-up. Implements this method to
     * load your plugins settings from the file system.
     */
    public void loadSettings(Properties settings) {
      if(settings == null) {
        mSettings = new Properties();
      } else {
        mSettings = settings;
      }
    }

    /**
     * Called by the host-application during shut-down. Implements this method
     * to store your plugins settings to the file system.
     */
    public Properties storeSettings() {
        return mSettings;
    }

    public static Version getVersion() {
      return mVersion;
    }

    /**
     * Implement this function to provide information about your plugin.
     */
    public PluginInfo getInfo() {
      if(mPluginInfo == null) {
        String name = mLocalizer.msg("CapturePlugin", "Capture Plugin");
        String desc = mLocalizer.msg("Desc", "Starts a external Program with configurable Parameters");
        String author = "Bodo Tasche, Andreas Hessel";

        mPluginInfo = new PluginInfo(CapturePlugin.class, name, desc, author);
      }
      return mPluginInfo;
    }

    /**
     * Returns a new SettingsTab object, which is added to the settings-window.
     */
    public SettingsTab getSettingsTab() {
        return new CapturePluginSettingsTab((JFrame) getParentFrame(), this);
    }

    public ActionMenu getContextMenuActions(final Program program) {

        final DeviceIf[] devices = mConfig.getDeviceArray();

        final Window parent = UiUtilities.getLastModalChildOf(getParentFrame());

        String menuText = mLocalizer.msg("record", "record Program");
        ImageIcon menuIcon = createImageIcon("mimetypes", "video-x-generic", 16);

        ArrayList<ActionMenu> actionList = new ArrayList<ActionMenu>();

        for (final DeviceIf dev : devices) {
            ArrayList<AbstractAction> commandList = new ArrayList<AbstractAction>();

            if (dev.isAbleToAddAndRemovePrograms()) {
                final Program test = dev.getProgramForProgramInList(program);

                if (test != null) {
                    AbstractAction caction = new AbstractAction() {
                        public void actionPerformed(ActionEvent evt) {
                            dev.remove(parent, test);
                            updateMarkedPrograms();
                        }
                    };
                    caction.putValue(Action.NAME, Localizer.getLocalization(Localizer.I18N_DELETE));
                    commandList.add(caction);
                } else {
                    AbstractAction caction = new AbstractAction() {
                        public void actionPerformed(ActionEvent evt) {
                            if(dev.add(parent, program)) {
                              dev.sendProgramsToReceiveTargets(new Program[] {program});
                            }
                            updateMarkedPrograms();
                        }
                    };
                    caction.putValue(Action.NAME, mLocalizer.msg("record", "record"));
                    commandList.add(caction);
                }

            }

            String[] commands = dev.getAdditionalCommands();

            if (commands != null) {
              for (int y = 0; y < commands.length; y++) {

                  final int num = y;

                  AbstractAction caction = new AbstractAction() {

                      public void actionPerformed(ActionEvent evt) {
                          dev.executeAdditionalCommand(parent, num, program);
                      }
                  };
                  caction.putValue(Action.NAME, commands[y]);
                  commandList.add(caction);
              }
            }

            if (!commandList.isEmpty()) {
              actionList.add(new ActionMenu(dev.getName(), commandList.toArray(new Action[commandList.size()])));
            }
        }

        if (actionList.size() == 1) {
            ActionMenu menu = actionList.get(0);

            if (menu.getSubItems().length == 0) {
                return null;
            }

            if (menu.getSubItems().length == 1) {
                Action action = menu.getSubItems()[0].getAction();
                action.putValue(Action.SMALL_ICON, menuIcon);
                return new ActionMenu(action);
            } else {
                return new ActionMenu(menu.getTitle(), menuIcon, menu.getSubItems());
            }

        }

        ActionMenu[] actions = new ActionMenu[actionList.size()];
        actionList.toArray(actions);

        if (actions.length == 0) {
            return null;
        }

        return new ActionMenu(menuText, menuIcon, actions);
    }

    /**
     * Updates the marked Programs.
     */
    protected void updateMarkedPrograms() {
        Vector<Program> list = getMarkedByDevices();

        for (Program aList : list) {

            if (mMarkedPrograms.contains(aList)) {
                mMarkedPrograms.remove(aList);
            }

            aList.mark(this);
        }

        for (Program mMarkedProgram : mMarkedPrograms) {
            mMarkedProgram.unmark(this);
        }

        mMarkedPrograms = list;

        updateTreeNode();
        super.saveMe();
    }

    /**
     * This Function Iterates over all Devices and collects the list of Programs
     * to mark...
     *
     * @return List with all Programs to mark
     */
    private Vector<Program> getMarkedByDevices() {
        Vector<Program> v = new Vector<Program>();

        for (Object o : mConfig.getDevices()) {
            DeviceIf device = (DeviceIf) o;

            Program[] programs = device.getProgramList();

            if (programs != null) {
                for (Program program : programs) {
                    if (!v.contains(program)) {
                        v.add(program);
                    }
                }
            }
        }

        return v;
    }

    public ActionMenu getButtonAction() {
        AbstractAction action = new AbstractAction() {

            public void actionPerformed(ActionEvent evt) {
                showDialog();
            }
        };
        action.putValue(Action.NAME, mLocalizer.msg("CapturePlugin", "Capture Plugin"));
        action.putValue(Action.SMALL_ICON, createImageIcon("mimetypes", "video-x-generic", 16));
        action.putValue(BIG_ICON, createImageIcon("mimetypes", "video-x-generic", 22));

        return new ActionMenu(action);
    }

    /**
     * This method is invoked by the host-application if the user has chosen
     * your plugin from the menu.
     */
    protected void showDialog() {
        CapturePluginDialog dialog = new CapturePluginDialog(getParentFrame(), mConfig);

        layoutWindow("captureDlg", dialog, new Dimension(500,450));

        if (mConfig.getDevices().isEmpty()) {
            dialog.show(CapturePluginPanel.TAB_DEVICELIST);
        } else {
            dialog.show(CapturePluginPanel.TAB_PROGRAMLIST);
        }

        updateMarkedPrograms();
    }

    public ThemeIcon getMarkIconFromTheme() {
        return new ThemeIcon("mimetypes", "video-x-generic", 16);
    }

    /**
     * Sets the CaputePluginData
     *
     * @param data CapturePluginData
     */
    public void setCapturePluginData(CapturePluginData data) {
        mConfig = data;
    }

    /**
     * Returns the CapturePluginData
     *
     * @return The CapaturePluginData
     */
    public CapturePluginData getCapturePluginData() {
        return mConfig;
    }

    /**
     * Update the TreeNode
     */
    private void updateTreeNode() {
        mRootNode.removeAllChildren();
        mRootNode.removeAllActions();

        for (Object o : mConfig.getDevices()) {
            final DeviceIf device = (DeviceIf) o;

            PluginTreeNode node;
            if (mConfig.getDevices().size() > 1) {
              node = new PluginTreeNode(device.getName());
              mRootNode.add(node);
            }
            else {
              node = mRootNode;
            }

            if(device.isAbleToAddAndRemovePrograms()) {
              node.getMutableTreeNode().setProgramReceiveTarget(new ProgramReceiveTarget(this, device.getName() + " - " + mLocalizer.msg("record", "record"), device.getId() + RECORD));
            }

            Program[] programs = device.getProgramList();

            if (programs != null) {
              for (Program program : programs) {
                  node.addProgram(program);
              }
            }

            node.addAction(new AbstractAction(mLocalizer.msg("configure", "Configure '{0}'", device.getName())) {
              @Override
              public void actionPerformed(ActionEvent e) {
                device.configDevice(UiUtilities.getBestDialogParent(getParentFrame()));
                updateTreeNode();
              }
            });
        }

        mRootNode.update();
    }

    /**
     * Get the Root-Node.
     * The CapturePlugin handles all Programs for itself. Some
     * Devices can remove Programs externaly
     */
    public PluginTreeNode getRootNode() {
        return mRootNode;
    }

    public boolean canUseProgramTree() {
        return true;
    }

    @Override
    public boolean canReceiveProgramsWithTarget() {
        return getProgramReceiveTargets().length >0;
    }

    @Override
    public boolean receivePrograms(Program[] programArr, ProgramReceiveTarget receiveTarget) {
        if (receiveTarget == null || receiveTarget.getTargetId() == null ||
            receiveTarget.getTargetId().indexOf('#') == -1) {
          return false;
        }

        String id = receiveTarget.getTargetId();
        String deviceid = StringUtils.substringBefore(id,"#");
    String command = id.substring(id.indexOf('#'));

        for (DeviceIf device : mConfig.getDevices()) {
            if (device.getId().equals(deviceid)) {
                if (command.equals(REMOVE)) {
                    for (Program program:programArr) {
                      if(device.isInList(program)) {
                        device.remove(getParentFrame(), program);
                      }
                    }
                    updateMarkedPrograms();
                    return true;
                } else if (command.equals(RECORD)) {
                    ArrayList<Program> successfullPrograms = new ArrayList<Program>(programArr.length);

                    for (Program program:programArr) {
                        if(device.add(getParentFrame(), program)) {
                          successfullPrograms.add(program);
                        }
                    }
                    device.sendProgramsToReceiveTargets(successfullPrograms.toArray(new Program[successfullPrograms.size()]));
                    updateMarkedPrograms();
                    return true;
                }

                if (command.startsWith("#_")) {
                    command = command.substring(2);

                    String[] cmdstr = device.getAdditionalCommands();

                    for (int i = 0;i < cmdstr.length;i++) {
                        if (cmdstr[i].equals(command)) {
                            for (Program program:programArr) {
                                device.executeAdditionalCommand(getParentFrame(), i, program);
                            }
                            return true;
                        }
                    }

                }
            }
        }

        return false;
    }

    @Override
    public ProgramReceiveTarget[] getProgramReceiveTargets() {
        ArrayList<ProgramReceiveTarget> targets = new ArrayList<ProgramReceiveTarget>();

        for (DeviceIf device : mConfig.getDevices()) {
            if (device.isAbleToAddAndRemovePrograms()) {
                targets.add(new ProgramReceiveTarget(this, device.getName() + " - " + mLocalizer.msg("record", "record"), device.getId() + RECORD));
                targets.add(new ProgramReceiveTarget(this, device.getName() + " - " + mLocalizer.msg("remove", "remove"), device.getId() + REMOVE));
            }

            for (String command : device.getAdditionalCommands()) {
                targets.add(new ProgramReceiveTarget(this, device.getName() + " - " + command, device.getId() + "#_" + command));
            }
        }

        return targets.toArray(new ProgramReceiveTarget[targets.size()]);
    }

    public void handleTvBrowserStartFinished() {
      mAllowedToShowDialog = true;

      if(mNeedsUpdate) {
        handleTvDataUpdateFinished();
      }
    }

    /**
     * Check the programs after data update.
     */
    public void handleTvDataUpdateFinished() {
      mNeedsUpdate = true;

      if(mAllowedToShowDialog) {
        mNeedsUpdate = false;

        final DeviceIf[] devices = mConfig.getDeviceArray();

        final DefaultTableModel model = new DefaultTableModel() {
          public boolean isCellEditable(int row, int column) {
            return false;
          }
        };

        model.setColumnCount(5);
        model.setColumnIdentifiers(new String[] {mLocalizer.msg("device","Device"),Localizer.getLocalization(Localizer.I18N_CHANNEL),mLocalizer.msg("date","Date"),ProgramFieldType.START_TIME_TYPE.getLocalizedName(),ProgramFieldType.TITLE_TYPE.getLocalizedName()});

        UIThreadRunner.invokeLater(new Runnable() {

          @Override
          public void run() {
            JTable table = new JTable(model);
            table.getTableHeader().setReorderingAllowed(false);
            table.getTableHeader().setResizingAllowed(false);
            table.getColumnModel().getColumn(0).setCellRenderer(new DefaultTableCellRenderer() {
              public Component getTableCellRendererComponent(JTable renderTable, Object value,
                  boolean isSelected, boolean hasFocus, int row, int column) {
                Component c = super.getTableCellRendererComponent(renderTable,value,isSelected,hasFocus,row,column);

                if(value instanceof DeviceIf) {
                  if(((DeviceIf)value).getDeleteRemovedProgramsAutomatically() && !isSelected) {
                    c.setForeground(Color.red);
                  }
                }

                return c;
              }
            });

            int[] columnWidth = new int[5];

            for(int i = 0; i < columnWidth.length; i++) {
              columnWidth[i] =  UiUtilities.getStringWidth(table.getFont(),model.getColumnName(i)) + 10;
            }

            for (DeviceIf device : devices) {
              Program[] deleted = device.checkProgramsAfterDataUpdateAndGetDeleted();

              if(deleted != null && deleted.length > 0) {
                for(Program p : deleted) {
                  if(device.getDeleteRemovedProgramsAutomatically() && !p.isExpired() && !p.isOnAir()) {
                    device.remove(UiUtilities.getLastModalChildOf(getParentFrame()), p);
                  } else {
                    device.removeProgramWithoutExecution(p);
                  }

                  if(!p.isExpired()) {
                    Object[] o = new Object[] {device,p.getChannel().getName(),p.getDateString(),p.getTimeString(),p.getTitle()};

                    for(int i = 0; i < columnWidth.length; i++) {
                      columnWidth[i] = Math.max(columnWidth[i],UiUtilities.getStringWidth(table.getFont(),o[i].toString())+10);
                    }

                    model.addRow(o);
                  }
                }
              }

              device.getProgramList();
            }

            if(model.getRowCount() > 0) {
              int sum = 0;

              for(int i = 0; i < columnWidth.length; i++) {
                table.getColumnModel().getColumn(i).setPreferredWidth(columnWidth[i]);

                if(i < columnWidth.length-1) {
                  table.getColumnModel().getColumn(i).setMaxWidth(columnWidth[i]);
                }

                sum += columnWidth[i];
              }

              JScrollPane scrollPane = new JScrollPane(table);
              scrollPane.setPreferredSize(new Dimension(450,250));

              if(sum > 500) {
                table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
                scrollPane.getViewport().setPreferredSize(new Dimension(sum,scrollPane.getViewport().getPreferredSize().height));
              }

              JButton export = new JButton(mLocalizer.msg("exportList","Export list"));
              export.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                  JFileChooser chooser = new JFileChooser();
                  chooser.setDialogType(JFileChooser.SAVE_DIALOG);
                  chooser.setFileFilter(new FileFilter() {
                    public boolean accept(File f) {
                      return f.isDirectory() || f.toString().toLowerCase().endsWith(".txt");
                    }

                    public String getDescription() {
                      return "*.txt";
                    }
                  });

                  chooser.setSelectedFile(new File("RemovedPrograms.txt"));
                  if (chooser.showSaveDialog(UiUtilities.getLastModalChildOf(getParentFrame())) == JFileChooser.APPROVE_OPTION) {
                    if(chooser.getSelectedFile() != null) {
                      String file = chooser.getSelectedFile().getAbsolutePath();

                      if (!file.toLowerCase().endsWith(".txt")
                        && file.indexOf('.') == -1) {
                        file = file + ".txt";
                      }

                      if (file.indexOf('.') != -1) {
                        try {
                          RandomAccessFile write = new RandomAccessFile(file,"rw");
                          write.setLength(0);

                          String eolStyle = File.separator.equals("/") ? "\n" : "\r\n";

                          for(int i = 0; i < model.getRowCount(); i++) {
                            StringBuilder line = new StringBuilder();

                            for(int j = 0; j < model.getColumnCount(); j++) {
                              line.append(model.getValueAt(i, j)).append(' ');
                            }

                            line.append(eolStyle);

                            write.writeBytes(line.toString());
                          }

                          write.close();
                        }catch(Exception ee) {}
                      }
                    }
                  }
                }
              });

              Object[] message = {mLocalizer.msg("deletedText","The data was changed and the following programs were deleted:"),scrollPane,export};

              JOptionPane pane = new JOptionPane();
              pane.setMessage(message);
              pane.setMessageType(JOptionPane.PLAIN_MESSAGE);

              final JDialog d = pane.createDialog(UiUtilities.getLastModalChildOf(getParentFrame()), mLocalizer.msg("CapturePlugin","CapturePlugin") + " - " + mLocalizer.msg("deletedTitle","Deleted programs"));
              d.setResizable(true);
              d.setModal(false);

              SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                  d.setVisible(true);
                }
              });
            }
          }
        });
      }
    }

    /**
     * @return The parent frame.
     */
    public Frame getSuperFrame() {
      return getParentFrame();
    }

    public int getMarkPriorityForProgram(Program p) {
      return mConfig.getMarkPriority();
    }
}
TOP

Related Classes of captureplugin.CapturePlugin

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.