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 {
\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 timerRised(TickTimerRiseEvent e) {
\r
1499 if (env.getDebug()) System.out.println("Timer Rised: now="+CommonUtils.getDateTimeYMDx(e.getCalendar()));
\r
1504 /*******************************************************************************
\r
1506 ******************************************************************************/
\r
1511 private LikeReserveList findLikeReserves(ProgDetailList tvd, String keyword, int threshold) {
\r
1513 String keywordVal = null;
\r
1514 int thresholdVal = 0;
\r
1517 if ( ! env.getDisableFazzySearch() ) {
\r
1518 if ( threshold > 0 ) {
\r
1520 keywordVal = TraceProgram.replacePop(keyword);
\r
1521 thresholdVal = threshold;
\r
1525 keywordVal = tvd.titlePop;
\r
1526 thresholdVal = env.getDefaultFazzyThreshold();
\r
1531 return recorders.findLikeReserves(tvd, keywordVal, thresholdVal, env.getRangeLikeRsv(), ! env.getDisableFazzySearchReverse());
\r
1541 * 番組追跡への追加とgoogle検索
\r
1543 public void showPopupForTraceProgram(
\r
1544 final JComponent comp,
\r
1545 final ProgDetailList tvd, final String keyword, final int threshold,
\r
1546 final int x, final int y, final String clickedDateTime)
\r
1548 JPopupMenu pop = new JPopupMenu();
\r
1550 String myself = toolBar.getSelectedRecorder();
\r
1553 LikeReserveList likeRsvList;
\r
1554 if ( env.getDisableFazzySearch() ) {
\r
1555 likeRsvList = recorders.findLikeReserves(tvd, null, 0, env.getRangeLikeRsv(), false);
\r
1558 likeRsvList = recorders.findLikeReserves(tvd, tvd.titlePop, env.getDefaultFazzyThreshold(), env.getRangeLikeRsv(), ! env.getDisableFazzySearchReverse());
\r
1562 LikeReserveList overlapRsvList = recorders.findOverlapReserves(tvd, null, true, env.getOverlapUp());
\r
1564 // 類似と重複で被るものを重複から除外
\r
1565 for ( LikeReserveItem item : likeRsvList ) {
\r
1566 overlapRsvList.removeDup(item);
\r
1570 if ( tvd.type == ProgType.PASSED ||
\r
1571 (tvd.type == ProgType.PROG && tvd.subtype == ProgSubtype.RADIO) ||
\r
1572 recorders.size() == 0 ) {
\r
1577 LikeReserveItem item = likeRsvList.getClosest(myself);
\r
1578 if ( env.getGivePriorityToReserved() && item != null && item.isCandidate(env.getOverlapUp()) ) {
\r
1579 target = "予約を編集する";
\r
1582 target = "新規予約を登録する";
\r
1585 JMenuItem menuItem = new JMenuItem(String.format("%s【%s %s - %s(%s)】",target,tvd.accurateDate,tvd.start,tvd.title,tvd.center));
\r
1587 menuItem.setForeground(Color.BLUE);
\r
1588 Font f = menuItem.getFont();
\r
1589 menuItem.setFont(f.deriveFont(f.getStyle()|Font.BOLD));
\r
1592 menuItem.addActionListener(new ActionListener() {
\r
1593 public void actionPerformed(ActionEvent e) {
\r
1595 CommonSwingUtils.setLocationCenter(mainWindow,rdialog);
\r
1597 if ( rdialog.open(tvd) ) {
\r
1598 rdialog.setVisible(true);
\r
1601 rdialog.setVisible(false);
\r
1605 if (rdialog.isSucceededReserve()) {
\r
1606 listed.updateReserveMark();
\r
1607 paper.updateReserveBorder(tvd.center);
\r
1608 reserved.redrawReservedList();
\r
1612 pop.add(menuItem);
\r
1617 for ( final LikeReserveItem item : overlapRsvList ) {
\r
1619 if ( ! item.getRec().Myself().equals(toolBar.getSelectedRecorder()) ) {
\r
1620 continue; // 選択中のレコーダ以外はスルーで
\r
1624 ReserveList rsv = item.getRsv();
\r
1625 String start = CommonUtils.getDateTimeW(CommonUtils.getCalendar(rsv.getStartDateTime()));
\r
1626 JMenuItem menuItem = new JMenuItem(String.format("隣接予約を上書する【%s - %s(%s)】",start,rsv.getTitle(),rsv.getCh_name()));
\r
1628 menuItem.addActionListener(new ActionListener() {
\r
1629 public void actionPerformed(ActionEvent e) {
\r
1631 CommonSwingUtils.setLocationCenter(mainWindow,rdialog);
\r
1633 if ( rdialog.open(tvd,item) ) {
\r
1634 rdialog.setVisible(true);
\r
1637 rdialog.setVisible(false);
\r
1641 if (rdialog.isSucceededReserve()) {
\r
1642 listed.updateReserveMark();
\r
1643 paper.updateReserveBorder(tvd.center);
\r
1644 reserved.redrawReservedList();
\r
1648 pop.add(menuItem);
\r
1652 pop.addSeparator();
\r
1655 if ( tvd.type != ProgType.PASSED )
\r
1657 for ( int n=0; n<2; n++ ) {
\r
1659 LikeReserveList rsvList = null;
\r
1661 rsvList = likeRsvList;
\r
1664 rsvList = overlapRsvList;
\r
1667 for ( LikeReserveItem rsvItem : rsvList ) {
\r
1669 final boolean fexec = rsvItem.getRsv().getExec();
\r
1670 final String start = rsvItem.getRsv().getAhh()+":"+rsvItem.getRsv().getAmm();
\r
1671 final String title = rsvItem.getRsv().getTitle();
\r
1672 final String chnam = rsvItem.getRsv().getCh_name();
\r
1673 final String rsvId = rsvItem.getRsv().getId();
\r
1674 final String recId = rsvItem.getRec().Myself();
\r
1676 pop.add(getExecOnOffMenuItem(fexec,start,title,chnam,rsvId,recId,n));
\r
1679 pop.addSeparator();
\r
1683 pop.addSeparator();
\r
1686 if ( tvd.type != ProgType.PASSED ) // 過去ログは処理対象外です
\r
1688 for ( int n=0; n<2; n++ ) {
\r
1690 LikeReserveList rsvList = null;
\r
1692 rsvList = likeRsvList;
\r
1695 rsvList = overlapRsvList;
\r
1698 for ( LikeReserveItem rsvItem : rsvList ) {
\r
1700 final String start = rsvItem.getRsv().getAhh()+":"+rsvItem.getRsv().getAmm();
\r
1701 final String title = rsvItem.getRsv().getTitle();
\r
1702 final String chnam = rsvItem.getRsv().getCh_name();
\r
1703 final String rsvId = rsvItem.getRsv().getId();
\r
1704 final String recId = rsvItem.getRec().Myself();
\r
1706 pop.add(getRemoveRsvMenuItem(start, title,chnam,rsvId,recId,n));
\r
1709 pop.addSeparator();
\r
1713 pop.addSeparator();
\r
1714 pop.addSeparator();
\r
1719 if ( mainWindow.isTabSelected(MWinTab.LISTED) ) {
\r
1720 pop.add(getJumpMenuItem(tvd.title,tvd.center,tvd.accurateDate+" "+tvd.start));
\r
1722 if ( mainWindow.isTabSelected(MWinTab.LISTED) || mainWindow.isTabSelected(MWinTab.PAPER) ) {
\r
1723 JMenuItem mi = getJumpToLastWeekMenuItem(tvd.title,tvd.center,tvd.startDateTime);
\r
1724 if ( mi != null ) {
\r
1730 pop.addSeparator();
\r
1734 final String label = TraceProgram.getNewLabel(tvd.title, tvd.center);
\r
1735 JMenuItem menuItem = new JMenuItem("番組追跡への追加【"+label+"】");
\r
1736 menuItem.addActionListener(new ActionListener() {
\r
1737 public void actionPerformed(ActionEvent e) {
\r
1739 VWTraceKeyDialog tD = new VWTraceKeyDialog(0,0);
\r
1740 CommonSwingUtils.setLocationCenter(mainWindow,tD);
\r
1742 tD.open(trKeys, tvd, env.getDefaultFazzyThreshold());
\r
1743 tD.setVisible(true);
\r
1745 if (tD.isRegistered()) {
\r
1750 mpList.clear(env.getDisableFazzySearch(), env.getDisableFazzySearchReverse());
\r
1751 mpList.build(tvprograms, trKeys.getTraceKeys(), srKeys.getSearchKeys());
\r
1754 listed.redrawTreeByTrace();
\r
1757 paper.updateBangumiColumns();
\r
1758 listed.reselectTree();
\r
1760 mwin.appendMessage("番組追跡へ追加しました【"+label+"】");
\r
1763 trKeys.remove(label);
\r
1767 pop.add(menuItem);
\r
1772 final String label = tvd.title+" ("+tvd.center+")";
\r
1773 JMenuItem menuItem = new JMenuItem("キーワード検索への追加【"+label+"】");
\r
1774 menuItem.addActionListener(new ActionListener(){
\r
1775 public void actionPerformed(ActionEvent e){
\r
1777 // 「キーワード検索の設定」ウィンドウを開く
\r
1779 AbsKeywordDialog kD = new VWKeywordDialog();
\r
1780 CommonSwingUtils.setLocationCenter(mainWindow,kD);
\r
1782 kD.open(srKeys, srGrps, tvd);
\r
1783 kD.setVisible(true);
\r
1785 if (kD.isRegistered()) {
\r
1787 mpList.clear(env.getDisableFazzySearch(), env.getDisableFazzySearchReverse());
\r
1788 mpList.build(tvprograms, trKeys.getTraceKeys(), srKeys.getSearchKeys());
\r
1791 listed.redrawTreeByKeyword();
\r
1794 paper.updateBangumiColumns();
\r
1795 listed.reselectTree();
\r
1797 mwin.appendMessage("キーワード検索へ追加しました【"+label+"】");
\r
1801 pop.add(menuItem);
\r
1806 boolean isRemoveItem = false;
\r
1807 if ( mainWindow.isTabSelected(MWinTab.LISTED) && tvd.type == ProgType.PICKED ) {
\r
1808 isRemoveItem = true;
\r
1811 PickedProgram tvp = tvprograms.getPickup();
\r
1812 if ( tvp != null ) {
\r
1813 isRemoveItem = tvp.remove(tvd, tvd.center, tvd.accurateDate, false);
\r
1817 if ( ! isRemoveItem ) // 過去ログは処理対象外です
\r
1819 final String label = String.format("%s(%s)",tvd.title,tvd.center);
\r
1820 JMenuItem menuItem = new JMenuItem(String.format("ピックアップへの追加【%s %s - %s】",tvd.accurateDate,tvd.start,label));
\r
1821 menuItem.addActionListener(new ActionListener() {
\r
1822 public void actionPerformed(ActionEvent e) {
\r
1824 PickedProgram tvp = tvprograms.getPickup();
\r
1825 if ( tvp != null ) {
\r
1830 if ( listed.isNodeSelected(ListedTreeNode.PICKUP) ) {
\r
1831 // ピックアップノードが選択されていたらリストを更新する
\r
1832 listed.reselectTree();
\r
1835 listed.updateReserveMark();
\r
1837 paper.updateReserveBorder(tvd.center);
\r
1838 mwin.appendMessage("【ピックアップ】追加しました: "+tvd.title+" ("+tvd.center+")");
\r
1843 pop.add(menuItem);
\r
1846 final String label = tvd.title+" ("+tvd.center+")";
\r
1847 JMenuItem menuItem = new JMenuItem("ピックアップからの削除【"+label+"】");
\r
1848 menuItem.setForeground(Color.RED);
\r
1849 menuItem.addActionListener(new ActionListener() {
\r
1850 public void actionPerformed(ActionEvent e) {
\r
1852 PickedProgram tvp = tvprograms.getPickup();
\r
1853 if ( tvp != null ) {
\r
1855 tvp.remove(tvd, tvd.center, tvd.accurateDate, true);
\r
1858 if ( listed.isNodeSelected(ListedTreeNode.PICKUP) || listed.isNodeSelected(ListedTreeNode.STANDBY) ) {
\r
1859 // ピックアップノードが選択されていたらリストを更新する
\r
1860 listed.reselectTree();
\r
1863 listed.updateReserveMark();
\r
1864 paper.updateReserveBorder(tvd.center);
\r
1865 mwin.appendMessage("【ピックアップ】削除しました: "+tvd.title+" ("+tvd.center+")");
\r
1870 pop.add(menuItem);
\r
1874 pop.addSeparator();
\r
1878 for (final TextValueSet tv : env.getTvCommand()) {
\r
1879 JMenuItem menuItem = new JMenuItem(tv.getText());
\r
1880 String escepedTitle = "";
\r
1881 String escepedChName = "";
\r
1882 String escepedDetail = "";
\r
1884 escepedTitle = URLEncoder.encode(tvd.title,"UTF-8");
\r
1885 escepedDetail = URLEncoder.encode(tvd.detail,"UTF-8");
\r
1886 escepedChName = URLEncoder.encode(tvd.center,"UTF-8");
\r
1887 } catch (UnsupportedEncodingException e2) {
\r
1891 String cmd = tv.getValue();
\r
1892 if ( cmd.matches(".*%DETAILURL%.*") ) {
\r
1893 if ( tvd.link == null || tvd.link.length() == 0 ) {
\r
1894 // このメニューは利用できません!
\r
1895 menuItem.setEnabled(false);
\r
1896 menuItem.setForeground(Color.lightGray);
\r
1899 cmd = cmd.replaceAll("%ENCTITLE%", escepedTitle);
\r
1900 cmd = cmd.replaceAll("%ENCDETAIL%", escepedDetail);
\r
1901 cmd = cmd.replaceAll("%ENCCHNAME%", escepedChName);
\r
1902 cmd = cmd.replaceAll("%TITLE%", tvd.title);
\r
1903 cmd = cmd.replaceAll("%DETAIL%", tvd.detail);
\r
1904 cmd = cmd.replaceAll("%CHNAME%", tvd.center);
\r
1905 cmd = cmd.replaceAll("%DATE%", tvd.accurateDate);
\r
1906 cmd = cmd.replaceAll("%START%", tvd.start);
\r
1907 cmd = cmd.replaceAll("%END%", tvd.end);
\r
1908 cmd = cmd.replaceAll("%DETAILURL%", tvd.link);
\r
1911 if ( cmd.matches(".*%TVKAREACODE%.*") && cmd.matches(".*%TVKPID%.*") ) {
\r
1913 for ( TVProgram tvp : progPlugins ) {
\r
1914 if ( tvp.getTVProgramId().startsWith("Gガイド.テレビ王国") ) {
\r
1915 for ( Center tempcr : tvp.getCRlist() ) {
\r
1916 // CH設定が完了している必要がある
\r
1917 if ( tvp.getSubtype() == ProgSubtype.TERRA && tvp.getSelectedCode().equals(TVProgram.allCode) && ! tempcr.getAreaCode().equals(TVProgram.bsCode) ) {
\r
1918 // 地域が全国の地デジの場合のみ、有効局かどうかを確認する必要がある
\r
1919 if ( tempcr.getCenter().equals(tvd.center) && tempcr.getOrder() > 0 ) {
\r
1926 if ( tempcr.getCenter().equals(tvd.center) ) {
\r
1934 if ( cr != null ) {
\r
1939 if ( cr != null ) {
\r
1940 String areacode = null;
\r
1941 String centercode = cr.getLink();
\r
1942 String cat = cr.getLink().substring(0,1);
\r
1943 if ( cat.equals("1") ) {
\r
1944 areacode = cr.getAreaCode();
\r
1947 if ( cat.equals("4") ) {
\r
1950 else if ( cat.equals("5") ) {
\r
1956 cmd = cmd.replaceAll("%TVKAREACODE%", areacode);
\r
1957 cmd = cmd.replaceAll("%TVKCAT%", cat);
\r
1958 cmd = cmd.replaceAll("%TVKPID%", centercode+CommonUtils.getDateTimeYMD(CommonUtils.getCalendar(tvd.startDateTime)).replaceFirst("..$", ""));
\r
1959 System.out.println("[DEBUG] "+cmd);
\r
1961 menuItem.setEnabled(true);
\r
1962 menuItem.setForeground(Color.BLACK);
\r
1965 menuItem.setEnabled(false);
\r
1966 menuItem.setForeground(Color.lightGray);
\r
1970 final String run = cmd;
\r
1972 menuItem.addActionListener(new ActionListener() {
\r
1974 public void actionPerformed(ActionEvent e) {
\r
1976 if (run.indexOf("http") == 0) {
\r
1977 Desktop desktop = Desktop.getDesktop();
\r
1978 desktop.browse(new URI(run));
\r
1981 CommonUtils.executeCommand(run);
\r
1983 } catch (IOException e1) {
\r
1984 e1.printStackTrace();
\r
1985 } catch (URISyntaxException e1) {
\r
1986 e1.printStackTrace();
\r
1991 pop.add(menuItem);
\r
1995 pop.addSeparator();
\r
1999 JMenuItem menuItem = new JMenuItem("番組名をコピー【"+tvd.title+"】");
\r
2000 menuItem.addActionListener(new ActionListener() {
\r
2001 public void actionPerformed(ActionEvent e) {
\r
2002 String msg = tvd.title;
\r
2003 Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard();
\r
2004 StringSelection s = new StringSelection(msg);
\r
2005 cb.setContents(s, null);
\r
2008 pop.add(menuItem);
\r
2011 JMenuItem menuItem = new JMenuItem("番組名と詳細をコピー【"+tvd.title+"】");
\r
2012 menuItem.addActionListener(new ActionListener() {
\r
2013 public void actionPerformed(ActionEvent e) {
\r
2014 String msg = tvd.title+System.getProperty("line.separator")+tvd.detail+"\0"+tvd.getAddedDetail();
\r
2015 Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard();
\r
2016 StringSelection s = new StringSelection(msg);
\r
2017 cb.setContents(s, null);
\r
2020 pop.add(menuItem);
\r
2023 JMenuItem menuItem = new JMenuItem("番組情報をコピー【"+tvd.title+"】");
\r
2024 menuItem.addActionListener(new ActionListener() {
\r
2025 public void actionPerformed(ActionEvent e) {
\r
2028 for (ClipboardInfo cb : cbitems) {
\r
2030 switch (cb.getId()) {
\r
2032 msg += tvd.title+"\t";
\r
2035 msg += tvd.center+"\t";
\r
2038 msg += tvd.accurateDate+"\t";
\r
2041 msg += tvd.start+"\t";
\r
2045 msg = msg.substring(0,msg.length()-1)+"-";
\r
2047 msg += tvd.end+"\t";
\r
2050 msg += tvd.genre+"\t";
\r
2053 msg += tvd.detail+"\0"+tvd.getAddedDetail()+"\t";
\r
2057 preId = cb.getId();
\r
2059 if (msg.length() > 0) {
\r
2060 msg = msg.substring(0,msg.length()-1);
\r
2062 Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard();
\r
2063 StringSelection s = new StringSelection(msg);
\r
2064 cb.setContents(s, null);
\r
2067 pop.add(menuItem);
\r
2070 pop.addSeparator();
\r
2074 tvd.type == ProgType.SYOBO ||
\r
2075 tvd.type == ProgType.PASSED ||
\r
2076 tvd.type == ProgType.PICKED ||
\r
2077 (tvd.type == ProgType.PROG && tvd.subtype != ProgSubtype.RADIO) ) // ラジオは処理対象外です
\r
2079 JMenuItem menuItem = new JMenuItem("延長感染源にしない【"+tvd.title+" ("+tvd.center+")】");
\r
2080 menuItem.addActionListener(new ActionListener() {
\r
2081 public void actionPerformed(ActionEvent e) {
\r
2083 mwin.appendMessage("延長感染源を隔離します【"+tvd.title+"("+tvd.center+")】");
\r
2085 AbsExtensionDialog eD = new VWExtensionDialog();
\r
2086 CommonSwingUtils.setLocationCenter(mainWindow,eD);
\r
2088 eD.open(tvd.title,tvd.center,false,extKeys);
\r
2089 eD.setVisible(true);
\r
2091 if (eD.isRegistered()) {
\r
2093 for (TVProgram tvp : tvprograms) {
\r
2094 if (tvp.getType() == ProgType.PROG) {
\r
2095 tvp.setExtension(null, null, false, extKeys.getSearchKeys());
\r
2100 listed.redrawTreeByExtension();
\r
2102 mainWindow.setSelectedTab(MWinTab.LISTED);
\r
2106 pop.add(menuItem);
\r
2108 if ( tvd.type == ProgType.PASSED || (tvd.type == ProgType.PROG && tvd.subtype != ProgSubtype.RADIO) ) // ラジオは処理対象外です
\r
2110 JMenuItem menuItem = new JMenuItem("延長感染源にする【"+tvd.title+" ("+tvd.center+")】");
\r
2111 menuItem.addActionListener(new ActionListener() {
\r
2112 public void actionPerformed(ActionEvent e) {
\r
2114 AbsExtensionDialog eD = new VWExtensionDialog();
\r
2115 CommonSwingUtils.setLocationCenter(mainWindow,eD);
\r
2117 eD.open(tvd.title,tvd.center,true,extKeys);
\r
2118 eD.setVisible(true);
\r
2120 if (eD.isRegistered()) {
\r
2122 for (TVProgram tvp : tvprograms) {
\r
2123 if (tvp.getType() == ProgType.PROG) {
\r
2124 tvp.setExtension(null, null, false, extKeys.getSearchKeys());
\r
2129 listed.redrawTreeByExtension();
\r
2131 mainWindow.setSelectedTab(MWinTab.LISTED);
\r
2135 pop.add(menuItem);
\r
2138 pop.addSeparator();
\r
2141 if ( tvd.type == ProgType.PROG && tvd.subtype != ProgSubtype.RADIO) // ラジオは処理対象外です
\r
2143 for (HDDRecorder recorder : recorders ) {
\r
2145 if (recorder.ChangeChannel(null) == false) {
\r
2149 final String recorderName = recorder.Myself();
\r
2150 JMenuItem menuItem = new JMenuItem("【"+recorderName+"】で【"+tvd.center+"】を視聴する");
\r
2152 menuItem.addActionListener(new ActionListener() {
\r
2153 public void actionPerformed(ActionEvent e) {
\r
2154 for (HDDRecorder recorder : recorders ) {
\r
2155 if (recorder.isMyself(recorderName)) {
\r
2156 if (recorder.ChangeChannel(tvd.center) == false) {
\r
2158 mwin.appendError("【警告】チャンネルを変更できませんでした:"+recorder.getErrmsg());
\r
2160 else if (recorder.getErrmsg() !=null && recorder.getErrmsg().length() > 0) {
\r
2161 mwin.appendError("[追加情報] "+recorder.getErrmsg());
\r
2168 menuItem.setEnabled(recorder.getUseChChange());
\r
2170 pop.add(menuItem);
\r
2174 pop.show(comp, x, y);
\r
2178 public boolean addToPickup(final ProgDetailList tvd) {
\r
2180 if (tvd.start.equals("")) {
\r
2185 PickedProgram tvp = tvprograms.getPickup();
\r
2186 if ( tvp == null ) {
\r
2192 if ( tvp.remove(tvd, tvd.center, tvd.accurateDate, true) ) {
\r
2194 if ( listed.isNodeSelected(JTreeLabel.Nodes.PICKUP) || listed.isNodeSelected(JTreeLabel.Nodes.STANDBY) ) {
\r
2195 // ピックアップノードor予約待機ノードが選択されていたらリストを更新する
\r
2196 listed.reselectTree();
\r
2197 //listed.updateReserveMark();
\r
2200 // 予約マークだけ変えておけばいいよね
\r
2201 listed.updateReserveMark();
\r
2204 paper.updateReserveBorder(tvd.center);
\r
2205 mwin.appendMessage("【ピックアップ】削除しました: "+tvd.title+" ("+tvd.center+")");
\r
2210 if ( tvd.endDateTime.compareTo(CommonUtils.getDateTime(0)) > 0 ) {
\r
2214 if ( listed.isNodeSelected(JTreeLabel.Nodes.PICKUP) ) {
\r
2215 // ピックアップノードが選択されていたらリストを更新する
\r
2216 listed.reselectTree();
\r
2217 //listed.updateReserveMark();
\r
2220 listed.updateReserveMark();
\r
2223 paper.updateReserveBorder(tvd.center);
\r
2224 mwin.appendMessage("【ピックアップ】追加しました: "+tvd.title+" ("+tvd.center+")");
\r
2229 mwin.appendMessage("【ピックアップ】過去情報はピックアップできません.");
\r
2236 private JMenuItem getRemoveRsvMenuItem(final String start, final String title, final String chnam, final String rsvId, final String recId, int n) {
\r
2238 JMenuItem menuItem = new JMenuItem();
\r
2240 String mode = "削除";
\r
2241 menuItem.setForeground(Color.RED);
\r
2243 String target = ( n==0 ) ? "予約" : "隣接予約";
\r
2245 menuItem.setText(String.format("%sを%sする【%s - %s(%s)/%s】",target,mode,start,title,chnam,recId));
\r
2247 if ( recId.equals(toolBar.getSelectedRecorder()) ) {
\r
2248 // 選択中のレコーダのものは太字に
\r
2249 Font f = menuItem.getFont();
\r
2250 menuItem.setFont(f.deriveFont(f.getStyle()|Font.BOLD));
\r
2253 menuItem.addActionListener(new ActionListener() {
\r
2254 public void actionPerformed(ActionEvent e) {
\r
2256 if (env.getShowWarnDialog()) {
\r
2257 Container cp = getContentPane();
\r
2258 int ret = JOptionPane.showConfirmDialog(cp, "削除しますか?【"+title+"("+chnam+")】("+recId+")", "確認", JOptionPane.YES_NO_OPTION);
\r
2259 if (ret != JOptionPane.YES_OPTION) {
\r
2267 new SwingBackgroundWorker(false) {
\r
2270 protected Object doWorks() throws Exception {
\r
2272 for (HDDRecorder recorder : recorders) {
\r
2273 if (recorder.isMyself(recId)) { // IPAddr:PortNo:RecorderIdで比較
\r
2275 String title = "";
\r
2276 for (ReserveList r : recorder.getReserves()) {
\r
2277 if (r.getId().equals(rsvId)) {
\r
2278 title = r.getTitle();
\r
2283 stwin.appendMessage("予約を削除します:"+title+"("+rsvId+")");
\r
2284 //recorder.setProgressArea(stwin);
\r
2285 ReserveList r = recorder.RemoveRdEntry(rsvId); // Noで検索
\r
2287 mwin.appendMessage("正常に削除できました:"+r.getTitle()+"("+r.getCh_name()+")");
\r
2289 if ( ! r.getTitle().equals(title) || ! r.getId().equals(rsvId)) {
\r
2290 mwin.appendError("【警告】削除結果が一致しません!:"+title+"/"+r.getTitle());
\r
2293 if ( recorder.getUseCalendar()) {
\r
2295 for ( HDDRecorder calendar : recorders ) {
\r
2296 if (calendar.getType() == RecType.CALENDAR) {
\r
2297 stwin.appendMessage("カレンダーから予約情報を削除します");
\r
2298 //calendar.setProgressArea(stwin);
\r
2299 if ( ! calendar.UpdateRdEntry(r, null)) {
\r
2300 mwin.appendError("【カレンダー】"+calendar.getErrmsg());
\r
2310 mwin.appendError("削除に失敗しました:"+title);
\r
2314 if ( ! recorder.getErrmsg().equals("")) {
\r
2315 mwin.appendError("【追加情報】"+recorder.getErrmsg());
\r
2325 protected void doFinally() {
\r
2326 StWinSetVisible(false);
\r
2330 CommonSwingUtils.setLocationCenter(Viewer.this, stwin);
\r
2331 StWinSetVisible(true);
\r
2334 listed.updateReserveMark();
\r
2335 paper.updateReserveBorder(chnam);
\r
2336 reserved.redrawReservedList();
\r
2347 * 他のクラスに分離できなかったというか、しなかったというか、そんなメソッド群
\r
2353 private boolean doExecOnOff(final boolean fexec, final String title, final String chnam, final String rsvId, final String recId) {
\r
2355 CommonSwingUtils.setLocationCenter(mainWindow,rdialog);
\r
2357 String mode = (fexec ? "ON" : "OFF");
\r
2360 if ( rdialog.open(recId,rsvId,fexec) ) {
\r
2362 rdialog.doUpdate();
\r
2364 if (rdialog.isSucceededReserve()) {
\r
2366 listed.updateReserveMark();
\r
2367 paper.updateReserveBorder(chnam);
\r
2368 reserved.redrawReservedList();
\r
2371 String msg = "予約を"+mode+"にしました【"+title+"("+chnam+")/"+recId+"】";
\r
2372 //StdAppendMessage(msg);
\r
2373 mwin.appendMessage(msg);
\r
2384 * 予約実行をONOFFするメニューアイテム
\r
2386 private JMenuItem getExecOnOffMenuItem(final boolean fexec, final String start, final String title, final String chnam, final String rsvId, final String recId, int n) {
\r
2388 JMenuItem menuItem = new JMenuItem();
\r
2393 menuItem.setForeground(Color.BLUE);
\r
2397 menuItem.setForeground(Color.BLACK);
\r
2400 String target = ( n==0 ) ? "予約" : "隣接予約";
\r
2402 menuItem.setText(String.format("%sを%sにする【%s - %s(%s)/%s】",target,mode,start,title,chnam,recId));
\r
2404 if ( recId.equals(toolBar.getSelectedRecorder()) ) {
\r
2405 // 選択中のレコーダのものは太字に
\r
2406 Font f = menuItem.getFont();
\r
2407 menuItem.setFont(f.deriveFont(f.getStyle()|Font.BOLD));
\r
2410 final String xmode = mode;
\r
2411 menuItem.addActionListener(new ActionListener() {
\r
2412 public void actionPerformed(ActionEvent e) {
\r
2414 CommonSwingUtils.setLocationCenter(mainWindow,rdialog);
\r
2417 if ( rdialog.open(recId,rsvId, ! fexec) ) {
\r
2419 rdialog.doUpdate();
\r
2421 if (rdialog.isSucceededReserve()) {
\r
2423 listed.updateReserveMark();
\r
2424 paper.updateReserveBorder(chnam);
\r
2425 reserved.redrawReservedList();
\r
2428 String msg = "予約を"+xmode+"にしました【"+title+"("+chnam+")/"+recId+"】";
\r
2429 StdAppendMessage(msg);
\r
2430 mwin.appendMessage(msg);
\r
2435 //rdialog.setVisible(false);
\r
2444 * 新聞形式へジャンプするメニューアイテム
\r
2446 private JMenuItem getJumpMenuItem(final String title, final String chnam, final String startDT) {
\r
2447 JMenuItem menuItem = new JMenuItem(String.format("番組欄へジャンプする【%s - %s(%s)】",startDT,title,chnam));
\r
2448 menuItem.addActionListener(new ActionListener() {
\r
2449 public void actionPerformed(ActionEvent e) {
\r
2450 paper.jumpToBangumi(chnam,startDT);
\r
2455 private JMenuItem getJumpToLastWeekMenuItem( final String title, final String chnam, final String startDT) {
\r
2456 GregorianCalendar cal = CommonUtils.getCalendar(startDT);
\r
2458 if ( cal != null ) {
\r
2459 cal.add(Calendar.DATE, -7);
\r
2460 final String lastdatetime = CommonUtils.getDateTimeW(cal);
\r
2462 JMenuItem menuItem = new JMenuItem(String.format("先週の番組欄へジャンプする【%s - (%s)】",lastdatetime,chnam));
\r
2464 menuItem.addActionListener(new ActionListener() {
\r
2465 public void actionPerformed(ActionEvent e) {
\r
2466 paper.jumpToBangumi(chnam,lastdatetime);
\r
2475 /*******************************************************************************
\r
2477 ******************************************************************************/
\r
2479 /***************************************
\r
2481 **************************************/
\r
2486 private boolean doLoadRdRecorder(LoadRsvedFor lrf) {
\r
2488 if ( lrf == null ) {
\r
2489 return doLoadRdRecorderAll();
\r
2494 return doLoadRdReserveDetails();
\r
2496 return doLoadRdRecorded();
\r
2498 return doLoadRdAutoReserves();
\r
2507 * レコーダの情報を全部DLする(ステータスウィンドウは自前で用意 する)
\r
2509 private boolean doLoadRdRecorderAll() {
\r
2511 final String myself = getSelectedMySelf();
\r
2516 new SwingBackgroundWorker(false) {
\r
2519 protected Object doWorks() throws Exception {
\r
2521 TatCount tc = new TatCount();
\r
2524 _loadRdRecorderAll(true,myself);
\r
2526 // エンコーダ情報が更新されるかもしれないので、一覧のエンコーダ表示にも反映する
\r
2527 recsetting.redrawRecorderEncoderEntry();
\r
2530 paper.updateReserveBorder(null);
\r
2531 listed.updateReserveMark();
\r
2532 reserved.redrawReservedList();
\r
2533 recorded.redrawRecordedList();
\r
2535 mwin.appendMessage(String.format("【予約一覧の取得処理が完了しました】 所要時間: %.2f秒",tc.end()));
\r
2540 protected void doFinally() {
\r
2541 StWinSetVisible(false);
\r
2545 StWinSetLocationCenter(this);
\r
2546 StWinSetVisible(true);
\r
2555 private boolean doLoadRdReserveDetails() {
\r
2557 final String myself = getSelectedMySelf();
\r
2562 new SwingBackgroundWorker(false) {
\r
2565 protected Object doWorks() throws Exception {
\r
2567 TatCount tc = new TatCount();
\r
2569 boolean succeeded = true;
\r
2571 HDDRecorderList recs;
\r
2572 if ( myself != null ) {
\r
2573 recs = recorders.findInstance(myself);
\r
2578 for ( HDDRecorder recorder : recs ) {
\r
2580 if ( ! recorder.isReserveListSupported() ) {
\r
2585 if ( ! recorder.GetRdSettings(true) ) {
\r
2586 succeeded = false;
\r
2591 if ( ! recorder.GetRdReserve(true) ) {
\r
2592 succeeded = false;
\r
2596 // レコーダから取得したエンコーダ情報で、登録済みレコーダ一覧を更新する
\r
2597 setEncoderInfo2RecorderList(recorder,true);
\r
2600 if ( recorder.isThereAdditionalDetails() ) {
\r
2601 if ( ! recorder.GetRdReserveDetails() ) {
\r
2602 succeeded = false;
\r
2607 // レコーダの放送局名をWeb番組表の放送局名に置き換え
\r
2608 checkChNameIsRight(recorder);
\r
2611 if ( recorder.isRecordedListSupported() ) {
\r
2612 recorder.GetRdRecorded(false);
\r
2616 if ( succeeded ) {
\r
2617 reserved.redrawReservedList();
\r
2618 recorded.redrawRecordedList();
\r
2620 mwin.appendMessage(String.format("【予約詳細の取得処理が完了しました】 所要時間: %.2f秒",tc.end()));
\r
2624 mwin.appendMessage(String.format("【予約詳細の取得処理に失敗しました】 所要時間: %.2f秒",tc.end()));
\r
2630 protected void doFinally() {
\r
2631 StWinSetVisible(false);
\r
2635 StWinSetLocationCenter(this);
\r
2636 StWinSetVisible(true);
\r
2645 private boolean doLoadRdRecorded() {
\r
2647 final String myself = getSelectedMySelf();
\r
2652 new SwingBackgroundWorker(false) {
\r
2655 protected Object doWorks() throws Exception {
\r
2657 TatCount tc = new TatCount();
\r
2659 boolean succeeded = true;
\r
2661 HDDRecorderList recs;
\r
2662 if ( myself != null ) {
\r
2663 recs = recorders.findInstance(myself);
\r
2668 for ( HDDRecorder recorder : recs ) {
\r
2669 if ( ! recorder.isRecordedListSupported() ) {
\r
2670 succeeded = false;
\r
2674 if ( ! recorder.GetRdRecorded(true) ) {
\r
2675 succeeded = false;
\r
2679 if ( succeeded ) {
\r
2680 reserved.redrawReservedList();
\r
2681 recorded.redrawRecordedList();
\r
2683 mwin.appendMessage(String.format("【録画結果一覧の取得処理が完了しました】 所要時間: %.2f秒",tc.end()));
\r
2687 mwin.appendMessage(String.format("【録画結果一覧の取得処理に失敗しました】 所要時間: %.2f秒",tc.end()));
\r
2693 protected void doFinally() {
\r
2694 StWinSetVisible(false);
\r
2698 StWinSetLocationCenter(this);
\r
2699 StWinSetVisible(true);
\r
2708 private boolean doLoadRdAutoReserves() {
\r
2710 final String myself = getSelectedMySelf();
\r
2715 new SwingBackgroundWorker(false) {
\r
2718 protected Object doWorks() throws Exception {
\r
2720 TatCount tc = new TatCount();
\r
2722 boolean succeeded = true;
\r
2724 HDDRecorderList recs;
\r
2725 if ( myself != null ) {
\r
2726 recs = recorders.findInstance(myself);
\r
2731 for ( HDDRecorder recorder : recs ) {
\r
2732 if ( ! recorder.isEditAutoReserveSupported() ) {
\r
2733 succeeded = false;
\r
2737 if ( ! recorder.GetRdAutoReserve(true) ) {
\r
2738 succeeded = false;
\r
2742 if ( succeeded ) {
\r
2744 mwin.appendMessage(String.format("【自動予約一覧の取得処理が完了しました】 所要時間: %.2f秒",tc.end()));
\r
2748 mwin.appendMessage(String.format("【自動予約一覧の取得処理に失敗しました】 所要時間: %.2f秒",tc.end()));
\r
2754 protected void doFinally() {
\r
2755 StWinSetVisible(false);
\r
2759 StWinSetLocationCenter(this);
\r
2760 StWinSetVisible(true);
\r
2765 /***************************************
\r
2767 **************************************/
\r
2770 * レコーダの情報を全部DLする(ステータスウィンドウは呼び出し元が準備する)
\r
2772 private void loadRdReservesAll(final boolean force, final String myself) {
\r
2774 new SwingBackgroundWorker(true) {
\r
2777 protected Object doWorks() throws Exception {
\r
2779 _loadRdRecorderAll(force,myself);
\r
2785 protected void doFinally() {
\r
2790 /***************************************
\r
2792 **************************************/
\r
2794 private boolean _loadRdRecorderAll(final boolean force, final String myself) {
\r
2796 HDDRecorderList recs;
\r
2797 if ( myself != null ) {
\r
2798 recs = recorders.findInstance(myself);
\r
2804 boolean success = true;
\r
2806 for ( HDDRecorder recorder : recs ) {
\r
2807 if ( recorder.isReserveListSupported() ) {
\r
2808 success = success & _loadRdRecorder(recorder, force);
\r
2815 private boolean _loadRdRecorder(HDDRecorder recorder, boolean force) {
\r
2817 mwin.appendMessage("【レコーダ情報取得】情報を取得します: "+recorder.Myself());
\r
2818 if ( recorder.isThereAdditionalDetails() && env.getForceLoadReserveDetails() == 2 ) {
\r
2819 mwin.appendMessage("<<<注意!>>>このレコーダでは予約詳細の個別取得を実行しないと正確な情報を得られない場合があります。");
\r
2825 if ( ! _loadRdSettings(recorder,force) ) {
\r
2830 if ( ! _loadRdReserves(recorder,force) ) {
\r
2834 // レコーダから取得したエンコーダ情報で、登録済みレコーダ一覧を更新する
\r
2835 setEncoderInfo2RecorderList(recorder,force);
\r
2837 // 予約詳細の取得(強制取得じゃなければ処理不要)
\r
2838 if ( force && ! _loadRdReserveDetails(recorder,force) ) {
\r
2842 // レコーダの放送局名をWeb番組表の放送局名に置き換え
\r
2843 checkChNameIsRight(recorder);
\r
2846 if ( ! _loadRdAutoReserves(recorder,force) ) {
\r
2851 if ( ! _loadRdRecorded(recorder,force) ) {
\r
2855 catch (Exception e) {
\r
2856 e.printStackTrace();
\r
2857 mwin.appendError("【致命的エラー】予約一覧の取得で例外が発生 "+recorder.getIPAddr()+":"+recorder.getPortNo()+":"+recorder.getRecorderId());
\r
2865 /***************************************
\r
2867 **************************************/
\r
2869 private boolean _loadRdSettings(HDDRecorder recorder, boolean force) {
\r
2870 if ( recorder.GetRdSettings(force) ) {
\r
2874 mwin.appendError(recorder.getErrmsg()+" "+recorder.Myself()); // 取得に失敗
\r
2879 private boolean _loadRdReserves(HDDRecorder recorder, boolean force) {
\r
2880 if ( recorder.GetRdReserve(force) ) {
\r
2884 mwin.appendError(recorder.getErrmsg()+" "+recorder.Myself()); // 取得に失敗
\r
2889 private boolean _loadRdReserveDetails(HDDRecorder recorder, boolean force) {
\r
2891 if ( ! recorder.isThereAdditionalDetails() ) {
\r
2892 return true; // 非対応レコーダ
\r
2895 boolean skip = false;
\r
2896 if ( force && env.getForceLoadReserveDetails() == 2 ) {
\r
2899 else if ( force && env.getForceLoadReserveDetails() == 0 ) {
\r
2900 int ret = JOptOptionPane.showConfirmDialog(stwin, "<HTML>詳細情報を取得しますか?(時間がかかります)<BR><BR>"+recorder.Myself()+"</HTML>", "今回の選択を既定の動作とする", "※既定動作は各種設定で変更できます", "確認", JOptionPane.YES_NO_OPTION);
\r
2901 skip = (ret != JOptOptionPane.YES_OPTION);
\r
2903 if ( JOptOptionPane.isSelected() ) {
\r
2905 env.setForceLoadReserveDetails(skip ? 2 : 1);
\r
2907 if (setting!=null) setting.updateSelections();
\r
2911 mwin.appendMessage("【!】予約詳細情報の取得はスキップされました");
\r
2915 if ( recorder.GetRdReserveDetails()) {
\r
2916 return true; // 取得成功
\r
2919 mwin.appendError(recorder.getErrmsg()+" "+recorder.Myself());
\r
2921 return false; // 取得失敗
\r
2924 private boolean _loadRdAutoReserves(HDDRecorder recorder, boolean force) {
\r
2926 if ( ! recorder.isEditAutoReserveSupported() ) {
\r
2930 boolean skip = false;
\r
2931 if ( force && env.getForceLoadAutoReserves() == 2 ) {
\r
2934 else if ( force && env.getForceLoadAutoReserves() == 0 ) {
\r
2935 int ret = JOptOptionPane.showConfirmDialog(stwin, "<HTML>自動予約一覧を取得しますか?(時間がかかります)<BR><BR>"+recorder.Myself()+"</HTML>", "今回の選択を既定の動作とする", "※既定動作は各種設定で変更できます", "確認", JOptionPane.YES_NO_OPTION);
\r
2936 skip = (ret != JOptOptionPane.YES_OPTION);
\r
2938 if ( JOptOptionPane.isSelected() ) {
\r
2940 env.setForceLoadAutoReserves(skip ? 2 : 1);
\r
2942 if (setting!=null) setting.updateSelections();
\r
2946 mwin.appendMessage("【!】自動予約一覧の取得はスキップされました");
\r
2950 if ( recorder.GetRdAutoReserve(force) ) {
\r
2954 mwin.appendError(recorder.getErrmsg()+" "+recorder.Myself());
\r
2959 private boolean _loadRdRecorded(HDDRecorder recorder, boolean force) {
\r
2961 if ( ! recorder.isRecordedListSupported() ) {
\r
2965 boolean skip = false;
\r
2966 if ( force && env.getForceLoadRecorded() == 2 ) {
\r
2969 if ( force && env.getForceLoadRecorded() == 0 ) {
\r
2970 int ret = JOptOptionPane.showConfirmDialog(stwin, "<HTML>録画結果一覧を取得しますか?(時間がかかります)<BR><BR>"+recorder.Myself()+"</HTML>", "今回の選択を既定の動作とする", "※既定動作は各種設定で変更できます", "確認", JOptionPane.YES_NO_OPTION);
\r
2971 skip = (ret != JOptOptionPane.YES_OPTION);
\r
2973 if ( JOptOptionPane.isSelected() ) {
\r
2975 env.setForceLoadRecorded(skip ? 2 : 1);
\r
2977 if (setting!=null) setting.updateSelections();
\r
2981 mwin.appendMessage("【!】録画結果一覧の取得はスキップされました");
\r
2985 if ( recorder.GetRdRecorded(force) ) {
\r
2989 mwin.appendError(recorder.getErrmsg()+" "+recorder.Myself());
\r
2995 * レコーダから取得したエンコーダ情報で、登録済みレコーダ一覧を更新する
\r
2998 private void setEncoderInfo2RecorderList(HDDRecorder recorder, boolean force) {
\r
2999 for (RecorderInfo ri : recInfoList ) {
\r
3000 //if (rl.getRecorderEncoderList().size() == 0)
\r
3002 //String mySelf = ri.getRecorderIPAddr()+":"+ri.getRecorderPortNo()+":"+ri.getRecorderId();
\r
3003 //String myMail = "MAIL"+":"+ri.getRecorderMacAddr()+":"+ri.getRecorderId();
\r
3004 //if (recorder.isMyself(mySelf) || recorder.isMyself(myMail)) {
\r
3005 if ( recorder.isMyself(ri.MySelf()) ) {
\r
3006 ri.clearEncoders();
\r
3007 for (TextValueSet enc : recorder.getEncoderList()) {
\r
3008 ri.addEncoder(enc.getText());
\r
3012 recInfoList.save();
\r
3021 * 予約一覧の放送局名が正しい形式であるかどうかのチェック
\r
3023 private void checkChNameIsRight(HDDRecorder recorder) {
\r
3024 HashMap<String,String> misCN = new HashMap<String,String>();
\r
3025 for ( ReserveList r : recorder.getReserves() ) {
\r
3026 if ( r.getCh_name() == null ) {
\r
3027 misCN.put(r.getChannel(),recorder.getRecorderId());
\r
3030 if ( misCN.size() > 0 ) {
\r
3031 for ( String cn : misCN.keySet() ) {
\r
3032 String msg = "【警告(予約一覧)】 <"+misCN.get(cn)+"> \"レコーダの放送局名\"を\"Web番組表の放送局名\"に変換できません。CHコード設定に設定を追加してください:\"レコーダの放送局名\"="+cn;
\r
3033 mwin.appendMessage(msg);
\r
3039 /*******************************************************************************
\r
3041 ******************************************************************************/
\r
3043 /***************************************
\r
3044 * ツールバートリガー(と、各種設定変更トリガー)による
\r
3045 **************************************/
\r
3049 * <P>単体実行の場合はこちらを呼び出す
\r
3050 * <P>部品実行の場合はこちらを呼び出す:{@link #loadTVProgram(boolean, LoadFor)}
\r
3051 * @see #doRedrawTVProgram()
\r
3053 private boolean doLoadTVProgram(final boolean force, final LoadFor lf) {
\r
3057 new SwingBackgroundWorker(false) {
\r
3060 protected Object doWorks() throws Exception {
\r
3062 TatCount tc = new TatCount();
\r
3064 loadTVProgram(force, lf);
\r
3066 mwin.appendMessage(String.format("[Web番組表取得] 【完了しました】 所要時間: %.2f秒",tc.end()));
\r
3071 protected void doFinally() {
\r
3072 StWinSetVisible(false);
\r
3076 StWinSetLocationCenter(this);
\r
3077 StWinSetVisible(true);
\r
3084 * @see #doLoadTVProgram(boolean, LoadFor)
\r
3086 private void doRedrawTVProgram() {
\r
3089 paper.clearPanel();
\r
3090 paper.buildMainViewByDate();
\r
3093 paper.redrawTreeByDate();
\r
3094 paper.redrawTreeByPassed();
\r
3096 listed.redrawTreeByHistory();
\r
3097 listed.redrawTreeByCenter();
\r
3100 paper.reselectTree();
\r
3101 listed.reselectTree();
\r
3104 /***************************************
\r
3106 **************************************/
\r
3110 * <P>単体実行の場合はこちらを呼び出す:{@link #doLoadTVProgram(LoadFor)}
\r
3111 * <P>部品実行の場合はこちらを呼び出す
\r
3113 private boolean loadTVProgram(final boolean force, final LoadFor lf) {
\r
3115 final String FUNCID = "[Web番組表取得] ";
\r
3116 final String ERRID = "[ERROR]"+FUNCID;
\r
3122 tvp = tvprograms.getTvProgPlugin(null);
\r
3123 if ( tvp != null )
\r
3125 String sType = "地上波&BS番組表";
\r
3126 if (lf == LoadFor.ALL || lf == LoadFor.TERRA) {
\r
3127 loadTVProgramOnce(tvp, sType, tvp.getSelectedArea(), false, force);
\r
3130 stwin.appendMessage(FUNCID+sType+"へのアクセスはスキップされました: "+tvp.getTVProgramId());
\r
3134 tvp = tvprograms.getCsProgPlugin(null);
\r
3135 if ( tvp != null )
\r
3137 String sType = "CS番組表[プライマリ]";
\r
3138 if (lf == LoadFor.ALL || lf == LoadFor.CS || lf == LoadFor.CSo1 || lf == LoadFor.CSwSD) {
\r
3139 loadTVProgramOnce(tvp, sType, tvp.getSelectedArea(), false, force);
\r
3142 stwin.appendMessage(FUNCID+sType+"へのアクセスはスキップされました: "+tvp.getTVProgramId());
\r
3146 tvp = tvprograms.getCs2ProgPlugin(null);
\r
3147 if ( tvp != null )
\r
3149 String sType = "CS番組表[セカンダリ]";
\r
3150 if (lf == LoadFor.ALL || lf == LoadFor.CS || lf == LoadFor.CSo2 || lf == LoadFor.CSwSD) {
\r
3151 loadTVProgramOnce(tvp, sType, tvp.getSelectedArea(), false, force);
\r
3154 stwin.appendMessage(FUNCID+sType+"へのアクセスはスキップされました: "+tvp.getTVProgramId());
\r
3158 tvp = tvprograms.getSyobo();
\r
3159 if ( tvp != null ) {
\r
3160 String sType = "しょぼかる";
\r
3161 if ( (lf == LoadFor.ALL || lf == LoadFor.SYOBO) && enableWebAccess && env.getUseSyobocal()) {
\r
3162 tvp.loadCenter(tvp.getSelectedCode(), force); // しょぼかるには放送局リストを取得するイベントが他にないので
\r
3163 loadTVProgramOnce(tvp, sType, null, true, force);
\r
3166 stwin.appendMessage(FUNCID+sType+"へのアクセスはスキップされました.");
\r
3169 // しょぼかるの新番組マークを引き継ぐ
\r
3173 PickedProgram pickup = tvprograms.getPickup();
\r
3174 if ( tvp != null ) {
\r
3184 stwin.appendMessage(FUNCID+"検索結果を生成します.");
\r
3185 mpList.clear(env.getDisableFazzySearch(), env.getDisableFazzySearchReverse());
\r
3186 mpList.build(tvprograms, trKeys.getTraceKeys(), srKeys.getSearchKeys());
\r
3189 if ( env.getUsePassedProgram() ) {
\r
3190 TatCount tc = new TatCount();
\r
3191 stwin.appendMessage(FUNCID+"過去ログを生成します.");
\r
3192 if ( tvprograms.getPassed().save(tvprograms.getIterator(), chsort.getClst(), env.getPrepPassedProgramCount()) ) {
\r
3193 msg = String.format(FUNCID+"過去ログを生成しました [%.2f秒].",tc.end());
\r
3194 StdAppendMessage(msg);
\r
3196 //PassedProgramList.getDateList(env.getPassedLogLimit());
\r
3199 stwin.appendMessage(FUNCID+"過去ログは記録されません.");
\r
3202 catch (Exception e) {
\r
3203 e.printStackTrace();
\r
3204 mwin.appendError(ERRID+"番組情報の取得で例外が発生");
\r
3213 private void loadTVProgramOnce(TVProgram tvp, String sType, String aName, boolean loadonly, boolean force) {
\r
3215 final String FUNCID = "[Web番組表取得] ";
\r
3216 // final String ERRID = "[ERROR]"+FUNCID;
\r
3219 String msg = FUNCID+sType+"を取得します: "+tvp.getTVProgramId();
\r
3220 stwin.appendMessage(msg);
\r
3221 if (aName!=null) stwin.appendMessage(FUNCID+"+選択されているエリア="+aName);
\r
3224 //tvp.setProgressArea(stwin);
\r
3225 tvp.loadProgram(tvp.getSelectedCode(), force);
\r
3232 tvp.setExtension(null, null, false, extKeys.getSearchKeys()); // 最初の3引数は盲腸。ダミー
\r
3234 tvp.abon(env.getNgword());
\r
3236 String errmsg = tvp.chkComplete();
\r
3237 if (errmsg != null) {
\r
3238 stwin.appendError(FUNCID+"取得した情報が不正です:"+errmsg);
\r
3239 if (mainWindow!=null) mwin.appendMessage(msg);
\r
3244 // しょぼかるの番組詳細を番組表に反映する
\r
3245 private void attachSyoboNew() {
\r
3246 TVProgram syobo = tvprograms.getSyobo();
\r
3247 if (syobo == null) {
\r
3251 for ( TVProgram tvp : tvprograms ) {
\r
3253 if ( tvp.getType() != ProgType.PROG ) {
\r
3256 if ( ! (tvp.getSubtype() == ProgSubtype.TERRA || tvp.getSubtype() == ProgSubtype.CS || tvp.getSubtype() == ProgSubtype.CS2) ) {
\r
3260 for ( ProgList tvpl : tvp.getCenters() ) {
\r
3261 if ( ! tvpl.enabled) {
\r
3264 for ( ProgList svpl : syobo.getCenters() ) {
\r
3265 if ( ! tvpl.Center.equals(svpl.Center)) {
\r
3268 for ( ProgDateList tvc : tvpl.pdate ) {
\r
3270 ProgDateList mSvc = null;
\r
3271 for ( ProgDateList svc : svpl.pdate ) {
\r
3272 if (tvc.Date.equals(svc.Date) ) {
\r
3277 if (mSvc == null) {
\r
3278 // しょぼかる側に該当する日付自体ないので全部フラグを立てっぱなしでいい
\r
3279 for ( ProgDetailList tvd : tvc.pdetail ) {
\r
3280 if ( tvd.isEqualsGenre(ProgGenre.ANIME, null) ) {
\r
3281 tvd.addOption(ProgOption.NOSYOBO);
\r
3286 // しょぼかる側に該当する日付があるのでマッチング。アニメと映画と音楽
\r
3287 for ( ProgDetailList tvd : tvc.pdetail ) {
\r
3289 // アニメはいったんフラグを立てる
\r
3290 if ( tvd.isEqualsGenre(ProgGenre.ANIME, null) ) {
\r
3291 tvd.addOption(ProgOption.NOSYOBO);
\r
3294 boolean isFind = false;
\r
3295 for ( ProgDetailList svd : mSvc.pdetail ) {
\r
3296 if ( tvd.start.equals(svd.start) ) {
\r
3300 //svd.progid = tvd.progid;
\r
3301 svd.setContentIdStr();
\r
3304 boolean isAnime = tvd.isEqualsGenre(ProgGenre.ANIME, null);
\r
3305 if ( ! isAnime && ! tvd.isEqualsGenre(ProgGenre.MOVIE, null) && ! tvd.isEqualsGenre(ProgGenre.MUSIC, null) ) {
\r
3312 // しょぼかるとWeb番組表の両方に存在する
\r
3313 svd.nosyobo = true;
\r
3317 boolean isAttached = false;
\r
3320 if ( svd.flag == ProgFlags.NEW && tvd.flag != ProgFlags.NEW ) {
\r
3321 tvd.flag = ProgFlags.NEW;
\r
3322 isAttached = true;
\r
3326 if ( svd.flag == ProgFlags.LAST && tvd.flag != ProgFlags.LAST ) {
\r
3327 tvd.flag = ProgFlags.LAST;
\r
3328 isAttached = true;
\r
3332 if ( tvd.isEqualsGenre(ProgGenre.MOVIE, null) && ! tvd.isEqualsGenre(ProgGenre.MOVIE, ProgSubgenre.MOVIE_ANIME) ) {
\r
3333 if ( tvd.genrelist == null ) {
\r
3334 tvd.genrelist = new ArrayList<ProgGenre>();
\r
3335 tvd.genrelist.add(tvd.genre);
\r
3336 tvd.genrelist.add(ProgGenre.MOVIE);
\r
3337 tvd.subgenrelist = new ArrayList<ProgSubgenre>();
\r
3338 tvd.subgenrelist.add(tvd.subgenre);
\r
3339 tvd.subgenrelist.add(ProgSubgenre.MOVIE_ANIME);
\r
3342 tvd.genrelist.add(ProgGenre.MOVIE);
\r
3343 tvd.subgenrelist.add(ProgSubgenre.MOVIE_ANIME);
\r
3345 isAttached = true;
\r
3349 for ( ProgOption sopt : svd.getOption() ) {
\r
3350 if ( tvd.addOption(sopt) && isAttached == false ) {
\r
3351 isAttached = true;
\r
3356 if (isAttached && env.getDebug()) {
\r
3357 StdAppendMessage("しょぼかるのフラグを引き継ぎました: ("+tvpl.Center+") "+tvd.title);
\r
3362 if ( tvd.detail.length() < svd.detail.length() ) {
\r
3363 tvd.detail = svd.detail;
\r
3366 int idx = svd.detail.indexOf("<!");
\r
3368 tvd.detail += svd.detail.substring(idx);
\r
3372 // 「しょぼかるにのみ存在」フラグの上げ下げ(これはアニメ限定)
\r
3375 tvd.removeOption(ProgOption.NOSYOBO); // NOSYOBOって…
\r
3378 //tvd.addOption(ProgOption.NOSYOBO);
\r
3395 private void fixTitle() {
\r
3397 if ( ! env.getFixTitle()) {
\r
3401 for ( TVProgram tvp : tvprograms ) {
\r
3402 //if ( ! (tvp.getType() == ProgType.PROG && tvp.getSubtype() == ProgSubtype.TERRA) ) {
\r
3403 if ( tvp.getType() != ProgType.PROG ) {
\r
3407 for ( ProgList pl : tvp.getCenters() ) {
\r
3408 if ( ! pl.enabled ) {
\r
3412 for ( ProgDateList pcl : pl.pdate ) {
\r
3414 for ( ProgDetailList tvd : pcl.pdetail ) {
\r
3415 if ( tvd.isEqualsGenre(ProgGenre.ANIME, null) ) {
\r
3416 if ( pl.Center.startsWith("NHK") || pl.Center.startsWith("NHK") ) {
\r
3417 // NHK系で先頭が「アニメ 」ではじまるものから「アニメ 」を削除する
\r
3418 tvd.title = tvd.title.replaceFirst("^アニメ[ ・]+","");
\r
3419 tvd.titlePop = TraceProgram.replacePop(tvd.title);
\r
3420 tvd.SearchStrKeys = TraceProgram.splitKeys(tvd.titlePop);
\r
3422 if ( tvd.title.contains("コメンタリ") || tvd.detail.contains("コメンタリ") ) {
\r
3423 // "コメンタリ"の記述のあるものは「副音声」扱いにする(副音声でなくても)
\r
3424 tvd.option.add(ProgOption.MULTIVOICE);
\r
3426 if ( (tvd.title.contains("劇場版") || (tvd.detail.contains("映画") && ! tvd.detail.contains("映画館"))) && ! tvd.isEqualsGenre(ProgGenre.MOVIE, ProgSubgenre.MOVIE_ANIME) ) {
\r
3427 // ジャンル=アニメだがタイトルに「劇場版」が含まれるならジャンル=映画(アニメ映画)を追加する
\r
3428 if ( tvd.genrelist == null ) {
\r
3429 tvd.genrelist = new ArrayList<ProgGenre>();
\r
3430 tvd.genrelist.add(tvd.genre);
\r
3431 tvd.genrelist.add(ProgGenre.MOVIE);
\r
3432 tvd.subgenrelist = new ArrayList<ProgSubgenre>();
\r
3433 tvd.subgenrelist.add(tvd.subgenre);
\r
3434 tvd.subgenrelist.add(ProgSubgenre.MOVIE_ANIME);
\r
3437 tvd.genrelist.add(ProgGenre.MOVIE);
\r
3438 tvd.subgenrelist.add(ProgSubgenre.MOVIE_ANIME);
\r
3442 else if ( tvd.isEqualsGenre(ProgGenre.MOVIE, ProgSubgenre.MOVIE_ANIME) && tvd.subgenre != ProgSubgenre.MOVIE_ANIME ) {
\r
3443 // ジャンル=映画でサブジャンルが複数ありアニメが優先されてないものはアニメを優先する
\r
3444 tvd.subgenre = ProgSubgenre.MOVIE_ANIME;
\r
3447 // サブタイトルを番組追跡の対象から外す
\r
3448 if ( env.getTraceOnlyTitle() && tvd.title != tvd.splitted_title ) {
\r
3449 tvd.SearchStrKeys = TraceProgram.splitKeys(TraceProgram.replacePop(tvd.splitted_title)); // 番組追跡の検索用インデックスは、サブタイトルを削除したもので置き換える
\r
3458 * {@link ProgDetailList} の情報を整形する
\r
3460 private void fixDetail() {
\r
3461 for ( TVProgram tvp : tvprograms ) {
\r
3462 for ( ProgList pl : tvp.getCenters() ) {
\r
3463 if ( ! pl.enabled ) {
\r
3466 for ( ProgDateList pcl : pl.pdate ) {
\r
3467 for ( ProgDetailList tvd : pcl.pdetail ) {
\r
3468 if ( tvd.start == null || tvd.start.length() == 0 ) {
\r
3472 fixDetailSub(tvp, pl, tvd);
\r
3479 private void fixDetailSub(TVProgram tvp, ProgList pl, ProgDetailList tvd) {
\r
3480 tvd.type = tvp.getType();
\r
3481 tvd.subtype = tvp.getSubtype();
\r
3482 tvd.center = pl.Center;
\r
3484 tvd.recmin = CommonUtils.getRecMinVal(tvd.startDateTime, tvd.endDateTime);
\r
3486 tvd.extension_mark = markchar.getExtensionMark(tvd);
\r
3487 tvd.prefix_mark = markchar.getOptionMark(tvd);
\r
3488 tvd.newlast_mark = markchar.getNewLastMark(tvd);
\r
3489 tvd.postfix_mark = markchar.getPostfixMark(tvd);
\r
3491 tvd.dontoverlapdown = (tvd.center.startsWith("NHK") || tvd.center.startsWith("NHK"));
\r
3495 /*******************************************************************************
\r
3497 ******************************************************************************/
\r
3500 * <P>過去ログから検索キーワードにマッチする情報を取得する
\r
3501 * <P>全部検索がヒットした結果がかえるのだから {@link ProgDetailList} ではなく {@link MarkedProgramList} を使うべきなのだが…
\r
3503 private boolean searchPassedProgram(final SearchKey sKey, final String target) {
\r
3505 Matcher ma = Pattern.compile("^(\\d\\d\\d\\d/\\d\\d/\\d\\d)-(\\d\\d\\d\\d/\\d\\d/\\d\\d)$").matcher(target);
\r
3506 if ( ! ma.find() ) {
\r
3510 final GregorianCalendar s = CommonUtils.getCalendar(ma.group(1));
\r
3511 final GregorianCalendar e = CommonUtils.getCalendar(ma.group(2));
\r
3512 final long dDays = (e.getTimeInMillis() - s.getTimeInMillis())/86400000 + 1;
\r
3514 final ArrayList<ProgDetailList> srchpdl = tvprograms.getSearched().getResultBuffer(sKey.getLabel()) ;
\r
3518 // 検索実行(時間がかかるので状況表示する)
\r
3519 new SwingBackgroundWorker(false) {
\r
3522 protected Object doWorks() throws Exception {
\r
3524 TatCount tc = new TatCount();
\r
3527 int resultCnt = 0;
\r
3528 for (int cnt=1; cnt<=dDays; cnt++) {
\r
3530 String passdt = CommonUtils.getDate(e);
\r
3531 stwin.appendMessage(String.format("[過去ログ検索] 検索中:(%d/%d) %s", cnt, dDays, passdt));
\r
3533 PassedProgram tvp = new PassedProgram();
\r
3534 if ( tvp.loadAllCenters(passdt) ) {
\r
3535 for ( ProgList pl : tvp.getCenters() ) {
\r
3536 if ( ! pl.enabled ) {
\r
3540 for ( ProgDateList pcl : pl.pdate ) {
\r
3541 for ( ProgDetailList tvd : pcl.pdetail ) {
\r
3542 if ( tvd.start == null || tvd.start.length() == 0 ) {
\r
3546 if ( SearchProgram.isMatchKeyword(sKey, pl.Center, tvd) ) {
\r
3547 tvd.dynKey = sKey;
\r
3548 tvd.dynMatched = SearchProgram.getMatchedString();
\r
3549 fixDetailSub(tvp, pl, tvd);
\r
3551 if ( ++resultCnt >= env.getSearchResultMax() ) {
\r
3552 mwin.appendMessage(String.format("[過去ログ検索] 検索件数の上限に到達しました。所要時間: %.2f秒",tc.end()));
\r
3561 e.add(Calendar.DATE,-1);
\r
3564 mwin.appendMessage(String.format("[過去ログ検索] 検索完了。所要時間: %.2f秒",tc.end()));
\r
3569 protected void doFinally() {
\r
3570 StWinSetVisible(false);
\r
3574 StWinSetLocationCenter(this);
\r
3575 StWinSetVisible(true);
\r
3581 /*******************************************************************************
\r
3583 ******************************************************************************/
\r
3586 * 番組表のスナップショットをファイルに保存したり印刷したりする
\r
3588 private boolean getSnapshot(int currentpage, int numberofpages) {
\r
3592 if ( mainWindow.isTabSelected(MWinTab.LISTED) ) {
\r
3594 fname = String.format("snapshot.%s",env.getSnapshotFmt().getExtension());
\r
3595 CommonSwingUtils.saveComponentAsJPEG(listed.getCurrentView(), listed.getTableHeader(), null, listed.getTableBody(), fname, env.getSnapshotFmt(), Viewer.this);
\r
3597 else if ( mainWindow.isTabSelected(MWinTab.PAPER) ){
\r
3599 if ( env.getDrawcacheEnable() || ! env.isPagerEnabled() ) {
\r
3600 fname = String.format("snapshot.%s",env.getSnapshotFmt().getExtension());
\r
3603 if ( env.getAllPageSnapshot() ) {
\r
3604 for ( int i=0; i<numberofpages; i++ ) {
\r
3605 if ( i != currentpage ) {
\r
3606 // カレントページは最後にスナップる(再描画を1回で済ませるため)
\r
3607 toolBar.setSelectedPagerIndex(i);
\r
3608 fname = String.format("snapshot%02d.%s",i+1,env.getSnapshotFmt().getExtension());
\r
3609 CommonSwingUtils.saveComponentAsJPEG(paper.getCurrentView(), paper.getCenterPane(), paper.getTimebarPane(), paper.getCurrentPane(), fname, env.getSnapshotFmt(), Viewer.this);
\r
3613 fname = String.format("snapshot%02d.%s",currentpage+1,env.getSnapshotFmt().getExtension());
\r
3614 toolBar.setSelectedPagerIndex(currentpage);
\r
3616 CommonSwingUtils.saveComponentAsJPEG(paper.getCurrentView(), paper.getCenterPane(), paper.getTimebarPane(), paper.getCurrentPane(), fname, env.getSnapshotFmt(), Viewer.this);
\r
3623 Desktop desktop = Desktop.getDesktop();
\r
3624 if (env.getPrintSnapshot()) {
\r
3626 desktop.print(new File(fname));
\r
3630 String emsg = CommonUtils.openFile(fname);
\r
3631 if (emsg != null) {
\r
3632 mwin.appendError(emsg);
\r
3639 } catch (IOException e) {
\r
3640 e.printStackTrace();
\r
3647 /*******************************************************************************
\r
3648 * ここからおおむね初期化処理にかかわるメソッド群
\r
3649 ******************************************************************************/
\r
3654 private boolean setEnv(final boolean reload_prog) {
\r
3660 // CommonUtilsの設定変更
\r
3661 CommonUtils.setAdjLateNight(env.getAdjLateNight());
\r
3662 CommonUtils.setExpandTo8(env.getExpandTo8());
\r
3663 CommonUtils.setUseRundll32(env.getUseRundll32());
\r
3664 CommonUtils.setDisplayPassedReserve(env.getDisplayPassedReserve());
\r
3665 CommonUtils.setDebug(env.getDebug());
\r
3667 SwingBackgroundWorker.setDebug(env.getDebug());
\r
3670 toolBar.setDebug(env.getDebug());
\r
3671 autores.setDebug(env.getDebug());
\r
3672 rdialog.setDebug(env.getDebug());
\r
3674 // PassedProgramListの設定変更
\r
3675 tvprograms.getPassed().setPassedDir(env.getPassedDir());
\r
3678 for ( HDDRecorder rec : recorders ) {
\r
3680 setSettingRecPluginExt(rec, env);
\r
3684 setSettingProgPluginCommon(env);
\r
3687 setSettingProgPluginAll(env);
\r
3690 toolBar.updateReloadReservedExtension();
\r
3691 toolBar.updateReloadProgramExtension();
\r
3693 // ページャーコンボボックスの書き換え
\r
3694 toolBar.setPagerItems();
\r
3697 listed.setMarkColumnVisible(env.getSplitMarkAndTitle());
\r
3698 listed.setDetailColumnVisible(env.getShowDetailOnList());
\r
3699 listed.setRowHeaderVisible(env.getRowHeaderVisible());
\r
3700 reserved.setRowHeaderVisible(env.getRowHeaderVisible());
\r
3703 listed.setMatchedKeywordColor(env.getMatchedKeywordColor());
\r
3704 listed.setRsvdLineColor((env.getRsvdLineEnhance())?(env.getRsvdLineColor()):(null));
\r
3705 listed.setPickedLineColor((env.getRsvdLineEnhance())?(env.getPickedLineColor()):(null));
\r
3706 listed.setCurrentLineColor((env.getCurrentLineEnhance())?(env.getCurrentLineColor()):(null));
\r
3709 setTrayIconVisible(env.getShowSysTray());
\r
3710 setXButtonAction(env.getShowSysTray() && env.getHideToTray());
\r
3712 // 新聞形式のツールチップの表示時間を変更する
\r
3713 setTooltipDelay();
\r
3716 if ( reload_prog ) {
\r
3717 loadTVProgram(false, LoadFor.ALL); // 部品呼び出し
\r
3721 mpList.setHistoryOnlyUpdateOnce(env.getHistoryOnlyUpdateOnce());
\r
3722 mpList.setShowOnlyNonrepeated(env.getShowOnlyNonrepeated());
\r
3724 doRedrawTVProgram(); // か き な お し
\r
3730 private void getTrayIcon() {
\r
3731 if ( trayicon != null ) {
\r
3736 Image image = ImageIO.read(new File(ICONFILE_SYSTRAY));
\r
3737 trayicon = new TrayIcon(image,"Tainavi");
\r
3739 final Viewer thisClass = this;
\r
3742 PopupMenu popup = new PopupMenu();
\r
3744 MenuItem item = new MenuItem("開く");
\r
3745 item.addActionListener(new ActionListener() {
\r
3747 public void actionPerformed(ActionEvent e) {
\r
3748 thisClass.setVisible(true);
\r
3749 thisClass.setState(Frame.NORMAL);
\r
3755 MenuItem item = new MenuItem("終了する");
\r
3756 item.addActionListener(new ActionListener() {
\r
3758 public void actionPerformed(ActionEvent e) {
\r
3765 trayicon.setPopupMenu(popup);
\r
3768 trayicon.addMouseListener(new MouseAdapter() {
\r
3770 public void mouseClicked(MouseEvent e) {
\r
3771 if (e.getButton() == MouseEvent.BUTTON1) {
\r
3772 thisClass.setVisible(true);
\r
3773 thisClass.setState(Frame.NORMAL);
\r
3778 } catch (IOException e) {
\r
3779 StdAppendError("アイコンファイルが読み込めませんでした: "+ICONFILE_SYSTRAY);
\r
3780 e.printStackTrace();
\r
3783 private void setTrayIconVisible(boolean b) {
\r
3785 if ( ! SystemTray.isSupported() || trayicon == null ) {
\r
3792 SystemTray.getSystemTray().remove(trayicon);
\r
3793 SystemTray.getSystemTray().add(trayicon);
\r
3797 SystemTray.getSystemTray().remove(trayicon);
\r
3799 } catch (AWTException e) {
\r
3800 e.printStackTrace();
\r
3803 private void HideToTray() {
\r
3804 if ( SystemTray.isSupported() && trayicon != null && (env.getShowSysTray() && env.getHideToTray()) ) {
\r
3805 this.setVisible(false);
\r
3808 private void setXButtonAction(boolean b) {
\r
3810 this.setDefaultCloseOperation(JFrame.ICONIFIED);
\r
3813 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
\r
3818 private void procArgs(String[] args) {
\r
3820 for (String arg : args) {
\r
3823 if (arg.compareTo("-L") == 0) {
\r
3825 //logging = false;
\r
3827 else if (arg.compareTo("-L") == 0) {
\r
3831 else if (arg.compareTo("-w") == 0) {
\r
3833 runRecWakeup = true;
\r
3835 else if (arg.compareTo("-nowebaccess") == 0) {
\r
3836 // -nowebaccess : 起動時のWeb番組表へのアクセス無効
\r
3837 enableWebAccess = false;
\r
3839 else if (arg.compareTo("-proxy") == 0) {
\r
3840 // -proxy : Web番組表へのアクセスにProxy経由を強制する
\r
3843 else if (arg.compareTo("-loadrec") == 0) {
\r
3844 // -loadrec : 起動時にレコーダにアクセスする
\r
3845 runRecLoad = true;
\r
3847 else if (arg.compareTo("-onlyLoadProgram") == 0) {
\r
3848 // -onlyLoadProgram : 番組表の取得だけ行う
\r
3849 onlyLoadProgram = true;
\r
3853 String[] dat = arg.split(":");
\r
3854 if (dat.length == 1 ) {
\r
3857 } if (dat.length >= 2 ) {
\r
3867 // メインの環境設定ファイルを読みだす
\r
3868 private void loadEnvfile() {
\r
3869 StdAppendMessage("【環境設定】環境設定ファイルを読み込みます.");
\r
3873 // 引き続きその他の環境設定ファイルも読みだす
\r
3874 private void procEnvs() {
\r
3876 StdAppendMessage("【環境設定】環境設定ファイル類を読み込みます.");
\r
3882 recInfoList.load();
\r
3885 if (pxaddr != null) {
\r
3886 env.setUseProxy(true);
\r
3887 env.setProxyAddr(pxaddr);
\r
3888 env.setProxyPort(pxport);
\r
3891 // Cookieの処理を入れようとしたけど無理だった
\r
3894 CookieManager manager = new CookieManager();
\r
3895 manager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
\r
3896 CookieHandler.setDefault(manager);
\r
3903 // 深夜の帯予約の補正(一日前にずらす)
\r
3904 // 可能なら番組表を8日分取得する
\r
3905 // 【WIN】ファイルオープンにrundll32を使用する
\r
3906 CommonUtils.setAdjLateNight(env.getAdjLateNight());
\r
3907 CommonUtils.setExpandTo8(env.getExpandTo8());
\r
3908 CommonUtils.setUseRundll32(env.getUseRundll32());
\r
3909 CommonUtils.setDisplayPassedReserve(env.getDisplayPassedReserve());
\r
3910 CommonUtils.setDebug(env.getDebug());
\r
3912 SwingBackgroundWorker.setDebug(env.getDebug());
\r
3918 bounds.setLoaded(bounds.load());
\r
3936 // スポーツ延長警告のデフォルト設定のコードはもういらないので削除(3.15.4β)
\r
3938 // 簡易描画はもういらないので削除
\r
3945 private void chkDualBoot() {
\r
3946 if ( ! env.getOnlyOneInstance() ) {
\r
3950 if ( ! CommonUtils.getLock() ) {
\r
3956 Runtime.getRuntime().addShutdownHook(new Thread() {
\r
3957 public void run() {
\r
3958 // 鯛ナビ終了時にロックを解除する
\r
3959 CommonUtils.getUnlock();
\r
3965 private void chkVerUp() {
\r
3966 if ( ! enableWebAccess || onlyLoadProgram ) {
\r
3967 stwin.appendError("【オンラインアップデート】オンラインアップデートは無効です");
\r
3971 VWUpdate vu = new VWUpdate(stwin);
\r
3972 if ( ! vu.isExpired(env.getUpdateMethod()) ) {
\r
3973 // メッセージはVWUpdate内で出力されます
\r
3976 if ( doVerUp(vu) ) {
\r
3981 private boolean doVerUp(VWUpdate vu) {
\r
3982 UpdateResult res = vu.checkUpdate(VersionInfo.getVersion());
\r
3986 // 履歴は更新しない(連続アップデートがあるかも知れないので)
\r
3987 LogViewer lv = new LogViewer(HISTORY_FILE);
\r
3988 lv.setModal(true);
\r
3989 lv.setCaretPosition(0);
\r
3990 lv.setVisible(true);
\r
3994 // 履歴は更新しない(次回に持ち越し)
\r
3998 vu.updateHistory();
\r
4002 // 履歴は更新しない(次回再挑戦)
\r
4009 * レコーダプラグインをすべて読み込みます。
\r
4011 private boolean loadRecPlugins() {
\r
4013 stwin.appendMessage("【レコーダプラグイン】プラグインを読み込みます.");
\r
4015 boolean isMailPluginEnabled = false;
\r
4017 Class.forName("javax.mail.Session");
\r
4018 isMailPluginEnabled = true;
\r
4020 catch ( Exception e ) {
\r
4021 System.err.println("【レコーダプラグイン】メール系プラグイン用の外部ライブラリがみつかりません: "+e.toString());
\r
4024 boolean isCalendarPluginEnabled = false;
\r
4026 Class.forName("com.google.gdata.client.calendar.CalendarService");
\r
4027 isCalendarPluginEnabled = true;
\r
4029 catch ( Exception e ) {
\r
4030 System.err.println("【レコーダプラグイン】カレンダー系プラグイン用の外部ライブラリがみつかりません: "+e.toString());
\r
4034 ArrayList<String> recIda = new ArrayList<String>();
\r
4035 for ( File f : new File(CommonUtils.joinPath(new String[]{"bin","tainavi"})).listFiles() ) {
\r
4036 Matcher ma = Pattern.compile("^(PlugIn_Rec[^$]+)[^$]*\\.class$").matcher(f.getName());
\r
4037 if ( ma.find() ) {
\r
4038 if ( ! isMailPluginEnabled && f.getName().toLowerCase().contains("mail") ) {
\r
4039 System.out.println("【レコーダプラグイン】メール系プラグインは無効です: "+f.getName());
\r
4042 if ( ! isCalendarPluginEnabled && f.getName().toLowerCase().contains("calendar") ) {
\r
4043 System.out.println("【レコーダプラグイン】カレンダー系プラグインは無効です: "+f.getName());
\r
4047 recIda.add(ma.group(1));
\r
4050 String[] recIdd = recIda.toArray(new String[0]);
\r
4051 Arrays.sort(recIdd);
\r
4054 StringBuilder sb = new StringBuilder();
\r
4055 for ( String recId : recIdd ) {
\r
4056 sb.append("tainavi.");
\r
4060 if ( ! CommonUtils.write2file(CommonUtils.joinPath(new String[] {"bin","META-INF","services","tainavi.HDDRecorder"}), sb.toString()) ) {
\r
4061 stwin.appendError("【レコーダプラグイン】プラグインの読み込みに失敗しました: ");
\r
4065 // ここで例外が起きてもトラップできない、スレッドが落ちる
\r
4066 ServiceLoader<HDDRecorder> r = ServiceLoader.load(HDDRecorder.class);
\r
4068 recPlugins.clear();
\r
4069 for ( HDDRecorder recorder : r ) {
\r
4070 if (env.getDebug()) {
\r
4071 StdAppendMessage("+追加します: "+recorder.getRecorderId());
\r
4073 recPlugins.add(recorder.clone());
\r
4074 StdAppendMessage("+追加しました: "+recorder.getRecorderId());
\r
4081 * レコーダ設定をもとにレコーダプラグインから実レコーダのインスタンスを生成します。
\r
4083 private void initRecPluginAll() {
\r
4085 recorders.clear();
\r
4086 for ( RecorderInfo ri : recInfoList ) {
\r
4087 ArrayList<HDDRecorder> rl = recPlugins.findPlugin(ri.getRecorderId());
\r
4088 if ( rl.size() == 0 ) {
\r
4089 stwin.appendError("【レコーダプラグイン】プラグインがみつかりません: "+ri.getRecorderId()+"("+ri.getRecorderIPAddr()+":"+ri.getRecorderPortNo()+")");
\r
4092 stwin.appendMessage("【レコーダプラグイン】プラグインを初期化します: "+ri.getRecorderId()+"("+ri.getRecorderIPAddr()+":"+ri.getRecorderPortNo()+")");
\r
4093 for ( HDDRecorder rPlugin : rl ) {
\r
4094 initRecPlugin(rPlugin, ri);
\r
4099 protected HDDRecorder initRecPlugin(HDDRecorder rPlugin, RecorderInfo ri) {
\r
4100 HDDRecorder rec = rPlugin.clone();
\r
4101 recorders.add(rec);
\r
4103 rec.getChCode().load(true); // true : ログ出力あり
\r
4104 setSettingRecPluginBase(rec, ri);
\r
4105 setSettingRecPluginExt(rec,env);
\r
4106 rec.setProgressArea(stwin);
\r
4109 protected void setSettingRecPluginBase(HDDRecorder to, RecorderInfo from) {
\r
4110 to.setIPAddr(from.getRecorderIPAddr());
\r
4111 to.setPortNo(from.getRecorderPortNo());
\r
4112 to.setUser(from.getRecorderUser());
\r
4113 to.setPasswd(from.getRecorderPasswd());
\r
4114 to.setMacAddr(from.getRecorderMacAddr());
\r
4115 to.setBroadcast(from.getRecorderBroadcast());
\r
4116 to.setUseCalendar(from.getUseCalendar());
\r
4117 to.setUseChChange(from.getUseChChange());
\r
4118 to.setRecordedCheckScope(from.getRecordedCheckScope());
\r
4119 to.setTunerNum(from.getTunerNum());
\r
4120 to.setColor(from.getRecorderColor());
\r
4122 protected void setSettingRecPluginExt(HDDRecorder recorder, Env nEnv) {
\r
4123 recorder.setUserAgent(nEnv.getUserAgent());
\r
4124 recorder.setDebug(nEnv.getDebug());
\r
4125 recorder.setAdjNotRep(nEnv.getAdjoiningNotRepetition());
\r
4126 recorder.setRecordedSaveScope(nEnv.getRecordedSaveScope());
\r
4130 protected void doRecWakeup() {
\r
4131 for ( HDDRecorder rec : recorders ) {
\r
4132 if ( ! rec.getMacAddr().equals("") && ! rec.getBroadcast().equals("") ) {
\r
4141 private boolean isOLPExpired(int expire) {
\r
4142 String fname = "env"+File.separator+"olp.history";
\r
4143 if ( ! new File(fname).exists() || ! new File(fname).canWrite() ) {
\r
4144 stwin.appendError("【警告】実行履歴ファイルがないから実行させないよ!");
\r
4148 String dat = CommonUtils.read4file(fname, true);
\r
4149 if ( dat == null ) {
\r
4150 stwin.appendError("【警告】実行履歴を取得できなかったから実行させないよ!");
\r
4154 GregorianCalendar ca = null;
\r
4155 dat = EncryptPassword.dec(b64.dec(dat));
\r
4156 if ( dat != null ) {
\r
4157 ca = CommonUtils.getCalendar(dat);
\r
4159 if ( ca == null ) {
\r
4160 stwin.appendError("【警告】実行履歴の内容が不正だったから実行させないよ! "+dat);
\r
4164 if ( CommonUtils.getCompareDateTime(ca, CommonUtils.getCalendar(-expire*3600)) >= 0 ) {
\r
4165 ca.add(Calendar.HOUR,expire);
\r
4166 stwin.appendError("【警告】"+expire+"時間以内の再実行は許さないよ!"+CommonUtils.getDateTime(ca)+"まで待って!");
\r
4170 if ( ! CommonUtils.write2file(fname, b64.enc(EncryptPassword.enc(CommonUtils.getDateTime(0)))) ) {
\r
4171 stwin.appendError("【警告】実行履歴を保存できなかったから実行させないよ!");
\r
4180 * Web番組表プラグインをすべて読み込みます。
\r
4182 private boolean loadProgPlugins() {
\r
4184 final String FUNCID = "[Web番組表プラグイン組込] ";
\r
4185 final String ERRID = "[ERROR]"+FUNCID;
\r
4188 stwin.appendMessage(FUNCID+"プラグインを読み込みます.");
\r
4191 setSettingProgPluginCommon(env);
\r
4197 // TVProgramListのインスタンスは別途初期化が必要
\r
4198 progPlugins.clear();
\r
4199 tvprograms.clear();
\r
4205 ArrayList<String> prgIda = new ArrayList<String>();
\r
4206 for ( File f : new File(CommonUtils.joinPath("bin","tainavi")).listFiles() ) {
\r
4207 Matcher ma = Pattern.compile("^(PlugIn_(TV|CS|RAD)P[^$]+)\\.class$").matcher(f.getName());
\r
4209 prgIda.add(ma.group(1));
\r
4212 String[] prgIdd = prgIda.toArray(new String[0]);
\r
4213 Arrays.sort(prgIdd);
\r
4216 StringBuilder sb = new StringBuilder();
\r
4217 for ( String prgId : prgIdd ) {
\r
4218 sb.append("tainavi.");
\r
4222 if ( ! CommonUtils.write2file(CommonUtils.joinPath("bin","META-INF","services","tainavi.TVProgram"), sb.toString()) ) {
\r
4223 stwin.appendError(ERRID+"プラグインの読み込みに失敗しました: ");
\r
4227 ServiceLoader<TVProgram> p = ServiceLoader.load(TVProgram.class);
\r
4229 // 実際必要ないのだが、プラグインのインスタンスはclone()して使う
\r
4230 for ( TVProgram pg : p ) {
\r
4231 TVProgram prog = pg.clone();
\r
4233 stwin.appendMessage("+追加しました: "+prog.getTVProgramId());
\r
4235 // CH設定タブではプラグイン側のインスタンスを使うので情報を追加してやる必要があるのであった
\r
4236 setSettingProgPlugin(prog, env);
\r
4238 progPlugins.add(prog);
\r
4247 * 設定にあわせてWeb番組表プラグインを絞り込みます。
\r
4249 private void setSelectedProgPlugin() {
\r
4252 Syobocal syobo = tvprograms.getSyobo();
\r
4253 PassedProgram passed = tvprograms.getPassed();
\r
4254 PickedProgram pickup = tvprograms.getPickup();
\r
4255 SearchResult searched = tvprograms.getSearched();
\r
4257 tvprograms.clear();
\r
4260 TVProgram tvp = progPlugins.getTvProgPlugin(env.getTVProgramSite());
\r
4261 if ( tvp == null ) {
\r
4262 // デフォルトもなければ先頭にあるもの
\r
4263 tvp = progPlugins.getTvProgPlugin(null);
\r
4265 if ( tvp == null ) {
\r
4267 StdAppendError("【Web番組表選択】地上波&BS番組表が選択されていません: "+env.getTVProgramSite());
\r
4270 StdAppendMessage("【Web番組表選択】地上波&BS番組表が選択されました: "+tvp.getTVProgramId());
\r
4271 tvprograms.add(tvp.clone());
\r
4275 TVProgram tvp = progPlugins.getCsProgPlugin(env.getCSProgramSite());
\r
4276 if ( tvp == null ) {
\r
4277 tvp = progPlugins.getCsProgPlugin(null);
\r
4279 if ( tvp == null ) {
\r
4280 StdAppendError("【Web番組表選択】CS番組表[プライマリ]が選択されていません: "+env.getCSProgramSite());
\r
4283 StdAppendMessage("【Web番組表選択】CS番組表[プライマリ]が選択されました: "+tvp.getTVProgramId());
\r
4284 tvprograms.add(tvp.clone());
\r
4288 TVProgram tvp = progPlugins.getCs2ProgPlugin(env.getCS2ProgramSite());
\r
4289 if ( tvp == null ) {
\r
4290 tvp = progPlugins.getCs2ProgPlugin(null);
\r
4292 if ( tvp == null ) {
\r
4293 StdAppendError("【Web番組表選択】CS番組表[プライマリ]が選択されていません: "+env.getCS2ProgramSite());
\r
4296 StdAppendMessage("【Web番組表選択】CS番組表[プライマリ]が選択されました: "+tvp.getTVProgramId());
\r
4297 tvprograms.add(tvp.clone());
\r
4301 if ( progPlugins.getRadioProgPlugins().size() > 0 )
\r
4303 TVProgram tvp = progPlugins.getCsProgPlugin(env.getRadioProgramSite());
\r
4304 if ( tvp == null ) {
\r
4305 tvp = progPlugins.getCsProgPlugin(null);
\r
4307 if ( tvp == null ) {
\r
4308 StdAppendError("【Web番組表選択】ラジオ番組表が選択されていません: "+env.getRadioProgramSite());
\r
4311 StdAppendMessage("【Web番組表選択】ラジオ番組表が選択されました: "+tvp.getTVProgramId());
\r
4312 tvprograms.add(tvp.clone());
\r
4318 if ( syobo == null ) {
\r
4319 syobo = new Syobocal();
\r
4321 tvprograms.add(syobo);
\r
4324 if ( passed == null ) {
\r
4325 passed = new PassedProgram();
\r
4327 tvprograms.add(passed);
\r
4330 if ( pickup == null ) {
\r
4331 pickup = new PickedProgram();
\r
4332 pickup.loadProgram(null, false);
\r
4334 tvprograms.add(pickup);
\r
4337 if ( searched == null ) {
\r
4338 searched = new SearchResult();
\r
4340 tvprograms.add(searched);
\r
4345 * Web番組表設定をもとにレコーダプラグインのインスタンスを生成します。
\r
4347 private void initProgPluginAll() {
\r
4349 final String FUNCID = "[Web番組表プラグイン初期化] ";
\r
4350 final LinkedHashMap<ArrayList<TVProgram>,String> map = new LinkedHashMap<ArrayList<TVProgram>, String>();
\r
4351 map.put(tvprograms.getTvProgPlugins(), "地上波&BS番組表");
\r
4352 map.put(tvprograms.getCsProgPlugins(), "CS番組表[プライマリ]");
\r
4353 map.put(tvprograms.getCs2ProgPlugins(), "CS番組表[セカンダリ]");
\r
4354 //map.put(progPlugins.getRadioProgPlugins(), "ラジオ番組表");
\r
4356 new SwingBackgroundWorker(true) {
\r
4359 protected Object doWorks() throws Exception {
\r
4361 for ( ArrayList<TVProgram> tvpa : map.keySet() ) {
\r
4362 stwin.appendMessage(FUNCID+map.get(tvpa)+"のベース情報(放送局リストなど)を取得します.");
\r
4363 for ( TVProgram p : tvpa ) {
\r
4364 stwin.appendMessage(FUNCID+"プラグインを初期化します: "+p.getTVProgramId());
\r
4367 // 個別設定(2) …(1)と(2)の順番が逆だったので前に移動してきました(3.17.3β)
\r
4368 setSettingProgPlugin(p,env); // 他からも呼び出される部分だけ分離
\r
4371 p.setOptString(null); // フリーオプション初期化
\r
4372 p.loadAreaCode(); // 放送エリア情報取得
\r
4373 p.loadCenter(p.getSelectedCode(),false); // 放送局情報取得
\r
4374 p.setSortedCRlist(); // 有効放送局だけよりわける
\r
4376 catch (Exception e) {
\r
4377 stwin.appendError(FUNCID+"ベース情報の取得に失敗しました.");
\r
4378 e.printStackTrace();
\r
4384 //setSettingProgPluginAll(env);
\r
4386 if ( env.getUseSyobocal() ) {
\r
4387 TVProgram syobo = tvprograms.getSyobo();
\r
4388 if ( syobo != null ) {
\r
4389 stwin.appendMessage(FUNCID+"しょぼかるを初期化します.");
\r
4390 setSettingProgPlugin(syobo,env); // 他からも呼び出される部分だけ分離
\r
4391 syobo.setUserAgent("tainavi");
\r
4392 syobo.setOptString(null); // フリーオプション初期化
\r
4393 syobo.loadCenter(syobo.getSelectedCode(), false);
\r
4401 protected void doFinally() {
\r
4405 protected void setSettingProgPluginAll(Env nEnv) {
\r
4407 setSettingProgPlugin(tvprograms.getTvProgPlugin(null),nEnv);
\r
4408 setSettingProgPlugin(tvprograms.getCsProgPlugin(null),nEnv);
\r
4409 setSettingProgPlugin(tvprograms.getCs2ProgPlugin(null),nEnv);
\r
4410 //setSettingProgPlugin(tvprograms.getRadioProgPlugin(null),nEnv);
\r
4411 setSettingProgPlugin(tvprograms.getSyobo(),nEnv);
\r
4414 tvprograms.getSyobo().setUserAgent("tainavi");
\r
4416 tvprograms.getSearched().setResultBufferMax(nEnv.getSearchResultBufferMax());
\r
4418 protected void setSettingProgPlugin(TVProgram p, Env nEnv) {
\r
4419 if ( p == null ) {
\r
4422 p.setUserAgent(nEnv.getUserAgent());
\r
4423 p.setProgDir(nEnv.getProgDir());
\r
4424 p.setCacheExpired((enableWebAccess)?(nEnv.getCacheTimeLimit()):(0));
\r
4425 p.setContinueTomorrow(nEnv.getContinueTomorrow());
\r
4426 p.setExpandTo8(nEnv.getExpandTo8());
\r
4427 //p.setUseDetailCache(nEnv.getUseDetailCache());
\r
4428 p.setUseDetailCache(false);
\r
4429 p.setSplitEpno(nEnv.getSplitEpno());
\r
4433 * staticで持っている共通設定の更新
\r
4435 protected void setSettingProgPluginCommon(Env nEnv) {
\r
4437 if ( nEnv.getUseProxy() && (nEnv.getProxyAddr().length() > 0 && nEnv.getProxyPort().length() > 0) ) {
\r
4438 stwin.appendMessage("+Web番組表へのアクセスにProxyが設定されています: "+nEnv.getProxyAddr()+":"+nEnv.getProxyPort());
\r
4439 TVProgramUtils.setProxy(nEnv.getProxyAddr(),nEnv.getProxyPort());
\r
4442 TVProgramUtils.setProxy(null,null);
\r
4445 TVProgramUtils.setProgressArea(stwin);
\r
4446 TVProgramUtils.setChConv(chconv);
\r
4450 private void initMpList() {
\r
4451 //mpList = new MarkedProgramList(); // 検索結果リスト
\r
4452 mpList.setHistoryOnlyUpdateOnce(env.getHistoryOnlyUpdateOnce());
\r
4453 mpList.setShowOnlyNonrepeated(env.getShowOnlyNonrepeated());
\r
4457 private void initLookAndFeelAndFont() {
\r
4461 vwlaf = new VWLookAndFeel();
\r
4463 String lafname = vwlaf.update(env.getLookAndFeel());
\r
4464 if ( lafname != null && ! lafname.equals(env.getLookAndFeel())) {
\r
4465 env.setLookAndFeel(lafname);
\r
4468 if ( CommonUtils.isMac() ) {
\r
4469 UIManager.getDefaults().put("Table.gridColor", new Color(128,128,128));
\r
4470 //UIManager.getDefaults().put("Table.selectionBackground", new Color(182,207,229));
\r
4471 //UIManager.getDefaults().put("Table.selectionForeground", new Color(0,0,0));
\r
4476 vwfont = new VWFont();
\r
4478 String fname = vwfont.update(env.getFontName(),env.getFontSize());
\r
4479 if ( fname != null && ! fname.equals(env.getFontName())) {
\r
4480 env.setFontName(fname);
\r
4484 catch ( Exception e ) {
\r
4485 // 落ちられると困るからトラップしておこうぜ
\r
4486 e.printStackTrace();
\r
4490 // L&FやFontを変えたらコンポーネントに通知が必要
\r
4491 protected void updateComponentTreeUI() {
\r
4493 SwingUtilities.updateComponentTreeUI(this);
\r
4494 SwingUtilities.updateComponentTreeUI(stwin);
\r
4495 SwingUtilities.updateComponentTreeUI(mwin);
\r
4496 SwingUtilities.updateComponentTreeUI(pcwin);
\r
4497 SwingUtilities.updateComponentTreeUI(rdialog);
\r
4498 SwingUtilities.updateComponentTreeUI(ccwin);
\r
4500 catch ( Exception e ) {
\r
4501 // 落ちられると困るからトラップしておこうぜ
\r
4502 e.printStackTrace();
\r
4506 // ツールチップの表示遅延時間を設定する
\r
4507 private void setTooltipDelay() {
\r
4508 ToolTipManager tp = ToolTipManager.sharedInstance();
\r
4509 tp.setInitialDelay(env.getTooltipInitialDelay()*100);
\r
4510 tp.setDismissDelay(env.getTooltipDismissDelay()*100);
\r
4515 * @return true:前回終了時の設定がある場合
\r
4517 private boolean buildMainWindow() {
\r
4522 mainWindow = new VWMainWindow();
\r
4525 toolBar = new VWToolBar();
\r
4526 listed = new VWListedView();
\r
4527 paper = new VWPaperView();
\r
4528 reserved = new VWReserveListView();
\r
4529 recorded = new VWRecordedListView();
\r
4530 autores = new VWAutoReserveListView();
\r
4531 setting = new VWSettingView();
\r
4532 recsetting = new VWRecorderSettingView();
\r
4533 chsetting = new VWChannelSettingView();
\r
4534 chdatsetting = new VWChannelDatSettingView();
\r
4535 chsortsetting = new VWChannelSortView();
\r
4536 chconvsetting = new VWChannelConvertView();
\r
4542 toolBar.setDebug(env.getDebug());
\r
4543 autores.setDebug(env.getDebug());
\r
4544 rdialog.setDebug(env.getDebug());
\r
4547 toolBar.setPagerItems();
\r
4553 mainWindow.addToolBar(toolBar);
\r
4554 mainWindow.addStatusArea(mwin);
\r
4557 mainWindow.addTab(listed, MWinTab.LISTED);
\r
4558 mainWindow.addTab(paper, MWinTab.PAPER);
\r
4559 mainWindow.addTab(reserved, MWinTab.RSVED);
\r
4560 mainWindow.addTab(recorded, MWinTab.RECED);
\r
4561 mainWindow.addTab(autores, MWinTab.AUTORES);
\r
4562 mainWindow.addTab(setting, MWinTab.SETTING);
\r
4563 mainWindow.addTab(recsetting, MWinTab.RECSET);
\r
4564 mainWindow.addTab(chsetting, MWinTab.CHSET);
\r
4565 mainWindow.addTab(chsortsetting, MWinTab.CHSORT);
\r
4566 mainWindow.addTab(chconvsetting, MWinTab.CHCONV);
\r
4567 mainWindow.addTab(chdatsetting, MWinTab.CHDAT);
\r
4571 setStatusVisible(bounds.getShowStatus());
\r
4574 paper.clearPanel();
\r
4575 paper.buildMainViewByDate();
\r
4580 private void ShowInitTab() {
\r
4583 mainWindow.setSelectedTab(null);
\r
4585 if ( recInfoList.size() <= 0 ) {
\r
4587 mainWindow.setSelectedTab(MWinTab.RECSET);
\r
4591 MWinTab tab = MWinTab.getAt(bounds.getSelectedTab());
\r
4592 mainWindow.setSelectedTab(tab);
\r
4597 private void setInitBounds() {
\r
4598 // ウィンドウのサイズと表示位置を設定する
\r
4599 Rectangle window = bounds.getWinRectangle();
\r
4600 if (bounds.isLoaded()) {
\r
4601 // 設定ファイルを読み込んであったらそれを設定する
\r
4602 System.out.println(DBGID+"set bounds "+window);
\r
4603 this.setBounds(window.x, window.y, window.width, window.height);
\r
4606 // 設定ファイルがなければ自動設定する
\r
4607 Rectangle screen = this.getGraphicsConfiguration().getBounds();
\r
4609 int w = window.width;
\r
4610 if (window.width > screen.width) {
\r
4615 x = (screen.width - window.width)/2;
\r
4618 int h = window.height;
\r
4619 if (window.height > screen.height) {
\r
4621 h = screen.height;
\r
4624 y = (screen.height - window.height)/2;
\r
4626 this.setBounds(x, y, w, h);
\r
4632 * {@link VWMainWindow#setStatusVisible(boolean)}の置き換え
\r
4634 private void setStatusVisible(boolean b) {
\r
4637 listed.setDetailVisible(true);
\r
4638 paper.setDetailVisible(true);
\r
4639 MWinSetVisible(true);
\r
4642 listed.setDetailVisible(false);
\r
4643 paper.setDetailVisible(false);
\r
4644 MWinSetVisible(false);
\r
4648 // フルスクリーンモードをトグル切り替え
\r
4649 private Dimension f_dim;
\r
4650 private Point f_pnt;
\r
4651 private int divloc_l = 0;
\r
4652 private int divloc_p = 0;
\r
4654 private void setFullScreen(boolean b) {
\r
4656 if ( b == true ) {
\r
4659 this.setUndecorated(true);
\r
4660 this.setVisible(true);
\r
4663 Toolkit tk = getToolkit();
\r
4664 Insets in = tk.getScreenInsets(getGraphicsConfiguration());
\r
4665 Dimension d = tk.getScreenSize();
\r
4666 f_dim = this.getSize();
\r
4667 f_pnt = this.getLocation();
\r
4668 this.setBounds(in.left, in.top, d.width-(in.left+in.right), d.height-(in.top+in.bottom));
\r
4670 divloc_l = bounds.getTreeWidth();
\r
4671 divloc_p = bounds.getTreeWidthPaper();
\r
4674 paper.setCollapseTree();
\r
4675 listed.setCollapseTree();
\r
4678 if ( f_pnt != null && f_dim != null ) { // 起動直後などは値がないですしね
\r
4682 this.setUndecorated(false);
\r
4683 this.setVisible(true);
\r
4686 this.setBounds(f_pnt.x, f_pnt.y, f_dim.width, f_dim.height);
\r
4688 bounds.setTreeWidth(divloc_l);
\r
4689 bounds.setTreeWidthPaper(divloc_p);
\r
4692 paper.setExpandTree();
\r
4693 listed.setExpandTree();
\r
4699 private void setTitleBar() {
\r
4700 MemoryMXBean mbean = ManagementFactory.getMemoryMXBean();
\r
4701 MemoryUsage heapUsage = mbean.getHeapMemoryUsage();
\r
4705 "%s - %s - Memory Usage Max:%dM Committed:%dM Used:%dM - FrameBuffer Status:%s",
\r
4706 VersionInfo.getVersion(),
\r
4707 CommonUtils.getDateTime(0),
\r
4708 heapUsage.getMax()/(1024*1024),
\r
4709 heapUsage.getCommitted()/(1024*1024),
\r
4710 heapUsage.getUsed()/(1024*1024),
\r
4711 (paper!=null)?(paper.getFrameBufferStatus()):("N/A")
\r
4717 private void ExitOnClose() {
\r
4719 if ( ! this.toolBar.isFullScreen()) {
\r
4720 Rectangle r = this.getBounds();
\r
4721 bounds.setWinRectangle(r);
\r
4724 Rectangle r = new Rectangle();
\r
4725 r.x = this.f_pnt.x;
\r
4726 r.y = this.f_pnt.y;
\r
4727 r.width = this.f_dim.width;
\r
4728 r.height = this.f_dim.height;
\r
4729 bounds.setWinRectangle(r);
\r
4731 listed.copyColumnWidth();
\r
4732 reserved.copyColumnWidth();
\r
4734 bounds.setStatusRows(mwin.getRows());
\r
4737 bounds.setSelectedTab(mainWindow.getSelectedTab().getIndex());
\r
4738 bounds.setShowSettingTabs(mainWindow.getShowSettingTabs());
\r
4739 bounds.setSelectedRecorderId(toolBar.getSelectedRecorder());
\r
4740 bounds.setShowStatus(toolBar.isStatusShown());
\r
4746 listed.saveTreeExpansion();
\r
4747 paper.saveTreeExpansion();
\r
4751 /*******************************************************************************
\r
4753 ******************************************************************************/
\r
4756 private static boolean initialized = false;
\r
4757 private static Viewer myClass = null;
\r
4762 * @throws NoSuchAlgorithmException
\r
4763 * @version 今まで初期化を行ってからウィンドウを作成していたが<BR>
\r
4764 * 途中で例外が起こるとダンマリの上にゾンビになってたりとヒドかったので<BR>
\r
4765 * 先にウィンドウを作成してから初期化を行うように変えました
\r
4766 * @throws InterruptedException
\r
4767 * @throws InvocationTargetException
\r
4769 public static void main(final String[] args) throws NoSuchAlgorithmException, InvocationTargetException, InterruptedException {
\r
4771 if ( myClass != null ) {
\r
4772 // 既に起動していたらフォアグラウンドにする
\r
4773 SwingUtilities.invokeAndWait(new Runnable() {
\r
4775 public void run() {
\r
4777 myClass.setVisible(true);
\r
4778 myClass.setState(Frame.NORMAL);
\r
4784 SwingUtilities.invokeLater(new Runnable() {
\r
4785 public void run() {
\r
4787 final Viewer thisClass = myClass = new Viewer(args);
\r
4789 thisClass.addComponentListener(new ComponentAdapter() {
\r
4791 public void componentShown(ComponentEvent e) {
\r
4794 thisClass.removeComponentListener(this);
\r
4797 thisClass.initialize(args);
\r
4802 thisClass.setVisible(true);
\r
4809 /*******************************************************************************
\r
4811 ******************************************************************************/
\r
4816 public Viewer(final String[] args) {
\r
4821 bounds.loadText();
\r
4824 // 初期化が終わるまでは閉じられないよ → どうせステータスウィンドウにブロックされて操作できない
\r
4825 //setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
\r
4826 //setResizable(false);
\r
4828 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
\r
4833 Image image = ImageIO.read(new File(ICONFILE_TAINAVI));
\r
4834 setIconImage(image);
\r
4836 catch (IOException e) {
\r
4837 StdAppendError("[ERROR] アイコンが設定できない: "+e.toString());
\r
4840 JLabel jLabel_splash_img = new JLabel(new ImageIcon("splash.gif"));
\r
4841 jLabel_splash_img.setPreferredSize(new Dimension(400,300));
\r
4842 //getContentPane().setLayout(new BorderLayout());
\r
4843 getContentPane().add(jLabel_splash_img, BorderLayout.CENTER);
\r
4846 setLocationRelativeTo(null); // 画面の真ん中に
\r
4848 // SwingLocker共有設定
\r
4849 SwingLocker.setOwner(this);
\r
4851 // とりあえずルックアンドフィールはリセットしておかないとだめっぽいよ
\r
4852 initLookAndFeelAndFont();
\r
4853 updateComponentTreeUI();
\r
4856 // 初期化をバックグラウンドで行う
\r
4857 private void initialize(final String[] args) {
\r
4861 // 初期化処理はバックグラウンドで行う
\r
4862 new SwingBackgroundWorker(false) {
\r
4865 protected Object doWorks() throws Exception {
\r
4867 TatCount tc = new TatCount();
\r
4870 _initialize(args);
\r
4872 // 終わったら閉じられるようにするよ
\r
4873 //setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
\r
4874 //setResizable(true);
\r
4877 stwin.appendMessage(String.format("【タイニー番組ナビゲータが起動しました】 所要時間: %.2f秒",tc.end()));
\r
4882 protected void doFinally() {
\r
4883 if ( ! initialized ) System.err.println("[ERROR][鯛ナビ] 【致命的エラー】 初期化処理を行っていたスレッドが異常終了しました。");
\r
4884 stwin.setClosingEnabled(false);
\r
4885 CommonUtils.milSleep(OPENING_WIAT);
\r
4886 StWinSetVisible(false);
\r
4890 StWinSetLocationUnder(this);
\r
4891 StWinSetVisible(true);
\r
4895 private void _initialize(final String[] args) {
\r
4900 // ログ出力を設定する(Windowsの場合は文字コードをMS932にする) →DOS窓を殺したので終了
\r
4901 System.setOut(new DebugPrintStream(System.out,LOG_FILE,logging));
\r
4902 System.setErr(new DebugPrintStream(System.err,LOG_FILE,logging));
\r
4905 StdAppendMessage("================================================================================");
\r
4906 StdAppendMessage("以下のメッセージは無視してください(原因調査中)");
\r
4907 StdAppendMessage("Exception occurred during event dispatching:");
\r
4908 StdAppendMessage(" java.lang.NullPointerException");
\r
4909 StdAppendMessage(" at javax.swing.plaf.basic.BasicScrollBarUI.layoutHScrollbar(Unknown Source)");
\r
4910 StdAppendMessage(" (以下略)");
\r
4911 StdAppendMessage("================================================================================");
\r
4912 stwin.appendMessage(CommonUtils.getDateTime(0));
\r
4913 stwin.appendMessage(String.format("タイニー番組ナビゲータが起動を開始しました(VersionInfo:%s on %s)",VersionInfo.getVersion(),VersionInfo.getEnvironment()));
\r
4915 // 起動時にアップデートを確認する
\r
4919 // メインの環境設定ファイルを読み込む
\r
4925 // その他の環境設定ファイルを読み込む
\r
4928 if ( onlyLoadProgram ) {
\r
4929 if ( ! isOLPExpired(4) ) {
\r
4930 CommonUtils.milSleep(3000);
\r
4934 loadProgPlugins();
\r
4936 setSelectedProgPlugin();
\r
4937 initProgPluginAll();
\r
4938 // 検索結果リストの初期化(loadTVProgram()中で使うので)
\r
4941 loadTVProgram(true,LoadFor.ALL);
\r
4942 stwin.appendMessage("番組表を取得したので終了します");
\r
4943 CommonUtils.milSleep(3000);
\r
4948 loadProgPlugins();
\r
4952 setSelectedProgPlugin();
\r
4953 initProgPluginAll();
\r
4955 initRecPluginAll();
\r
4958 if ( runRecWakeup ) {
\r
4962 // 検索結果リストの初期化(loadTVProgram()中で使うので)
\r
4966 loadTVProgram(false,LoadFor.ALL);
\r
4971 loadRdReservesAll(runRecLoad, null);
\r
4973 catch ( Exception e ) {
\r
4974 System.err.println("【致命的エラー】設定の初期化に失敗しました");
\r
4975 e.printStackTrace();
\r
4979 // 背景色設定ダイアログにフォント名の一覧を設定する
\r
4980 pcwin.setFontList(vwfont);
\r
4982 // (新聞形式の)ツールチップの表示時間を変更する
\r
4983 setTooltipDelay();
\r
4987 buildMainWindow();
\r
4989 catch ( Exception e ) {
\r
4990 System.err.println("【致命的エラー】ウィンドウの構築に失敗しました");
\r
4991 e.printStackTrace();
\r
4996 //int x = 2/0; // サブスレッドの突然死のトラップを確認するためのコード
\r
5001 setTrayIconVisible(env.getShowSysTray());
\r
5004 setXButtonAction(env.getShowSysTray() && env.getHideToTray());
\r
5007 this.addWindowListener(new WindowAdapter() {
\r
5008 // ウィンドウを最小化したときの処理
\r
5010 public void windowIconified(WindowEvent e) {
\r
5016 public void windowClosing(WindowEvent e) {
\r
5021 // 初回起動時はレコーダの登録を促す
\r
5022 if ( recorders.size() == 0 ) {
\r
5023 Container cp = getContentPane();
\r
5024 JOptionPane.showMessageDialog(cp, "レコーダが登録されていません。\n最初に登録を行ってください。\n番組表だけを使いたい場合は、\nNULLプラグインを登録してください。");
\r
5027 // ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
\r
5029 // ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
\r
5031 // [ツールバー/共通] レコーダ情報変更
\r
5032 toolBar.addHDDRecorderChangeListener(autores);
\r
5035 toolBar.addHDDRecorderSelectionListener(this); // 新聞形式
\r
5036 toolBar.addHDDRecorderSelectionListener(paper); // 新聞形式
\r
5037 toolBar.addHDDRecorderSelectionListener(autores); // 自動予約一覧
\r
5038 toolBar.addHDDRecorderSelectionListener(rdialog); // 予約ダイアログ
\r
5040 // [タイマー] タイトルバー更新/リスト形式の現在時刻ノード/新聞形式の現在時刻ノード
\r
5041 timer_now.addTickTimerRiseListener(this);
\r
5042 timer_now.addTickTimerRiseListener(listed);
\r
5043 timer_now.addTickTimerRiseListener(paper);
\r
5045 // ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
\r
5047 // ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
\r
5048 toolBar.setSelectedRecorder(bounds.getSelectedRecorderId());
\r
5050 // ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
\r
5051 // [Fire!] サイドツリーのデフォルトを選択することで番組情報の描画を開始する
\r
5052 // ※ここ以前だとぬぽとかOOBとか出るかもよ!
\r
5053 // ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
\r
5054 paper.selectTreeDefault();
\r
5055 listed.selectTreeDefault();
\r
5057 // ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
\r
5058 // メインウィンドウをスプラッシュからコンポーネントに入れ替える
\r
5059 // ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
\r
5060 this.setVisible(false);
\r
5061 this.setContentPane(mainWindow);
\r
5063 this.setVisible(true);
\r
5065 setTitleBar(); // タイトルバー更新
\r
5067 ShowInitTab(); // 前回開いていたタブを開く
\r
5069 // ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
\r
5071 // ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
\r
5072 timer_now.start();
\r
5074 // ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
\r
5076 // ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
\r
5077 mwin.appendMessage(String.format("タイニー番組ナビゲータが起動しました (VersionInfo:%s on %s)",VersionInfo.getVersion(),VersionInfo.getEnvironment()));
\r
5078 initialized = true;
\r