*/
package yukihane.inqubus.gui;
+import java.awt.Dimension;
+import java.awt.Image;
import java.awt.ItemSelectable;
-import java.awt.datatransfer.DataFlavor;
-import java.awt.datatransfer.Transferable;
+import java.awt.Point;
+import java.awt.Toolkit;
+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.util.Collection;
+import java.io.IOException;
+import java.net.MalformedURLException;
+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.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 org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+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.TransferHandler;
-import javax.swing.UIManager;
-import javax.swing.UIManager.LookAndFeelInfo;
-import yukihane.inqubus.conifg.Properties;
+import javax.swing.KeyStroke;
+import javax.swing.LayoutStyle.ComponentPlacement;
+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 saccubus.MainFrame_AboutBox;
+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;
/**
*
* @author yuki
*/
-public class MainFrame extends javax.swing.JFrame {
+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());
- /** 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")
- // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
- private void initComponents() {
-
- jPanel1 = new javax.swing.JPanel();
- jScrollPane1 = new javax.swing.JScrollPane();
- jTable1 = new javax.swing.JTable();
- jPanel2 = new javax.swing.JPanel();
- jButton2 = new javax.swing.JButton();
- jButton3 = new javax.swing.JButton();
- jButton4 = new javax.swing.JButton();
- jPanel3 = new javax.swing.JPanel();
- idLabel = new javax.swing.JLabel();
- idField = new javax.swing.JTextField();
- movieLabel = new javax.swing.JLabel();
- useMovieLocalCheckBox = new javax.swing.JCheckBox();
- movieFileField = new javax.swing.JTextField();
- movieFileSelectButton = new javax.swing.JButton();
- commentLabel = new javax.swing.JLabel();
- useCommentLocalCheckBox = new javax.swing.JCheckBox();
- commentFileField = new javax.swing.JTextField();
- commentFileSelectButton = new javax.swing.JButton();
- outputLabel = new javax.swing.JLabel();
- outputConvertCheckBox = new javax.swing.JCheckBox();
- outputFileField = new javax.swing.JTextField();
- applyButton = new javax.swing.JButton();
- jMenuBar1 = new javax.swing.JMenuBar();
- jMenu1 = new javax.swing.JMenu();
- jMenu2 = new javax.swing.JMenu();
-
- setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
-
- jPanel1.setBorder(javax.swing.BorderFactory.createEtchedBorder());
-
- jTable1.setModel(targetModel);
- jTable1.setDropMode(javax.swing.DropMode.INSERT_ROWS);
- jScrollPane1.setViewportView(jTable1);
-
- jPanel2.setBorder(javax.swing.BorderFactory.createEtchedBorder());
-
- jButton2.setText("開始");
-
- jButton3.setText("停止");
-
- jButton4.setText("選択解除");
-
- javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
- jPanel2.setLayout(jPanel2Layout);
- jPanel2Layout.setHorizontalGroup(
- jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(jPanel2Layout.createSequentialGroup()
+ 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<String> videoSearchDirs = p.getSearchVideoDirs();
+ videoSearchDirs.add(p.getVideoDir());
+ final Set<Path> 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<String> commentSearchDirs = p.getSearchCommentDirs();
+ commentSearchDirs.add(p.getCommentDir());
+ final Set<Path> 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);
+
+ 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<Image> images = new ArrayList<>(2);
+ images.add(icon1);
+ images.add(icon2);
+ setIconImages(images);
+
+ final JPanel pnlMain = new JPanel();
+ final JScrollPane scrDisplay = new JScrollPane();
+ tblDisplay = new JTable(targetModel, new TargetsColumnModel()) {
+
+ @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 + ": 動画情報未取得";
+ }
+
+ final URL imageUrl = thumbnail.getImageFile().toURI().toURL();
+
+ return "<html>" + videoId + ": " + thumbnail.getTitle()
+ + " (" + thumbnail.getLength() + ")" + "<br/>"
+ + "<img src=\"" + imageUrl + "\"/>"
+ + "</html>";
+ } 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() {
+
+ @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();
+ cbCommentLocal.addItemListener(new ItemListener() {
+
+ @Override
+ public void itemStateChanged(ItemEvent e) {
+ final boolean selected = (e.getStateChange() == ItemEvent.SELECTED);
+ cbBackLogReduce.setEnabled(!selected);
+ cbBackLog.setEnabled(!selected);
+ }
+ });
+ 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();
+ }
+ });
+
+ pnlMain.setBorder(BorderFactory.createEtchedBorder());
+
+ tblDisplay.setDropMode(DropMode.INSERT_ROWS);
+ scrDisplay.setViewportView(tblDisplay);
+
+ pnlButton.setBorder(BorderFactory.createEtchedBorder());
+
+ 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(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addComponent(jButton3)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 250, Short.MAX_VALUE)
- .addComponent(jButton4)
+ .addPreferredGap(ComponentPlacement.RELATED)
+ .addComponent(btnStop)
+ .addPreferredGap(ComponentPlacement.RELATED, 250, Short.MAX_VALUE)
.addContainerGap())
);
- jPanel2Layout.setVerticalGroup(
- jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(jPanel2Layout.createSequentialGroup()
+ gl_pnlButton.setVerticalGroup(
+ gl_pnlButton.createParallelGroup(Alignment.LEADING)
+ .addGroup(gl_pnlButton.createSequentialGroup()
.addContainerGap()
- .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
- .addComponent(jButton2)
- .addComponent(jButton3)
- .addComponent(jButton4))
- .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ .addGroup(gl_pnlButton.createParallelGroup(Alignment.BASELINE)
+ .addComponent(btnStop)
+ )
+ .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ )
);
- jPanel3.setBorder(javax.swing.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() {
+
public void focusLost(java.awt.event.FocusEvent evt) {
idFieldFocusLost(evt);
}
});
- movieLabel.setText("動画");
+ lblVideo.setText("動画");
+
+ cbVideoLocal.setText("local");
+ cbVideoLocal.addItemListener(new java.awt.event.ItemListener() {
- useMovieLocalCheckBox.setText("local");
- useMovieLocalCheckBox.addItemListener(new java.awt.event.ItemListener() {
public void itemStateChanged(java.awt.event.ItemEvent evt) {
useMovieLocalCheckBoxItemStateChanged(evt);
}
});
- movieFileSelectButton.setText("...");
+ lblComment.setText("コメント");
- commentLabel.setText("コメント");
+ cbCommentLocal.setText("local");
+ cbCommentLocal.addItemListener(new java.awt.event.ItemListener() {
- useCommentLocalCheckBox.setText("local");
- useCommentLocalCheckBox.addItemListener(new java.awt.event.ItemListener() {
public void itemStateChanged(java.awt.event.ItemEvent evt) {
useMovieLocalCheckBoxItemStateChanged(evt);
}
});
- commentFileSelectButton.setText("...");
+ lblOutput.setText("出力");
- outputLabel.setText("出力");
+ cbOutputEnable.setText("変換");
+ cbOutputEnable.addItemListener(new java.awt.event.ItemListener() {
- outputConvertCheckBox.setText("変換");
- outputConvertCheckBox.addItemListener(new java.awt.event.ItemListener() {
public void itemStateChanged(java.awt.event.ItemEvent evt) {
outputConvertCheckBoxItemStateChanged(evt);
}
});
- applyButton.setText("適用");
- javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);
- jPanel3.setLayout(jPanel3Layout);
- jPanel3Layout.setHorizontalGroup(
- jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.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(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(jPanel3Layout.createSequentialGroup()
- .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(commentLabel)
- .addComponent(movieLabel)
- .addComponent(idLabel)
- .addComponent(outputLabel))
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(jPanel3Layout.createSequentialGroup()
- .addComponent(useMovieLocalCheckBox)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addComponent(movieFileField, javax.swing.GroupLayout.DEFAULT_SIZE, 317, Short.MAX_VALUE)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addComponent(movieFileSelectButton))
- .addComponent(idField, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel3Layout.createSequentialGroup()
- .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
- .addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanel3Layout.createSequentialGroup()
- .addComponent(outputConvertCheckBox)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addComponent(outputFileField, javax.swing.GroupLayout.DEFAULT_SIZE, 317, Short.MAX_VALUE))
- .addGroup(jPanel3Layout.createSequentialGroup()
- .addComponent(useCommentLocalCheckBox)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addComponent(commentFileField, javax.swing.GroupLayout.DEFAULT_SIZE, 317, Short.MAX_VALUE)))
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addComponent(commentFileSelectButton))))
- .addComponent(applyButton, javax.swing.GroupLayout.Alignment.TRAILING))
- .addContainerGap())
+ .addComponent(lblId)
+ .addPreferredGap(ComponentPlacement.RELATED)
+ .addComponent(cmbId, GroupLayout.PREFERRED_SIZE, 100, Short.MAX_VALUE)
+ .addPreferredGap(ComponentPlacement.UNRELATED)
+ .addComponent(cbBackLogReduce)
+ .addPreferredGap(ComponentPlacement.UNRELATED)
+ .addComponent(cbBackLog)
+ .addPreferredGap(ComponentPlacement.RELATED)
+ .addComponent(fldBackLog, GroupLayout.PREFERRED_SIZE, 150, GroupLayout.PREFERRED_SIZE)
+ .addContainerGap()
+ )
+ .addGroup(glInputMain.createSequentialGroup()
+ .addContainerGap()
+ .addGroup(glInputMain.createParallelGroup(Alignment.LEADING)
+ .addComponent(lblVideo)
+ .addComponent(lblComment)
+ .addComponent(lblOutput)
+ )
+ .addPreferredGap(ComponentPlacement.RELATED)
+ .addGroup(glInputMain.createParallelGroup(Alignment.LEADING)
+ .addComponent(cbVideoLocal)
+ .addComponent(cbCommentLocal)
+ .addComponent(cbOutputEnable)
+ )
+ .addPreferredGap(ComponentPlacement.RELATED)
+ .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()
+ )
);
- jPanel3Layout.setVerticalGroup(
- jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(jPanel3Layout.createSequentialGroup()
+
+ glInputMain.setVerticalGroup(
+ glInputMain.createParallelGroup(Alignment.LEADING)
+ .addGroup(glInputMain.createSequentialGroup()
.addContainerGap()
- .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
- .addComponent(idField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(idLabel))
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
- .addComponent(movieLabel)
- .addComponent(movieFileField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(movieFileSelectButton)
- .addComponent(useMovieLocalCheckBox))
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
- .addComponent(commentLabel)
- .addComponent(commentFileField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(commentFileSelectButton)
- .addComponent(useCommentLocalCheckBox))
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
- .addComponent(outputLabel)
- .addComponent(outputFileField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addComponent(outputConvertCheckBox))
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
- .addComponent(applyButton)
- .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ .addGroup(glInputMain.createParallelGroup(Alignment.BASELINE)
+ .addComponent(cmbId, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
+ .addComponent(lblId)
+ .addComponent(cbBackLogReduce)
+ .addComponent(cbBackLog)
+ .addComponent(fldBackLog)
+ )
+ .addPreferredGap(ComponentPlacement.RELATED)
+ .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(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(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()
);
- javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
- jPanel1.setLayout(jPanel1Layout);
- jPanel1Layout.setHorizontalGroup(
- jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(javax.swing.GroupLayout.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(javax.swing.GroupLayout.Alignment.TRAILING)
- .addComponent(jPanel3, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
- .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 480, Short.MAX_VALUE)
- .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.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(javax.swing.GroupLayout.Alignment.LEADING)
- .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
+ gl_pnlMain.setVerticalGroup(
+ gl_pnlMain.createParallelGroup(Alignment.LEADING)
+ .addGroup(Alignment.TRAILING, gl_pnlMain.createSequentialGroup()
+ .addContainerGap()
+ .addComponent(scrDisplay, GroupLayout.DEFAULT_SIZE, 197, Short.MAX_VALUE)
+ .addPreferredGap(ComponentPlacement.RELATED)
+ .addComponent(pnlButton, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
+ .addPreferredGap(ComponentPlacement.RELATED)
+ .addComponent(pnlInputAll, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addContainerGap()
- .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 197, Short.MAX_VALUE)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
- .addComponent(jPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
- .addGap(24, 24, 24))
+ )
);
- jMenu1.setText("File");
- jMenuBar1.add(jMenu1);
- jMenu2.setText("Edit");
- jMenuBar1.add(jMenu2);
+ JMenuBar menuBar = initMenuBar();
+ setJMenuBar(menuBar);
- setJMenuBar(jMenuBar1);
-
- javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
+ GroupLayout layout = new GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
- layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ layout.createParallelGroup(Alignment.LEADING)
+ .addComponent(pnlMain, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
);
layout.setVerticalGroup(
- layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
- .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+ layout.createParallelGroup(Alignment.LEADING)
+ .addComponent(pnlMain, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
);
pack();
- }// </editor-fold>//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<Path> allFiles) {
+ if (useLocal) {
+ final SortedSet<String> matchFiles = FileWatchUtil.getFileNamesContain(allFiles, text);
+ DefaultComboBoxModel<String> model = new DefaultComboBoxModel<>(matchFiles.toArray(new String[0]));
+ combo.setModel(model);
} else {
- return null;
+ combo.setModel(new DefaultComboBoxModel<String>());
+ combo.getEditorComponent().setText(pattern);
}
}
-private void useMovieLocalCheckBoxItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_useMovieLocalCheckBoxItemStateChanged
- final Properties p = Properties.INSTANCE;
-
- final ItemSelectable source = evt.getItemSelectable();
-
- JButton btn;
- JTextField field;
- File dir;
- if (source == useMovieLocalCheckBox) {
- btn = movieFileSelectButton;
- field = movieFileField;
- dir = p.getMovieDirectory();
- } else {
- btn = commentFileSelectButton;
- field = commentFileField;
- dir = p.getCommentDirectory();
- }
+ private class GuiTaskManageListener implements TaskManageListener {
- final boolean useLocal = (evt.getStateChange() == ItemEvent.SELECTED);
- btn.setEnabled(useLocal);
+ @Override
+ public void process(final int id, final TaskKind kind, final TaskStatus status, final double percentage,
+ final String message) {
+ SwingUtilities.invokeLater(new Runnable() {
- String text;
- if (useLocal) {
- final File f = searchFileMatchId(dir, idField.getText());
- if (f != null) {
- text = f.getPath();
- } else {
- text = "";
+ @Override
+ public void run() {
+ targetModel.setStatus(id, kind, status, percentage, message);
+ }
+ });
}
- } else {
- text = p.getFileNamePattern();
- }
- field.setText(text);
-}//GEN-LAST:event_useMovieLocalCheckBoxItemStateChanged
-
-private void outputConvertCheckBoxItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_outputConvertCheckBoxItemStateChanged
- final boolean convert = (evt.getStateChange() == ItemEvent.SELECTED);
- outputFileField.setEnabled(convert);
-}//GEN-LAST:event_outputConvertCheckBoxItemStateChanged
-
-private void idFieldFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_idFieldFocusLost
- final Properties p = Properties.INSTANCE;
- final String id = idField.getText();
- if (id.isEmpty()) {
- return;
}
- if (useMovieLocalCheckBox.isSelected() && movieFileField.getText().isEmpty()) {
- final File dir = p.getMovieDirectory();
- final File file = searchFileMatchId(dir, id);
- if (file != null) {
- movieFileField.setText(file.getPath());
+ 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, "キャンセル");
+ }
}
}
- if (useCommentLocalCheckBox.isSelected() && commentFileField.getText().isEmpty()) {
- final File dir = p.getCommentDirectory();
- final File file = searchFileMatchId(dir, id);
- if (file != null) {
- commentFileField.setText(file.getPath());
+ 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);
+ taskManager.add(rp);
+ targetModel.addTarget(new Target(rp));
+ initInputPanel();
+ } catch (Throwable th) {
+ logger.error(null, th);
+ JOptionPane.showMessageDialog(MainFrame.this, th.getMessage(), "中断しました", JOptionPane.ERROR_MESSAGE);
+ }
}
}
-}//GEN-LAST:event_idFieldFocusLost
-
/**
- * @param args the command line arguments
+ * 動画, コメントの"local"チェックボックス更新時の処理.
*/
- public static void main(String args[]) {
- try {
- for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
- if ("Nimbus".equals(info.getName())) {
- UIManager.setLookAndFeel(info.getClassName());
- break;
- }
- }
- } catch (Exception e) {
- try {
- UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
- } catch (Exception ex) {
- }
+ private void useMovieLocalCheckBoxItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_useMovieLocalCheckBoxItemStateChanged
+ final Config p = Config.INSTANCE;
+
+ final ItemSelectable source = evt.getItemSelectable();
+
+ JButton button;
+ FileComboBox combo;
+ Set<Path> allFiles;
+ String pattern;
+ if (source == cbVideoLocal) {
+ button = btnVideo;
+ combo = cmbVideo;
+ allFiles = videoFileWatcher.getFiles();
+ pattern = p.getVideoFileNamePattern();
+ } else {
+ button = btnComment;
+ combo = cmbComment;
+ allFiles = commentFileWatcher.getFiles();
+ pattern = p.getCommentFileNamePattern();
}
- java.awt.EventQueue.invokeLater(new Runnable() {
- public void run() {
- new MainFrame().setVisible(true);
- }
- });
+ final boolean useLocal = (evt.getStateChange() == ItemEvent.SELECTED);
+
+ 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);
+ 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 = 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 javax.swing.JButton applyButton;
- private javax.swing.JTextField commentFileField;
- private javax.swing.JButton commentFileSelectButton;
- private javax.swing.JLabel commentLabel;
- private javax.swing.JTextField idField;
- private javax.swing.JLabel idLabel;
- private javax.swing.JButton jButton2;
- private javax.swing.JButton jButton3;
- private javax.swing.JButton jButton4;
- private javax.swing.JMenu jMenu1;
- private javax.swing.JMenu jMenu2;
- private javax.swing.JMenuBar jMenuBar1;
- private javax.swing.JPanel jPanel1;
- private javax.swing.JPanel jPanel2;
- private javax.swing.JPanel jPanel3;
- private javax.swing.JScrollPane jScrollPane1;
- private javax.swing.JTable jTable1;
- private javax.swing.JTextField movieFileField;
- private javax.swing.JButton movieFileSelectButton;
- private javax.swing.JLabel movieLabel;
- private javax.swing.JCheckBox outputConvertCheckBox;
- private javax.swing.JTextField outputFileField;
- private javax.swing.JLabel outputLabel;
- private javax.swing.JCheckBox useCommentLocalCheckBox;
- private javax.swing.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 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("");
+ initMainTab();
+ initFfmpegTab();
+ tbpInput.setSelectedIndex(0);
+ cmbId.requestFocus();
+ }
+
+ private void initMainTab() {
+ final Config p = Config.INSTANCE;
- final Properties p = Properties.INSTANCE;
+ cmbId.setText("");
+ cbBackLogReduce.setSelected(p.getCommentMinDisabled());
+ cbBackLog.setEnabled(true);
+ cbBackLog.setSelected(false);
+ fldBackLog.setEnabled(false);
+ fldBackLog.setText("");
- final boolean movieLocal = p.getUseMovieFileLocal();
- useMovieLocalCheckBox.setSelected(movieLocal);
- movieFileSelectButton.setEnabled(movieLocal);
- if (!movieLocal) {
- movieFileField.setText(p.getFileNamePattern());
+ final boolean videoLocal = p.getVideoUseLocal();
+ cbVideoLocal.setSelected(videoLocal);
+ if (!videoLocal) {
+ fldVideo.setText(p.getVideoFileNamePattern());
}
+ btnVideo.setEnabled(videoLocal);
- final boolean commentLocal = p.getCommentFileLocal();
- useCommentLocalCheckBox.setSelected(commentLocal);
- commentFileSelectButton.setEnabled(commentLocal);
+ final boolean commentLocal = p.getCommentUseLocal();
+ cbCommentLocal.setSelected(commentLocal);
if (!commentLocal) {
- commentFileField.setText(p.getFileNamePattern());
+ fldComment.setText(p.getCommentFileNamePattern());
}
+ btnComment.setEnabled(commentLocal);
- final boolean convert = p.getOutputConvert();
- outputConvertCheckBox.setSelected(convert);
- outputFileField.setEnabled(convert);
- outputFileField.setText(p.getFileNamePattern());
+ final boolean convert = p.getOutputEnable();
+ cbOutputEnable.setSelected(convert);
+ fldOutput.setEnabled(convert);
+ fldOutput.setText(p.getOutputFileNamePattern());
+ }
+ private void initFfmpegTab() {
+ pnlInputFfmpeg.init(Config.INSTANCE);
}
- private class DownloadListTransferHandler extends TransferHandler {
+ private JMenuBar initMenuBar() {
+ final JMenuBar menuBar = new JMenuBar();
+
+ final JMenu mnFile = new JMenu("ファイル(F)");
+ menuBar.add(mnFile);
+
+ final JMenuItem itExit = new JMenuItem("終了(X)", KeyEvent.VK_X);
+ itExit.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, ActionEvent.CTRL_MASK));
+ final ActionListener exitActionListener = new ActionListener() {
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ 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);
+ itOption.addActionListener(new ActionListener() {
- private static final long serialVersionUID = 1L;
- private final Pattern movieIdPattern = Pattern.compile("(\\w\\w\\d+)");
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ final yukihane.inqubus.gui.ConfigDialog dlg = new yukihane.inqubus.gui.ConfigDialog(MainFrame.this);
+ dlg.setLocationRelativeTo(MainFrame.this);
+ dlg.setModal(true);
+ dlg.setVisible(true);
+ }
+ });
+ mnTool.add(itOption);
+
+ final JMenu mnHelp = new JMenu("ヘルプ(H)");
+ menuBar.add(mnHelp);
+
+ final JMenuItem itAbout = new JMenuItem("このソフトウェアについて(A)...", KeyEvent.VK_A);
+ itAbout.addActionListener(new ActionListener() {
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ MainFrame_AboutBox dlg = new MainFrame_AboutBox(MainFrame.this);
+ dlg.pack();
+ dlg.setLocationRelativeTo(MainFrame.this);
+ dlg.setModal(true);
+ dlg.setVisible(true);
+ }
+ });
+ mnHelp.add(itAbout);
+
+ return menuBar;
+ }
+ private class MainFrameWindowListener extends WindowAdapter {
@Override
- public boolean canImport(TransferHandler.TransferSupport support) {
- Transferable transferable = support.getTransferable();
- if (transferable.isDataFlavorSupported(DataFlavor.javaFileListFlavor)
- || transferable.isDataFlavorSupported(DataFlavor.stringFlavor)) {
- return true;
+ 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);
}
- return false;
+ }
+ }
+
+ /*
+ * ここから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 importData(TransferHandler.TransferSupport support) {
- try {
- Transferable transferable = support.getTransferable();
- if (transferable.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
- @SuppressWarnings("unchecked")
- final List<File> data = (List<File>) transferable.getTransferData(DataFlavor.javaFileListFlavor);
- Collection<Target> 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 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());
+ }
+ }
+
+ @Override
+ 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 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;
+ } else {
+ this.dir = null;
+ this.fileName = null;
+ this.localFile = new File(fldComment.getText());
+ }
+
+ 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 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);
+ }
+ }
+
+ /*
+ * ここから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();
+
+ 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 TableTransferHandler extends DownloadListTransferHandler {
- private static final long serialVersionUID = 1L;
+ 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);
}
}
}