3 import java.awt.AWTException;
\r
4 import java.awt.BorderLayout;
\r
5 import java.awt.Color;
\r
6 import java.awt.Component;
\r
7 import java.awt.Container;
\r
8 import java.awt.Desktop;
\r
9 import java.awt.Dimension;
\r
10 import java.awt.Font;
\r
11 import java.awt.Frame;
\r
12 import java.awt.Image;
\r
13 import java.awt.Insets;
\r
14 import java.awt.MenuItem;
\r
15 import java.awt.Point;
\r
16 import java.awt.PopupMenu;
\r
17 import java.awt.Rectangle;
\r
18 import java.awt.SystemTray;
\r
19 import java.awt.Toolkit;
\r
20 import java.awt.TrayIcon;
\r
21 import java.awt.datatransfer.Clipboard;
\r
22 import java.awt.datatransfer.StringSelection;
\r
23 import java.awt.event.ActionEvent;
\r
24 import java.awt.event.ActionListener;
\r
25 import java.awt.event.ComponentAdapter;
\r
26 import java.awt.event.ComponentEvent;
\r
27 import java.awt.event.MouseAdapter;
\r
28 import java.awt.event.MouseEvent;
\r
29 import java.awt.event.WindowAdapter;
\r
30 import java.awt.event.WindowEvent;
\r
31 import java.io.File;
\r
32 import java.io.IOException;
\r
33 import java.io.UnsupportedEncodingException;
\r
34 import java.lang.management.ManagementFactory;
\r
35 import java.lang.management.MemoryMXBean;
\r
36 import java.lang.management.MemoryUsage;
\r
37 import java.lang.reflect.InvocationTargetException;
\r
38 import java.net.URI;
\r
39 import java.net.URISyntaxException;
\r
40 import java.net.URLEncoder;
\r
41 import java.security.NoSuchAlgorithmException;
\r
42 import java.util.ArrayList;
\r
43 import java.util.Arrays;
\r
44 import java.util.Calendar;
\r
45 import java.util.GregorianCalendar;
\r
46 import java.util.HashMap;
\r
47 import java.util.LinkedHashMap;
\r
48 import java.util.ServiceLoader;
\r
49 import java.util.regex.Matcher;
\r
50 import java.util.regex.Pattern;
\r
52 import javax.imageio.ImageIO;
\r
53 import javax.swing.ImageIcon;
\r
54 import javax.swing.JComponent;
\r
55 import javax.swing.JFrame;
\r
56 import javax.swing.JLabel;
\r
57 import javax.swing.JMenuItem;
\r
58 import javax.swing.JOptionPane;
\r
59 import javax.swing.JPopupMenu;
\r
60 import javax.swing.SwingUtilities;
\r
61 import javax.swing.ToolTipManager;
\r
62 import javax.swing.UIManager;
\r
63 import javax.swing.event.ChangeEvent;
\r
64 import javax.swing.event.ChangeListener;
\r
66 import tainavi.HDDRecorder.RecType;
\r
67 import tainavi.SearchKey.TargetId;
\r
68 import tainavi.TVProgram.ProgFlags;
\r
69 import tainavi.TVProgram.ProgGenre;
\r
70 import tainavi.TVProgram.ProgOption;
\r
71 import tainavi.TVProgram.ProgSubgenre;
\r
72 import tainavi.TVProgram.ProgSubtype;
\r
73 import tainavi.TVProgram.ProgType;
\r
74 import tainavi.VWMainWindow.MWinTab;
\r
75 import tainavi.VWUpdate.UpdateResult;
\r
81 public class Viewer extends JFrame implements ChangeListener,TickTimerListener,HDDRecorderListener,CancelListener {
\r
83 private static final long serialVersionUID = 1L;
\r
90 private void StdAppendMessage(String message) { System.out.println(message); }
\r
91 private void StdAppendError(String message) { System.err.println(message); }
\r
93 private void MWinSetVisible(boolean b) { mwin.setVisible(b); }
\r
95 private void StWinClear() { stwin.clear(); }
\r
96 private void StWinSetVisible(boolean b) { stwin.setVisible(b); }
\r
97 private void StWinSetLocationCenter(Component frame) { CommonSwingUtils.setLocationCenter(frame, (VWStatusWindow)stwin); }
\r
98 private void StWinSetLocationUnder(Component frame) { CommonSwingUtils.setLocationUnder(frame, (VWStatusWindow)stwin); }
\r
100 private void ringBeep() { if (env!=null && ! env.getDisableBeep()) { Toolkit.getDefaultToolkit().beep(); if ( env.getDebug() ) CommonUtils.printStackTrace(); } }
\r
108 private final Env env = new Env(); // 主要な設定
\r
109 private final Bounds bounds = new Bounds(); // ウィンドウサイズとか動的に変化するもの
\r
110 private final ClipboardInfoList cbitems = new ClipboardInfoList(); // クリップボード対応機能でどの項目をコピーするかとかの設定
\r
111 private final PaperColorsMap pColors = new PaperColorsMap(); // 新聞形式のジャンル別背景色の設定
\r
112 private final AVSetting avs = new AVSetting(); // ジャンル別録画画質・音質等設定
\r
113 private final CHAVSetting chavs = new CHAVSetting(); // CH別録画画質・音質等設定
\r
114 private final ChannelSort chsort = new ChannelSort(); // CHソート設定
\r
115 private final ChannelConvert chconv = new ChannelConvert(); // ChannelConvert.dat
\r
116 private final MarkChar markchar = new MarkChar(env); // タイトルにつけるマークを操作する
\r
118 private final MarkedProgramList mpList = new MarkedProgramList(); // 検索結果のキャッシュ(表示高速化用)
\r
119 private final TraceProgram trKeys = new TraceProgram(); // 番組追跡の設定
\r
120 private final SearchProgram srKeys = new SearchProgram(); // キーワード検索の設定
\r
121 private final SearchGroupList srGrps = new SearchGroupList(); // キーワード検索グループの設定
\r
122 private final ExtProgram extKeys = new ExtProgram(); // 延長警告管理の設定
\r
124 private final RecorderInfoList recInfoList = new RecorderInfoList(); // レコーダ一覧の設定
\r
126 private final HDDRecorderList recPlugins = new HDDRecorderList(); // レコーダプラグイン(テンプレート)
\r
127 private final HDDRecorderList recorders = new HDDRecorderList(); // レコーダプラグイン(実際に利用するもの)
\r
129 private final TVProgramList progPlugins = new TVProgramList(); // Web番組表プラグイン(テンプレート)
\r
130 private final TVProgramList tvprograms = new TVProgramList(); // Web番組表プラグイン(実際に利用するもの)
\r
132 private final TickTimer timer_now = new TickTimer(); // 毎分00秒に起動して処理をキックするタイマー
\r
135 private boolean logging = true; // ログ出力する
\r
136 private boolean runRecWakeup = false; // 起動時にレコーダを起こす
\r
137 private boolean runRecLoad = false; // 起動時にレコーダから予約一覧を取得する
\r
138 private boolean enableWebAccess = true; // 起動時のWeb番組表へのアクセスを禁止する
\r
139 private boolean onlyLoadProgram = false;
\r
140 private String pxaddr = null; // ProxyAddress指定
\r
141 private String pxport = null; // ProxtPort指定
\r
144 /*******************************************************************************
\r
146 ******************************************************************************/
\r
148 public static final String LOG_FILE = "log.txt"; // ログファイル名
\r
149 public static final String HISTORY_FILE = "05_history.txt"; // 更新履歴だよ
\r
151 private static final String ICONFILE_SYSTRAY = "icon"+File.separator+"tainavi16.png";
\r
152 private static final String ICONFILE_TAINAVI = "icon"+File.separator+"tainavi.png";
\r
154 public static final int TIMEBAR_START = 5; // 新聞形式の開始時刻
\r
155 private static final int OPENING_WIAT = 500; // まあ起動時しか使わないんですけども
\r
157 private static final String MSGID = "[鯛ナビ] ";
\r
158 // private static final String ERRID = "[ERROR]"+MSGID;
\r
159 private static final String DBGID = "[DEBUG]"+MSGID;
\r
162 * [メモ] enumのtoString()をoverrideすると、シリアライズの際とても困るのでやらないこと
\r
166 * Web番組表のどれとどれを読めばいいのか
\r
168 public static enum LoadFor {
\r
169 TERRA ("地上波&BSのみ取得"),
\r
171 CSo1 ("CS[プライマリ]のみ取得"),
\r
172 CSo2 ("CS[セカンダリ]のみ取得"),
\r
173 CSwSD ("CSのみ取得(取得後シャットダウン)"),
\r
175 SYOBO ("しょぼかるのみ取得"),
\r
178 private String name;
\r
180 private LoadFor(String name) {
\r
184 public String getName() {
\r
188 public static LoadFor get(String s) {
\r
189 for ( LoadFor lf : LoadFor.values() ) {
\r
190 if ( lf.name.equals(s) ) {
\r
199 * レコーダ情報のどれとどれを読めばいいのか
\r
201 public static enum LoadRsvedFor {
\r
202 // SETTING ( "設定情報のみ取得(future use.)" ),
\r
203 DETAILS ( "予約一覧+録画詳細のみ取得" ),
\r
204 RECORDED ( "録画結果一覧のみ取得" ),
\r
205 AUTORESERVE ( "自動予約一覧のみ取得" ),
\r
208 private String name;
\r
210 private LoadRsvedFor(String name) {
\r
214 public String getName() {
\r
218 public static LoadRsvedFor get(String s) {
\r
219 for ( LoadRsvedFor lrf : LoadRsvedFor.values() ) {
\r
220 if ( lrf.name.equals(s) ) {
\r
230 * @deprecated しっぱいした 半年くらいしたら削除する
\r
233 public static enum ListedColumn {
\r
234 RSVMARK ("予約", 35),
\r
235 DUPMARK ("重複", 35),
\r
236 CHNAME ("チャンネル名", 100),
\r
237 TITLE ("番組タイトル", 300),
\r
238 DETAIL ("番組詳細", 200),
\r
239 START ("開始時刻", 150),
\r
242 GENRE ("ジャンル", 85),
\r
243 SITEM ("検索アイテム名", 100),
\r
244 STAR ("お気に入り度", 100),
\r
246 THRESHOLD ("閾値", 35),
\r
247 HID_PRGID ("PRGID", -1),
\r
248 HID_STIME ("STIME", -1),
\r
249 HID_ETIME ("ETIME", -1),
\r
250 HID_EXFLG ("EXFLG", -1),
\r
251 HID_TITLE ("TITLE", -1),
\r
254 @SuppressWarnings("unused")
\r
255 private String name;
\r
256 private int iniWidth;
\r
258 private ListedColumn(String name, int iniWidth) {
\r
260 this.iniWidth = iniWidth;
\r
265 public String toString() {
\r
270 public int getIniWidth() {
\r
274 public int getColumn() {
\r
281 * @deprecated しっぱいした 半年くらいしたら削除する
\r
284 public static enum RsvedColumn {
\r
285 PATTERN ("パタン", 110),
\r
286 DUPMARK ("重複", 35),
\r
289 NEXTSTART ("次回実行予定", 150),
\r
292 ENCODER ("エンコーダ", 50),
\r
295 TITLE ("番組タイトル", 300),
\r
296 CHNAME ("チャンネル名", 150),
\r
297 RECORDER ("レコーダ", 200),
\r
298 HID_INDEX ("INDEX", -1),
\r
299 HID_RSVID ("RSVID", -1),
\r
302 @SuppressWarnings("unused")
\r
303 private String name;
\r
304 private int iniWidth;
\r
306 private RsvedColumn(String name, int iniWidth) {
\r
308 this.iniWidth = iniWidth;
\r
313 public String toString() {
\r
318 public int getIniWidth() {
\r
322 public int getColumn() {
\r
334 private final VWStatusWindow stwin = new VWStatusWindow();
\r
335 private final VWStatusTextArea mwin = new VWStatusTextArea();
\r
336 private final VWColorChooserDialog ccwin = new VWColorChooserDialog();
\r
337 private final VWPaperColorsDialog pcwin = new VWPaperColorsDialog();
\r
338 private final VWReserveDialog rdialog = new VWReserveDialog(0, 0);
\r
340 // 初期化処理の中で生成していくもの
\r
341 private VWMainWindow mainWindow = null;
\r
342 private VWToolBar toolBar = null;
\r
343 private VWListedView listed = null;
\r
344 private VWPaperView paper = null;
\r
345 private VWReserveListView reserved = null;
\r
346 private VWRecordedListView recorded = null;
\r
347 private VWAutoReserveListView autores = null;
\r
348 private VWSettingView setting = null;
\r
349 private VWRecorderSettingView recsetting = null;
\r
350 private VWChannelSettingView chsetting = null;
\r
351 private VWChannelDatSettingView chdatsetting = null;
\r
352 private VWChannelSortView chsortsetting = null;
\r
353 private VWChannelConvertView chconvsetting = null;
\r
354 private VWLookAndFeel vwlaf = null;
\r
355 private VWFont vwfont = null;
\r
357 private TrayIcon trayicon = null;
\r
361 /*******************************************************************************
\r
362 * タブやダイアログのインスタンス作成用クラス定義
\r
363 ******************************************************************************/
\r
368 private class VWListedView extends AbsListedView {
\r
370 private static final long serialVersionUID = 1L;
\r
374 protected Env getEnv() { return env; }
\r
376 protected Bounds getBoundsEnv() { return bounds; }
\r
378 protected ChannelSort getChannelSort() { return chsort; }
\r
381 protected MarkedProgramList getMarkedProgramList() { return mpList; }
\r
383 protected TraceProgram getTraceProgram() { return trKeys; }
\r
385 protected SearchProgram getSearchProgram() { return srKeys; }
\r
387 protected SearchGroupList getSearchGroupList() { return srGrps; }
\r
389 protected ExtProgram getExtProgram() { return extKeys; }
\r
392 protected TVProgramList getTVProgramList() { return tvprograms; }
\r
394 protected HDDRecorderList getRecorderList() { return recorders; }
\r
398 protected StatusWindow getStWin() { return stwin; }
\r
400 protected StatusTextArea getMWin() { return mwin; }
\r
404 protected AbsReserveDialog getReserveDialog() { return rdialog; }
\r
406 protected Component getParentComponent() { return Viewer.this; }
\r
409 protected void ringBeep() { Viewer.this.ringBeep(); }
\r
412 * AbsListedView内でのイベントから呼び出されるメソッド群
\r
416 protected void onShown() {
\r
417 // キーワード登録ボタンはリスト形式のみ
\r
418 toolBar.setAddkeywordEnabled(true);
\r
420 toolBar.setBatchReservationEnabled(true);
\r
422 toolBar.setSnapShotEnabled(true);
\r
426 protected void onHidden() {
\r
427 // キーワード登録ボタンはリスト形式のみ
\r
428 toolBar.setAddkeywordEnabled(false);
\r
430 toolBar.setBatchReservationEnabled(false);
\r
432 toolBar.setSnapShotEnabled(false);
\r
436 protected void showPopupForTraceProgram(
\r
437 final JComponent comp,
\r
438 final ProgDetailList tvd, final String keyword, final int threshold,
\r
439 final int x, final int y) {
\r
441 timer_now.pause(); // 停止
\r
443 Viewer.this.showPopupForTraceProgram(comp, tvd, keyword, threshold, x, y, null);
\r
445 timer_now.start(); // 再開
\r
449 protected void updateReserveDisplay(String chname) {
\r
451 paper.updateReserveBorder(chname);
\r
452 reserved.redrawReservedList();
\r
457 protected void updateBangumiColumns() {
\r
459 paper.updateBangumiColumns();
\r
464 protected void clearPaper() {
\r
466 paper.clearPanel();
\r
471 protected void previewKeywordSearch(SearchKey search) {
\r
472 //timer_now.pause();
\r
473 if (search.alTarget.size() > 0) {
\r
474 mainWindow.setSelectedTab(MWinTab.LISTED);
\r
475 listed.redrawListByPreview(search);
\r
477 //timer_now.start();
\r
481 protected void jumpToPaper(String Center, String StartDateTime) {
\r
482 //timer_now.pause();
\r
483 paper.jumpToBangumi(Center,StartDateTime);
\r
484 //timer_now.start();
\r
488 protected boolean addToPickup(ProgDetailList tvd) { return Viewer.this.addToPickup(tvd); }
\r
491 protected boolean isTabSelected(MWinTab tab) { return mainWindow.isTabSelected(tab); }
\r
493 protected void setSelectedTab(MWinTab tab) { mainWindow.setSelectedTab(tab); }
\r
496 protected String getSelectedRecorderOnToolbar() { return toolBar.getSelectedRecorder(); }
\r
498 protected boolean isFullScreen() { return toolBar.isFullScreen(); }
\r
500 protected void setPagerEnabled(boolean b) { toolBar.setPagerEnabled(b); }
\r
502 protected int getPagerCount() { return toolBar.getPagerCount(); }
\r
504 protected int getSelectedPagerIndex() { return toolBar.getSelectedPagerIndex(); }
\r
507 protected void setDividerEnvs(int loc) {
\r
508 if ( ! toolBar.isFullScreen() && mainWindow.isTabSelected(MWinTab.LISTED) ) {
\r
509 if (env.getSyncTreeWidth()) {
\r
510 bounds.setTreeWidth(loc);
\r
511 bounds.setTreeWidthPaper(loc);
\r
514 bounds.setTreeWidth(loc);
\r
525 private class VWPaperView extends AbsPaperView {
\r
527 private static final long serialVersionUID = 1L;
\r
531 protected Env getEnv() { return env; }
\r
533 protected Bounds getBoundsEnv() { return bounds; }
\r
535 protected PaperColorsMap getPaperColorMap() { return pColors; }
\r
537 protected ChannelSort getChannelSort() { return chsort; }
\r
540 protected TVProgramList getTVProgramList() { return tvprograms; }
\r
542 protected HDDRecorderList getRecorderList() { return recorders; }
\r
546 protected StatusWindow getStWin() { return stwin; }
\r
548 protected StatusTextArea getMWin() { return mwin; }
\r
552 protected AbsReserveDialog getReserveDialog() { return rdialog; }
\r
554 protected Component getParentComponent() { return Viewer.this; }
\r
557 protected void ringBeep() { Viewer.this.ringBeep(); }
\r
560 * AbsPaperView内でのイベントから呼び出されるメソッド群
\r
564 protected void onShown() {
\r
565 // ページャーコンボボックスを有効にする(状況次第で有効にならない場合もある)(ツリーの選択次第で変わるのでもどし)
\r
566 //toolBar.setPagerEnabled(true);
\r
568 toolBar.setSnapShotEnabled(true);
\r
570 toolBar.setPaperColorDialogEnabled(true);
\r
572 toolBar.setBorderToggleEnabled(true);
\r
576 protected void onHidden() {
\r
577 // 新聞形式以外ではページャーコンボボックスを無効にする(ツリーの選択次第で変わるのでもどし)
\r
578 //toolBar.setPagerEnabled(false);
\r
579 // 新聞形式以外ではスナップショットを無効にする
\r
580 toolBar.setSnapShotEnabled(false);
\r
581 // 新聞形式以外ではジャンル別背景色を無効にする
\r
582 toolBar.setPaperColorDialogEnabled(false);
\r
583 // 新聞形式以外ではマッチ枠を無効にする
\r
584 toolBar.setBorderToggleEnabled(false);
\r
588 protected void showPopupForTraceProgram(
\r
589 final JComponent comp,
\r
590 final ProgDetailList tvd, final String keyword, final int threshold,
\r
591 final int x, final int y, final String clickedDateTime) {
\r
593 timer_now.pause(); // 停止
\r
595 Viewer.this.showPopupForTraceProgram(comp, tvd, keyword, threshold, x, y, clickedDateTime);
\r
597 timer_now.start(); // 再開
\r
601 protected void updateReserveDisplay() {
\r
603 listed.updateReserveMark();
\r
604 reserved.redrawReservedList();
\r
609 protected void addToPickup(ProgDetailList tvd) { Viewer.this.addToPickup(tvd); }
\r
612 protected boolean isTabSelected(MWinTab tab) { return mainWindow.isTabSelected(tab); }
\r
614 protected void setSelectedTab(MWinTab tab) { mainWindow.setSelectedTab(tab); }
\r
617 protected boolean isFullScreen() { return toolBar.isFullScreen(); }
\r
619 protected void setSelectedPagerIndex(int idx) {
\r
620 toolBar.setSelectedPagerIndex(idx);
\r
623 protected void setPagerEnabled(boolean b) { toolBar.setPagerEnabled(b); }
\r
625 protected int getPagerCount() { return toolBar.getPagerCount(); }
\r
627 protected int getSelectedPagerIndex() { return toolBar.getSelectedPagerIndex(); }
\r
629 protected void setPagerItems(TVProgramIterator pli, int curindex) {
\r
630 toolBar.setPagerItems(pli,curindex);
\r
634 protected String getExtensionMark(ProgDetailList tvd) { return markchar.getExtensionMark(tvd); }
\r
636 protected String getOptionMark(ProgDetailList tvd) { return markchar.getOptionMark(tvd)+markchar.getNewLastMark(tvd); }
\r
638 protected String getPostfixMark(ProgDetailList tvd) { return markchar.getPostfixMark(tvd); }
\r
641 protected void setDividerEnvs(int loc) {
\r
642 if ( ! toolBar.isFullScreen() && mainWindow.isTabSelected(MWinTab.PAPER) ) {
\r
643 if (env.getSyncTreeWidth()) {
\r
644 bounds.setTreeWidth(loc);
\r
645 bounds.setTreeWidthPaper(loc);
\r
648 bounds.setTreeWidthPaper(loc);
\r
661 private class VWReserveListView extends AbsReserveListView {
\r
663 private static final long serialVersionUID = 1L;
\r
667 protected Env getEnv() { return env; }
\r
669 protected Bounds getBoundsEnv() { return bounds; }
\r
672 protected HDDRecorderList getRecorderList() { return recorders; }
\r
678 protected AbsReserveDialog getReserveDialog() { return rdialog; }
\r
680 protected Component getParentComponent() { return Viewer.this; }
\r
683 protected void ringBeep() { Viewer.this.ringBeep(); }
\r
686 * AbsReserveListView内でのイベントから呼び出されるメソッド群
\r
690 protected void updateReserveDisplay(String chname) {
\r
692 listed.updateReserveMark();
\r
693 paper.updateReserveBorder(chname);
\r
698 protected boolean doExecOnOff(boolean fexec, String title, String chnam, String rsvId, String recId) {
\r
699 return Viewer.this.doExecOnOff(fexec, title, chnam, rsvId, recId);
\r
703 protected JMenuItem getExecOnOffMenuItem(boolean fexec,
\r
704 String start, String title, String chnam, String rsvId, String recId) {
\r
706 return Viewer.this.getExecOnOffMenuItem(fexec, start, title, chnam, rsvId, recId, 0);
\r
710 protected JMenuItem getRemoveRsvMenuItem(
\r
711 String start, String title, String chnam, String rsvId, String recId) {
\r
713 return Viewer.this.getRemoveRsvMenuItem(start, title, chnam, rsvId, recId, 0);
\r
717 protected JMenuItem getJumpMenuItem(String title, String chnam,
\r
720 return Viewer.this.getJumpMenuItem(title, chnam, startDT);
\r
724 protected JMenuItem getJumpToLastWeekMenuItem(String title,
\r
725 String chnam, String startDT) {
\r
727 return Viewer.this.getJumpToLastWeekMenuItem(title, chnam, startDT);
\r
731 protected String getSelectedRecorderOnToolbar() { return toolBar.getSelectedRecorder(); }
\r
740 private class VWRecordedListView extends AbsRecordedListView {
\r
742 private static final long serialVersionUID = 1L;
\r
746 protected Env getEnv() { return env; }
\r
748 protected Bounds getBoundsEnv() { return bounds; }
\r
751 protected HDDRecorderList getRecorderList() { return recorders; }
\r
757 protected Component getParentComponent() { return Viewer.this; }
\r
760 protected void ringBeep() { Viewer.this.ringBeep(); }
\r
763 * AbsReserveListView内でのイベントから呼び出されるメソッド群
\r
767 protected String getSelectedRecorderOnToolbar() { return toolBar.getSelectedRecorder(); }
\r
776 private class VWAutoReserveListView extends AbsAutoReserveListView {
\r
778 private static final long serialVersionUID = 1L;
\r
782 protected Env getEnv() { return env; }
\r
784 protected Bounds getBoundsEnv() { return bounds; }
\r
791 private class VWSettingView extends AbsSettingView {
\r
793 private static final long serialVersionUID = 1L;
\r
797 protected Env getEnv() { return env; }
\r
799 protected ClipboardInfoList getCbItemEnv() { return cbitems; }
\r
801 protected VWLookAndFeel getLAFEnv() { return vwlaf; }
\r
803 protected VWFont getFontEnv() { return vwfont; }
\r
807 protected StatusWindow getStWin() { return stwin; }
\r
809 protected StatusTextArea getMWin() { return mwin; }
\r
813 protected Component getParentComponent() { return Viewer.this; }
\r
815 protected VWColorChooserDialog getCcWin() { return ccwin; }
\r
818 * AbsSettingView内でのイベントから呼び出されるメソッド群
\r
822 protected void lafChanged(String lafname) {
\r
823 vwlaf.update(lafname);
\r
824 Viewer.this.updateComponentTreeUI();
\r
825 StdAppendMessage("Set LookAndFeel="+lafname);
\r
829 protected void fontChanged(String fn, int fontSize) {
\r
830 vwfont.update(fn, fontSize);
\r
831 Viewer.this.updateComponentTreeUI();
\r
832 StdAppendMessage("システムのフォントを変更しました: "+fn+", size="+fontSize);
\r
836 protected void setEnv(final boolean reload_prog) {
\r
838 //listed.pauseTimer();
\r
841 Viewer.this.setEnv(reload_prog);
\r
849 * @see AbsRecorderSettingView
\r
851 private class VWRecorderSettingView extends AbsRecorderSettingView {
\r
853 private static final long serialVersionUID = 1L;
\r
857 protected Env getEnv() { return env; }
\r
859 protected RecorderInfoList getRecInfos() { return recInfoList; }
\r
861 protected HDDRecorderList getRecPlugins() { return recPlugins; }
\r
865 protected VWStatusWindow getStWin() { return stwin; }
\r
867 protected StatusTextArea getMWin() { return mwin; }
\r
871 protected Component getParentComponent() { return Viewer.this; }
\r
873 protected VWColorChooserDialog getCcWin() { return ccwin; }
\r
876 protected void ringBeep() { Viewer.this.ringBeep(); }
\r
879 * AbsRecorderSettingView内でのイベントから呼び出されるメソッド群
\r
883 protected void setRecInfos() {
\r
888 recInfoList.save();
\r
890 // レコーダプラグインのリフレッシュ
\r
891 initRecPluginAll();
\r
894 toolBar.updateRecorderComboBox();
\r
897 loadRdReservesAll(false, null); // toolBarの内容がリセットされているので recId = null で
\r
900 this.redrawRecorderEncoderEntry();
\r
902 // レコーダ一覧をCHコード設定のコンボボックスに設定
\r
903 chdatsetting.updateRecorderComboBox();
\r
905 // Web番組表の再構築(予約マークのリフレッシュ)
\r
906 paper.updateReserveBorder(null);
\r
907 listed.updateReserveMark();
\r
918 private class VWChannelSettingView extends AbsChannelSettingView {
\r
920 private static final long serialVersionUID = 1L;
\r
924 protected Env getEnv() { return Viewer.this.env; }
\r
926 protected TVProgramList getProgPlugins() { return progPlugins; }
\r
930 protected StatusWindow getStWin() { return stwin; }
\r
932 protected StatusTextArea getMWin() { return mwin; }
\r
936 protected Component getParentComponent() { return Viewer.this; }
\r
938 protected VWColorChooserDialog getCcWin() { return ccwin; }
\r
941 protected void ringBeep() {
\r
942 Viewer.this.ringBeep();
\r
945 protected void updateProgPlugin() {
\r
949 // 設定を保存(プラグイン内部の設定はChannelSettingPanel内で実施)
\r
952 // Web番組表プラグインのリフレッシュ
\r
953 setSelectedProgPlugin();
\r
954 initProgPluginAll();
\r
957 chsortsetting.updateChannelSortTable();
\r
959 // CHコンバート設定をリフレッシュ
\r
960 chconvsetting.updateChannelConvertTable();
\r
963 chdatsetting.updateChannelDatTable();
\r
966 loadTVProgram(false,LoadFor.ALL); // 部品呼び出し
\r
969 toolBar.setPagerItems();
\r
972 paper.clearPanel();
\r
973 paper.buildMainViewByDate();
\r
976 paper.redrawTreeByCenter();
\r
978 listed.redrawTreeByCenter();
\r
981 paper.reselectTree();
\r
982 listed.reselectTree();
\r
992 private class VWChannelDatSettingView extends AbsChannelDatSettingView {
\r
994 private static final long serialVersionUID = 1L;
\r
998 protected Env getEnv() { return Viewer.this.env; }
\r
1000 protected TVProgramList getTVProgramList() { return tvprograms; }
\r
1002 protected ChannelSort getChannelSort() { return chsort; }
\r
1004 protected HDDRecorderList getHDDRecorderList() { return recorders; }
\r
1008 protected StatusWindow getStWin() { return stwin; }
\r
1010 protected StatusTextArea getMWin() { return mwin; }
\r
1014 protected Component getParentComponent() { return Viewer.this; }
\r
1017 protected void ringBeep() {
\r
1018 Viewer.this.ringBeep();
\r
1026 private class VWChannelSortView extends AbsChannelSortView {
\r
1028 private static final long serialVersionUID = 1L;
\r
1031 protected Env getEnv() { return Viewer.this.env; }
\r
1033 protected TVProgramList getTVProgramList() { return tvprograms; }
\r
1035 protected ChannelSort getChannelSort() { return chsort; }
\r
1039 protected StatusTextArea getMWin() { return mwin; }
\r
1042 protected void updProc() {
\r
1044 timer_now.pause();
\r
1048 toolBar.setPagerItems();
\r
1049 toolBar.setSelectedPagerIndex(toolBar.getSelectedPagerIndex());
\r
1052 paper.clearPanel();
\r
1053 paper.buildMainViewByDate();
\r
1056 paper.redrawTreeByCenter();
\r
1058 listed.redrawTreeByCenter();
\r
1061 paper.reselectTree();
\r
1062 listed.reselectTree();
\r
1064 timer_now.start();
\r
1069 * CHコンバート設定タブの内部クラス
\r
1071 private class VWChannelConvertView extends AbsChannelConvertView {
\r
1073 private static final long serialVersionUID = 1L;
\r
1077 protected Env getEnv() { return env; }
\r
1079 protected TVProgramList getProgPlugins() { return progPlugins; }
\r
1081 protected ChannelConvert getChannelConvert() { return chconv; }
\r
1088 private class VWReserveDialog extends AbsReserveDialog {
\r
1090 private static final long serialVersionUID = 1L;
\r
1093 public VWReserveDialog(int x, int y) {
\r
1099 protected Env getEnv() { return env; }
\r
1101 protected TVProgramList getTVProgramList() { return tvprograms; }
\r
1103 protected HDDRecorderList getRecorderList() { return recorders; }
\r
1105 protected AVSetting getAVSetting() { return avs; }
\r
1107 protected CHAVSetting getCHAVSetting() { return chavs; }
\r
1111 protected StatusWindow getStWin() { return stwin; }
\r
1113 protected StatusTextArea getMWin() { return mwin; }
\r
1117 protected Component getParentComponent() { return Viewer.this; }
\r
1120 protected void ringBeep() { Viewer.this.ringBeep(); }
\r
1123 * ReserveDialog内でのイベントから呼び出されるメソッド群
\r
1127 protected LikeReserveList findLikeReserves(ProgDetailList tvd, String keyword, int threshold) {
\r
1128 return Viewer.this.findLikeReserves(tvd, keyword, threshold);
\r
1133 * 新聞の表示形式を操作するダイアログ
\r
1135 private class VWPaperColorsDialog extends AbsPaperColorsDialog {
\r
1137 private static final long serialVersionUID = 1L;
\r
1140 protected Env getEnv() { return env; }
\r
1142 protected Bounds getBoundsEnv() { return bounds; }
\r
1144 protected PaperColorsMap getPaperColorMap() { return pColors; }
\r
1147 protected VWColorChooserDialog getCCWin() { return ccwin; }
\r
1150 * PaperColorsDialog内でのイベントから呼び出されるメソッド群
\r
1155 protected void updatePaperColors(Env ec,PaperColorsMap pc) {
\r
1156 paper.updateColors(ec,pc);
\r
1161 protected void updatePaperFonts(Env ec) {
\r
1162 paper.updateFonts(ec);
\r
1167 protected void updatePaperBounds(Env ec, Bounds bc) {
\r
1168 paper.updateBounds(ec,bc);
\r
1173 protected void updatePaperRepaint() {
\r
1174 paper.updateRepaint();
\r
1179 * キーワード検索ウィンドウの内部クラス
\r
1181 private class VWKeywordDialog extends AbsKeywordDialog {
\r
1183 private static final long serialVersionUID = 1L;
\r
1186 void preview(SearchKey search) {
\r
1188 if (search.alTarget.size() > 0) {
\r
1189 mainWindow.setSelectedTab(MWinTab.LISTED);
\r
1190 listed.redrawListByPreview(search);
\r
1196 * 延長警告管理ウィンドウの内部クラス
\r
1198 private class VWExtensionDialog extends AbsExtensionDialog {
\r
1200 private static final long serialVersionUID = 1L;
\r
1203 void preview(SearchKey search) {
\r
1205 if (search.alTarget.size() > 0) {
\r
1206 mainWindow.setSelectedTab(MWinTab.LISTED);
\r
1207 listed.redrawListByPreview(search);
\r
1217 private class VWToolBar extends AbsToolBar {
\r
1219 private static final long serialVersionUID = 1L;
\r
1222 protected Env getEnv() { return env; }
\r
1224 protected Bounds getBoundsEnv() { return bounds; }
\r
1226 protected TVProgramList getTVPrograms() { return tvprograms; }
\r
1228 protected ChannelSort getChannelSort() { return chsort; }
\r
1230 protected HDDRecorderList getHDDRecorders() { return recorders; }
\r
1233 protected StatusWindow getStWin() { return stwin; }
\r
1235 protected StatusTextArea getMWin() { return mwin; }
\r
1237 protected Component getParentComponent() { return Viewer.this; }
\r
1240 protected void ringBeep() { Viewer.this.ringBeep(); }
\r
1243 protected boolean doKeywordSerach(SearchKey search, String kStr, String sStr, boolean doFilter) {
\r
1245 timer_now.pause();
\r
1247 if ( mainWindow.getSelectedTab() == MWinTab.RSVED ) {
\r
1248 reserved.redrawListByKeywordFilter(search, kStr);
\r
1250 else if ( mainWindow.getSelectedTab() == MWinTab.RECED ) {
\r
1251 recorded.redrawListByKeywordFilter(search, kStr);
\r
1254 if ( search != null ) {
\r
1255 mainWindow.setSelectedTab(MWinTab.LISTED);
\r
1258 listed.clearSelection();
\r
1259 listed.redrawListByKeywordFilter(search, kStr);
\r
1261 else if (sStr != null) {
\r
1263 searchPassedProgram(search, sStr);
\r
1264 listed.clearSelection();
\r
1265 listed.redrawListBySearched(ProgType.PASSED, 0);
\r
1267 listed.redrawTreeByHistory();
\r
1271 listed.clearSelection();
\r
1272 listed.redrawListByKeywordDyn(search, kStr);
\r
1277 timer_now.start();
\r
1283 protected boolean doBatchReserve() {
\r
1284 timer_now.pause();
\r
1285 listed.doBatchReserve();
\r
1286 timer_now.start();
\r
1291 protected boolean jumpToNow() {
\r
1292 timer_now.pause();
\r
1293 if ( ! mainWindow.isTabSelected(MWinTab.PAPER) ) {
\r
1294 mainWindow.setSelectedTab(MWinTab.PAPER);
\r
1296 paper.jumpToNow();
\r
1297 timer_now.start();
\r
1302 protected boolean jumpToPassed(String passed) {
\r
1303 timer_now.pause();
\r
1304 boolean b = paper.jumpToPassed(passed);
\r
1305 timer_now.start();
\r
1310 protected boolean redrawByPager() {
\r
1311 timer_now.pause();
\r
1312 boolean b = paper.redrawByPager();
\r
1313 timer_now.start();
\r
1318 protected void toggleMatchBorder() {
\r
1319 timer_now.pause();
\r
1320 paper.toggleMatchBorder();
\r
1321 timer_now.start();
\r
1325 protected void setPaperColorDialogVisible(boolean b) {
\r
1326 //paper.stopTimer(); xxxx
\r
1327 timer_now.pause();
\r
1328 CommonSwingUtils.setLocationCenter(Viewer.this,pcwin);
\r
1329 pcwin.setVisible(true);
\r
1330 timer_now.start();
\r
1334 protected void setPaperZoom(int n) {
\r
1335 timer_now.pause();
\r
1337 timer_now.start();
\r
1341 protected boolean recorderSelectorChanged() {
\r
1343 timer_now.pause();
\r
1345 if (mainWindow.isTabSelected(MWinTab.LISTED)) {
\r
1346 listed.updateReserveMark();
\r
1347 listed.selectBatchTarget();
\r
1349 else if (mainWindow.isTabSelected(MWinTab.RSVED)) {
\r
1350 reserved.redrawReservedList();
\r
1352 else if (mainWindow.isTabSelected(MWinTab.RECED)) {
\r
1353 recorded.redrawRecordedList();
\r
1357 // 新聞形式の予約枠を書き換えるかもよ?
\r
1358 if (env.getEffectComboToPaper()) {
\r
1359 paper.updateReserveBorder(null);
\r
1363 timer_now.start();
\r
1369 protected void takeSnapShot() {
\r
1371 timer_now.pause();
\r
1373 Viewer.this.getSnapshot(getSelectedPagerIndex(),getPagerCount());
\r
1375 timer_now.start();
\r
1379 protected void setStatusVisible(boolean b) {
\r
1380 Viewer.this.setStatusVisible(b);
\r
1384 protected void setFullScreen(boolean b) {
\r
1385 Viewer.this.setFullScreen(b);
\r
1389 protected void toggleSettingTabVisible() {
\r
1390 mainWindow.toggleShowSettingTabs();
\r
1394 protected boolean isTabSelected(MWinTab tab) {
\r
1395 return mainWindow.isTabSelected(tab);
\r
1399 protected boolean addKeywordSearch(SearchKey search) {
\r
1401 timer_now.pause();
\r
1403 AbsKeywordDialog kD = new VWKeywordDialog();
\r
1404 CommonSwingUtils.setLocationCenter(Viewer.this,kD);
\r
1406 kD.open(search.getLabel(), srKeys, srGrps, search);
\r
1407 kD.setVisible(true);
\r
1409 if (kD.isRegistered()) {
\r
1411 mpList.clear(env.getDisableFazzySearch(), env.getDisableFazzySearchReverse());
\r
1412 mpList.build(tvprograms, trKeys.getTraceKeys(), srKeys.getSearchKeys());
\r
1415 listed.redrawTreeByKeyword();
\r
1417 mainWindow.setSelectedTab(MWinTab.LISTED);
\r
1420 timer_now.start();
\r
1426 protected boolean doLoadTVProgram(String selected) {
\r
1427 timer_now.pause();
\r
1429 LoadFor lf = (selected != null) ? LoadFor.get(selected) : LoadFor.ALL;
\r
1430 boolean b = Viewer.this.doLoadTVProgram(true, lf);
\r
1432 if ( b && lf == LoadFor.CSwSD ) {
\r
1434 CommonUtils.executeCommand(env.getShutdownCmd());
\r
1437 Viewer.this.doRedrawTVProgram(); // か き な お し
\r
1439 timer_now.start();
\r
1444 protected boolean doLoadRdRecorder(String selected) {
\r
1445 timer_now.pause();
\r
1447 LoadRsvedFor lrf = (selected != null) ? LoadRsvedFor.get(selected) : null;
\r
1448 boolean b = Viewer.this.doLoadRdRecorder(lrf);
\r
1450 timer_now.start();
\r
1455 /*******************************************************************************
\r
1457 ******************************************************************************/
\r
1463 public void stateChanged(ChangeEvent e){
\r
1464 StdAppendMessage("イベント発生");
\r
1468 * ツールバーでレコーダの選択イベントが発生
\r
1471 public void valueChanged(HDDRecorderSelectionEvent e) {
\r
1472 // 選択中のレコーダ情報を保存する
\r
1473 src_recsel = (HDDRecorderSelectable) e.getSource();
\r
1476 private String getSelectedMySelf() {
\r
1477 return ( src_recsel!=null ? src_recsel.getSelectedMySelf() : null );
\r
1480 private HDDRecorderList getSelectedRecorderList() {
\r
1481 return ( src_recsel!=null ? src_recsel.getSelectedList() : null );
\r
1484 private HDDRecorderSelectable src_recsel;
\r
1487 * レコーダ情報の変更イベントが発生
\r
1490 public void stateChanged(HDDRecorderChangeEvent e) {
\r
1498 public void cancelRised(CancelEvent e) {
\r
1499 if ( mainWindow.isTabSelected(MWinTab.RSVED) ) {
\r
1500 if ( e.getCause() == CancelEvent.Cause.TOOLBAR_SEARCH ) {
\r
1501 reserved.redrawListByKeywordFilter(null,null);
\r
1504 else if ( mainWindow.isTabSelected(MWinTab.RECED) ) {
\r
1505 if ( e.getCause() == CancelEvent.Cause.TOOLBAR_SEARCH ) {
\r
1506 recorded.redrawListByKeywordFilter(null,null);
\r
1515 public void timerRised(TickTimerRiseEvent e) {
\r
1516 if (env.getDebug()) System.out.println("Timer Rised: now="+CommonUtils.getDateTimeYMDx(e.getCalendar()));
\r
1521 /*******************************************************************************
\r
1523 ******************************************************************************/
\r
1528 private LikeReserveList findLikeReserves(ProgDetailList tvd, String keyword, int threshold) {
\r
1530 String keywordVal = null;
\r
1531 int thresholdVal = 0;
\r
1534 if ( ! env.getDisableFazzySearch() ) {
\r
1535 if ( threshold > 0 ) {
\r
1537 keywordVal = TraceProgram.replacePop(keyword);
\r
1538 thresholdVal = threshold;
\r
1542 keywordVal = tvd.titlePop;
\r
1543 thresholdVal = env.getDefaultFazzyThreshold();
\r
1548 return recorders.findLikeReserves(tvd, keywordVal, thresholdVal, env.getRangeLikeRsv(), ! env.getDisableFazzySearchReverse());
\r
1558 * 番組追跡への追加とgoogle検索
\r
1560 public void showPopupForTraceProgram(
\r
1561 final JComponent comp,
\r
1562 final ProgDetailList tvd, final String keyword, final int threshold,
\r
1563 final int x, final int y, final String clickedDateTime)
\r
1565 JPopupMenu pop = new JPopupMenu();
\r
1567 String myself = toolBar.getSelectedRecorder();
\r
1570 LikeReserveList likeRsvList;
\r
1571 if ( env.getDisableFazzySearch() ) {
\r
1572 likeRsvList = recorders.findLikeReserves(tvd, null, 0, env.getRangeLikeRsv(), false);
\r
1575 likeRsvList = recorders.findLikeReserves(tvd, tvd.titlePop, env.getDefaultFazzyThreshold(), env.getRangeLikeRsv(), ! env.getDisableFazzySearchReverse());
\r
1579 LikeReserveList overlapRsvList = recorders.findOverlapReserves(tvd, null, true, env.getOverlapUp());
\r
1581 // 類似と重複で被るものを重複から除外
\r
1582 for ( LikeReserveItem item : likeRsvList ) {
\r
1583 overlapRsvList.removeDup(item);
\r
1587 if ( tvd.type == ProgType.PASSED ||
\r
1588 (tvd.type == ProgType.PROG && tvd.subtype == ProgSubtype.RADIO) ||
\r
1589 recorders.size() == 0 ) {
\r
1594 LikeReserveItem item = likeRsvList.getClosest(myself);
\r
1595 if ( env.getGivePriorityToReserved() && item != null && item.isCandidate(env.getOverlapUp()) ) {
\r
1596 target = "予約を編集する";
\r
1599 target = "新規予約を登録する";
\r
1602 JMenuItem menuItem = new JMenuItem(String.format("%s【%s %s - %s(%s)】",target,tvd.accurateDate,tvd.start,tvd.title,tvd.center));
\r
1604 menuItem.setForeground(Color.BLUE);
\r
1605 Font f = menuItem.getFont();
\r
1606 menuItem.setFont(f.deriveFont(f.getStyle()|Font.BOLD));
\r
1609 menuItem.addActionListener(new ActionListener() {
\r
1610 public void actionPerformed(ActionEvent e) {
\r
1612 CommonSwingUtils.setLocationCenter(mainWindow,rdialog);
\r
1614 if ( rdialog.open(tvd) ) {
\r
1615 rdialog.setVisible(true);
\r
1618 rdialog.setVisible(false);
\r
1622 if (rdialog.isSucceededReserve()) {
\r
1623 listed.updateReserveMark();
\r
1624 paper.updateReserveBorder(tvd.center);
\r
1625 reserved.redrawReservedList();
\r
1629 pop.add(menuItem);
\r
1634 for ( final LikeReserveItem item : overlapRsvList ) {
\r
1636 if ( ! item.getRec().Myself().equals(toolBar.getSelectedRecorder()) ) {
\r
1637 continue; // 選択中のレコーダ以外はスルーで
\r
1641 ReserveList rsv = item.getRsv();
\r
1642 String start = CommonUtils.getDateTimeW(CommonUtils.getCalendar(rsv.getStartDateTime()));
\r
1643 JMenuItem menuItem = new JMenuItem(String.format("隣接予約を上書する【%s - %s(%s)】",start,rsv.getTitle(),rsv.getCh_name()));
\r
1645 menuItem.addActionListener(new ActionListener() {
\r
1646 public void actionPerformed(ActionEvent e) {
\r
1648 CommonSwingUtils.setLocationCenter(mainWindow,rdialog);
\r
1650 if ( rdialog.open(tvd,item) ) {
\r
1651 rdialog.setVisible(true);
\r
1654 rdialog.setVisible(false);
\r
1658 if (rdialog.isSucceededReserve()) {
\r
1659 listed.updateReserveMark();
\r
1660 paper.updateReserveBorder(tvd.center);
\r
1661 reserved.redrawReservedList();
\r
1665 pop.add(menuItem);
\r
1669 pop.addSeparator();
\r
1672 if ( tvd.type != ProgType.PASSED )
\r
1674 for ( int n=0; n<2; n++ ) {
\r
1676 LikeReserveList rsvList = null;
\r
1678 rsvList = likeRsvList;
\r
1681 rsvList = overlapRsvList;
\r
1684 for ( LikeReserveItem rsvItem : rsvList ) {
\r
1686 final boolean fexec = rsvItem.getRsv().getExec();
\r
1687 final String start = rsvItem.getRsv().getAhh()+":"+rsvItem.getRsv().getAmm();
\r
1688 final String title = rsvItem.getRsv().getTitle();
\r
1689 final String chnam = rsvItem.getRsv().getCh_name();
\r
1690 final String rsvId = rsvItem.getRsv().getId();
\r
1691 final String recId = rsvItem.getRec().Myself();
\r
1693 pop.add(getExecOnOffMenuItem(fexec,start,title,chnam,rsvId,recId,n));
\r
1696 pop.addSeparator();
\r
1700 pop.addSeparator();
\r
1703 if ( tvd.type != ProgType.PASSED ) // 過去ログは処理対象外です
\r
1705 for ( int n=0; n<2; n++ ) {
\r
1707 LikeReserveList rsvList = null;
\r
1709 rsvList = likeRsvList;
\r
1712 rsvList = overlapRsvList;
\r
1715 for ( LikeReserveItem rsvItem : rsvList ) {
\r
1717 final String start = rsvItem.getRsv().getAhh()+":"+rsvItem.getRsv().getAmm();
\r
1718 final String title = rsvItem.getRsv().getTitle();
\r
1719 final String chnam = rsvItem.getRsv().getCh_name();
\r
1720 final String rsvId = rsvItem.getRsv().getId();
\r
1721 final String recId = rsvItem.getRec().Myself();
\r
1723 pop.add(getRemoveRsvMenuItem(start, title,chnam,rsvId,recId,n));
\r
1726 pop.addSeparator();
\r
1730 pop.addSeparator();
\r
1731 pop.addSeparator();
\r
1736 if ( mainWindow.isTabSelected(MWinTab.LISTED) ) {
\r
1737 pop.add(getJumpMenuItem(tvd.title,tvd.center,tvd.accurateDate+" "+tvd.start));
\r
1739 if ( mainWindow.isTabSelected(MWinTab.LISTED) || mainWindow.isTabSelected(MWinTab.PAPER) ) {
\r
1740 JMenuItem mi = getJumpToLastWeekMenuItem(tvd.title,tvd.center,tvd.startDateTime);
\r
1741 if ( mi != null ) {
\r
1747 pop.addSeparator();
\r
1751 final String label = TraceProgram.getNewLabel(tvd.title, tvd.center);
\r
1752 JMenuItem menuItem = new JMenuItem("番組追跡への追加【"+label+"】");
\r
1753 menuItem.addActionListener(new ActionListener() {
\r
1754 public void actionPerformed(ActionEvent e) {
\r
1756 VWTraceKeyDialog tD = new VWTraceKeyDialog(0,0);
\r
1757 CommonSwingUtils.setLocationCenter(mainWindow,tD);
\r
1759 tD.open(trKeys, tvd, env.getDefaultFazzyThreshold());
\r
1760 tD.setVisible(true);
\r
1762 if (tD.isRegistered()) {
\r
1767 mpList.clear(env.getDisableFazzySearch(), env.getDisableFazzySearchReverse());
\r
1768 mpList.build(tvprograms, trKeys.getTraceKeys(), srKeys.getSearchKeys());
\r
1771 listed.redrawTreeByTrace();
\r
1774 paper.updateBangumiColumns();
\r
1775 listed.reselectTree();
\r
1777 mwin.appendMessage("番組追跡へ追加しました【"+label+"】");
\r
1780 trKeys.remove(label);
\r
1784 pop.add(menuItem);
\r
1789 final String label = tvd.title+" ("+tvd.center+")";
\r
1790 JMenuItem menuItem = new JMenuItem("キーワード検索への追加【"+label+"】");
\r
1791 menuItem.addActionListener(new ActionListener(){
\r
1792 public void actionPerformed(ActionEvent e){
\r
1794 // 「キーワード検索の設定」ウィンドウを開く
\r
1796 AbsKeywordDialog kD = new VWKeywordDialog();
\r
1797 CommonSwingUtils.setLocationCenter(mainWindow,kD);
\r
1799 kD.open(srKeys, srGrps, tvd);
\r
1800 kD.setVisible(true);
\r
1802 if (kD.isRegistered()) {
\r
1804 mpList.clear(env.getDisableFazzySearch(), env.getDisableFazzySearchReverse());
\r
1805 mpList.build(tvprograms, trKeys.getTraceKeys(), srKeys.getSearchKeys());
\r
1808 listed.redrawTreeByKeyword();
\r
1811 paper.updateBangumiColumns();
\r
1812 listed.reselectTree();
\r
1814 mwin.appendMessage("キーワード検索へ追加しました【"+label+"】");
\r
1818 pop.add(menuItem);
\r
1823 boolean isRemoveItem = false;
\r
1824 if ( mainWindow.isTabSelected(MWinTab.LISTED) && tvd.type == ProgType.PICKED ) {
\r
1825 isRemoveItem = true;
\r
1828 PickedProgram tvp = tvprograms.getPickup();
\r
1829 if ( tvp != null ) {
\r
1830 isRemoveItem = tvp.remove(tvd, tvd.center, tvd.accurateDate, false);
\r
1834 if ( ! isRemoveItem ) // 過去ログは処理対象外です
\r
1836 final String label = String.format("%s(%s)",tvd.title,tvd.center);
\r
1837 JMenuItem menuItem = new JMenuItem(String.format("ピックアップへの追加【%s %s - %s】",tvd.accurateDate,tvd.start,label));
\r
1838 menuItem.addActionListener(new ActionListener() {
\r
1839 public void actionPerformed(ActionEvent e) {
\r
1841 PickedProgram tvp = tvprograms.getPickup();
\r
1842 if ( tvp != null ) {
\r
1847 if ( listed.isNodeSelected(ListedTreeNode.PICKUP) ) {
\r
1848 // ピックアップノードが選択されていたらリストを更新する
\r
1849 listed.reselectTree();
\r
1852 listed.updateReserveMark();
\r
1854 paper.updateReserveBorder(tvd.center);
\r
1855 mwin.appendMessage("【ピックアップ】追加しました: "+tvd.title+" ("+tvd.center+")");
\r
1860 pop.add(menuItem);
\r
1863 final String label = tvd.title+" ("+tvd.center+")";
\r
1864 JMenuItem menuItem = new JMenuItem("ピックアップからの削除【"+label+"】");
\r
1865 menuItem.setForeground(Color.RED);
\r
1866 menuItem.addActionListener(new ActionListener() {
\r
1867 public void actionPerformed(ActionEvent e) {
\r
1869 PickedProgram tvp = tvprograms.getPickup();
\r
1870 if ( tvp != null ) {
\r
1872 tvp.remove(tvd, tvd.center, tvd.accurateDate, true);
\r
1875 if ( listed.isNodeSelected(ListedTreeNode.PICKUP) || listed.isNodeSelected(ListedTreeNode.STANDBY) ) {
\r
1876 // ピックアップノードが選択されていたらリストを更新する
\r
1877 listed.reselectTree();
\r
1880 listed.updateReserveMark();
\r
1881 paper.updateReserveBorder(tvd.center);
\r
1882 mwin.appendMessage("【ピックアップ】削除しました: "+tvd.title+" ("+tvd.center+")");
\r
1887 pop.add(menuItem);
\r
1891 pop.addSeparator();
\r
1895 for (final TextValueSet tv : env.getTvCommand()) {
\r
1896 JMenuItem menuItem = new JMenuItem(tv.getText());
\r
1897 String escepedTitle = "";
\r
1898 String escepedChName = "";
\r
1899 String escepedDetail = "";
\r
1901 escepedTitle = URLEncoder.encode(tvd.title,"UTF-8");
\r
1902 escepedDetail = URLEncoder.encode(tvd.detail,"UTF-8");
\r
1903 escepedChName = URLEncoder.encode(tvd.center,"UTF-8");
\r
1904 } catch (UnsupportedEncodingException e2) {
\r
1908 String cmd = tv.getValue();
\r
1909 if ( cmd.matches(".*%DETAILURL%.*") ) {
\r
1910 if ( tvd.link == null || tvd.link.length() == 0 ) {
\r
1911 // このメニューは利用できません!
\r
1912 menuItem.setEnabled(false);
\r
1913 menuItem.setForeground(Color.lightGray);
\r
1916 cmd = cmd.replaceAll("%ENCTITLE%", escepedTitle);
\r
1917 cmd = cmd.replaceAll("%ENCDETAIL%", escepedDetail);
\r
1918 cmd = cmd.replaceAll("%ENCCHNAME%", escepedChName);
\r
1919 cmd = cmd.replaceAll("%TITLE%", tvd.title);
\r
1920 cmd = cmd.replaceAll("%DETAIL%", tvd.detail);
\r
1921 cmd = cmd.replaceAll("%CHNAME%", tvd.center);
\r
1922 cmd = cmd.replaceAll("%DATE%", tvd.accurateDate);
\r
1923 cmd = cmd.replaceAll("%START%", tvd.start);
\r
1924 cmd = cmd.replaceAll("%END%", tvd.end);
\r
1925 cmd = cmd.replaceAll("%DETAILURL%", tvd.link);
\r
1928 if ( cmd.matches(".*%TVKAREACODE%.*") && cmd.matches(".*%TVKPID%.*") ) {
\r
1930 for ( TVProgram tvp : progPlugins ) {
\r
1931 if ( tvp.getTVProgramId().startsWith("Gガイド.テレビ王国") ) {
\r
1932 for ( Center tempcr : tvp.getCRlist() ) {
\r
1933 // CH設定が完了している必要がある
\r
1934 if ( tvp.getSubtype() == ProgSubtype.TERRA && tvp.getSelectedCode().equals(TVProgram.allCode) && ! tempcr.getAreaCode().equals(TVProgram.bsCode) ) {
\r
1935 // 地域が全国の地デジの場合のみ、有効局かどうかを確認する必要がある
\r
1936 if ( tempcr.getCenter().equals(tvd.center) && tempcr.getOrder() > 0 ) {
\r
1943 if ( tempcr.getCenter().equals(tvd.center) ) {
\r
1951 if ( cr != null ) {
\r
1956 if ( cr != null ) {
\r
1957 String areacode = null;
\r
1958 String centercode = cr.getLink();
\r
1959 String cat = cr.getLink().substring(0,1);
\r
1960 if ( cat.equals("1") ) {
\r
1961 areacode = cr.getAreaCode();
\r
1964 if ( cat.equals("4") ) {
\r
1967 else if ( cat.equals("5") ) {
\r
1973 cmd = cmd.replaceAll("%TVKAREACODE%", areacode);
\r
1974 cmd = cmd.replaceAll("%TVKCAT%", cat);
\r
1975 cmd = cmd.replaceAll("%TVKPID%", centercode+CommonUtils.getDateTimeYMD(CommonUtils.getCalendar(tvd.startDateTime)).replaceFirst("..$", ""));
\r
1976 System.out.println("[DEBUG] "+cmd);
\r
1978 menuItem.setEnabled(true);
\r
1979 menuItem.setForeground(Color.BLACK);
\r
1982 menuItem.setEnabled(false);
\r
1983 menuItem.setForeground(Color.lightGray);
\r
1987 final String run = cmd;
\r
1989 menuItem.addActionListener(new ActionListener() {
\r
1991 public void actionPerformed(ActionEvent e) {
\r
1993 if (run.indexOf("http") == 0) {
\r
1994 Desktop desktop = Desktop.getDesktop();
\r
1995 desktop.browse(new URI(run));
\r
1998 CommonUtils.executeCommand(run);
\r
2000 } catch (IOException e1) {
\r
2001 e1.printStackTrace();
\r
2002 } catch (URISyntaxException e1) {
\r
2003 e1.printStackTrace();
\r
2008 pop.add(menuItem);
\r
2012 pop.addSeparator();
\r
2016 JMenuItem menuItem = new JMenuItem("番組名をコピー【"+tvd.title+"】");
\r
2017 menuItem.addActionListener(new ActionListener() {
\r
2018 public void actionPerformed(ActionEvent e) {
\r
2019 String msg = tvd.title;
\r
2020 Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard();
\r
2021 StringSelection s = new StringSelection(msg);
\r
2022 cb.setContents(s, null);
\r
2025 pop.add(menuItem);
\r
2028 JMenuItem menuItem = new JMenuItem("番組名と詳細をコピー【"+tvd.title+"】");
\r
2029 menuItem.addActionListener(new ActionListener() {
\r
2030 public void actionPerformed(ActionEvent e) {
\r
2031 String msg = tvd.title+System.getProperty("line.separator")+tvd.detail+"\0"+tvd.getAddedDetail();
\r
2032 Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard();
\r
2033 StringSelection s = new StringSelection(msg);
\r
2034 cb.setContents(s, null);
\r
2037 pop.add(menuItem);
\r
2040 JMenuItem menuItem = new JMenuItem("番組情報をコピー【"+tvd.title+"】");
\r
2041 menuItem.addActionListener(new ActionListener() {
\r
2042 public void actionPerformed(ActionEvent e) {
\r
2045 for (ClipboardInfo cb : cbitems) {
\r
2047 switch (cb.getId()) {
\r
2049 msg += tvd.title+"\t";
\r
2052 msg += tvd.center+"\t";
\r
2055 msg += tvd.accurateDate+"\t";
\r
2058 msg += tvd.start+"\t";
\r
2062 msg = msg.substring(0,msg.length()-1)+"-";
\r
2064 msg += tvd.end+"\t";
\r
2067 msg += tvd.genre+"\t";
\r
2070 msg += tvd.detail+"\0"+tvd.getAddedDetail()+"\t";
\r
2074 preId = cb.getId();
\r
2076 if (msg.length() > 0) {
\r
2077 msg = msg.substring(0,msg.length()-1);
\r
2079 Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard();
\r
2080 StringSelection s = new StringSelection(msg);
\r
2081 cb.setContents(s, null);
\r
2084 pop.add(menuItem);
\r
2087 pop.addSeparator();
\r
2091 tvd.type == ProgType.SYOBO ||
\r
2092 tvd.type == ProgType.PASSED ||
\r
2093 tvd.type == ProgType.PICKED ||
\r
2094 (tvd.type == ProgType.PROG && tvd.subtype != ProgSubtype.RADIO) ) // ラジオは処理対象外です
\r
2096 JMenuItem menuItem = new JMenuItem("延長感染源にしない【"+tvd.title+" ("+tvd.center+")】");
\r
2097 menuItem.addActionListener(new ActionListener() {
\r
2098 public void actionPerformed(ActionEvent e) {
\r
2100 mwin.appendMessage("延長感染源を隔離します【"+tvd.title+"("+tvd.center+")】");
\r
2102 AbsExtensionDialog eD = new VWExtensionDialog();
\r
2103 CommonSwingUtils.setLocationCenter(mainWindow,eD);
\r
2105 eD.open(tvd.title,tvd.center,false,extKeys);
\r
2106 eD.setVisible(true);
\r
2108 if (eD.isRegistered()) {
\r
2110 for (TVProgram tvp : tvprograms) {
\r
2111 if (tvp.getType() == ProgType.PROG) {
\r
2112 tvp.setExtension(null, null, false, extKeys.getSearchKeys());
\r
2117 listed.redrawTreeByExtension();
\r
2119 mainWindow.setSelectedTab(MWinTab.LISTED);
\r
2123 pop.add(menuItem);
\r
2125 if ( tvd.type == ProgType.PASSED || (tvd.type == ProgType.PROG && tvd.subtype != ProgSubtype.RADIO) ) // ラジオは処理対象外です
\r
2127 JMenuItem menuItem = new JMenuItem("延長感染源にする【"+tvd.title+" ("+tvd.center+")】");
\r
2128 menuItem.addActionListener(new ActionListener() {
\r
2129 public void actionPerformed(ActionEvent e) {
\r
2131 AbsExtensionDialog eD = new VWExtensionDialog();
\r
2132 CommonSwingUtils.setLocationCenter(mainWindow,eD);
\r
2134 eD.open(tvd.title,tvd.center,true,extKeys);
\r
2135 eD.setVisible(true);
\r
2137 if (eD.isRegistered()) {
\r
2139 for (TVProgram tvp : tvprograms) {
\r
2140 if (tvp.getType() == ProgType.PROG) {
\r
2141 tvp.setExtension(null, null, false, extKeys.getSearchKeys());
\r
2146 listed.redrawTreeByExtension();
\r
2148 mainWindow.setSelectedTab(MWinTab.LISTED);
\r
2152 pop.add(menuItem);
\r
2155 pop.addSeparator();
\r
2158 if ( tvd.type == ProgType.PROG && tvd.subtype != ProgSubtype.RADIO) // ラジオは処理対象外です
\r
2160 for (HDDRecorder recorder : recorders ) {
\r
2162 if (recorder.ChangeChannel(null) == false) {
\r
2166 final String recorderName = recorder.Myself();
\r
2167 JMenuItem menuItem = new JMenuItem("【"+recorderName+"】で【"+tvd.center+"】を視聴する");
\r
2169 menuItem.addActionListener(new ActionListener() {
\r
2170 public void actionPerformed(ActionEvent e) {
\r
2171 for (HDDRecorder recorder : recorders ) {
\r
2172 if (recorder.isMyself(recorderName)) {
\r
2173 if (recorder.ChangeChannel(tvd.center) == false) {
\r
2175 mwin.appendError("【警告】チャンネルを変更できませんでした:"+recorder.getErrmsg());
\r
2177 else if (recorder.getErrmsg() !=null && recorder.getErrmsg().length() > 0) {
\r
2178 mwin.appendError("[追加情報] "+recorder.getErrmsg());
\r
2185 menuItem.setEnabled(recorder.getUseChChange());
\r
2187 pop.add(menuItem);
\r
2191 pop.show(comp, x, y);
\r
2195 public boolean addToPickup(final ProgDetailList tvd) {
\r
2197 if (tvd.start.equals("")) {
\r
2202 PickedProgram tvp = tvprograms.getPickup();
\r
2203 if ( tvp == null ) {
\r
2209 if ( tvp.remove(tvd, tvd.center, tvd.accurateDate, true) ) {
\r
2211 if ( listed.isNodeSelected(JTreeLabel.Nodes.PICKUP) || listed.isNodeSelected(JTreeLabel.Nodes.STANDBY) ) {
\r
2212 // ピックアップノードor予約待機ノードが選択されていたらリストを更新する
\r
2213 listed.reselectTree();
\r
2214 //listed.updateReserveMark();
\r
2217 // 予約マークだけ変えておけばいいよね
\r
2218 listed.updateReserveMark();
\r
2221 paper.updateReserveBorder(tvd.center);
\r
2222 mwin.appendMessage("【ピックアップ】削除しました: "+tvd.title+" ("+tvd.center+")");
\r
2227 if ( tvd.endDateTime.compareTo(CommonUtils.getDateTime(0)) > 0 ) {
\r
2231 if ( listed.isNodeSelected(JTreeLabel.Nodes.PICKUP) ) {
\r
2232 // ピックアップノードが選択されていたらリストを更新する
\r
2233 listed.reselectTree();
\r
2234 //listed.updateReserveMark();
\r
2237 listed.updateReserveMark();
\r
2240 paper.updateReserveBorder(tvd.center);
\r
2241 mwin.appendMessage("【ピックアップ】追加しました: "+tvd.title+" ("+tvd.center+")");
\r
2246 mwin.appendMessage("【ピックアップ】過去情報はピックアップできません.");
\r
2253 private JMenuItem getRemoveRsvMenuItem(final String start, final String title, final String chnam, final String rsvId, final String recId, int n) {
\r
2255 JMenuItem menuItem = new JMenuItem();
\r
2257 String mode = "削除";
\r
2258 menuItem.setForeground(Color.RED);
\r
2260 String target = ( n==0 ) ? "予約" : "隣接予約";
\r
2262 menuItem.setText(String.format("%sを%sする【%s - %s(%s)/%s】",target,mode,start,title,chnam,recId));
\r
2264 if ( recId.equals(toolBar.getSelectedRecorder()) ) {
\r
2265 // 選択中のレコーダのものは太字に
\r
2266 Font f = menuItem.getFont();
\r
2267 menuItem.setFont(f.deriveFont(f.getStyle()|Font.BOLD));
\r
2270 menuItem.addActionListener(new ActionListener() {
\r
2271 public void actionPerformed(ActionEvent e) {
\r
2273 if (env.getShowWarnDialog()) {
\r
2274 Container cp = getContentPane();
\r
2275 int ret = JOptionPane.showConfirmDialog(cp, "削除しますか?【"+title+"("+chnam+")】("+recId+")", "確認", JOptionPane.YES_NO_OPTION);
\r
2276 if (ret != JOptionPane.YES_OPTION) {
\r
2284 new SwingBackgroundWorker(false) {
\r
2287 protected Object doWorks() throws Exception {
\r
2289 for (HDDRecorder recorder : recorders) {
\r
2290 if (recorder.isMyself(recId)) { // IPAddr:PortNo:RecorderIdで比較
\r
2292 String title = "";
\r
2293 for (ReserveList r : recorder.getReserves()) {
\r
2294 if (r.getId().equals(rsvId)) {
\r
2295 title = r.getTitle();
\r
2300 stwin.appendMessage("予約を削除します:"+title+"("+rsvId+")");
\r
2301 //recorder.setProgressArea(stwin);
\r
2302 ReserveList r = recorder.RemoveRdEntry(rsvId); // Noで検索
\r
2304 mwin.appendMessage("正常に削除できました:"+r.getTitle()+"("+r.getCh_name()+")");
\r
2306 if ( ! r.getTitle().equals(title) || ! r.getId().equals(rsvId)) {
\r
2307 mwin.appendError("【警告】削除結果が一致しません!:"+title+"/"+r.getTitle());
\r
2310 if ( recorder.getUseCalendar()) {
\r
2312 for ( HDDRecorder calendar : recorders ) {
\r
2313 if (calendar.getType() == RecType.CALENDAR) {
\r
2314 stwin.appendMessage("カレンダーから予約情報を削除します");
\r
2315 //calendar.setProgressArea(stwin);
\r
2316 if ( ! calendar.UpdateRdEntry(r, null)) {
\r
2317 mwin.appendError("【カレンダー】"+calendar.getErrmsg());
\r
2327 mwin.appendError("削除に失敗しました:"+title);
\r
2331 if ( ! recorder.getErrmsg().equals("")) {
\r
2332 mwin.appendError("【追加情報】"+recorder.getErrmsg());
\r
2342 protected void doFinally() {
\r
2343 StWinSetVisible(false);
\r
2347 CommonSwingUtils.setLocationCenter(Viewer.this, stwin);
\r
2348 StWinSetVisible(true);
\r
2351 listed.updateReserveMark();
\r
2352 paper.updateReserveBorder(chnam);
\r
2353 reserved.redrawReservedList();
\r
2364 * 他のクラスに分離できなかったというか、しなかったというか、そんなメソッド群
\r
2370 private boolean doExecOnOff(final boolean fexec, final String title, final String chnam, final String rsvId, final String recId) {
\r
2372 CommonSwingUtils.setLocationCenter(mainWindow,rdialog);
\r
2374 String mode = (fexec ? "ON" : "OFF");
\r
2377 if ( rdialog.open(recId,rsvId,fexec) ) {
\r
2379 rdialog.doUpdate();
\r
2381 if (rdialog.isSucceededReserve()) {
\r
2383 listed.updateReserveMark();
\r
2384 paper.updateReserveBorder(chnam);
\r
2385 reserved.redrawReservedList();
\r
2388 String msg = "予約を"+mode+"にしました【"+title+"("+chnam+")/"+recId+"】";
\r
2389 //StdAppendMessage(msg);
\r
2390 mwin.appendMessage(msg);
\r
2401 * 予約実行をONOFFするメニューアイテム
\r
2403 private JMenuItem getExecOnOffMenuItem(final boolean fexec, final String start, final String title, final String chnam, final String rsvId, final String recId, int n) {
\r
2405 JMenuItem menuItem = new JMenuItem();
\r
2410 menuItem.setForeground(Color.BLUE);
\r
2414 menuItem.setForeground(Color.BLACK);
\r
2417 String target = ( n==0 ) ? "予約" : "隣接予約";
\r
2419 menuItem.setText(String.format("%sを%sにする【%s - %s(%s)/%s】",target,mode,start,title,chnam,recId));
\r
2421 if ( recId.equals(toolBar.getSelectedRecorder()) ) {
\r
2422 // 選択中のレコーダのものは太字に
\r
2423 Font f = menuItem.getFont();
\r
2424 menuItem.setFont(f.deriveFont(f.getStyle()|Font.BOLD));
\r
2427 final String xmode = mode;
\r
2428 menuItem.addActionListener(new ActionListener() {
\r
2429 public void actionPerformed(ActionEvent e) {
\r
2431 CommonSwingUtils.setLocationCenter(mainWindow,rdialog);
\r
2434 if ( rdialog.open(recId,rsvId, ! fexec) ) {
\r
2436 rdialog.doUpdate();
\r
2438 if (rdialog.isSucceededReserve()) {
\r
2440 listed.updateReserveMark();
\r
2441 paper.updateReserveBorder(chnam);
\r
2442 reserved.redrawReservedList();
\r
2445 String msg = "予約を"+xmode+"にしました【"+title+"("+chnam+")/"+recId+"】";
\r
2446 StdAppendMessage(msg);
\r
2447 mwin.appendMessage(msg);
\r
2452 //rdialog.setVisible(false);
\r
2461 * 新聞形式へジャンプするメニューアイテム
\r
2463 private JMenuItem getJumpMenuItem(final String title, final String chnam, final String startDT) {
\r
2464 JMenuItem menuItem = new JMenuItem(String.format("番組欄へジャンプする【%s - %s(%s)】",startDT,title,chnam));
\r
2465 menuItem.addActionListener(new ActionListener() {
\r
2466 public void actionPerformed(ActionEvent e) {
\r
2467 paper.jumpToBangumi(chnam,startDT);
\r
2472 private JMenuItem getJumpToLastWeekMenuItem( final String title, final String chnam, final String startDT) {
\r
2473 GregorianCalendar cal = CommonUtils.getCalendar(startDT);
\r
2475 if ( cal != null ) {
\r
2476 cal.add(Calendar.DATE, -7);
\r
2477 final String lastdatetime = CommonUtils.getDateTimeW(cal);
\r
2479 JMenuItem menuItem = new JMenuItem(String.format("先週の番組欄へジャンプする【%s - (%s)】",lastdatetime,chnam));
\r
2481 menuItem.addActionListener(new ActionListener() {
\r
2482 public void actionPerformed(ActionEvent e) {
\r
2483 paper.jumpToBangumi(chnam,lastdatetime);
\r
2492 /*******************************************************************************
\r
2494 ******************************************************************************/
\r
2496 /***************************************
\r
2498 **************************************/
\r
2503 private boolean doLoadRdRecorder(LoadRsvedFor lrf) {
\r
2505 if ( lrf == null ) {
\r
2506 return doLoadRdRecorderAll();
\r
2511 return doLoadRdReserveDetails();
\r
2513 return doLoadRdRecorded();
\r
2515 return doLoadRdAutoReserves();
\r
2524 * レコーダの情報を全部DLする(ステータスウィンドウは自前で用意 する)
\r
2526 private boolean doLoadRdRecorderAll() {
\r
2528 final String myself = getSelectedMySelf();
\r
2533 new SwingBackgroundWorker(false) {
\r
2536 protected Object doWorks() throws Exception {
\r
2538 TatCount tc = new TatCount();
\r
2541 _loadRdRecorderAll(true,myself);
\r
2543 // エンコーダ情報が更新されるかもしれないので、一覧のエンコーダ表示にも反映する
\r
2544 recsetting.redrawRecorderEncoderEntry();
\r
2547 paper.updateReserveBorder(null);
\r
2548 listed.updateReserveMark();
\r
2549 reserved.redrawReservedList();
\r
2550 recorded.redrawRecordedList();
\r
2552 mwin.appendMessage(String.format("【予約一覧の取得処理が完了しました】 所要時間: %.2f秒",tc.end()));
\r
2557 protected void doFinally() {
\r
2558 StWinSetVisible(false);
\r
2562 StWinSetLocationCenter(this);
\r
2563 StWinSetVisible(true);
\r
2572 private boolean doLoadRdReserveDetails() {
\r
2574 final String myself = getSelectedMySelf();
\r
2579 new SwingBackgroundWorker(false) {
\r
2582 protected Object doWorks() throws Exception {
\r
2584 TatCount tc = new TatCount();
\r
2586 boolean succeeded = true;
\r
2588 HDDRecorderList recs;
\r
2589 if ( myself != null ) {
\r
2590 recs = recorders.findInstance(myself);
\r
2595 for ( HDDRecorder recorder : recs ) {
\r
2597 if ( ! recorder.isReserveListSupported() ) {
\r
2602 if ( ! recorder.GetRdSettings(true) ) {
\r
2603 succeeded = false;
\r
2608 if ( ! recorder.GetRdReserve(true) ) {
\r
2609 succeeded = false;
\r
2613 // レコーダから取得したエンコーダ情報で、登録済みレコーダ一覧を更新する
\r
2614 setEncoderInfo2RecorderList(recorder,true);
\r
2617 if ( recorder.isThereAdditionalDetails() ) {
\r
2618 if ( ! recorder.GetRdReserveDetails() ) {
\r
2619 succeeded = false;
\r
2624 // レコーダの放送局名をWeb番組表の放送局名に置き換え
\r
2625 checkChNameIsRight(recorder);
\r
2628 if ( recorder.isRecordedListSupported() ) {
\r
2629 recorder.GetRdRecorded(false);
\r
2633 if ( succeeded ) {
\r
2634 reserved.redrawReservedList();
\r
2635 recorded.redrawRecordedList();
\r
2637 mwin.appendMessage(String.format("【予約詳細の取得処理が完了しました】 所要時間: %.2f秒",tc.end()));
\r
2641 mwin.appendMessage(String.format("【予約詳細の取得処理に失敗しました】 所要時間: %.2f秒",tc.end()));
\r
2647 protected void doFinally() {
\r
2648 StWinSetVisible(false);
\r
2652 StWinSetLocationCenter(this);
\r
2653 StWinSetVisible(true);
\r
2662 private boolean doLoadRdRecorded() {
\r
2664 final String myself = getSelectedMySelf();
\r
2669 new SwingBackgroundWorker(false) {
\r
2672 protected Object doWorks() throws Exception {
\r
2674 TatCount tc = new TatCount();
\r
2676 boolean succeeded = true;
\r
2678 HDDRecorderList recs;
\r
2679 if ( myself != null ) {
\r
2680 recs = recorders.findInstance(myself);
\r
2685 for ( HDDRecorder recorder : recs ) {
\r
2686 if ( ! recorder.isRecordedListSupported() ) {
\r
2687 succeeded = false;
\r
2691 if ( ! recorder.GetRdRecorded(true) ) {
\r
2692 succeeded = false;
\r
2696 if ( succeeded ) {
\r
2697 reserved.redrawReservedList();
\r
2698 recorded.redrawRecordedList();
\r
2700 mwin.appendMessage(String.format("【録画結果一覧の取得処理が完了しました】 所要時間: %.2f秒",tc.end()));
\r
2704 mwin.appendMessage(String.format("【録画結果一覧の取得処理に失敗しました】 所要時間: %.2f秒",tc.end()));
\r
2710 protected void doFinally() {
\r
2711 StWinSetVisible(false);
\r
2715 StWinSetLocationCenter(this);
\r
2716 StWinSetVisible(true);
\r
2725 private boolean doLoadRdAutoReserves() {
\r
2727 final String myself = getSelectedMySelf();
\r
2732 new SwingBackgroundWorker(false) {
\r
2735 protected Object doWorks() throws Exception {
\r
2737 TatCount tc = new TatCount();
\r
2739 boolean succeeded = true;
\r
2741 HDDRecorderList recs;
\r
2742 if ( myself != null ) {
\r
2743 recs = recorders.findInstance(myself);
\r
2748 for ( HDDRecorder recorder : recs ) {
\r
2749 if ( ! recorder.isEditAutoReserveSupported() ) {
\r
2750 succeeded = false;
\r
2754 if ( ! recorder.GetRdAutoReserve(true) ) {
\r
2755 succeeded = false;
\r
2759 if ( succeeded ) {
\r
2761 mwin.appendMessage(String.format("【自動予約一覧の取得処理が完了しました】 所要時間: %.2f秒",tc.end()));
\r
2765 mwin.appendMessage(String.format("【自動予約一覧の取得処理に失敗しました】 所要時間: %.2f秒",tc.end()));
\r
2771 protected void doFinally() {
\r
2772 StWinSetVisible(false);
\r
2776 StWinSetLocationCenter(this);
\r
2777 StWinSetVisible(true);
\r
2782 /***************************************
\r
2784 **************************************/
\r
2787 * レコーダの情報を全部DLする(ステータスウィンドウは呼び出し元が準備する)
\r
2789 private void loadRdReservesAll(final boolean force, final String myself) {
\r
2791 new SwingBackgroundWorker(true) {
\r
2794 protected Object doWorks() throws Exception {
\r
2796 _loadRdRecorderAll(force,myself);
\r
2802 protected void doFinally() {
\r
2807 /***************************************
\r
2809 **************************************/
\r
2811 private boolean _loadRdRecorderAll(final boolean force, final String myself) {
\r
2813 HDDRecorderList recs;
\r
2814 if ( myself != null ) {
\r
2815 recs = recorders.findInstance(myself);
\r
2821 boolean success = true;
\r
2823 for ( HDDRecorder recorder : recs ) {
\r
2824 if ( recorder.isReserveListSupported() ) {
\r
2825 success = success & _loadRdRecorder(recorder, force);
\r
2832 private boolean _loadRdRecorder(HDDRecorder recorder, boolean force) {
\r
2834 mwin.appendMessage("【レコーダ情報取得】情報を取得します: "+recorder.Myself());
\r
2835 if ( recorder.isThereAdditionalDetails() && env.getForceLoadReserveDetails() == 2 ) {
\r
2836 mwin.appendMessage("<<<注意!>>>このレコーダでは予約詳細の個別取得を実行しないと正確な情報を得られない場合があります。");
\r
2842 if ( ! _loadRdSettings(recorder,force) ) {
\r
2847 if ( ! _loadRdReserves(recorder,force) ) {
\r
2851 // レコーダから取得したエンコーダ情報で、登録済みレコーダ一覧を更新する
\r
2852 setEncoderInfo2RecorderList(recorder,force);
\r
2854 // 予約詳細の取得(強制取得じゃなければ処理不要)
\r
2855 if ( force && ! _loadRdReserveDetails(recorder,force) ) {
\r
2859 // レコーダの放送局名をWeb番組表の放送局名に置き換え
\r
2860 checkChNameIsRight(recorder);
\r
2863 if ( ! _loadRdAutoReserves(recorder,force) ) {
\r
2868 if ( ! _loadRdRecorded(recorder,force) ) {
\r
2872 catch (Exception e) {
\r
2873 e.printStackTrace();
\r
2874 mwin.appendError("【致命的エラー】予約一覧の取得で例外が発生 "+recorder.getIPAddr()+":"+recorder.getPortNo()+":"+recorder.getRecorderId());
\r
2882 /***************************************
\r
2884 **************************************/
\r
2886 private boolean _loadRdSettings(HDDRecorder recorder, boolean force) {
\r
2887 if ( recorder.GetRdSettings(force) ) {
\r
2891 mwin.appendError(recorder.getErrmsg()+" "+recorder.Myself()); // 取得に失敗
\r
2896 private boolean _loadRdReserves(HDDRecorder recorder, boolean force) {
\r
2897 if ( recorder.GetRdReserve(force) ) {
\r
2901 mwin.appendError(recorder.getErrmsg()+" "+recorder.Myself()); // 取得に失敗
\r
2906 private boolean _loadRdReserveDetails(HDDRecorder recorder, boolean force) {
\r
2908 if ( ! recorder.isThereAdditionalDetails() ) {
\r
2909 return true; // 非対応レコーダ
\r
2912 boolean skip = false;
\r
2913 if ( force && env.getForceLoadReserveDetails() == 2 ) {
\r
2916 else if ( force && env.getForceLoadReserveDetails() == 0 ) {
\r
2917 int ret = JOptOptionPane.showConfirmDialog(stwin, "<HTML>詳細情報を取得しますか?(時間がかかります)<BR><BR>"+recorder.Myself()+"</HTML>", "今回の選択を既定の動作とする", "※既定動作は各種設定で変更できます", "確認", JOptionPane.YES_NO_OPTION);
\r
2918 skip = (ret != JOptOptionPane.YES_OPTION);
\r
2920 if ( JOptOptionPane.isSelected() ) {
\r
2922 env.setForceLoadReserveDetails(skip ? 2 : 1);
\r
2924 if (setting!=null) setting.updateSelections();
\r
2928 mwin.appendMessage("【!】予約詳細情報の取得はスキップされました");
\r
2932 if ( recorder.GetRdReserveDetails()) {
\r
2933 return true; // 取得成功
\r
2936 mwin.appendError(recorder.getErrmsg()+" "+recorder.Myself());
\r
2938 return false; // 取得失敗
\r
2941 private boolean _loadRdAutoReserves(HDDRecorder recorder, boolean force) {
\r
2943 if ( ! recorder.isEditAutoReserveSupported() ) {
\r
2947 boolean skip = false;
\r
2948 if ( force && env.getForceLoadAutoReserves() == 2 ) {
\r
2951 else if ( force && env.getForceLoadAutoReserves() == 0 ) {
\r
2952 int ret = JOptOptionPane.showConfirmDialog(stwin, "<HTML>自動予約一覧を取得しますか?(時間がかかります)<BR><BR>"+recorder.Myself()+"</HTML>", "今回の選択を既定の動作とする", "※既定動作は各種設定で変更できます", "確認", JOptionPane.YES_NO_OPTION);
\r
2953 skip = (ret != JOptOptionPane.YES_OPTION);
\r
2955 if ( JOptOptionPane.isSelected() ) {
\r
2957 env.setForceLoadAutoReserves(skip ? 2 : 1);
\r
2959 if (setting!=null) setting.updateSelections();
\r
2963 mwin.appendMessage("【!】自動予約一覧の取得はスキップされました");
\r
2967 if ( recorder.GetRdAutoReserve(force) ) {
\r
2971 mwin.appendError(recorder.getErrmsg()+" "+recorder.Myself());
\r
2976 private boolean _loadRdRecorded(HDDRecorder recorder, boolean force) {
\r
2978 if ( ! recorder.isRecordedListSupported() ) {
\r
2982 boolean skip = false;
\r
2983 if ( force && env.getForceLoadRecorded() == 2 ) {
\r
2986 if ( force && env.getForceLoadRecorded() == 0 ) {
\r
2987 int ret = JOptOptionPane.showConfirmDialog(stwin, "<HTML>録画結果一覧を取得しますか?(時間がかかります)<BR><BR>"+recorder.Myself()+"</HTML>", "今回の選択を既定の動作とする", "※既定動作は各種設定で変更できます", "確認", JOptionPane.YES_NO_OPTION);
\r
2988 skip = (ret != JOptOptionPane.YES_OPTION);
\r
2990 if ( JOptOptionPane.isSelected() ) {
\r
2992 env.setForceLoadRecorded(skip ? 2 : 1);
\r
2994 if (setting!=null) setting.updateSelections();
\r
2998 mwin.appendMessage("【!】録画結果一覧の取得はスキップされました");
\r
3002 if ( recorder.GetRdRecorded(force) ) {
\r
3006 mwin.appendError(recorder.getErrmsg()+" "+recorder.Myself());
\r
3012 * レコーダから取得したエンコーダ情報で、登録済みレコーダ一覧を更新する
\r
3015 private void setEncoderInfo2RecorderList(HDDRecorder recorder, boolean force) {
\r
3016 for (RecorderInfo ri : recInfoList ) {
\r
3017 //if (rl.getRecorderEncoderList().size() == 0)
\r
3019 //String mySelf = ri.getRecorderIPAddr()+":"+ri.getRecorderPortNo()+":"+ri.getRecorderId();
\r
3020 //String myMail = "MAIL"+":"+ri.getRecorderMacAddr()+":"+ri.getRecorderId();
\r
3021 //if (recorder.isMyself(mySelf) || recorder.isMyself(myMail)) {
\r
3022 if ( recorder.isMyself(ri.MySelf()) ) {
\r
3023 ri.clearEncoders();
\r
3024 for (TextValueSet enc : recorder.getEncoderList()) {
\r
3025 ri.addEncoder(enc.getText());
\r
3029 recInfoList.save();
\r
3038 * 予約一覧の放送局名が正しい形式であるかどうかのチェック
\r
3040 private void checkChNameIsRight(HDDRecorder recorder) {
\r
3041 HashMap<String,String> misCN = new HashMap<String,String>();
\r
3042 for ( ReserveList r : recorder.getReserves() ) {
\r
3043 if ( r.getCh_name() == null ) {
\r
3044 misCN.put(r.getChannel(),recorder.getRecorderId());
\r
3047 if ( misCN.size() > 0 ) {
\r
3048 for ( String cn : misCN.keySet() ) {
\r
3049 String msg = "【警告(予約一覧)】 <"+misCN.get(cn)+"> \"レコーダの放送局名\"を\"Web番組表の放送局名\"に変換できません。CHコード設定に設定を追加してください:\"レコーダの放送局名\"="+cn;
\r
3050 mwin.appendMessage(msg);
\r
3056 /*******************************************************************************
\r
3058 ******************************************************************************/
\r
3060 /***************************************
\r
3061 * ツールバートリガー(と、各種設定変更トリガー)による
\r
3062 **************************************/
\r
3066 * <P>単体実行の場合はこちらを呼び出す
\r
3067 * <P>部品実行の場合はこちらを呼び出す:{@link #loadTVProgram(boolean, LoadFor)}
\r
3068 * @see #doRedrawTVProgram()
\r
3070 private boolean doLoadTVProgram(final boolean force, final LoadFor lf) {
\r
3074 new SwingBackgroundWorker(false) {
\r
3077 protected Object doWorks() throws Exception {
\r
3079 TatCount tc = new TatCount();
\r
3081 loadTVProgram(force, lf);
\r
3083 mwin.appendMessage(String.format("[Web番組表取得] 【完了しました】 所要時間: %.2f秒",tc.end()));
\r
3088 protected void doFinally() {
\r
3089 StWinSetVisible(false);
\r
3093 StWinSetLocationCenter(this);
\r
3094 StWinSetVisible(true);
\r
3101 * @see #doLoadTVProgram(boolean, LoadFor)
\r
3103 private void doRedrawTVProgram() {
\r
3106 paper.clearPanel();
\r
3107 paper.buildMainViewByDate();
\r
3110 paper.redrawTreeByDate();
\r
3111 paper.redrawTreeByPassed();
\r
3113 listed.redrawTreeByHistory();
\r
3114 listed.redrawTreeByCenter();
\r
3117 paper.reselectTree();
\r
3118 listed.reselectTree();
\r
3121 /***************************************
\r
3123 **************************************/
\r
3127 * <P>単体実行の場合はこちらを呼び出す:{@link #doLoadTVProgram(LoadFor)}
\r
3128 * <P>部品実行の場合はこちらを呼び出す
\r
3130 private boolean loadTVProgram(final boolean force, final LoadFor lf) {
\r
3132 final String FUNCID = "[Web番組表取得] ";
\r
3133 final String ERRID = "[ERROR]"+FUNCID;
\r
3139 tvp = tvprograms.getTvProgPlugin(null);
\r
3140 if ( tvp != null )
\r
3142 String sType = "地上波&BS番組表";
\r
3143 if (lf == LoadFor.ALL || lf == LoadFor.TERRA) {
\r
3144 loadTVProgramOnce(tvp, sType, tvp.getSelectedArea(), false, force);
\r
3147 stwin.appendMessage(FUNCID+sType+"へのアクセスはスキップされました: "+tvp.getTVProgramId());
\r
3151 tvp = tvprograms.getCsProgPlugin(null);
\r
3152 if ( tvp != null )
\r
3154 String sType = "CS番組表[プライマリ]";
\r
3155 if (lf == LoadFor.ALL || lf == LoadFor.CS || lf == LoadFor.CSo1 || lf == LoadFor.CSwSD) {
\r
3156 loadTVProgramOnce(tvp, sType, tvp.getSelectedArea(), false, force);
\r
3159 stwin.appendMessage(FUNCID+sType+"へのアクセスはスキップされました: "+tvp.getTVProgramId());
\r
3163 tvp = tvprograms.getCs2ProgPlugin(null);
\r
3164 if ( tvp != null )
\r
3166 String sType = "CS番組表[セカンダリ]";
\r
3167 if (lf == LoadFor.ALL || lf == LoadFor.CS || lf == LoadFor.CSo2 || lf == LoadFor.CSwSD) {
\r
3168 loadTVProgramOnce(tvp, sType, tvp.getSelectedArea(), false, force);
\r
3171 stwin.appendMessage(FUNCID+sType+"へのアクセスはスキップされました: "+tvp.getTVProgramId());
\r
3175 tvp = tvprograms.getSyobo();
\r
3176 if ( tvp != null ) {
\r
3177 String sType = "しょぼかる";
\r
3178 if ( (lf == LoadFor.ALL || lf == LoadFor.SYOBO) && enableWebAccess && env.getUseSyobocal()) {
\r
3179 tvp.loadCenter(tvp.getSelectedCode(), force); // しょぼかるには放送局リストを取得するイベントが他にないので
\r
3180 loadTVProgramOnce(tvp, sType, null, true, force);
\r
3183 stwin.appendMessage(FUNCID+sType+"へのアクセスはスキップされました.");
\r
3186 // しょぼかるの新番組マークを引き継ぐ
\r
3190 PickedProgram pickup = tvprograms.getPickup();
\r
3191 if ( tvp != null ) {
\r
3201 stwin.appendMessage(FUNCID+"検索結果を生成します.");
\r
3202 mpList.clear(env.getDisableFazzySearch(), env.getDisableFazzySearchReverse());
\r
3203 mpList.build(tvprograms, trKeys.getTraceKeys(), srKeys.getSearchKeys());
\r
3206 if ( env.getUsePassedProgram() ) {
\r
3207 TatCount tc = new TatCount();
\r
3208 stwin.appendMessage(FUNCID+"過去ログを生成します.");
\r
3209 if ( tvprograms.getPassed().save(tvprograms.getIterator(), chsort.getClst(), env.getPrepPassedProgramCount()) ) {
\r
3210 msg = String.format(FUNCID+"過去ログを生成しました [%.2f秒].",tc.end());
\r
3211 StdAppendMessage(msg);
\r
3213 //PassedProgramList.getDateList(env.getPassedLogLimit());
\r
3216 stwin.appendMessage(FUNCID+"過去ログは記録されません.");
\r
3219 catch (Exception e) {
\r
3220 e.printStackTrace();
\r
3221 mwin.appendError(ERRID+"番組情報の取得で例外が発生");
\r
3230 private void loadTVProgramOnce(TVProgram tvp, String sType, String aName, boolean loadonly, boolean force) {
\r
3232 final String FUNCID = "[Web番組表取得] ";
\r
3233 // final String ERRID = "[ERROR]"+FUNCID;
\r
3236 String msg = FUNCID+sType+"を取得します: "+tvp.getTVProgramId();
\r
3237 stwin.appendMessage(msg);
\r
3238 if (aName!=null) stwin.appendMessage(FUNCID+"+選択されているエリア="+aName);
\r
3241 //tvp.setProgressArea(stwin);
\r
3242 tvp.loadProgram(tvp.getSelectedCode(), force);
\r
3249 tvp.setExtension(null, null, false, extKeys.getSearchKeys()); // 最初の3引数は盲腸。ダミー
\r
3251 tvp.abon(env.getNgword());
\r
3253 String errmsg = tvp.chkComplete();
\r
3254 if (errmsg != null) {
\r
3255 stwin.appendError(FUNCID+"取得した情報が不正です:"+errmsg);
\r
3256 if (mainWindow!=null) mwin.appendMessage(msg);
\r
3261 // しょぼかるの番組詳細を番組表に反映する
\r
3262 private void attachSyoboNew() {
\r
3263 TVProgram syobo = tvprograms.getSyobo();
\r
3264 if (syobo == null) {
\r
3268 for ( TVProgram tvp : tvprograms ) {
\r
3270 if ( tvp.getType() != ProgType.PROG ) {
\r
3273 if ( ! (tvp.getSubtype() == ProgSubtype.TERRA || tvp.getSubtype() == ProgSubtype.CS || tvp.getSubtype() == ProgSubtype.CS2) ) {
\r
3277 for ( ProgList tvpl : tvp.getCenters() ) {
\r
3278 if ( ! tvpl.enabled) {
\r
3281 for ( ProgList svpl : syobo.getCenters() ) {
\r
3282 if ( ! tvpl.Center.equals(svpl.Center)) {
\r
3285 for ( ProgDateList tvc : tvpl.pdate ) {
\r
3287 ProgDateList mSvc = null;
\r
3288 for ( ProgDateList svc : svpl.pdate ) {
\r
3289 if (tvc.Date.equals(svc.Date) ) {
\r
3294 if (mSvc == null) {
\r
3295 // しょぼかる側に該当する日付自体ないので全部フラグを立てっぱなしでいい
\r
3296 for ( ProgDetailList tvd : tvc.pdetail ) {
\r
3297 if ( tvd.isEqualsGenre(ProgGenre.ANIME, null) ) {
\r
3298 tvd.addOption(ProgOption.NOSYOBO);
\r
3303 // しょぼかる側に該当する日付があるのでマッチング。アニメと映画と音楽
\r
3304 for ( ProgDetailList tvd : tvc.pdetail ) {
\r
3306 // アニメはいったんフラグを立てる
\r
3307 if ( tvd.isEqualsGenre(ProgGenre.ANIME, null) ) {
\r
3308 tvd.addOption(ProgOption.NOSYOBO);
\r
3311 boolean isFind = false;
\r
3312 for ( ProgDetailList svd : mSvc.pdetail ) {
\r
3313 if ( tvd.start.equals(svd.start) ) {
\r
3317 //svd.progid = tvd.progid;
\r
3318 svd.setContentIdStr();
\r
3321 boolean isAnime = tvd.isEqualsGenre(ProgGenre.ANIME, null);
\r
3322 if ( ! isAnime && ! tvd.isEqualsGenre(ProgGenre.MOVIE, null) && ! tvd.isEqualsGenre(ProgGenre.MUSIC, null) ) {
\r
3329 // しょぼかるとWeb番組表の両方に存在する
\r
3330 svd.nosyobo = true;
\r
3334 boolean isAttached = false;
\r
3337 if ( svd.flag == ProgFlags.NEW && tvd.flag != ProgFlags.NEW ) {
\r
3338 tvd.flag = ProgFlags.NEW;
\r
3339 isAttached = true;
\r
3343 if ( svd.flag == ProgFlags.LAST && tvd.flag != ProgFlags.LAST ) {
\r
3344 tvd.flag = ProgFlags.LAST;
\r
3345 isAttached = true;
\r
3349 if ( tvd.isEqualsGenre(ProgGenre.MOVIE, null) && ! tvd.isEqualsGenre(ProgGenre.MOVIE, ProgSubgenre.MOVIE_ANIME) ) {
\r
3350 if ( tvd.genrelist == null ) {
\r
3351 tvd.genrelist = new ArrayList<ProgGenre>();
\r
3352 tvd.genrelist.add(tvd.genre);
\r
3353 tvd.genrelist.add(ProgGenre.MOVIE);
\r
3354 tvd.subgenrelist = new ArrayList<ProgSubgenre>();
\r
3355 tvd.subgenrelist.add(tvd.subgenre);
\r
3356 tvd.subgenrelist.add(ProgSubgenre.MOVIE_ANIME);
\r
3359 tvd.genrelist.add(ProgGenre.MOVIE);
\r
3360 tvd.subgenrelist.add(ProgSubgenre.MOVIE_ANIME);
\r
3362 isAttached = true;
\r
3366 for ( ProgOption sopt : svd.getOption() ) {
\r
3367 if ( tvd.addOption(sopt) && isAttached == false ) {
\r
3368 isAttached = true;
\r
3373 if (isAttached && env.getDebug()) {
\r
3374 StdAppendMessage("しょぼかるのフラグを引き継ぎました: ("+tvpl.Center+") "+tvd.title);
\r
3379 if ( tvd.detail.length() < svd.detail.length() ) {
\r
3380 tvd.detail = svd.detail;
\r
3383 int idx = svd.detail.indexOf("<!");
\r
3385 tvd.detail += svd.detail.substring(idx);
\r
3389 // 「しょぼかるにのみ存在」フラグの上げ下げ(これはアニメ限定)
\r
3392 tvd.removeOption(ProgOption.NOSYOBO); // NOSYOBOって…
\r
3395 //tvd.addOption(ProgOption.NOSYOBO);
\r
3412 private void fixTitle() {
\r
3413 // 番組追跡からサブタイトルを除外するかどうかのフラグ
\r
3414 ProgDetailList.tracenOnlyTitle = env.getFixTitle() && env.getTraceOnlyTitle();
\r
3416 if ( ! env.getFixTitle()) {
\r
3420 for ( TVProgram tvp : tvprograms ) {
\r
3421 //if ( ! (tvp.getType() == ProgType.PROG && tvp.getSubtype() == ProgSubtype.TERRA) ) {
\r
3422 if ( tvp.getType() != ProgType.PROG ) {
\r
3426 for ( ProgList pl : tvp.getCenters() ) {
\r
3427 if ( ! pl.enabled ) {
\r
3431 for ( ProgDateList pcl : pl.pdate ) {
\r
3433 for ( ProgDetailList tvd : pcl.pdetail ) {
\r
3434 if ( tvd.isEqualsGenre(ProgGenre.ANIME, null) ) {
\r
3435 if ( pl.Center.startsWith("NHK") || pl.Center.startsWith("NHK") ) {
\r
3436 // NHK系で先頭が「アニメ 」ではじまるものから「アニメ 」を削除する
\r
3437 tvd.title = tvd.title.replaceFirst("^アニメ[ ・]+","");
\r
3438 tvd.titlePop = TraceProgram.replacePop(tvd.title);
\r
3440 if ( tvd.title.contains("コメンタリ") || tvd.detail.contains("コメンタリ") ) {
\r
3441 // "コメンタリ"の記述のあるものは「副音声」扱いにする(副音声でなくても)
\r
3442 tvd.option.add(ProgOption.MULTIVOICE);
\r
3444 if ( (tvd.title.contains("劇場版") || (tvd.detail.contains("映画") && ! tvd.detail.contains("映画館"))) && ! tvd.isEqualsGenre(ProgGenre.MOVIE, ProgSubgenre.MOVIE_ANIME) ) {
\r
3445 // ジャンル=アニメだがタイトルに「劇場版」が含まれるならジャンル=映画(アニメ映画)を追加する
\r
3446 if ( tvd.genrelist == null ) {
\r
3447 tvd.genrelist = new ArrayList<ProgGenre>();
\r
3448 tvd.genrelist.add(tvd.genre);
\r
3449 tvd.genrelist.add(ProgGenre.MOVIE);
\r
3450 tvd.subgenrelist = new ArrayList<ProgSubgenre>();
\r
3451 tvd.subgenrelist.add(tvd.subgenre);
\r
3452 tvd.subgenrelist.add(ProgSubgenre.MOVIE_ANIME);
\r
3455 tvd.genrelist.add(ProgGenre.MOVIE);
\r
3456 tvd.subgenrelist.add(ProgSubgenre.MOVIE_ANIME);
\r
3460 else if ( tvd.isEqualsGenre(ProgGenre.MOVIE, ProgSubgenre.MOVIE_ANIME) && tvd.subgenre != ProgSubgenre.MOVIE_ANIME ) {
\r
3461 // ジャンル=映画でサブジャンルが複数ありアニメが優先されてないものはアニメを優先する
\r
3462 tvd.subgenre = ProgSubgenre.MOVIE_ANIME;
\r
3471 * {@link ProgDetailList} の情報を整形する
\r
3473 private void fixDetail() {
\r
3474 for ( TVProgram tvp : tvprograms ) {
\r
3475 for ( ProgList pl : tvp.getCenters() ) {
\r
3476 if ( ! pl.enabled ) {
\r
3479 for ( ProgDateList pcl : pl.pdate ) {
\r
3480 for ( ProgDetailList tvd : pcl.pdetail ) {
\r
3481 if ( tvd.start == null || tvd.start.length() == 0 ) {
\r
3485 fixDetailSub(tvp, pl, tvd);
\r
3492 private void fixDetailSub(TVProgram tvp, ProgList pl, ProgDetailList tvd) {
\r
3493 tvd.type = tvp.getType();
\r
3494 tvd.subtype = tvp.getSubtype();
\r
3495 tvd.center = pl.Center;
\r
3497 tvd.recmin = CommonUtils.getRecMinVal(tvd.startDateTime, tvd.endDateTime);
\r
3499 tvd.extension_mark = markchar.getExtensionMark(tvd);
\r
3500 tvd.prefix_mark = markchar.getOptionMark(tvd);
\r
3501 tvd.newlast_mark = markchar.getNewLastMark(tvd);
\r
3502 tvd.postfix_mark = markchar.getPostfixMark(tvd);
\r
3504 tvd.dontoverlapdown = (tvd.center.startsWith("NHK") || tvd.center.startsWith("NHK"));
\r
3508 /*******************************************************************************
\r
3510 ******************************************************************************/
\r
3513 * <P>過去ログから検索キーワードにマッチする情報を取得する
\r
3514 * <P>全部検索がヒットした結果がかえるのだから {@link ProgDetailList} ではなく {@link MarkedProgramList} を使うべきなのだが…
\r
3516 private boolean searchPassedProgram(final SearchKey sKey, final String target) {
\r
3518 Matcher ma = Pattern.compile("^(\\d\\d\\d\\d/\\d\\d/\\d\\d)-(\\d\\d\\d\\d/\\d\\d/\\d\\d)$").matcher(target);
\r
3519 if ( ! ma.find() ) {
\r
3523 final GregorianCalendar s = CommonUtils.getCalendar(ma.group(1));
\r
3524 final GregorianCalendar e = CommonUtils.getCalendar(ma.group(2));
\r
3525 final long dDays = (e.getTimeInMillis() - s.getTimeInMillis())/86400000 + 1;
\r
3527 final ArrayList<ProgDetailList> srchpdl = tvprograms.getSearched().getResultBuffer(sKey.getLabel()) ;
\r
3531 // 検索実行(時間がかかるので状況表示する)
\r
3532 new SwingBackgroundWorker(false) {
\r
3535 protected Object doWorks() throws Exception {
\r
3537 TatCount tc = new TatCount();
\r
3540 int resultCnt = 0;
\r
3541 for (int cnt=1; cnt<=dDays; cnt++) {
\r
3543 String passdt = CommonUtils.getDate(e);
\r
3544 stwin.appendMessage(String.format("[過去ログ検索] 検索中:(%d/%d) %s", cnt, dDays, passdt));
\r
3546 PassedProgram tvp = new PassedProgram();
\r
3547 if ( tvp.loadAllCenters(passdt) ) {
\r
3548 for ( ProgList pl : tvp.getCenters() ) {
\r
3549 if ( ! pl.enabled ) {
\r
3553 for ( ProgDateList pcl : pl.pdate ) {
\r
3554 for ( ProgDetailList tvd : pcl.pdetail ) {
\r
3555 if ( tvd.start == null || tvd.start.length() == 0 ) {
\r
3559 if ( SearchProgram.isMatchKeyword(sKey, pl.Center, tvd) ) {
\r
3560 tvd.dynKey = sKey;
\r
3561 tvd.dynMatched = SearchProgram.getMatchedString();
\r
3562 fixDetailSub(tvp, pl, tvd);
\r
3564 if ( ++resultCnt >= env.getSearchResultMax() ) {
\r
3565 mwin.appendMessage(String.format("[過去ログ検索] 検索件数の上限に到達しました。所要時間: %.2f秒",tc.end()));
\r
3574 e.add(Calendar.DATE,-1);
\r
3577 mwin.appendMessage(String.format("[過去ログ検索] 検索完了。所要時間: %.2f秒",tc.end()));
\r
3582 protected void doFinally() {
\r
3583 StWinSetVisible(false);
\r
3587 StWinSetLocationCenter(this);
\r
3588 StWinSetVisible(true);
\r
3594 /*******************************************************************************
\r
3596 ******************************************************************************/
\r
3599 * 番組表のスナップショットをファイルに保存したり印刷したりする
\r
3601 private boolean getSnapshot(int currentpage, int numberofpages) {
\r
3605 if ( mainWindow.isTabSelected(MWinTab.LISTED) ) {
\r
3607 fname = String.format("snapshot.%s",env.getSnapshotFmt().getExtension());
\r
3608 CommonSwingUtils.saveComponentAsJPEG(listed.getCurrentView(), listed.getTableHeader(), null, listed.getTableBody(), fname, env.getSnapshotFmt(), Viewer.this);
\r
3610 else if ( mainWindow.isTabSelected(MWinTab.PAPER) ){
\r
3612 if ( env.getDrawcacheEnable() || ! env.isPagerEnabled() ) {
\r
3613 fname = String.format("snapshot.%s",env.getSnapshotFmt().getExtension());
\r
3616 if ( env.getAllPageSnapshot() ) {
\r
3617 for ( int i=0; i<numberofpages; i++ ) {
\r
3618 if ( i != currentpage ) {
\r
3619 // カレントページは最後にスナップる(再描画を1回で済ませるため)
\r
3620 toolBar.setSelectedPagerIndex(i);
\r
3621 fname = String.format("snapshot%02d.%s",i+1,env.getSnapshotFmt().getExtension());
\r
3622 CommonSwingUtils.saveComponentAsJPEG(paper.getCurrentView(), paper.getCenterPane(), paper.getTimebarPane(), paper.getCurrentPane(), fname, env.getSnapshotFmt(), Viewer.this);
\r
3626 fname = String.format("snapshot%02d.%s",currentpage+1,env.getSnapshotFmt().getExtension());
\r
3627 toolBar.setSelectedPagerIndex(currentpage);
\r
3629 CommonSwingUtils.saveComponentAsJPEG(paper.getCurrentView(), paper.getCenterPane(), paper.getTimebarPane(), paper.getCurrentPane(), fname, env.getSnapshotFmt(), Viewer.this);
\r
3636 Desktop desktop = Desktop.getDesktop();
\r
3637 if (env.getPrintSnapshot()) {
\r
3639 desktop.print(new File(fname));
\r
3643 String emsg = CommonUtils.openFile(fname);
\r
3644 if (emsg != null) {
\r
3645 mwin.appendError(emsg);
\r
3652 } catch (IOException e) {
\r
3653 e.printStackTrace();
\r
3660 /*******************************************************************************
\r
3661 * ここからおおむね初期化処理にかかわるメソッド群
\r
3662 ******************************************************************************/
\r
3667 private boolean setEnv(final boolean reload_prog) {
\r
3673 // CommonUtilsの設定変更
\r
3674 CommonUtils.setAdjLateNight(env.getAdjLateNight());
\r
3675 CommonUtils.setExpandTo8(env.getExpandTo8());
\r
3676 CommonUtils.setUseRundll32(env.getUseRundll32());
\r
3677 CommonUtils.setDisplayPassedReserve(env.getDisplayPassedReserve());
\r
3678 CommonUtils.setDebug(env.getDebug());
\r
3680 SwingBackgroundWorker.setDebug(env.getDebug());
\r
3683 toolBar.setDebug(env.getDebug());
\r
3684 autores.setDebug(env.getDebug());
\r
3685 rdialog.setDebug(env.getDebug());
\r
3687 // PassedProgramListの設定変更
\r
3688 tvprograms.getPassed().setPassedDir(env.getPassedDir());
\r
3691 for ( HDDRecorder rec : recorders ) {
\r
3693 setSettingRecPluginExt(rec, env);
\r
3697 setSettingProgPluginCommon(env);
\r
3700 setSettingProgPluginAll(env);
\r
3703 toolBar.updateReloadReservedExtension();
\r
3704 toolBar.updateReloadProgramExtension();
\r
3706 // ページャーコンボボックスの書き換え
\r
3707 toolBar.setPagerItems();
\r
3710 listed.setMarkColumnVisible(env.getSplitMarkAndTitle());
\r
3711 listed.setDetailColumnVisible(env.getShowDetailOnList());
\r
3712 listed.setRowHeaderVisible(env.getRowHeaderVisible());
\r
3713 reserved.setRowHeaderVisible(env.getRowHeaderVisible());
\r
3716 listed.setMatchedKeywordColor(env.getMatchedKeywordColor());
\r
3717 listed.setRsvdLineColor((env.getRsvdLineEnhance())?(env.getRsvdLineColor()):(null));
\r
3718 listed.setPickedLineColor((env.getRsvdLineEnhance())?(env.getPickedLineColor()):(null));
\r
3719 listed.setCurrentLineColor((env.getCurrentLineEnhance())?(env.getCurrentLineColor()):(null));
\r
3722 setTrayIconVisible(env.getShowSysTray());
\r
3723 setXButtonAction(env.getShowSysTray() && env.getHideToTray());
\r
3725 // 新聞形式のツールチップの表示時間を変更する
\r
3726 setTooltipDelay();
\r
3729 if ( reload_prog ) {
\r
3730 loadTVProgram(false, LoadFor.ALL); // 部品呼び出し
\r
3734 mpList.setHistoryOnlyUpdateOnce(env.getHistoryOnlyUpdateOnce());
\r
3735 mpList.setShowOnlyNonrepeated(env.getShowOnlyNonrepeated());
\r
3737 doRedrawTVProgram(); // か き な お し
\r
3743 private void getTrayIcon() {
\r
3744 if ( trayicon != null ) {
\r
3749 Image image = ImageIO.read(new File(ICONFILE_SYSTRAY));
\r
3750 trayicon = new TrayIcon(image,"Tainavi");
\r
3752 final Viewer thisClass = this;
\r
3755 PopupMenu popup = new PopupMenu();
\r
3757 MenuItem item = new MenuItem("開く");
\r
3758 item.addActionListener(new ActionListener() {
\r
3760 public void actionPerformed(ActionEvent e) {
\r
3761 thisClass.setVisible(true);
\r
3762 thisClass.setState(Frame.NORMAL);
\r
3768 MenuItem item = new MenuItem("終了する");
\r
3769 item.addActionListener(new ActionListener() {
\r
3771 public void actionPerformed(ActionEvent e) {
\r
3778 trayicon.setPopupMenu(popup);
\r
3781 trayicon.addMouseListener(new MouseAdapter() {
\r
3783 public void mouseClicked(MouseEvent e) {
\r
3784 if (e.getButton() == MouseEvent.BUTTON1) {
\r
3785 thisClass.setVisible(true);
\r
3786 thisClass.setState(Frame.NORMAL);
\r
3791 } catch (IOException e) {
\r
3792 StdAppendError("アイコンファイルが読み込めませんでした: "+ICONFILE_SYSTRAY);
\r
3793 e.printStackTrace();
\r
3796 private void setTrayIconVisible(boolean b) {
\r
3798 if ( ! SystemTray.isSupported() || trayicon == null ) {
\r
3805 SystemTray.getSystemTray().remove(trayicon);
\r
3806 SystemTray.getSystemTray().add(trayicon);
\r
3810 SystemTray.getSystemTray().remove(trayicon);
\r
3812 } catch (AWTException e) {
\r
3813 e.printStackTrace();
\r
3816 private void HideToTray() {
\r
3817 if ( SystemTray.isSupported() && trayicon != null && (env.getShowSysTray() && env.getHideToTray()) ) {
\r
3818 this.setVisible(false);
\r
3821 private void setXButtonAction(boolean b) {
\r
3823 this.setDefaultCloseOperation(JFrame.ICONIFIED);
\r
3826 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
\r
3831 private void procArgs(String[] args) {
\r
3833 for (String arg : args) {
\r
3836 if (arg.compareTo("-L") == 0) {
\r
3838 //logging = false;
\r
3840 else if (arg.compareTo("-L") == 0) {
\r
3844 else if (arg.compareTo("-w") == 0) {
\r
3846 runRecWakeup = true;
\r
3848 else if (arg.compareTo("-nowebaccess") == 0) {
\r
3849 // -nowebaccess : 起動時のWeb番組表へのアクセス無効
\r
3850 enableWebAccess = false;
\r
3852 else if (arg.compareTo("-proxy") == 0) {
\r
3853 // -proxy : Web番組表へのアクセスにProxy経由を強制する
\r
3856 else if (arg.compareTo("-loadrec") == 0) {
\r
3857 // -loadrec : 起動時にレコーダにアクセスする
\r
3858 runRecLoad = true;
\r
3860 else if (arg.compareTo("-onlyLoadProgram") == 0) {
\r
3861 // -onlyLoadProgram : 番組表の取得だけ行う
\r
3862 onlyLoadProgram = true;
\r
3866 String[] dat = arg.split(":");
\r
3867 if (dat.length == 1 ) {
\r
3870 } if (dat.length >= 2 ) {
\r
3880 // メインの環境設定ファイルを読みだす
\r
3881 private void loadEnvfile() {
\r
3882 StdAppendMessage("【環境設定】環境設定ファイルを読み込みます.");
\r
3886 // 引き続きその他の環境設定ファイルも読みだす
\r
3887 private void procEnvs() {
\r
3889 StdAppendMessage("【環境設定】環境設定ファイル類を読み込みます.");
\r
3895 recInfoList.load();
\r
3898 if (pxaddr != null) {
\r
3899 env.setUseProxy(true);
\r
3900 env.setProxyAddr(pxaddr);
\r
3901 env.setProxyPort(pxport);
\r
3904 // Cookieの処理を入れようとしたけど無理だった
\r
3907 CookieManager manager = new CookieManager();
\r
3908 manager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
\r
3909 CookieHandler.setDefault(manager);
\r
3916 // 深夜の帯予約の補正(一日前にずらす)
\r
3917 // 可能なら番組表を8日分取得する
\r
3918 // 【WIN】ファイルオープンにrundll32を使用する
\r
3919 CommonUtils.setAdjLateNight(env.getAdjLateNight());
\r
3920 CommonUtils.setExpandTo8(env.getExpandTo8());
\r
3921 CommonUtils.setUseRundll32(env.getUseRundll32());
\r
3922 CommonUtils.setDisplayPassedReserve(env.getDisplayPassedReserve());
\r
3923 CommonUtils.setDebug(env.getDebug());
\r
3925 SwingBackgroundWorker.setDebug(env.getDebug());
\r
3931 bounds.setLoaded(bounds.load());
\r
3949 // スポーツ延長警告のデフォルト設定のコードはもういらないので削除(3.15.4β)
\r
3951 // 簡易描画はもういらないので削除
\r
3958 private void chkDualBoot() {
\r
3959 if ( ! env.getOnlyOneInstance() ) {
\r
3963 if ( ! CommonUtils.getLock() ) {
\r
3969 Runtime.getRuntime().addShutdownHook(new Thread() {
\r
3970 public void run() {
\r
3971 // 鯛ナビ終了時にロックを解除する
\r
3972 CommonUtils.getUnlock();
\r
3978 private void chkVerUp() {
\r
3979 if ( ! enableWebAccess || onlyLoadProgram ) {
\r
3980 stwin.appendError("【オンラインアップデート】オンラインアップデートは無効です");
\r
3984 VWUpdate vu = new VWUpdate(stwin);
\r
3985 if ( ! vu.isExpired(env.getUpdateMethod()) ) {
\r
3986 // メッセージはVWUpdate内で出力されます
\r
3989 if ( doVerUp(vu) ) {
\r
3994 private boolean doVerUp(VWUpdate vu) {
\r
3995 UpdateResult res = vu.checkUpdate(VersionInfo.getVersion());
\r
3999 // 履歴は更新しない(連続アップデートがあるかも知れないので)
\r
4000 LogViewer lv = new LogViewer(HISTORY_FILE);
\r
4001 lv.setModal(true);
\r
4002 lv.setCaretPosition(0);
\r
4003 lv.setVisible(true);
\r
4007 // 履歴は更新しない(次回に持ち越し)
\r
4011 vu.updateHistory();
\r
4015 // 履歴は更新しない(次回再挑戦)
\r
4022 * レコーダプラグインをすべて読み込みます。
\r
4024 private boolean loadRecPlugins() {
\r
4026 stwin.appendMessage("【レコーダプラグイン】プラグインを読み込みます.");
\r
4028 boolean isMailPluginEnabled = false;
\r
4030 Class.forName("javax.mail.Session");
\r
4031 isMailPluginEnabled = true;
\r
4033 catch ( Exception e ) {
\r
4034 System.err.println("【レコーダプラグイン】メール系プラグイン用の外部ライブラリがみつかりません: "+e.toString());
\r
4037 boolean isCalendarPluginEnabled = false;
\r
4039 Class.forName("com.google.gdata.client.calendar.CalendarService");
\r
4040 isCalendarPluginEnabled = true;
\r
4042 catch ( Exception e ) {
\r
4043 System.err.println("【レコーダプラグイン】カレンダー系プラグイン用の外部ライブラリがみつかりません: "+e.toString());
\r
4047 ArrayList<String> recIda = new ArrayList<String>();
\r
4048 for ( File f : new File(CommonUtils.joinPath(new String[]{"bin","tainavi"})).listFiles() ) {
\r
4049 Matcher ma = Pattern.compile("^(PlugIn_Rec[^$]+)[^$]*\\.class$").matcher(f.getName());
\r
4050 if ( ma.find() ) {
\r
4051 if ( ! isMailPluginEnabled && f.getName().toLowerCase().contains("mail") ) {
\r
4052 System.out.println("【レコーダプラグイン】メール系プラグインは無効です: "+f.getName());
\r
4055 if ( ! isCalendarPluginEnabled && f.getName().toLowerCase().contains("calendar") ) {
\r
4056 System.out.println("【レコーダプラグイン】カレンダー系プラグインは無効です: "+f.getName());
\r
4060 recIda.add(ma.group(1));
\r
4063 String[] recIdd = recIda.toArray(new String[0]);
\r
4064 Arrays.sort(recIdd);
\r
4067 StringBuilder sb = new StringBuilder();
\r
4068 for ( String recId : recIdd ) {
\r
4069 sb.append("tainavi.");
\r
4073 if ( ! CommonUtils.write2file(CommonUtils.joinPath(new String[] {"bin","META-INF","services","tainavi.HDDRecorder"}), sb.toString()) ) {
\r
4074 stwin.appendError("【レコーダプラグイン】プラグインの読み込みに失敗しました: ");
\r
4078 // ここで例外が起きてもトラップできない、スレッドが落ちる
\r
4079 ServiceLoader<HDDRecorder> r = ServiceLoader.load(HDDRecorder.class);
\r
4081 recPlugins.clear();
\r
4082 for ( HDDRecorder recorder : r ) {
\r
4083 if (env.getDebug()) {
\r
4084 StdAppendMessage("+追加します: "+recorder.getRecorderId());
\r
4086 recPlugins.add(recorder.clone());
\r
4087 StdAppendMessage("+追加しました: "+recorder.getRecorderId());
\r
4094 * レコーダ設定をもとにレコーダプラグインから実レコーダのインスタンスを生成します。
\r
4096 private void initRecPluginAll() {
\r
4098 recorders.clear();
\r
4099 for ( RecorderInfo ri : recInfoList ) {
\r
4100 ArrayList<HDDRecorder> rl = recPlugins.findPlugin(ri.getRecorderId());
\r
4101 if ( rl.size() == 0 ) {
\r
4102 stwin.appendError("【レコーダプラグイン】プラグインがみつかりません: "+ri.getRecorderId()+"("+ri.getRecorderIPAddr()+":"+ri.getRecorderPortNo()+")");
\r
4105 stwin.appendMessage("【レコーダプラグイン】プラグインを初期化します: "+ri.getRecorderId()+"("+ri.getRecorderIPAddr()+":"+ri.getRecorderPortNo()+")");
\r
4106 for ( HDDRecorder rPlugin : rl ) {
\r
4107 initRecPlugin(rPlugin, ri);
\r
4112 protected HDDRecorder initRecPlugin(HDDRecorder rPlugin, RecorderInfo ri) {
\r
4113 HDDRecorder rec = rPlugin.clone();
\r
4114 recorders.add(rec);
\r
4116 rec.getChCode().load(true); // true : ログ出力あり
\r
4117 setSettingRecPluginBase(rec, ri);
\r
4118 setSettingRecPluginExt(rec,env);
\r
4119 rec.setProgressArea(stwin);
\r
4122 protected void setSettingRecPluginBase(HDDRecorder to, RecorderInfo from) {
\r
4123 to.setIPAddr(from.getRecorderIPAddr());
\r
4124 to.setPortNo(from.getRecorderPortNo());
\r
4125 to.setUser(from.getRecorderUser());
\r
4126 to.setPasswd(from.getRecorderPasswd());
\r
4127 to.setMacAddr(from.getRecorderMacAddr());
\r
4128 to.setBroadcast(from.getRecorderBroadcast());
\r
4129 to.setUseCalendar(from.getUseCalendar());
\r
4130 to.setUseChChange(from.getUseChChange());
\r
4131 to.setRecordedCheckScope(from.getRecordedCheckScope());
\r
4132 to.setTunerNum(from.getTunerNum());
\r
4133 to.setColor(from.getRecorderColor());
\r
4135 protected void setSettingRecPluginExt(HDDRecorder recorder, Env nEnv) {
\r
4136 recorder.setUserAgent(nEnv.getUserAgent());
\r
4137 recorder.setDebug(nEnv.getDebug());
\r
4138 recorder.setAdjNotRep(nEnv.getAdjoiningNotRepetition());
\r
4139 recorder.setRecordedSaveScope(nEnv.getRecordedSaveScope());
\r
4143 protected void doRecWakeup() {
\r
4144 for ( HDDRecorder rec : recorders ) {
\r
4145 if ( ! rec.getMacAddr().equals("") && ! rec.getBroadcast().equals("") ) {
\r
4154 private boolean isOLPExpired(int expire) {
\r
4155 String fname = "env"+File.separator+"olp.history";
\r
4156 if ( ! new File(fname).exists() || ! new File(fname).canWrite() ) {
\r
4157 stwin.appendError("【警告】実行履歴ファイルがないから実行させないよ!");
\r
4161 String dat = CommonUtils.read4file(fname, true);
\r
4162 if ( dat == null ) {
\r
4163 stwin.appendError("【警告】実行履歴を取得できなかったから実行させないよ!");
\r
4167 GregorianCalendar ca = null;
\r
4168 dat = EncryptPassword.dec(b64.dec(dat));
\r
4169 if ( dat != null ) {
\r
4170 ca = CommonUtils.getCalendar(dat);
\r
4172 if ( ca == null ) {
\r
4173 stwin.appendError("【警告】実行履歴の内容が不正だったから実行させないよ! "+dat);
\r
4177 if ( CommonUtils.getCompareDateTime(ca, CommonUtils.getCalendar(-expire*3600)) >= 0 ) {
\r
4178 ca.add(Calendar.HOUR,expire);
\r
4179 stwin.appendError("【警告】"+expire+"時間以内の再実行は許さないよ!"+CommonUtils.getDateTime(ca)+"まで待って!");
\r
4183 if ( ! CommonUtils.write2file(fname, b64.enc(EncryptPassword.enc(CommonUtils.getDateTime(0)))) ) {
\r
4184 stwin.appendError("【警告】実行履歴を保存できなかったから実行させないよ!");
\r
4193 * Web番組表プラグインをすべて読み込みます。
\r
4195 private boolean loadProgPlugins() {
\r
4197 final String FUNCID = "[Web番組表プラグイン組込] ";
\r
4198 final String ERRID = "[ERROR]"+FUNCID;
\r
4201 stwin.appendMessage(FUNCID+"プラグインを読み込みます.");
\r
4204 setSettingProgPluginCommon(env);
\r
4210 // TVProgramListのインスタンスは別途初期化が必要
\r
4211 progPlugins.clear();
\r
4212 tvprograms.clear();
\r
4218 ArrayList<String> prgIda = new ArrayList<String>();
\r
4219 for ( File f : new File(CommonUtils.joinPath("bin","tainavi")).listFiles() ) {
\r
4220 Matcher ma = Pattern.compile("^(PlugIn_(TV|CS|RAD)P[^$]+)\\.class$").matcher(f.getName());
\r
4222 prgIda.add(ma.group(1));
\r
4225 String[] prgIdd = prgIda.toArray(new String[0]);
\r
4226 Arrays.sort(prgIdd);
\r
4229 StringBuilder sb = new StringBuilder();
\r
4230 for ( String prgId : prgIdd ) {
\r
4231 sb.append("tainavi.");
\r
4235 if ( ! CommonUtils.write2file(CommonUtils.joinPath("bin","META-INF","services","tainavi.TVProgram"), sb.toString()) ) {
\r
4236 stwin.appendError(ERRID+"プラグインの読み込みに失敗しました: ");
\r
4240 ServiceLoader<TVProgram> p = ServiceLoader.load(TVProgram.class);
\r
4242 // 実際必要ないのだが、プラグインのインスタンスはclone()して使う
\r
4243 for ( TVProgram pg : p ) {
\r
4244 TVProgram prog = pg.clone();
\r
4246 stwin.appendMessage("+追加しました: "+prog.getTVProgramId());
\r
4248 // CH設定タブではプラグイン側のインスタンスを使うので情報を追加してやる必要があるのであった
\r
4249 setSettingProgPlugin(prog, env);
\r
4251 progPlugins.add(prog);
\r
4260 * 設定にあわせてWeb番組表プラグインを絞り込みます。
\r
4262 private void setSelectedProgPlugin() {
\r
4265 Syobocal syobo = tvprograms.getSyobo();
\r
4266 PassedProgram passed = tvprograms.getPassed();
\r
4267 PickedProgram pickup = tvprograms.getPickup();
\r
4268 SearchResult searched = tvprograms.getSearched();
\r
4270 tvprograms.clear();
\r
4273 TVProgram tvp = progPlugins.getTvProgPlugin(env.getTVProgramSite());
\r
4274 if ( tvp == null ) {
\r
4275 // デフォルトもなければ先頭にあるもの
\r
4276 tvp = progPlugins.getTvProgPlugin(null);
\r
4278 if ( tvp == null ) {
\r
4280 StdAppendError("【Web番組表選択】地上波&BS番組表が選択されていません: "+env.getTVProgramSite());
\r
4283 StdAppendMessage("【Web番組表選択】地上波&BS番組表が選択されました: "+tvp.getTVProgramId());
\r
4284 tvprograms.add(tvp.clone());
\r
4288 TVProgram tvp = progPlugins.getCsProgPlugin(env.getCSProgramSite());
\r
4289 if ( tvp == null ) {
\r
4290 tvp = progPlugins.getCsProgPlugin(null);
\r
4292 if ( tvp == null ) {
\r
4293 StdAppendError("【Web番組表選択】CS番組表[プライマリ]が選択されていません: "+env.getCSProgramSite());
\r
4296 StdAppendMessage("【Web番組表選択】CS番組表[プライマリ]が選択されました: "+tvp.getTVProgramId());
\r
4297 tvprograms.add(tvp.clone());
\r
4301 TVProgram tvp = progPlugins.getCs2ProgPlugin(env.getCS2ProgramSite());
\r
4302 if ( tvp == null ) {
\r
4303 tvp = progPlugins.getCs2ProgPlugin(null);
\r
4305 if ( tvp == null ) {
\r
4306 StdAppendError("【Web番組表選択】CS番組表[プライマリ]が選択されていません: "+env.getCS2ProgramSite());
\r
4309 StdAppendMessage("【Web番組表選択】CS番組表[プライマリ]が選択されました: "+tvp.getTVProgramId());
\r
4310 tvprograms.add(tvp.clone());
\r
4314 if ( progPlugins.getRadioProgPlugins().size() > 0 )
\r
4316 TVProgram tvp = progPlugins.getCsProgPlugin(env.getRadioProgramSite());
\r
4317 if ( tvp == null ) {
\r
4318 tvp = progPlugins.getCsProgPlugin(null);
\r
4320 if ( tvp == null ) {
\r
4321 StdAppendError("【Web番組表選択】ラジオ番組表が選択されていません: "+env.getRadioProgramSite());
\r
4324 StdAppendMessage("【Web番組表選択】ラジオ番組表が選択されました: "+tvp.getTVProgramId());
\r
4325 tvprograms.add(tvp.clone());
\r
4331 if ( syobo == null ) {
\r
4332 syobo = new Syobocal();
\r
4334 tvprograms.add(syobo);
\r
4337 if ( passed == null ) {
\r
4338 passed = new PassedProgram();
\r
4340 tvprograms.add(passed);
\r
4343 if ( pickup == null ) {
\r
4344 pickup = new PickedProgram();
\r
4345 pickup.loadProgram(null, false);
\r
4347 tvprograms.add(pickup);
\r
4350 if ( searched == null ) {
\r
4351 searched = new SearchResult();
\r
4353 tvprograms.add(searched);
\r
4358 * Web番組表設定をもとにレコーダプラグインのインスタンスを生成します。
\r
4360 private void initProgPluginAll() {
\r
4362 final String FUNCID = "[Web番組表プラグイン初期化] ";
\r
4363 final LinkedHashMap<ArrayList<TVProgram>,String> map = new LinkedHashMap<ArrayList<TVProgram>, String>();
\r
4364 map.put(tvprograms.getTvProgPlugins(), "地上波&BS番組表");
\r
4365 map.put(tvprograms.getCsProgPlugins(), "CS番組表[プライマリ]");
\r
4366 map.put(tvprograms.getCs2ProgPlugins(), "CS番組表[セカンダリ]");
\r
4367 //map.put(progPlugins.getRadioProgPlugins(), "ラジオ番組表");
\r
4369 new SwingBackgroundWorker(true) {
\r
4372 protected Object doWorks() throws Exception {
\r
4374 for ( ArrayList<TVProgram> tvpa : map.keySet() ) {
\r
4375 stwin.appendMessage(FUNCID+map.get(tvpa)+"のベース情報(放送局リストなど)を取得します.");
\r
4376 for ( TVProgram p : tvpa ) {
\r
4377 stwin.appendMessage(FUNCID+"プラグインを初期化します: "+p.getTVProgramId());
\r
4380 // 個別設定(2) …(1)と(2)の順番が逆だったので前に移動してきました(3.17.3β)
\r
4381 setSettingProgPlugin(p,env); // 他からも呼び出される部分だけ分離
\r
4384 p.setOptString(null); // フリーオプション初期化
\r
4385 p.loadAreaCode(); // 放送エリア情報取得
\r
4386 p.loadCenter(p.getSelectedCode(),false); // 放送局情報取得
\r
4387 p.setSortedCRlist(); // 有効放送局だけよりわける
\r
4389 catch (Exception e) {
\r
4390 stwin.appendError(FUNCID+"ベース情報の取得に失敗しました.");
\r
4391 e.printStackTrace();
\r
4397 //setSettingProgPluginAll(env);
\r
4399 if ( env.getUseSyobocal() ) {
\r
4400 TVProgram syobo = tvprograms.getSyobo();
\r
4401 if ( syobo != null ) {
\r
4402 stwin.appendMessage(FUNCID+"しょぼかるを初期化します.");
\r
4403 setSettingProgPlugin(syobo,env); // 他からも呼び出される部分だけ分離
\r
4404 syobo.setUserAgent("tainavi");
\r
4405 syobo.setOptString(null); // フリーオプション初期化
\r
4406 syobo.loadCenter(syobo.getSelectedCode(), false);
\r
4414 protected void doFinally() {
\r
4418 protected void setSettingProgPluginAll(Env nEnv) {
\r
4420 setSettingProgPlugin(tvprograms.getTvProgPlugin(null),nEnv);
\r
4421 setSettingProgPlugin(tvprograms.getCsProgPlugin(null),nEnv);
\r
4422 setSettingProgPlugin(tvprograms.getCs2ProgPlugin(null),nEnv);
\r
4423 //setSettingProgPlugin(tvprograms.getRadioProgPlugin(null),nEnv);
\r
4424 setSettingProgPlugin(tvprograms.getSyobo(),nEnv);
\r
4427 tvprograms.getSyobo().setUserAgent("tainavi");
\r
4429 tvprograms.getSearched().setResultBufferMax(nEnv.getSearchResultBufferMax());
\r
4431 protected void setSettingProgPlugin(TVProgram p, Env nEnv) {
\r
4432 if ( p == null ) {
\r
4435 p.setUserAgent(nEnv.getUserAgent());
\r
4436 p.setProgDir(nEnv.getProgDir());
\r
4437 p.setCacheExpired((enableWebAccess)?(nEnv.getCacheTimeLimit()):(0));
\r
4438 p.setContinueTomorrow(nEnv.getContinueTomorrow());
\r
4439 p.setExpandTo8(nEnv.getExpandTo8());
\r
4440 //p.setUseDetailCache(nEnv.getUseDetailCache());
\r
4441 p.setUseDetailCache(false);
\r
4442 p.setSplitEpno(nEnv.getSplitEpno());
\r
4446 * staticで持っている共通設定の更新
\r
4448 protected void setSettingProgPluginCommon(Env nEnv) {
\r
4450 if ( nEnv.getUseProxy() && (nEnv.getProxyAddr().length() > 0 && nEnv.getProxyPort().length() > 0) ) {
\r
4451 stwin.appendMessage("+Web番組表へのアクセスにProxyが設定されています: "+nEnv.getProxyAddr()+":"+nEnv.getProxyPort());
\r
4452 TVProgramUtils.setProxy(nEnv.getProxyAddr(),nEnv.getProxyPort());
\r
4455 TVProgramUtils.setProxy(null,null);
\r
4458 TVProgramUtils.setProgressArea(stwin);
\r
4459 TVProgramUtils.setChConv(chconv);
\r
4463 private void initMpList() {
\r
4464 //mpList = new MarkedProgramList(); // 検索結果リスト
\r
4465 mpList.setHistoryOnlyUpdateOnce(env.getHistoryOnlyUpdateOnce());
\r
4466 mpList.setShowOnlyNonrepeated(env.getShowOnlyNonrepeated());
\r
4470 private void initLookAndFeelAndFont() {
\r
4474 vwlaf = new VWLookAndFeel();
\r
4476 String lafname = vwlaf.update(env.getLookAndFeel());
\r
4477 if ( lafname != null && ! lafname.equals(env.getLookAndFeel())) {
\r
4478 env.setLookAndFeel(lafname);
\r
4481 if ( CommonUtils.isMac() ) {
\r
4482 UIManager.getDefaults().put("Table.gridColor", new Color(128,128,128));
\r
4483 //UIManager.getDefaults().put("Table.selectionBackground", new Color(182,207,229));
\r
4484 //UIManager.getDefaults().put("Table.selectionForeground", new Color(0,0,0));
\r
4489 vwfont = new VWFont();
\r
4491 String fname = vwfont.update(env.getFontName(),env.getFontSize());
\r
4492 if ( fname != null && ! fname.equals(env.getFontName())) {
\r
4493 env.setFontName(fname);
\r
4497 catch ( Exception e ) {
\r
4498 // 落ちられると困るからトラップしておこうぜ
\r
4499 e.printStackTrace();
\r
4503 // L&FやFontを変えたらコンポーネントに通知が必要
\r
4504 protected void updateComponentTreeUI() {
\r
4506 SwingUtilities.updateComponentTreeUI(this);
\r
4507 SwingUtilities.updateComponentTreeUI(stwin);
\r
4508 SwingUtilities.updateComponentTreeUI(mwin);
\r
4509 SwingUtilities.updateComponentTreeUI(pcwin);
\r
4510 SwingUtilities.updateComponentTreeUI(rdialog);
\r
4511 SwingUtilities.updateComponentTreeUI(ccwin);
\r
4513 catch ( Exception e ) {
\r
4514 // 落ちられると困るからトラップしておこうぜ
\r
4515 e.printStackTrace();
\r
4519 // ツールチップの表示遅延時間を設定する
\r
4520 private void setTooltipDelay() {
\r
4521 ToolTipManager tp = ToolTipManager.sharedInstance();
\r
4522 tp.setInitialDelay(env.getTooltipInitialDelay()*100);
\r
4523 tp.setDismissDelay(env.getTooltipDismissDelay()*100);
\r
4528 * @return true:前回終了時の設定がある場合
\r
4530 private boolean buildMainWindow() {
\r
4535 mainWindow = new VWMainWindow();
\r
4538 toolBar = new VWToolBar();
\r
4539 listed = new VWListedView();
\r
4540 paper = new VWPaperView();
\r
4541 reserved = new VWReserveListView();
\r
4542 recorded = new VWRecordedListView();
\r
4543 autores = new VWAutoReserveListView();
\r
4544 setting = new VWSettingView();
\r
4545 recsetting = new VWRecorderSettingView();
\r
4546 chsetting = new VWChannelSettingView();
\r
4547 chdatsetting = new VWChannelDatSettingView();
\r
4548 chsortsetting = new VWChannelSortView();
\r
4549 chconvsetting = new VWChannelConvertView();
\r
4555 toolBar.setDebug(env.getDebug());
\r
4556 autores.setDebug(env.getDebug());
\r
4557 rdialog.setDebug(env.getDebug());
\r
4560 toolBar.setPagerItems();
\r
4566 mainWindow.addToolBar(toolBar);
\r
4567 mainWindow.addStatusArea(mwin);
\r
4570 mainWindow.addTab(listed, MWinTab.LISTED);
\r
4571 mainWindow.addTab(paper, MWinTab.PAPER);
\r
4572 mainWindow.addTab(reserved, MWinTab.RSVED);
\r
4573 mainWindow.addTab(recorded, MWinTab.RECED);
\r
4574 mainWindow.addTab(autores, MWinTab.AUTORES);
\r
4575 mainWindow.addTab(setting, MWinTab.SETTING);
\r
4576 mainWindow.addTab(recsetting, MWinTab.RECSET);
\r
4577 mainWindow.addTab(chsetting, MWinTab.CHSET);
\r
4578 mainWindow.addTab(chsortsetting, MWinTab.CHSORT);
\r
4579 mainWindow.addTab(chconvsetting, MWinTab.CHCONV);
\r
4580 mainWindow.addTab(chdatsetting, MWinTab.CHDAT);
\r
4584 setStatusVisible(bounds.getShowStatus());
\r
4587 paper.clearPanel();
\r
4588 paper.buildMainViewByDate();
\r
4593 private void ShowInitTab() {
\r
4596 mainWindow.setSelectedTab(null);
\r
4598 if ( recInfoList.size() <= 0 ) {
\r
4600 mainWindow.setSelectedTab(MWinTab.RECSET);
\r
4604 MWinTab tab = MWinTab.getAt(bounds.getSelectedTab());
\r
4605 mainWindow.setSelectedTab(tab);
\r
4610 private void setInitBounds() {
\r
4611 // ウィンドウのサイズと表示位置を設定する
\r
4612 Rectangle window = bounds.getWinRectangle();
\r
4613 if (bounds.isLoaded()) {
\r
4614 // 設定ファイルを読み込んであったらそれを設定する
\r
4615 System.out.println(DBGID+"set bounds "+window);
\r
4616 this.setBounds(window.x, window.y, window.width, window.height);
\r
4619 // 設定ファイルがなければ自動設定する
\r
4620 Rectangle screen = this.getGraphicsConfiguration().getBounds();
\r
4622 int w = window.width;
\r
4623 if (window.width > screen.width) {
\r
4628 x = (screen.width - window.width)/2;
\r
4631 int h = window.height;
\r
4632 if (window.height > screen.height) {
\r
4634 h = screen.height;
\r
4637 y = (screen.height - window.height)/2;
\r
4639 this.setBounds(x, y, w, h);
\r
4645 * {@link VWMainWindow#setStatusVisible(boolean)}の置き換え
\r
4647 private void setStatusVisible(boolean b) {
\r
4650 listed.setDetailVisible(true);
\r
4651 paper.setDetailVisible(true);
\r
4652 MWinSetVisible(true);
\r
4655 listed.setDetailVisible(false);
\r
4656 paper.setDetailVisible(false);
\r
4657 MWinSetVisible(false);
\r
4661 // フルスクリーンモードをトグル切り替え
\r
4662 private Dimension f_dim;
\r
4663 private Point f_pnt;
\r
4664 private int divloc_l = 0;
\r
4665 private int divloc_p = 0;
\r
4667 private void setFullScreen(boolean b) {
\r
4669 if ( b == true ) {
\r
4672 this.setUndecorated(true);
\r
4673 this.setVisible(true);
\r
4676 Toolkit tk = getToolkit();
\r
4677 Insets in = tk.getScreenInsets(getGraphicsConfiguration());
\r
4678 Dimension d = tk.getScreenSize();
\r
4679 f_dim = this.getSize();
\r
4680 f_pnt = this.getLocation();
\r
4681 this.setBounds(in.left, in.top, d.width-(in.left+in.right), d.height-(in.top+in.bottom));
\r
4683 divloc_l = bounds.getTreeWidth();
\r
4684 divloc_p = bounds.getTreeWidthPaper();
\r
4687 paper.setCollapseTree();
\r
4688 listed.setCollapseTree();
\r
4691 if ( f_pnt != null && f_dim != null ) { // 起動直後などは値がないですしね
\r
4695 this.setUndecorated(false);
\r
4696 this.setVisible(true);
\r
4699 this.setBounds(f_pnt.x, f_pnt.y, f_dim.width, f_dim.height);
\r
4701 bounds.setTreeWidth(divloc_l);
\r
4702 bounds.setTreeWidthPaper(divloc_p);
\r
4705 paper.setExpandTree();
\r
4706 listed.setExpandTree();
\r
4712 private void setTitleBar() {
\r
4713 MemoryMXBean mbean = ManagementFactory.getMemoryMXBean();
\r
4714 MemoryUsage heapUsage = mbean.getHeapMemoryUsage();
\r
4718 "%s - %s - Memory Usage Max:%dM Committed:%dM Used:%dM - FrameBuffer Status:%s",
\r
4719 VersionInfo.getVersion(),
\r
4720 CommonUtils.getDateTime(0),
\r
4721 heapUsage.getMax()/(1024*1024),
\r
4722 heapUsage.getCommitted()/(1024*1024),
\r
4723 heapUsage.getUsed()/(1024*1024),
\r
4724 (paper!=null)?(paper.getFrameBufferStatus()):("N/A")
\r
4730 private void ExitOnClose() {
\r
4732 if ( ! this.toolBar.isFullScreen()) {
\r
4733 Rectangle r = this.getBounds();
\r
4734 bounds.setWinRectangle(r);
\r
4737 Rectangle r = new Rectangle();
\r
4738 r.x = this.f_pnt.x;
\r
4739 r.y = this.f_pnt.y;
\r
4740 r.width = this.f_dim.width;
\r
4741 r.height = this.f_dim.height;
\r
4742 bounds.setWinRectangle(r);
\r
4744 listed.copyColumnWidth();
\r
4745 reserved.copyColumnWidth();
\r
4747 bounds.setStatusRows(mwin.getRows());
\r
4750 bounds.setSelectedTab(mainWindow.getSelectedTab().getIndex());
\r
4751 bounds.setShowSettingTabs(mainWindow.getShowSettingTabs());
\r
4752 bounds.setSelectedRecorderId(toolBar.getSelectedRecorder());
\r
4753 bounds.setShowStatus(toolBar.isStatusShown());
\r
4759 listed.saveTreeExpansion();
\r
4760 paper.saveTreeExpansion();
\r
4764 /*******************************************************************************
\r
4766 ******************************************************************************/
\r
4769 private static boolean initialized = false;
\r
4770 private static Viewer myClass = null;
\r
4775 * @throws NoSuchAlgorithmException
\r
4776 * @version 今まで初期化を行ってからウィンドウを作成していたが<BR>
\r
4777 * 途中で例外が起こるとダンマリの上にゾンビになってたりとヒドかったので<BR>
\r
4778 * 先にウィンドウを作成してから初期化を行うように変えました
\r
4779 * @throws InterruptedException
\r
4780 * @throws InvocationTargetException
\r
4782 public static void main(final String[] args) throws NoSuchAlgorithmException, InvocationTargetException, InterruptedException {
\r
4784 if ( myClass != null ) {
\r
4785 // 既に起動していたらフォアグラウンドにする
\r
4786 SwingUtilities.invokeAndWait(new Runnable() {
\r
4788 public void run() {
\r
4790 myClass.setVisible(true);
\r
4791 myClass.setState(Frame.NORMAL);
\r
4797 SwingUtilities.invokeLater(new Runnable() {
\r
4798 public void run() {
\r
4800 final Viewer thisClass = myClass = new Viewer(args);
\r
4802 thisClass.addComponentListener(new ComponentAdapter() {
\r
4804 public void componentShown(ComponentEvent e) {
\r
4807 thisClass.removeComponentListener(this);
\r
4810 thisClass.initialize(args);
\r
4815 thisClass.setVisible(true);
\r
4822 /*******************************************************************************
\r
4824 ******************************************************************************/
\r
4829 public Viewer(final String[] args) {
\r
4834 bounds.loadText();
\r
4837 // 初期化が終わるまでは閉じられないよ → どうせステータスウィンドウにブロックされて操作できない
\r
4838 //setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
\r
4839 //setResizable(false);
\r
4841 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
\r
4846 Image image = ImageIO.read(new File(ICONFILE_TAINAVI));
\r
4847 setIconImage(image);
\r
4849 catch (IOException e) {
\r
4850 StdAppendError("[ERROR] アイコンが設定できない: "+e.toString());
\r
4853 JLabel jLabel_splash_img = new JLabel(new ImageIcon("splash.gif"));
\r
4854 jLabel_splash_img.setPreferredSize(new Dimension(400,300));
\r
4855 //getContentPane().setLayout(new BorderLayout());
\r
4856 getContentPane().add(jLabel_splash_img, BorderLayout.CENTER);
\r
4859 setLocationRelativeTo(null); // 画面の真ん中に
\r
4861 // SwingLocker共有設定
\r
4862 SwingLocker.setOwner(this);
\r
4864 // とりあえずルックアンドフィールはリセットしておかないとだめっぽいよ
\r
4865 initLookAndFeelAndFont();
\r
4866 updateComponentTreeUI();
\r
4869 // 初期化をバックグラウンドで行う
\r
4870 private void initialize(final String[] args) {
\r
4874 // 初期化処理はバックグラウンドで行う
\r
4875 new SwingBackgroundWorker(false) {
\r
4878 protected Object doWorks() throws Exception {
\r
4880 TatCount tc = new TatCount();
\r
4883 _initialize(args);
\r
4885 // 終わったら閉じられるようにするよ
\r
4886 //setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
\r
4887 //setResizable(true);
\r
4890 stwin.appendMessage(String.format("【タイニー番組ナビゲータが起動しました】 所要時間: %.2f秒",tc.end()));
\r
4895 protected void doFinally() {
\r
4896 if ( ! initialized ) System.err.println("[ERROR][鯛ナビ] 【致命的エラー】 初期化処理を行っていたスレッドが異常終了しました。");
\r
4897 stwin.setClosingEnabled(false);
\r
4898 CommonUtils.milSleep(OPENING_WIAT);
\r
4899 StWinSetVisible(false);
\r
4903 StWinSetLocationUnder(this);
\r
4904 StWinSetVisible(true);
\r
4908 private void _initialize(final String[] args) {
\r
4913 // ログ出力を設定する(Windowsの場合は文字コードをMS932にする) →DOS窓を殺したので終了
\r
4914 System.setOut(new DebugPrintStream(System.out,LOG_FILE,logging));
\r
4915 System.setErr(new DebugPrintStream(System.err,LOG_FILE,logging));
\r
4918 StdAppendMessage("================================================================================");
\r
4919 StdAppendMessage("以下のメッセージは無視してください(原因調査中)");
\r
4920 StdAppendMessage("Exception occurred during event dispatching:");
\r
4921 StdAppendMessage(" java.lang.NullPointerException");
\r
4922 StdAppendMessage(" at javax.swing.plaf.basic.BasicScrollBarUI.layoutHScrollbar(Unknown Source)");
\r
4923 StdAppendMessage(" (以下略)");
\r
4924 StdAppendMessage("================================================================================");
\r
4925 stwin.appendMessage(CommonUtils.getDateTime(0));
\r
4926 stwin.appendMessage(String.format("タイニー番組ナビゲータが起動を開始しました(VersionInfo:%s on %s)",VersionInfo.getVersion(),VersionInfo.getEnvironment()));
\r
4928 // 起動時にアップデートを確認する
\r
4932 // メインの環境設定ファイルを読み込む
\r
4938 // その他の環境設定ファイルを読み込む
\r
4941 if ( onlyLoadProgram ) {
\r
4942 if ( ! isOLPExpired(4) ) {
\r
4943 CommonUtils.milSleep(3000);
\r
4947 loadProgPlugins();
\r
4949 setSelectedProgPlugin();
\r
4950 initProgPluginAll();
\r
4951 // 検索結果リストの初期化(loadTVProgram()中で使うので)
\r
4954 loadTVProgram(true,LoadFor.ALL);
\r
4955 stwin.appendMessage("番組表を取得したので終了します");
\r
4956 CommonUtils.milSleep(3000);
\r
4961 loadProgPlugins();
\r
4965 setSelectedProgPlugin();
\r
4966 initProgPluginAll();
\r
4968 initRecPluginAll();
\r
4971 if ( runRecWakeup ) {
\r
4975 // 検索結果リストの初期化(loadTVProgram()中で使うので)
\r
4979 loadTVProgram(false,LoadFor.ALL);
\r
4984 loadRdReservesAll(runRecLoad, null);
\r
4986 catch ( Exception e ) {
\r
4987 System.err.println("【致命的エラー】設定の初期化に失敗しました");
\r
4988 e.printStackTrace();
\r
4992 // 背景色設定ダイアログにフォント名の一覧を設定する
\r
4993 pcwin.setFontList(vwfont);
\r
4995 // (新聞形式の)ツールチップの表示時間を変更する
\r
4996 setTooltipDelay();
\r
5000 buildMainWindow();
\r
5002 catch ( Exception e ) {
\r
5003 System.err.println("【致命的エラー】ウィンドウの構築に失敗しました");
\r
5004 e.printStackTrace();
\r
5009 //int x = 2/0; // サブスレッドの突然死のトラップを確認するためのコード
\r
5014 setTrayIconVisible(env.getShowSysTray());
\r
5017 setXButtonAction(env.getShowSysTray() && env.getHideToTray());
\r
5020 this.addWindowListener(new WindowAdapter() {
\r
5021 // ウィンドウを最小化したときの処理
\r
5023 public void windowIconified(WindowEvent e) {
\r
5029 public void windowClosing(WindowEvent e) {
\r
5034 // 初回起動時はレコーダの登録を促す
\r
5035 if ( recorders.size() == 0 ) {
\r
5036 Container cp = getContentPane();
\r
5037 JOptionPane.showMessageDialog(cp, "レコーダが登録されていません。\n最初に登録を行ってください。\n番組表だけを使いたい場合は、\nNULLプラグインを登録してください。");
\r
5040 // ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
\r
5042 // ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
\r
5044 // [ツールバー/共通] レコーダ情報変更
\r
5045 toolBar.addHDDRecorderChangeListener(autores);
\r
5048 toolBar.addHDDRecorderSelectionListener(this); // 新聞形式
\r
5049 toolBar.addHDDRecorderSelectionListener(paper); // 新聞形式
\r
5050 toolBar.addHDDRecorderSelectionListener(autores); // 自動予約一覧
\r
5051 toolBar.addHDDRecorderSelectionListener(rdialog); // 予約ダイアログ
\r
5053 // [ツールバー/キーワード入力] キャンセル動作
\r
5054 toolBar.addKeywordCancelListener(this);
\r
5056 // [タイマー] タイトルバー更新/リスト形式の現在時刻ノード/新聞形式の現在時刻ノード
\r
5057 timer_now.addTickTimerRiseListener(this);
\r
5058 timer_now.addTickTimerRiseListener(listed);
\r
5059 timer_now.addTickTimerRiseListener(paper);
\r
5061 // ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
\r
5063 // ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
\r
5064 toolBar.setSelectedRecorder(bounds.getSelectedRecorderId());
\r
5066 // ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
\r
5067 // [Fire!] サイドツリーのデフォルトを選択することで番組情報の描画を開始する
\r
5068 // ※ここ以前だとぬぽとかOOBとか出るかもよ!
\r
5069 // ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
\r
5070 paper.selectTreeDefault();
\r
5071 listed.selectTreeDefault();
\r
5073 // ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
\r
5074 // メインウィンドウをスプラッシュからコンポーネントに入れ替える
\r
5075 // ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
\r
5076 this.setVisible(false);
\r
5077 this.setContentPane(mainWindow);
\r
5079 this.setVisible(true);
\r
5081 setTitleBar(); // タイトルバー更新
\r
5083 ShowInitTab(); // 前回開いていたタブを開く
\r
5085 // ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
\r
5087 // ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
\r
5088 timer_now.start();
\r
5090 // ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
\r
5092 // ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
\r
5093 mwin.appendMessage(String.format("タイニー番組ナビゲータが起動しました (VersionInfo:%s on %s)",VersionInfo.getVersion(),VersionInfo.getEnvironment()));
\r
5094 initialized = true;
\r