X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=frontend%2Fsrc%2Fyukihane%2Finqubus%2Fgui%2FMainFrame.java;h=8e03253be23c270546be42d600c612f06a7684d8;hb=d8c098c12854caa93c6d08c9bd35380ffcfdc1df;hp=d20e3ffb17c0f053b09d8e208de77201fc97ca1a;hpb=6989bc8b30cbd580c2454ce0634efdd0ab0b4521;p=coroid%2Finqubus.git diff --git a/frontend/src/yukihane/inqubus/gui/MainFrame.java b/frontend/src/yukihane/inqubus/gui/MainFrame.java index d20e3ff..8e03253 100644 --- a/frontend/src/yukihane/inqubus/gui/MainFrame.java +++ b/frontend/src/yukihane/inqubus/gui/MainFrame.java @@ -5,49 +5,91 @@ */ package yukihane.inqubus.gui; +import java.awt.Dimension; import java.awt.Image; import java.awt.ItemSelectable; +import java.awt.Point; import java.awt.Toolkit; -import java.awt.datatransfer.DataFlavor; -import java.awt.datatransfer.Transferable; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; import java.io.File; -import java.io.FilenameFilter; +import java.io.IOException; import java.net.URL; +import java.nio.file.FileSystem; +import java.nio.file.FileSystems; +import java.nio.file.Path; import java.util.ArrayList; -import java.util.Collection; +import java.util.HashSet; import java.util.List; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.util.regex.Matcher; -import java.util.regex.Pattern; +import java.util.Set; +import java.util.SortedSet; import javax.swing.BorderFactory; +import javax.swing.DefaultComboBoxModel; import javax.swing.DropMode; import javax.swing.GroupLayout; import javax.swing.GroupLayout.Alignment; import javax.swing.JButton; import javax.swing.JCheckBox; +import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; +import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; +import javax.swing.JTabbedPane; import javax.swing.JTable; import javax.swing.JTextField; import javax.swing.KeyStroke; -import javax.swing.LayoutStyle; import javax.swing.LayoutStyle.ComponentPlacement; -import javax.swing.TransferHandler; +import javax.swing.SwingUtilities; import javax.swing.WindowConstants; +import javax.swing.border.BevelBorder; +import javax.swing.table.TableModel; +import org.apache.commons.configuration.ConfigurationException; +import org.apache.commons.lang.builder.ToStringBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import saccubus.MainFrame_AboutBox; -import yukihane.inqubus.Config; +import saccubus.util.WayBackTimeParser; +import saccubus.worker.profile.CommentProfile; +import saccubus.worker.profile.DownloadProfile; +import saccubus.worker.profile.FfmpegProfile; +import saccubus.worker.profile.GeneralProfile; +import saccubus.worker.profile.LoginProfile; +import saccubus.worker.profile.OutputProfile; +import saccubus.worker.profile.ProxyProfile; +import saccubus.worker.profile.VideoProfile; +import yukihane.Util; +import yukihane.inqubus.config.Config; +import yukihane.inqubus.config.ConfigCommentProfile; +import yukihane.inqubus.config.ConfigConvertProfile; +import yukihane.inqubus.config.ConfigFfmpegProfile; +import yukihane.inqubus.config.ConfigGeneralProfile; +import yukihane.inqubus.config.ConfigLoginProfile; +import yukihane.inqubus.config.ConfigOutputProfile; +import yukihane.inqubus.config.ConfigProxyProfile; +import yukihane.inqubus.filewatch.FileWatch; +import yukihane.inqubus.filewatch.FileWatchUtil; +import yukihane.inqubus.manager.RequestProcess; +import yukihane.inqubus.manager.TaskKind; +import yukihane.inqubus.manager.TaskManage; +import yukihane.inqubus.manager.TaskManageListener; +import yukihane.inqubus.manager.TaskStatus; import yukihane.inqubus.model.Target; import yukihane.inqubus.model.TargetsTableModel; +import yukihane.inqubus.thumbnail.Repository; +import yukihane.inqubus.thumbnail.Thumbnail; /** * @@ -56,232 +98,424 @@ import yukihane.inqubus.model.TargetsTableModel; public class MainFrame extends JFrame { private static final long serialVersionUID = 1L; - private static final Logger logger = Logger.getLogger(MainFrame.class.getName()); + private static final Logger logger = LoggerFactory.getLogger(MainFrame.class); + private final Repository thumbRepository = new Repository(); private final TargetsTableModel targetModel = new TargetsTableModel(); + private final TaskManage taskManager; + private final Thread videoFileWatcherThread; + private final FileWatch videoFileWatcher; + private final Thread commentFileWatcherThread; + private final FileWatch commentFileWatcher; + /** Creates new form MainFrame */ public MainFrame() { - initComponents(); - initInputPanel(); - jPanel1.setTransferHandler(new DownloadListTransferHandler()); - jTable1.setTransferHandler(new TableTransferHandler()); - } + super(); + addWindowListener(new MainFrameWindowListener()); + setTitle(MainFrame_AboutBox.VERSION); + + final Config p = Config.INSTANCE; + + // ワーカスレッド生成 + final int thDownload = p.getSystemDownloadThread(); + final int secDownload = p.getSystemDownloadWait(); + final int thConvert = p.getSystemConvertThread(); + taskManager = new TaskManage(thDownload, secDownload, thConvert, new GuiTaskManageListener()); + + // ディレクトリ監視スレッド生成 + final FileSystem fs = FileSystems.getDefault(); + + final List videoSearchDirs = p.getSearchVideoDirs(); + videoSearchDirs.add(p.getVideoDir()); + final Set videoPaths = new HashSet<>(videoSearchDirs.size()); + for (String s : videoSearchDirs) { + videoPaths.add(fs.getPath(s)); + } + videoFileWatcher = new FileWatch(videoPaths); + this.videoFileWatcherThread = new Thread(videoFileWatcher); + this.videoFileWatcherThread.setDaemon(true); + + final List commentSearchDirs = p.getSearchCommentDirs(); + commentSearchDirs.add(p.getCommentDir()); + final Set commentPaths = new HashSet<>(commentSearchDirs.size()); + for(String s : commentSearchDirs) { + commentPaths.add(fs.getPath(s)); + } + commentFileWatcher = new FileWatch(commentPaths); + this.commentFileWatcherThread = new Thread(commentFileWatcher); + this.commentFileWatcherThread.setDaemon(true); - /** This method is called from within the constructor to - * initialize the form. - * WARNING: Do NOT modify this code. The content of this method is - * always regenerated by the Form Editor. - */ - @SuppressWarnings("unchecked") - // //GEN-BEGIN:initComponents - private void initComponents() { final URL url = MainFrame_AboutBox.class.getResource("icon.png"); final Image icon1 = Toolkit.getDefaultToolkit().createImage(url); final URL url32 = MainFrame_AboutBox.class.getResource("icon32.png"); final Image icon2 = Toolkit.getDefaultToolkit().createImage(url32); - final List images = new ArrayList(2); + final List images = new ArrayList<>(2); images.add(icon1); images.add(icon2); setIconImages(images); - jPanel1 = new JPanel(); - jScrollPane1 = new JScrollPane(); - jTable1 = new JTable(); - jPanel2 = new JPanel(); - jButton2 = new JButton(); - jButton3 = new JButton(); - jButton4 = new JButton(); - jPanel3 = new JPanel(); - idLabel = new JLabel(); - idField = new JTextField(); - movieLabel = new JLabel(); - useMovieLocalCheckBox = new JCheckBox(); - movieFileField = new JTextField(); - movieFileSelectButton = new JButton(); - commentLabel = new JLabel(); - useCommentLocalCheckBox = new JCheckBox(); - commentFileField = new JTextField(); - commentFileSelectButton = new JButton(); - outputLabel = new JLabel(); - outputConvertCheckBox = new JCheckBox(); - outputFileField = new JTextField(); - applyButton = new JButton(); + final JPanel pnlMain = new JPanel(); + final JScrollPane scrDisplay = new JScrollPane(); + tblDisplay = new JTable(targetModel, new TargetsColumnModel()) { + private static final long serialVersionUID = 1L; - setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); + @Override + public String getToolTipText(MouseEvent e) { + int row = convertRowIndexToModel(rowAtPoint(e.getPoint())); + TableModel m = getModel(); + final String videoId = (String) m.getValueAt(row, 0); + try { + final Thumbnail thumbnail = thumbRepository.getThumnail(videoId); + if (thumbnail == null) { + return videoId + ": 動画情報未取得"; + } - jPanel1.setBorder(BorderFactory.createEtchedBorder()); + final URL imageUrl = thumbnail.getImageFile().toURI().toURL(); - jTable1.setModel(targetModel); - jTable1.setDropMode(DropMode.INSERT_ROWS); - jScrollPane1.setViewportView(jTable1); + return "" + videoId + ": " + thumbnail.getTitle() + + " (" + thumbnail.getLength() + ")" + "
" + + "" + + ""; + } catch (Throwable ex) { + logger.warn(null, ex); + return videoId + ": 情報取得できません"; + } + } + }; + tblDisplay.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); + final JPanel pnlButton = new JPanel(); + final JPanel pnlInputMain = new JPanel(); + final JLabel lblId = new JLabel(); + final JLabel lblVideo = new JLabel(); + cbVideoLocal = new JCheckBox(); + btnVideo.addActionListener( + new FileChooseActionListener(MainFrame.this, JFileChooser.FILES_ONLY, fldVideo)); + fldVideo.setTransferHandler(new ContentTransferHandler(fldVideo.getTransferHandler(), cbVideoLocal)); + final JLabel lblComment = new JLabel(); + + fldBackLog.setToolTipText("YYYY/MM/DD hh:mm:ss形式、あるいは1970/01/01からの経過秒を入力します。"); + cbBackLog.addItemListener(new ItemListener() { - jPanel2.setBorder(BorderFactory.createEtchedBorder()); + @Override + public void itemStateChanged(ItemEvent e) { + final boolean selected = (e.getStateChange() == ItemEvent.SELECTED); + fldBackLog.setEnabled(selected); + } + }); + cbBackLog.addPropertyChangeListener("enabled", new PropertyChangeListener() { + + @Override + public void propertyChange(PropertyChangeEvent evt) { + final boolean enabled = ((Boolean) evt.getNewValue()).booleanValue(); + final boolean fldEnabled = enabled ? cbBackLog.isSelected() : false; + fldBackLog.setEnabled(fldEnabled); + } + }); + cbBackLogReduce.setToolTipText("「コメントの量を減らす」場合はチェックを付けます。"); + + cbCommentLocal = new JCheckBox(); + cbOwnerComment = new JCheckBox(); + + btnComment.addActionListener( + new FileChooseActionListener(MainFrame.this, JFileChooser.FILES_ONLY, fldComment)); + fldComment.setTransferHandler(new ContentTransferHandler(fldComment.getTransferHandler(), cbCommentLocal)); + + final JLabel lblOutput = new JLabel(); + cbOutputEnable = new JCheckBox(); + fldOutput = new JTextField(); + + setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); + + btnStop.addActionListener(new StopActionListener()); + final ApplyActionListener applyListener = new ApplyActionListener(); + btnApply.addActionListener(applyListener); + btnClear.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + initInputPanel(); + } + }); - jButton2.setText("開始"); + pnlMain.setBorder(BorderFactory.createEtchedBorder()); - jButton3.setText("停止"); + tblDisplay.setDropMode(DropMode.INSERT_ROWS); + scrDisplay.setViewportView(tblDisplay); - jButton4.setText("選択解除"); + pnlButton.setBorder(BorderFactory.createEtchedBorder()); - GroupLayout jPanel2Layout = new GroupLayout(jPanel2); - jPanel2.setLayout(jPanel2Layout); - jPanel2Layout.setHorizontalGroup( - jPanel2Layout.createParallelGroup(Alignment.LEADING) - .addGroup(jPanel2Layout.createSequentialGroup() + GroupLayout gl_pnlButton = new GroupLayout(pnlButton); + pnlButton.setLayout(gl_pnlButton); + gl_pnlButton.setHorizontalGroup( + gl_pnlButton.createParallelGroup(Alignment.LEADING) + .addGroup(gl_pnlButton.createSequentialGroup() .addContainerGap() - .addComponent(jButton2) .addPreferredGap(ComponentPlacement.RELATED) - .addComponent(jButton3) + .addComponent(btnStop) .addPreferredGap(ComponentPlacement.RELATED, 250, Short.MAX_VALUE) - .addComponent(jButton4) .addContainerGap()) ); - jPanel2Layout.setVerticalGroup( - jPanel2Layout.createParallelGroup(Alignment.LEADING) - .addGroup(jPanel2Layout.createSequentialGroup() + gl_pnlButton.setVerticalGroup( + gl_pnlButton.createParallelGroup(Alignment.LEADING) + .addGroup(gl_pnlButton.createSequentialGroup() .addContainerGap() - .addGroup(jPanel2Layout.createParallelGroup(Alignment.BASELINE) - .addComponent(jButton2) - .addComponent(jButton3) - .addComponent(jButton4)) - .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(gl_pnlButton.createParallelGroup(Alignment.BASELINE) + .addComponent(btnStop) + ) + .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + ) ); - jPanel3.setBorder(BorderFactory.createEtchedBorder()); + lblId.setText("ID"); - idLabel.setText("ID"); - idField.addFocusListener(new java.awt.event.FocusAdapter() { + cmbId = new IdComboBox(videoFileWatcher); + cmbId.getEditorComponent().addActionListener(applyListener); + cmbId.getEditorComponent().addFocusListener(new java.awt.event.FocusAdapter() { + @Override public void focusLost(java.awt.event.FocusEvent evt) { idFieldFocusLost(evt); } }); - movieLabel.setText("動画"); + lblVideo.setText("動画"); - useMovieLocalCheckBox.setText("local"); - useMovieLocalCheckBox.addItemListener(new java.awt.event.ItemListener() { + cbVideoLocal.setText("local"); + cbVideoLocal.addItemListener(new java.awt.event.ItemListener() { + @Override public void itemStateChanged(java.awt.event.ItemEvent evt) { useMovieLocalCheckBoxItemStateChanged(evt); } }); - movieFileSelectButton.setText("..."); + lblComment.setText("コメント"); - commentLabel.setText("コメント"); + cbCommentLocal.setText("local"); + cbCommentLocal.addItemListener(new ItemListener() { - useCommentLocalCheckBox.setText("local"); - useCommentLocalCheckBox.addItemListener(new java.awt.event.ItemListener() { - - public void itemStateChanged(java.awt.event.ItemEvent evt) { - useMovieLocalCheckBoxItemStateChanged(evt); + @Override + public void itemStateChanged(ItemEvent e) { + useMovieLocalCheckBoxItemStateChanged(e); + final boolean selected = (e.getStateChange() == ItemEvent.SELECTED); + cbBackLogReduce.setEnabled(!selected); + cbBackLog.setEnabled(!selected); + cbOwnerComment.setEnabled(!selected); } }); - commentFileSelectButton.setText("..."); + cbOwnerComment.setText("投コメのみ"); - outputLabel.setText("出力"); + lblOutput.setText("出力"); - outputConvertCheckBox.setText("変換"); - outputConvertCheckBox.addItemListener(new java.awt.event.ItemListener() { + cbOutputEnable.setText("変換"); + cbOutputEnable.addItemListener(new java.awt.event.ItemListener() { + @Override public void itemStateChanged(java.awt.event.ItemEvent evt) { outputConvertCheckBoxItemStateChanged(evt); } }); - applyButton.setText("適用"); - GroupLayout jPanel3Layout = new GroupLayout(jPanel3); - jPanel3.setLayout(jPanel3Layout); - jPanel3Layout.setHorizontalGroup( - jPanel3Layout.createParallelGroup(Alignment.LEADING) - .addGroup(jPanel3Layout.createSequentialGroup() + final GroupLayout glInputMain = new GroupLayout(pnlInputMain); + pnlInputMain.setLayout(glInputMain); + glInputMain.setHorizontalGroup( + glInputMain.createParallelGroup(Alignment.LEADING) + .addGroup(glInputMain.createSequentialGroup() .addContainerGap() - .addGroup(jPanel3Layout.createParallelGroup(Alignment.LEADING) - .addGroup(jPanel3Layout.createSequentialGroup() - .addGroup(jPanel3Layout.createParallelGroup(Alignment.LEADING) - .addComponent(commentLabel) - .addComponent(movieLabel) - .addComponent(idLabel) - .addComponent(outputLabel)) + .addComponent(lblId) + .addPreferredGap(ComponentPlacement.RELATED) + .addComponent(cmbId, GroupLayout.PREFERRED_SIZE, 100, Short.MAX_VALUE) + .addContainerGap() + ) + .addGroup(glInputMain.createSequentialGroup() + .addContainerGap() + .addGroup(glInputMain.createParallelGroup(Alignment.LEADING) + .addComponent(lblVideo) + .addComponent(lblComment) + .addComponent(lblOutput) + ) + .addPreferredGap(ComponentPlacement.RELATED) + .addGroup(glInputMain.createParallelGroup(Alignment.LEADING) + .addGroup(glInputMain.createSequentialGroup() + .addGroup(glInputMain.createParallelGroup(Alignment.LEADING) + .addComponent(cbVideoLocal) + .addComponent(cbCommentLocal) + .addComponent(cbOutputEnable) + ) .addPreferredGap(ComponentPlacement.RELATED) - .addGroup(jPanel3Layout.createParallelGroup(Alignment.LEADING) - .addGroup(jPanel3Layout.createSequentialGroup() - .addComponent(useMovieLocalCheckBox) - .addPreferredGap(ComponentPlacement.RELATED) - .addComponent(movieFileField, GroupLayout.DEFAULT_SIZE, 317, Short.MAX_VALUE) - .addPreferredGap(ComponentPlacement.RELATED) - .addComponent(movieFileSelectButton)) - .addComponent(idField, GroupLayout.PREFERRED_SIZE, 100, GroupLayout.PREFERRED_SIZE) - .addGroup(Alignment.TRAILING, jPanel3Layout.createSequentialGroup() - .addGroup(jPanel3Layout.createParallelGroup(Alignment.TRAILING) - .addGroup(Alignment.LEADING, jPanel3Layout.createSequentialGroup() - .addComponent(outputConvertCheckBox) - .addPreferredGap(ComponentPlacement.RELATED) - .addComponent(outputFileField, GroupLayout.DEFAULT_SIZE, 317, Short.MAX_VALUE)) - .addGroup(jPanel3Layout.createSequentialGroup() - .addComponent(useCommentLocalCheckBox) - .addPreferredGap(ComponentPlacement.RELATED) - .addComponent(commentFileField, GroupLayout.DEFAULT_SIZE, 317, Short.MAX_VALUE))) - .addPreferredGap(ComponentPlacement.RELATED) - .addComponent(commentFileSelectButton)))) - .addComponent(applyButton, Alignment.TRAILING)) - .addContainerGap()) + .addGroup(glInputMain.createParallelGroup(Alignment.LEADING) + .addComponent(cmbVideo, 300, 300, Short.MAX_VALUE) + .addComponent(cmbComment, 300, 300, Short.MAX_VALUE) + .addComponent(fldOutput, 300, 300, Short.MAX_VALUE) + ) + .addGroup(glInputMain.createParallelGroup() + .addComponent(btnVideo) + .addComponent(btnComment) + ) + .addContainerGap() + ) + .addGroup(glInputMain.createSequentialGroup() + .addComponent(cbOwnerComment) + .addPreferredGap(ComponentPlacement.UNRELATED) + .addComponent(cbBackLogReduce) + .addPreferredGap(ComponentPlacement.UNRELATED) + .addComponent(cbBackLog) + .addPreferredGap(ComponentPlacement.RELATED) + .addComponent(fldBackLog, GroupLayout.PREFERRED_SIZE, 150, GroupLayout.PREFERRED_SIZE) + ) + ) + ) ); - jPanel3Layout.setVerticalGroup( - jPanel3Layout.createParallelGroup(Alignment.LEADING) - .addGroup(jPanel3Layout.createSequentialGroup() + + glInputMain.setVerticalGroup( + glInputMain.createParallelGroup(Alignment.LEADING) + .addGroup(glInputMain.createSequentialGroup() .addContainerGap() - .addGroup(jPanel3Layout.createParallelGroup(Alignment.BASELINE) - .addComponent(idField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(idLabel)) + .addGroup(glInputMain.createParallelGroup(Alignment.BASELINE) + .addComponent(cmbId, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(lblId) + ) .addPreferredGap(ComponentPlacement.RELATED) - .addGroup(jPanel3Layout.createParallelGroup(Alignment.BASELINE) - .addComponent(movieLabel) - .addComponent(movieFileField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(movieFileSelectButton) - .addComponent(useMovieLocalCheckBox)) + .addGroup(glInputMain.createParallelGroup(Alignment.BASELINE) + .addComponent(lblVideo) + .addComponent(cbVideoLocal) + .addComponent(cmbVideo, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(btnVideo) + ) .addPreferredGap(ComponentPlacement.RELATED) - .addGroup(jPanel3Layout.createParallelGroup(Alignment.BASELINE) - .addComponent(commentLabel) - .addComponent(commentFileField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(commentFileSelectButton) - .addComponent(useCommentLocalCheckBox)) + .addGroup(glInputMain.createParallelGroup(Alignment.BASELINE) + .addComponent(lblComment) + .addComponent(cbCommentLocal) + .addComponent(cmbComment, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(btnComment) + ) .addPreferredGap(ComponentPlacement.RELATED) - .addGroup(jPanel3Layout.createParallelGroup(Alignment.BASELINE) - .addComponent(outputLabel) - .addComponent(outputFileField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addComponent(outputConvertCheckBox)) - .addPreferredGap(ComponentPlacement.UNRELATED) - .addComponent(applyButton) - .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(glInputMain.createParallelGroup(Alignment.BASELINE) + .addComponent(cbOwnerComment) + .addComponent(cbBackLogReduce) + .addComponent(cbBackLog) + .addComponent(fldBackLog) + ) + .addPreferredGap(ComponentPlacement.RELATED) + .addGroup(glInputMain.createParallelGroup(Alignment.BASELINE) + .addComponent(lblOutput) + .addComponent(fldOutput, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(cbOutputEnable) + ) + ) + ); + + // ffmpeg入力パネル + pnlInputFfmpeg.fldFfmpegOptionResizeWidth.setEnabled(false); + pnlInputFfmpeg.fldFfmpegOptionResizeHeight.setEnabled(false); + pnlInputFfmpeg.cbFfmpegOptionKeepAspect.setEnabled(false); + pnlInputFfmpeg.cmbFfmpegOptionFile.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + final boolean notFile = !pnlInputFfmpeg.mdlFfmpegOption.isFile(); + pnlInputFfmpeg.fldFfmpegOptionExtension.setEnabled(notFile); + pnlInputFfmpeg.fldFfmpegOptionMain.setEnabled(notFile); + pnlInputFfmpeg.fldFfmpegOptionIn.setEnabled(notFile); + pnlInputFfmpeg.fldFfmpegOptionOut.setEnabled(notFile); + pnlInputFfmpeg.fldFfmpegOptionAv.setEnabled(notFile); + pnlInputFfmpeg.cbFfmpegOptionResize.setEnabled(notFile); + } + }); + pnlInputFfmpeg.cbFfmpegOptionResize.addItemListener(new ItemListener() { + + @Override + public void itemStateChanged(ItemEvent e) { + final boolean selected = (e.getStateChange() == ItemEvent.SELECTED); + pnlInputFfmpeg.fldFfmpegOptionResizeWidth.setEnabled(selected); + pnlInputFfmpeg.fldFfmpegOptionResizeHeight.setEnabled(selected); + pnlInputFfmpeg.cbFfmpegOptionKeepAspect.setEnabled(selected); + } + }); + pnlInputFfmpeg.cbFfmpegOptionResize.addPropertyChangeListener("enabled", new PropertyChangeListener() { + + @Override + public void propertyChange(PropertyChangeEvent evt) { + final boolean enabled = ((Boolean) evt.getNewValue()).booleanValue(); + final boolean fldEnabled = enabled ? pnlInputFfmpeg.cbFfmpegOptionResize.isSelected() : false; + pnlInputFfmpeg.fldFfmpegOptionResizeWidth.setEnabled(fldEnabled); + pnlInputFfmpeg.fldFfmpegOptionResizeHeight.setEnabled(fldEnabled); + pnlInputFfmpeg.cbFfmpegOptionKeepAspect.setEnabled(fldEnabled); + } + }); + + + tbpInput.add("メイン", pnlInputMain); + tbpInput.add("ffmpeg", pnlInputFfmpeg); + + // 入力部のボタンやメッセージ表示部 + fldInputMessage.setEditable(false); + fldInputMessage.setEnabled(false); + fldInputMessage.setBorder(BorderFactory.createEmptyBorder()); + + final JPanel pnlInputButton = new JPanel(); + final GroupLayout glInputButton = new GroupLayout(pnlInputButton); + pnlInputButton.setLayout(glInputButton); + glInputButton.setHorizontalGroup(glInputButton.createSequentialGroup() + .addContainerGap() + .addComponent(fldInputMessage, GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE) + .addPreferredGap(ComponentPlacement.UNRELATED) + .addComponent(btnClear) + .addPreferredGap(ComponentPlacement.UNRELATED) + .addComponent(btnApply) + .addContainerGap() + ); + glInputButton.setVerticalGroup(glInputButton.createSequentialGroup() + .addContainerGap() + .addGroup(glInputButton.createParallelGroup(Alignment.BASELINE) + .addComponent(fldInputMessage, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(btnClear) + .addComponent(btnApply) + ) + .addContainerGap() ); - GroupLayout jPanel1Layout = new GroupLayout(jPanel1); - jPanel1.setLayout(jPanel1Layout); - jPanel1Layout.setHorizontalGroup( - jPanel1Layout.createParallelGroup(Alignment.LEADING) - .addGroup(Alignment.TRAILING, jPanel1Layout.createSequentialGroup() + // 画面下半分の入力部分 + final JPanel pnlInputAll = new JPanel(); + pnlInputAll.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED)); + final GroupLayout glInputAll = new GroupLayout(pnlInputAll); + pnlInputAll.setLayout(glInputAll); + glInputAll.setHorizontalGroup(glInputAll.createParallelGroup() + .addComponent(tbpInput) + .addComponent(pnlInputButton) + ); + glInputAll.setVerticalGroup(glInputAll.createSequentialGroup() + .addComponent(tbpInput) + .addComponent(pnlInputButton) + ); + + GroupLayout gl_pnlMain = new GroupLayout(pnlMain); + pnlMain.setLayout(gl_pnlMain); + gl_pnlMain.setHorizontalGroup( + gl_pnlMain.createParallelGroup(Alignment.LEADING) + .addGroup(Alignment.TRAILING, gl_pnlMain.createSequentialGroup() .addContainerGap() - .addGroup(jPanel1Layout.createParallelGroup(Alignment.TRAILING) - .addComponent(jPanel3, Alignment.LEADING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(jScrollPane1, Alignment.LEADING, GroupLayout.DEFAULT_SIZE, 480, Short.MAX_VALUE) - .addComponent(jPanel2, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(gl_pnlMain.createParallelGroup(Alignment.TRAILING) + .addComponent(scrDisplay, Alignment.LEADING, GroupLayout.DEFAULT_SIZE, 480, Short.MAX_VALUE) + .addComponent(pnlButton, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(pnlInputAll, Alignment.LEADING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + ) .addContainerGap()) ); - jPanel1Layout.setVerticalGroup( - jPanel1Layout.createParallelGroup(Alignment.LEADING) - .addGroup(Alignment.TRAILING, jPanel1Layout.createSequentialGroup() + gl_pnlMain.setVerticalGroup( + gl_pnlMain.createParallelGroup(Alignment.LEADING) + .addGroup(Alignment.TRAILING, gl_pnlMain.createSequentialGroup() .addContainerGap() - .addComponent(jScrollPane1, GroupLayout.DEFAULT_SIZE, 197, Short.MAX_VALUE) + .addComponent(scrDisplay, GroupLayout.DEFAULT_SIZE, 197, Short.MAX_VALUE) .addPreferredGap(ComponentPlacement.RELATED) - .addComponent(jPanel2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addComponent(pnlButton, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) .addPreferredGap(ComponentPlacement.RELATED) - .addComponent(jPanel3, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) - .addGap(24, 24, 24)) + .addComponent(pnlInputAll, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) + .addContainerGap() + ) ); @@ -292,154 +526,234 @@ public class MainFrame extends JFrame { getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(Alignment.LEADING) - .addComponent(jPanel1, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(pnlMain, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) ); layout.setVerticalGroup( layout.createParallelGroup(Alignment.LEADING) - .addComponent(jPanel1, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(pnlMain, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) ); pack(); - }//
//GEN-END:initComponents + setMinimumSize(getSize()); + + /* + * 画面のサイズや位置を前回終了時のものに設定する + */ + final int windowWidth = p.getSystemWindowWidth(); + final int windowHeight = p.getSystemWindowHeight(); + if (windowWidth > 0 && windowHeight > 0) { + setSize(windowWidth, windowHeight); + } - private File searchFileMatchId(final File dir, final String id) throws UnsupportedOperationException { - // TODO 候補は複数返すようにして、その後の対処は呼び出しもとで行ってもらった方が良いかも - if (id.isEmpty()) { - return null; + final int windowPosX = p.getSystemWindowPosX(); + final int windowPosY = p.getSystemWindowPosY(); + final Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); + if (windowPosX + windowWidth > 0 && windowPosX < screenSize.width + && windowPosY + windowHeight > 0 && windowPosY < screenSize.height) { + setLocation(windowPosX, windowPosY); + } else { + setLocationByPlatform(true); } - final File[] lists = dir.listFiles(new FilenameFilter() { + final int colId = p.getSystemColumnId(); + if(colId > 0) { + tblDisplay.getColumnModel().getColumn(0).setPreferredWidth(colId); + } + final int colStatus = p.getSystemColumnStatus(); + if(colStatus > 0) { + tblDisplay.getColumnModel().getColumn(4).setPreferredWidth(colStatus); + } - final Pattern pattern = Pattern.compile(id + "\\D"); + initInputPanel(); + } - @Override - public boolean accept(File dir, String name) { - return pattern.matcher(name).find(); - } - }); + public void startWatcher() { + videoFileWatcherThread.start(); + commentFileWatcherThread.start(); + } - if (lists.length == 1) { - return lists[0]; - } else if (lists.length > 1) { - throw new UnsupportedOperationException(); + private static void createFieldInfo( FileComboBox combo, boolean useLocal, String text, String pattern, Set allFiles) { + if (useLocal) { + final SortedSet matchFiles = FileWatchUtil.getFileNamesContain(allFiles, text); + DefaultComboBoxModel model = new DefaultComboBoxModel<>(matchFiles.toArray(new String[0])); + combo.setModel(model); } else { - return null; + combo.setModel(new DefaultComboBoxModel()); + combo.getEditorComponent().setText(pattern); + } + } + + private class GuiTaskManageListener implements TaskManageListener { + + @Override + public void process(final int id, final TaskKind kind, final TaskStatus status, final double percentage, + final String message) { + SwingUtilities.invokeLater(new Runnable() { + + @Override + public void run() { + targetModel.setStatus(id, kind, status, percentage, message); + } + }); + } + } + + private class StopActionListener implements ActionListener { + + @Override + public void actionPerformed(ActionEvent e) { + final int row = tblDisplay.getSelectedRow(); + final Target t = targetModel.getTarget(row); + final boolean res = taskManager.cancel(t.getRowId()); + logger.debug("停止: {} {}", t.getVideoId(), res); + if (res) { + targetModel.setStatus(t.getRowId(), null, TaskStatus.CANCELLED, -1.0, "キャンセル"); + } + } + } + + private class ApplyActionListener implements ActionListener { + + @Override + public void actionPerformed(ActionEvent e) { + try { + final DownloadProfile downProf = new InqubusDownloadProfile(); + final String id = Util.getVideoId(cmbId.getText()); + final InqubusConvertProfile convProf = new InqubusConvertProfile(); + logger.debug(downProf.toString()); + logger.debug(convProf.toString()); + + final File tempDir = new File(Config.INSTANCE.getSystemTempDir()); + thumbRepository.request(downProf.getProxyProfile(), tempDir, id); + + final RequestProcess rp = new RequestProcess(downProf, id, convProf); + final boolean res = taskManager.add(rp); + if (res) { + targetModel.addTarget(new Target(rp)); + initInputPanel(); + } else { + fldInputMessage.setText("行うべき処理がありません"); + } + } catch (Throwable th) { + logger.error(null, th); + JOptionPane.showMessageDialog(MainFrame.this, th.getMessage(), "中断しました", JOptionPane.ERROR_MESSAGE); + } } } + /** + * 動画, コメントの"local"チェックボックス更新時の処理. + */ private void useMovieLocalCheckBoxItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_useMovieLocalCheckBoxItemStateChanged final Config p = Config.INSTANCE; final ItemSelectable source = evt.getItemSelectable(); - JButton btn; - JTextField field; - File dir; - if (source == useMovieLocalCheckBox) { - btn = movieFileSelectButton; - field = movieFileField; - dir = new File(p.getVideoDir()); + JButton button; + FileComboBox combo; + Set allFiles; + String pattern; + if (source == cbVideoLocal) { + button = btnVideo; + combo = cmbVideo; + allFiles = videoFileWatcher.getFiles(); + pattern = p.getVideoFileNamePattern(); } else { - btn = commentFileSelectButton; - field = commentFileField; - dir = new File(p.getCommentDir()); + button = btnComment; + combo = cmbComment; + allFiles = commentFileWatcher.getFiles(); + pattern = p.getCommentFileNamePattern(); } final boolean useLocal = (evt.getStateChange() == ItemEvent.SELECTED); - btn.setEnabled(useLocal); - String text; - if (useLocal) { - final File f = searchFileMatchId(dir, idField.getText()); - if (f != null) { - text = f.getPath(); - } else { - text = ""; - } - } else { - text = p.getVideoFileNamePattern(); - } - field.setText(text); - }//GEN-LAST:event_useMovieLocalCheckBoxItemStateChanged + button.setEnabled(useLocal); + createFieldInfo(combo, useLocal, cmbId.getText(), pattern, allFiles); + + } private void outputConvertCheckBoxItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_outputConvertCheckBoxItemStateChanged final boolean convert = (evt.getStateChange() == ItemEvent.SELECTED); - outputFileField.setEnabled(convert); + fldOutput.setEnabled(convert); }//GEN-LAST:event_outputConvertCheckBoxItemStateChanged private void idFieldFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_idFieldFocusLost final Config p = Config.INSTANCE; - final String id = idField.getText(); - if (id.isEmpty()) { - return; - } - - if (useMovieLocalCheckBox.isSelected() && movieFileField.getText().isEmpty()) { - final File dir = new File(p.getVideoDir()); - final File file = searchFileMatchId(dir, id); - if (file != null) { - movieFileField.setText(file.getPath()); - } - } - - if (useCommentLocalCheckBox.isSelected() && commentFileField.getText().isEmpty()) { - final File dir = new File(p.getCommentDir()); - final File file = searchFileMatchId(dir, id); - if (file != null) { - commentFileField.setText(file.getPath()); - } - } + final String id = cmbId.getText(); + createFieldInfo(cmbVideo, cbVideoLocal.isSelected(), id, p.getVideoFileNamePattern(), videoFileWatcher.getFiles()); + createFieldInfo(cmbComment, cbCommentLocal.isSelected(), id, p.getCommentFileNamePattern(), commentFileWatcher.getFiles()); }//GEN-LAST:event_idFieldFocusLost // Variables declaration - do not modify//GEN-BEGIN:variables - private JButton applyButton; - private JTextField commentFileField; - private JButton commentFileSelectButton; - private JLabel commentLabel; - private JTextField idField; - private JLabel idLabel; - private JButton jButton2; - private JButton jButton3; - private JButton jButton4; - private JPanel jPanel1; - private JPanel jPanel2; - private JPanel jPanel3; - private JScrollPane jScrollPane1; - private JTable jTable1; - private JTextField movieFileField; - private JButton movieFileSelectButton; - private JLabel movieLabel; - private JCheckBox outputConvertCheckBox; - private JTextField outputFileField; - private JLabel outputLabel; - private JCheckBox useCommentLocalCheckBox; - private JCheckBox useMovieLocalCheckBox; + private final JTable tblDisplay; + // ボタン領域 + private final JButton btnStop = new JButton("停止"); + // 入力領域 + private final JTabbedPane tbpInput = new JTabbedPane(JTabbedPane.BOTTOM); + // 入力領域 - メイン + private final IdComboBox cmbId; + private final JCheckBox cbBackLogReduce = new JCheckBox("少コメ"); + private final JCheckBox cbBackLog = new JCheckBox("過去ログ"); + private final JTextField fldBackLog = new JTextField(); + private final JCheckBox cbVideoLocal; + private final FileComboBox cmbVideo = new FileComboBox(); + private final JTextField fldVideo = cmbVideo.getEditorComponent(); + private final JButton btnVideo = new JButton("..."); + private final JCheckBox cbCommentLocal; + private final FileComboBox cmbComment = new FileComboBox(); + private final JTextField fldComment = cmbComment.getEditorComponent(); + private final JButton btnComment = new JButton("..."); + private final JCheckBox cbOwnerComment; + private final JCheckBox cbOutputEnable; + private final JTextField fldOutput; + // 入力領域 - ffmpeg + private final FfmpegParamPanel pnlInputFfmpeg = new FfmpegParamPanel(); + // 適用 + private final JTextField fldInputMessage = new JTextField(); + private final JButton btnClear = new JButton("クリア"); + private final JButton btnApply = new JButton("適用"); // End of variables declaration//GEN-END:variables private void initInputPanel() { - idField.setText(""); + fldInputMessage.setText(""); + initMainTab(); + initFfmpegTab(); + tbpInput.setSelectedIndex(0); + cmbId.requestFocus(); + } + private void initMainTab() { final Config p = Config.INSTANCE; - final boolean movieLocal = p.getVideoUseLocal(); - useMovieLocalCheckBox.setSelected(movieLocal); - movieFileSelectButton.setEnabled(movieLocal); - if (!movieLocal) { - movieFileField.setText(p.getVideoFileNamePattern()); + cmbId.setText(""); + cbBackLogReduce.setSelected(p.getCommentMinDisabled()); + cbBackLog.setEnabled(true); + cbBackLog.setSelected(false); + fldBackLog.setEnabled(false); + fldBackLog.setText(""); + + final boolean videoLocal = p.getVideoUseLocal(); + cbVideoLocal.setSelected(videoLocal); + if (!videoLocal) { + fldVideo.setText(p.getVideoFileNamePattern()); } + btnVideo.setEnabled(videoLocal); final boolean commentLocal = p.getCommentUseLocal(); - useCommentLocalCheckBox.setSelected(commentLocal); - commentFileSelectButton.setEnabled(commentLocal); + cbCommentLocal.setSelected(commentLocal); if (!commentLocal) { - commentFileField.setText(p.getCommentFileNamePattern()); + fldComment.setText(p.getCommentFileNamePattern()); } + btnComment.setEnabled(commentLocal); final boolean convert = p.getOutputEnable(); - outputConvertCheckBox.setSelected(convert); - outputFileField.setEnabled(convert); - outputFileField.setText(p.getOutputFileNamePattern()); + cbOutputEnable.setSelected(convert); + fldOutput.setEnabled(convert); + fldOutput.setText(p.getOutputFileNamePattern()); + } + private void initFfmpegTab() { + pnlInputFfmpeg.init(Config.INSTANCE); } private JMenuBar initMenuBar() { @@ -450,20 +764,20 @@ public class MainFrame extends JFrame { final JMenuItem itExit = new JMenuItem("終了(X)", KeyEvent.VK_X); itExit.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, ActionEvent.CTRL_MASK)); - itExit.addActionListener(new ActionListener() { + final ActionListener exitActionListener = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - throw new UnsupportedOperationException("Not supported yet."); + processWindowEvent(new WindowEvent(MainFrame.this, WindowEvent.WINDOW_CLOSING)); } - }); + }; + itExit.addActionListener(exitActionListener); mnFile.add(itExit); final JMenu mnTool = new JMenu("ツール(T)"); menuBar.add(mnTool); final JMenuItem itOption = new JMenuItem("オプション(O)...", KeyEvent.VK_O); - // TODO ショートカットキー itOption.addActionListener(new ActionListener() { @Override @@ -496,62 +810,369 @@ public class MainFrame extends JFrame { return menuBar; } - private class DownloadListTransferHandler extends TransferHandler { + private class MainFrameWindowListener extends WindowAdapter { + @Override + public void windowClosing(WindowEvent e) { + final Config p = Config.INSTANCE; + + // 保存するのは最大化していない場合だけ + if (JFrame.NORMAL == getExtendedState()) { + final Dimension size = getSize(); + p.setSystemWindowWidth(size.width); + p.setSystemWindowHeight(size.height); + + final Point pos = getLocation(); + p.setSystemWindowPosX(pos.x); + p.setSystemWindowPosY(pos.y); + } + + p.setSystemColumnId(tblDisplay.getColumnModel().getColumn(0).getWidth()); + p.setSystemColumnVideo(tblDisplay.getColumnModel().getColumn(1).getWidth()); + p.setSystemColumnComment(tblDisplay.getColumnModel().getColumn(2).getWidth()); + p.setSystemColumnConvert(tblDisplay.getColumnModel().getColumn(3).getWidth()); + p.setSystemColumnStatus(tblDisplay.getColumnModel().getColumn(4).getWidth()); + try { + p.save(); + } catch (ConfigurationException ex) { + logger.error("コンフィグ保存失敗", ex); + } + } + } - private static final long serialVersionUID = 1L; - private final Pattern movieIdPattern = Pattern.compile("(\\w\\w\\d+)"); + /* + * ここからDownloadProfile作成用クラスの定義 + */ + private class InqubusDownloadProfile implements DownloadProfile { + + private final LoginProfile loginProfile; + private final ProxyProfile proxyProfile; + private final VideoProfile videoProfile; + private final CommentProfile commentProfile; + private final GeneralProfile generalProfile; + + private InqubusDownloadProfile() { + this.loginProfile = new ConfigLoginProfile(); + this.proxyProfile = new ConfigProxyProfile(); + this.videoProfile = new InqubusVideoProfile(); + this.commentProfile = new InqubusCommentProfile(); + this.generalProfile = new ConfigGeneralProfile(); + } @Override - public boolean canImport(TransferHandler.TransferSupport support) { - Transferable transferable = support.getTransferable(); - if (transferable.isDataFlavorSupported(DataFlavor.javaFileListFlavor) - || transferable.isDataFlavorSupported(DataFlavor.stringFlavor)) { - return true; + public LoginProfile getLoginProfile() { + return this.loginProfile; + } + + @Override + public ProxyProfile getProxyProfile() { + return this.proxyProfile; + } + + @Override + public VideoProfile getVideoProfile() { + return this.videoProfile; + } + + @Override + public CommentProfile getCommentProfile() { + return this.commentProfile; + } + + @Override + public GeneralProfile getGeneralProfile() { + return this.generalProfile; + } + + @Override + public String toString(){ + return ToStringBuilder.reflectionToString(this); + } + } + + private class InqubusVideoProfile implements VideoProfile { + private final boolean download; + private final File dir; + private final String fileName; + private final File localFile; + + private InqubusVideoProfile(){ + final Config p = Config.INSTANCE; + this.download = !cbVideoLocal.isSelected(); + if (this.download) { + this.dir = new File(p.getVideoDir()); + this.fileName = fldVideo.getText(); + this.localFile = null; + } else { + this.dir = null; + this.fileName = null; + this.localFile = new File(fldVideo.getText()); } - return false; } @Override - public boolean importData(TransferHandler.TransferSupport support) { - try { - Transferable transferable = support.getTransferable(); - if (transferable.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) { - @SuppressWarnings("unchecked") - final List data = (List) transferable.getTransferData(DataFlavor.javaFileListFlavor); - Collection targets = Target.from(data); - targetModel.addTarget(targets); - } else if (transferable.isDataFlavorSupported(DataFlavor.stringFlavor)) { - String data = (String) transferable.getTransferData(DataFlavor.stringFlavor); - Matcher matcher = movieIdPattern.matcher(data); - if (matcher.find()) { - String movieId = matcher.group(1); - Target target = Target.fromId(movieId); - targetModel.addTarget(target); - } else { - return false; - } + public boolean isDownload() { + return this.download; + } + + @Override + public File getDir() { + return this.dir; + } + + @Override + public String getFileName() { + return this.fileName; + } + + @Override + public File getLocalFile() { + return this.localFile; + } + + @Override + public String toString(){ + return ToStringBuilder.reflectionToString(this); + } + } + + private class InqubusCommentProfile extends ConfigCommentProfile { + private final boolean download; + private final boolean ownerCommentOnly; + private final File dir; + private final String fileName; + private final File localFile; + private final boolean disablePerMinComment; + private final long backLogPoint; + + private InqubusCommentProfile() { + super(); + + final Config p = Config.INSTANCE; + this.download = !cbCommentLocal.isSelected(); + if (this.download) { + this.dir = new File(p.getCommentDir()); + this.fileName = fldComment.getText(); + this.localFile = null; + this.ownerCommentOnly = cbOwnerComment.isSelected(); + } else { + this.dir = null; + this.fileName = null; + this.localFile = new File(fldComment.getText()); + this.ownerCommentOnly = false; + } + if(cbBackLog.isSelected()) { + try { + this.backLogPoint = WayBackTimeParser.parse(fldBackLog.getText()); + } catch (IOException ex) { + throw new IllegalArgumentException("過去ログ時刻指定が誤っています。", ex); } - return false; - } catch (Exception e) { - logger.log(Level.SEVERE, null, e); - return false; + } else { + this.backLogPoint = -1L; } + + this.disablePerMinComment = cbBackLogReduce.isSelected(); + } + + @Override + public boolean isDownload() { + return this.download; + } + + @Override + public boolean isOwnerCommentOnly(){ + return this.ownerCommentOnly; + } + + @Override + public File getDir() { + return this.dir; + } + + @Override + public String getFileName() { + return this.fileName; + } + + @Override + public File getLocalFile() { + return this.localFile; + } + + @Override + public boolean isDisablePerMinComment() { + return this.disablePerMinComment; + } + + @Override + public long getBackLogPoint() { + return this.backLogPoint; + } + + @Override + public String toString(){ + return ToStringBuilder.reflectionToString(this); } } - private class TableTransferHandler extends DownloadListTransferHandler { + /* + * ここからConvertProfile作成用クラスの定義 + */ + private class InqubusConvertProfile extends ConfigConvertProfile { + private final OutputProfile outputProfile; + private final GeneralProfile generalProfile; + private final FfmpegProfile ffmpegProfile; + private final boolean convert; + + private InqubusConvertProfile() throws IOException { + this.outputProfile = new InqubusOutputProfile(); + this.generalProfile = new ConfigGeneralProfile(); - private static final long serialVersionUID = 1L; + final File file = pnlInputFfmpeg.mdlFfmpegOption.getSelectedFile(); + if (file != null) { + this.ffmpegProfile = new ConfigFfmpegProfile(); + } else { + this.ffmpegProfile = new InqubusFfmpegProfile(); + } + + this.convert = cbOutputEnable.isSelected(); + } + + @Override + public OutputProfile getOutputProfile() { + return this.outputProfile; + } + + @Override + public GeneralProfile getGeneralProfile() { + return this.generalProfile; + } + + @Override + public FfmpegProfile getFfmpegOption() { + return this.ffmpegProfile; + } + + @Override + public boolean isConvert() { + return this.convert; + } + + @Override + public String toString(){ + return ToStringBuilder.reflectionToString(this); + } + } + + private class InqubusOutputProfile extends ConfigOutputProfile { + private final String fileName; + private final String videoId; + private final String title; + + + private InqubusOutputProfile() { + this.fileName = fldOutput.getText(); + // TODO この時点でのID/Titleはどうするか… + this.videoId = ""; + this.title = ""; + } + + @Override + public String getFileName() { + return this.fileName; + } + + @Override + public String getVideoId() { + return this.videoId; + } + + @Override + public String getTitile() { + return this.title; + } + + @Override + public String toString(){ + return ToStringBuilder.reflectionToString(this); + } + } + + private class InqubusFfmpegProfile implements FfmpegProfile { + private final String extOption; + private final String inOption; + private final String mainOption; + private final String outOption; + private final String avOption; + private final boolean resize; + private final int resizeWidth; + private final int resizeHeight; + private final boolean adjustRatio; + + private InqubusFfmpegProfile() throws IOException { + String ext = pnlInputFfmpeg.fldFfmpegOptionExtension.getText(); + if (!ext.startsWith(".")) { + ext = "." + ext; + } + this.extOption = ext; + this.inOption = pnlInputFfmpeg.fldFfmpegOptionIn.getText(); + this.mainOption = pnlInputFfmpeg.fldFfmpegOptionMain.getText(); + this.outOption = pnlInputFfmpeg.fldFfmpegOptionOut.getText(); + this.avOption = pnlInputFfmpeg.fldFfmpegOptionAv.getText(); + this.resize = pnlInputFfmpeg.cbFfmpegOptionResize.isSelected(); + this.resizeWidth = Integer.parseInt(pnlInputFfmpeg.fldFfmpegOptionResizeWidth.getText()); + this.resizeHeight = Integer.parseInt(pnlInputFfmpeg.fldFfmpegOptionResizeHeight.getText()); + this.adjustRatio = pnlInputFfmpeg.cbFfmpegOptionKeepAspect.isSelected(); + } + + @Override + public String getExtOption() { + return this.extOption; + } + + @Override + public String getInOption() { + return this.inOption; + } + + @Override + public String getMainOption() { + return this.mainOption; + } + + @Override + public String getOutOption() { + return this.outOption; + } + + @Override + public String getAvfilterOption() { + return this.avOption; + } + + @Override + public boolean isResize() { + return this.resize; + } + + @Override + public int getResizeWidth() { + return this.resizeWidth; + } + + @Override + public int getResizeHeight() { + return this.resizeHeight; + } @Override - public boolean canImport(TransferHandler.TransferSupport support) { - return super.canImport(support); + public boolean isAdjustRatio() { + return this.adjustRatio; } @Override - public boolean importData(TransferHandler.TransferSupport support) { - return super.importData(support); + public String toString(){ + return ToStringBuilder.reflectionToString(this); } } }