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
3396 // 番組追跡からサブタイトルを除外するかどうかのフラグ
\r
3397 ProgDetailList.tracenOnlyTitle = env.getFixTitle() && env.getTraceOnlyTitle();
\r
3399 if ( ! env.getFixTitle()) {
\r
3403 for ( TVProgram tvp : tvprograms ) {
\r
3404 //if ( ! (tvp.getType() == ProgType.PROG && tvp.getSubtype() == ProgSubtype.TERRA) ) {
\r
3405 if ( tvp.getType() != ProgType.PROG ) {
\r
3409 for ( ProgList pl : tvp.getCenters() ) {
\r
3410 if ( ! pl.enabled ) {
\r
3414 for ( ProgDateList pcl : pl.pdate ) {
\r
3416 for ( ProgDetailList tvd : pcl.pdetail ) {
\r
3417 if ( tvd.isEqualsGenre(ProgGenre.ANIME, null) ) {
\r
3418 if ( pl.Center.startsWith("NHK") || pl.Center.startsWith("NHK") ) {
\r
3419 // NHK系で先頭が「アニメ 」ではじまるものから「アニメ 」を削除する
\r
3420 tvd.title = tvd.title.replaceFirst("^アニメ[ ・]+","");
\r
3421 tvd.titlePop = TraceProgram.replacePop(tvd.title);
\r
3423 if ( tvd.title.contains("コメンタリ") || tvd.detail.contains("コメンタリ") ) {
\r
3424 // "コメンタリ"の記述のあるものは「副音声」扱いにする(副音声でなくても)
\r
3425 tvd.option.add(ProgOption.MULTIVOICE);
\r
3427 if ( (tvd.title.contains("劇場版") || (tvd.detail.contains("映画") && ! tvd.detail.contains("映画館"))) && ! tvd.isEqualsGenre(ProgGenre.MOVIE, ProgSubgenre.MOVIE_ANIME) ) {
\r
3428 // ジャンル=アニメだがタイトルに「劇場版」が含まれるならジャンル=映画(アニメ映画)を追加する
\r
3429 if ( tvd.genrelist == null ) {
\r
3430 tvd.genrelist = new ArrayList<ProgGenre>();
\r
3431 tvd.genrelist.add(tvd.genre);
\r
3432 tvd.genrelist.add(ProgGenre.MOVIE);
\r
3433 tvd.subgenrelist = new ArrayList<ProgSubgenre>();
\r
3434 tvd.subgenrelist.add(tvd.subgenre);
\r
3435 tvd.subgenrelist.add(ProgSubgenre.MOVIE_ANIME);
\r
3438 tvd.genrelist.add(ProgGenre.MOVIE);
\r
3439 tvd.subgenrelist.add(ProgSubgenre.MOVIE_ANIME);
\r
3443 else if ( tvd.isEqualsGenre(ProgGenre.MOVIE, ProgSubgenre.MOVIE_ANIME) && tvd.subgenre != ProgSubgenre.MOVIE_ANIME ) {
\r
3444 // ジャンル=映画でサブジャンルが複数ありアニメが優先されてないものはアニメを優先する
\r
3445 tvd.subgenre = ProgSubgenre.MOVIE_ANIME;
\r
3454 * {@link ProgDetailList} の情報を整形する
\r
3456 private void fixDetail() {
\r
3457 for ( TVProgram tvp : tvprograms ) {
\r
3458 for ( ProgList pl : tvp.getCenters() ) {
\r
3459 if ( ! pl.enabled ) {
\r
3462 for ( ProgDateList pcl : pl.pdate ) {
\r
3463 for ( ProgDetailList tvd : pcl.pdetail ) {
\r
3464 if ( tvd.start == null || tvd.start.length() == 0 ) {
\r
3468 fixDetailSub(tvp, pl, tvd);
\r
3475 private void fixDetailSub(TVProgram tvp, ProgList pl, ProgDetailList tvd) {
\r
3476 tvd.type = tvp.getType();
\r
3477 tvd.subtype = tvp.getSubtype();
\r
3478 tvd.center = pl.Center;
\r
3480 tvd.recmin = CommonUtils.getRecMinVal(tvd.startDateTime, tvd.endDateTime);
\r
3482 tvd.extension_mark = markchar.getExtensionMark(tvd);
\r
3483 tvd.prefix_mark = markchar.getOptionMark(tvd);
\r
3484 tvd.newlast_mark = markchar.getNewLastMark(tvd);
\r
3485 tvd.postfix_mark = markchar.getPostfixMark(tvd);
\r
3487 tvd.dontoverlapdown = (tvd.center.startsWith("NHK") || tvd.center.startsWith("NHK"));
\r
3491 /*******************************************************************************
\r
3493 ******************************************************************************/
\r
3496 * <P>過去ログから検索キーワードにマッチする情報を取得する
\r
3497 * <P>全部検索がヒットした結果がかえるのだから {@link ProgDetailList} ではなく {@link MarkedProgramList} を使うべきなのだが…
\r
3499 private boolean searchPassedProgram(final SearchKey sKey, final String target) {
\r
3501 Matcher ma = Pattern.compile("^(\\d\\d\\d\\d/\\d\\d/\\d\\d)-(\\d\\d\\d\\d/\\d\\d/\\d\\d)$").matcher(target);
\r
3502 if ( ! ma.find() ) {
\r
3506 final GregorianCalendar s = CommonUtils.getCalendar(ma.group(1));
\r
3507 final GregorianCalendar e = CommonUtils.getCalendar(ma.group(2));
\r
3508 final long dDays = (e.getTimeInMillis() - s.getTimeInMillis())/86400000 + 1;
\r
3510 final ArrayList<ProgDetailList> srchpdl = tvprograms.getSearched().getResultBuffer(sKey.getLabel()) ;
\r
3514 // 検索実行(時間がかかるので状況表示する)
\r
3515 new SwingBackgroundWorker(false) {
\r
3518 protected Object doWorks() throws Exception {
\r
3520 TatCount tc = new TatCount();
\r
3523 int resultCnt = 0;
\r
3524 for (int cnt=1; cnt<=dDays; cnt++) {
\r
3526 String passdt = CommonUtils.getDate(e);
\r
3527 stwin.appendMessage(String.format("[過去ログ検索] 検索中:(%d/%d) %s", cnt, dDays, passdt));
\r
3529 PassedProgram tvp = new PassedProgram();
\r
3530 if ( tvp.loadAllCenters(passdt) ) {
\r
3531 for ( ProgList pl : tvp.getCenters() ) {
\r
3532 if ( ! pl.enabled ) {
\r
3536 for ( ProgDateList pcl : pl.pdate ) {
\r
3537 for ( ProgDetailList tvd : pcl.pdetail ) {
\r
3538 if ( tvd.start == null || tvd.start.length() == 0 ) {
\r
3542 if ( SearchProgram.isMatchKeyword(sKey, pl.Center, tvd) ) {
\r
3543 tvd.dynKey = sKey;
\r
3544 tvd.dynMatched = SearchProgram.getMatchedString();
\r
3545 fixDetailSub(tvp, pl, tvd);
\r
3547 if ( ++resultCnt >= env.getSearchResultMax() ) {
\r
3548 mwin.appendMessage(String.format("[過去ログ検索] 検索件数の上限に到達しました。所要時間: %.2f秒",tc.end()));
\r
3557 e.add(Calendar.DATE,-1);
\r
3560 mwin.appendMessage(String.format("[過去ログ検索] 検索完了。所要時間: %.2f秒",tc.end()));
\r
3565 protected void doFinally() {
\r
3566 StWinSetVisible(false);
\r
3570 StWinSetLocationCenter(this);
\r
3571 StWinSetVisible(true);
\r
3577 /*******************************************************************************
\r
3579 ******************************************************************************/
\r
3582 * 番組表のスナップショットをファイルに保存したり印刷したりする
\r
3584 private boolean getSnapshot(int currentpage, int numberofpages) {
\r
3588 if ( mainWindow.isTabSelected(MWinTab.LISTED) ) {
\r
3590 fname = String.format("snapshot.%s",env.getSnapshotFmt().getExtension());
\r
3591 CommonSwingUtils.saveComponentAsJPEG(listed.getCurrentView(), listed.getTableHeader(), null, listed.getTableBody(), fname, env.getSnapshotFmt(), Viewer.this);
\r
3593 else if ( mainWindow.isTabSelected(MWinTab.PAPER) ){
\r
3595 if ( env.getDrawcacheEnable() || ! env.isPagerEnabled() ) {
\r
3596 fname = String.format("snapshot.%s",env.getSnapshotFmt().getExtension());
\r
3599 if ( env.getAllPageSnapshot() ) {
\r
3600 for ( int i=0; i<numberofpages; i++ ) {
\r
3601 if ( i != currentpage ) {
\r
3602 // カレントページは最後にスナップる(再描画を1回で済ませるため)
\r
3603 toolBar.setSelectedPagerIndex(i);
\r
3604 fname = String.format("snapshot%02d.%s",i+1,env.getSnapshotFmt().getExtension());
\r
3605 CommonSwingUtils.saveComponentAsJPEG(paper.getCurrentView(), paper.getCenterPane(), paper.getTimebarPane(), paper.getCurrentPane(), fname, env.getSnapshotFmt(), Viewer.this);
\r
3609 fname = String.format("snapshot%02d.%s",currentpage+1,env.getSnapshotFmt().getExtension());
\r
3610 toolBar.setSelectedPagerIndex(currentpage);
\r
3612 CommonSwingUtils.saveComponentAsJPEG(paper.getCurrentView(), paper.getCenterPane(), paper.getTimebarPane(), paper.getCurrentPane(), fname, env.getSnapshotFmt(), Viewer.this);
\r
3619 Desktop desktop = Desktop.getDesktop();
\r
3620 if (env.getPrintSnapshot()) {
\r
3622 desktop.print(new File(fname));
\r
3626 String emsg = CommonUtils.openFile(fname);
\r
3627 if (emsg != null) {
\r
3628 mwin.appendError(emsg);
\r
3635 } catch (IOException e) {
\r
3636 e.printStackTrace();
\r
3643 /*******************************************************************************
\r
3644 * ここからおおむね初期化処理にかかわるメソッド群
\r
3645 ******************************************************************************/
\r
3650 private boolean setEnv(final boolean reload_prog) {
\r
3656 // CommonUtilsの設定変更
\r
3657 CommonUtils.setAdjLateNight(env.getAdjLateNight());
\r
3658 CommonUtils.setExpandTo8(env.getExpandTo8());
\r
3659 CommonUtils.setUseRundll32(env.getUseRundll32());
\r
3660 CommonUtils.setDisplayPassedReserve(env.getDisplayPassedReserve());
\r
3661 CommonUtils.setDebug(env.getDebug());
\r
3663 SwingBackgroundWorker.setDebug(env.getDebug());
\r
3666 toolBar.setDebug(env.getDebug());
\r
3667 autores.setDebug(env.getDebug());
\r
3668 rdialog.setDebug(env.getDebug());
\r
3670 // PassedProgramListの設定変更
\r
3671 tvprograms.getPassed().setPassedDir(env.getPassedDir());
\r
3674 for ( HDDRecorder rec : recorders ) {
\r
3676 setSettingRecPluginExt(rec, env);
\r
3680 setSettingProgPluginCommon(env);
\r
3683 setSettingProgPluginAll(env);
\r
3686 toolBar.updateReloadReservedExtension();
\r
3687 toolBar.updateReloadProgramExtension();
\r
3689 // ページャーコンボボックスの書き換え
\r
3690 toolBar.setPagerItems();
\r
3693 listed.setMarkColumnVisible(env.getSplitMarkAndTitle());
\r
3694 listed.setDetailColumnVisible(env.getShowDetailOnList());
\r
3695 listed.setRowHeaderVisible(env.getRowHeaderVisible());
\r
3696 reserved.setRowHeaderVisible(env.getRowHeaderVisible());
\r
3699 listed.setMatchedKeywordColor(env.getMatchedKeywordColor());
\r
3700 listed.setRsvdLineColor((env.getRsvdLineEnhance())?(env.getRsvdLineColor()):(null));
\r
3701 listed.setPickedLineColor((env.getRsvdLineEnhance())?(env.getPickedLineColor()):(null));
\r
3702 listed.setCurrentLineColor((env.getCurrentLineEnhance())?(env.getCurrentLineColor()):(null));
\r
3705 setTrayIconVisible(env.getShowSysTray());
\r
3706 setXButtonAction(env.getShowSysTray() && env.getHideToTray());
\r
3708 // 新聞形式のツールチップの表示時間を変更する
\r
3709 setTooltipDelay();
\r
3712 if ( reload_prog ) {
\r
3713 loadTVProgram(false, LoadFor.ALL); // 部品呼び出し
\r
3717 mpList.setHistoryOnlyUpdateOnce(env.getHistoryOnlyUpdateOnce());
\r
3718 mpList.setShowOnlyNonrepeated(env.getShowOnlyNonrepeated());
\r
3720 doRedrawTVProgram(); // か き な お し
\r
3726 private void getTrayIcon() {
\r
3727 if ( trayicon != null ) {
\r
3732 Image image = ImageIO.read(new File(ICONFILE_SYSTRAY));
\r
3733 trayicon = new TrayIcon(image,"Tainavi");
\r
3735 final Viewer thisClass = this;
\r
3738 PopupMenu popup = new PopupMenu();
\r
3740 MenuItem item = new MenuItem("開く");
\r
3741 item.addActionListener(new ActionListener() {
\r
3743 public void actionPerformed(ActionEvent e) {
\r
3744 thisClass.setVisible(true);
\r
3745 thisClass.setState(Frame.NORMAL);
\r
3751 MenuItem item = new MenuItem("終了する");
\r
3752 item.addActionListener(new ActionListener() {
\r
3754 public void actionPerformed(ActionEvent e) {
\r
3761 trayicon.setPopupMenu(popup);
\r
3764 trayicon.addMouseListener(new MouseAdapter() {
\r
3766 public void mouseClicked(MouseEvent e) {
\r
3767 if (e.getButton() == MouseEvent.BUTTON1) {
\r
3768 thisClass.setVisible(true);
\r
3769 thisClass.setState(Frame.NORMAL);
\r
3774 } catch (IOException e) {
\r
3775 StdAppendError("アイコンファイルが読み込めませんでした: "+ICONFILE_SYSTRAY);
\r
3776 e.printStackTrace();
\r
3779 private void setTrayIconVisible(boolean b) {
\r
3781 if ( ! SystemTray.isSupported() || trayicon == null ) {
\r
3788 SystemTray.getSystemTray().remove(trayicon);
\r
3789 SystemTray.getSystemTray().add(trayicon);
\r
3793 SystemTray.getSystemTray().remove(trayicon);
\r
3795 } catch (AWTException e) {
\r
3796 e.printStackTrace();
\r
3799 private void HideToTray() {
\r
3800 if ( SystemTray.isSupported() && trayicon != null && (env.getShowSysTray() && env.getHideToTray()) ) {
\r
3801 this.setVisible(false);
\r
3804 private void setXButtonAction(boolean b) {
\r
3806 this.setDefaultCloseOperation(JFrame.ICONIFIED);
\r
3809 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
\r
3814 private void procArgs(String[] args) {
\r
3816 for (String arg : args) {
\r
3819 if (arg.compareTo("-L") == 0) {
\r
3821 //logging = false;
\r
3823 else if (arg.compareTo("-L") == 0) {
\r
3827 else if (arg.compareTo("-w") == 0) {
\r
3829 runRecWakeup = true;
\r
3831 else if (arg.compareTo("-nowebaccess") == 0) {
\r
3832 // -nowebaccess : 起動時のWeb番組表へのアクセス無効
\r
3833 enableWebAccess = false;
\r
3835 else if (arg.compareTo("-proxy") == 0) {
\r
3836 // -proxy : Web番組表へのアクセスにProxy経由を強制する
\r
3839 else if (arg.compareTo("-loadrec") == 0) {
\r
3840 // -loadrec : 起動時にレコーダにアクセスする
\r
3841 runRecLoad = true;
\r
3843 else if (arg.compareTo("-onlyLoadProgram") == 0) {
\r
3844 // -onlyLoadProgram : 番組表の取得だけ行う
\r
3845 onlyLoadProgram = true;
\r
3849 String[] dat = arg.split(":");
\r
3850 if (dat.length == 1 ) {
\r
3853 } if (dat.length >= 2 ) {
\r
3863 // メインの環境設定ファイルを読みだす
\r
3864 private void loadEnvfile() {
\r
3865 StdAppendMessage("【環境設定】環境設定ファイルを読み込みます.");
\r
3869 // 引き続きその他の環境設定ファイルも読みだす
\r
3870 private void procEnvs() {
\r
3872 StdAppendMessage("【環境設定】環境設定ファイル類を読み込みます.");
\r
3878 recInfoList.load();
\r
3881 if (pxaddr != null) {
\r
3882 env.setUseProxy(true);
\r
3883 env.setProxyAddr(pxaddr);
\r
3884 env.setProxyPort(pxport);
\r
3887 // Cookieの処理を入れようとしたけど無理だった
\r
3890 CookieManager manager = new CookieManager();
\r
3891 manager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
\r
3892 CookieHandler.setDefault(manager);
\r
3899 // 深夜の帯予約の補正(一日前にずらす)
\r
3900 // 可能なら番組表を8日分取得する
\r
3901 // 【WIN】ファイルオープンにrundll32を使用する
\r
3902 CommonUtils.setAdjLateNight(env.getAdjLateNight());
\r
3903 CommonUtils.setExpandTo8(env.getExpandTo8());
\r
3904 CommonUtils.setUseRundll32(env.getUseRundll32());
\r
3905 CommonUtils.setDisplayPassedReserve(env.getDisplayPassedReserve());
\r
3906 CommonUtils.setDebug(env.getDebug());
\r
3908 SwingBackgroundWorker.setDebug(env.getDebug());
\r
3914 bounds.setLoaded(bounds.load());
\r
3932 // スポーツ延長警告のデフォルト設定のコードはもういらないので削除(3.15.4β)
\r
3934 // 簡易描画はもういらないので削除
\r
3941 private void chkDualBoot() {
\r
3942 if ( ! env.getOnlyOneInstance() ) {
\r
3946 if ( ! CommonUtils.getLock() ) {
\r
3952 Runtime.getRuntime().addShutdownHook(new Thread() {
\r
3953 public void run() {
\r
3954 // 鯛ナビ終了時にロックを解除する
\r
3955 CommonUtils.getUnlock();
\r
3961 private void chkVerUp() {
\r
3962 if ( ! enableWebAccess || onlyLoadProgram ) {
\r
3963 stwin.appendError("【オンラインアップデート】オンラインアップデートは無効です");
\r
3967 VWUpdate vu = new VWUpdate(stwin);
\r
3968 if ( ! vu.isExpired(env.getUpdateMethod()) ) {
\r
3969 // メッセージはVWUpdate内で出力されます
\r
3972 if ( doVerUp(vu) ) {
\r
3977 private boolean doVerUp(VWUpdate vu) {
\r
3978 UpdateResult res = vu.checkUpdate(VersionInfo.getVersion());
\r
3982 // 履歴は更新しない(連続アップデートがあるかも知れないので)
\r
3983 LogViewer lv = new LogViewer(HISTORY_FILE);
\r
3984 lv.setModal(true);
\r
3985 lv.setCaretPosition(0);
\r
3986 lv.setVisible(true);
\r
3990 // 履歴は更新しない(次回に持ち越し)
\r
3994 vu.updateHistory();
\r
3998 // 履歴は更新しない(次回再挑戦)
\r
4005 * レコーダプラグインをすべて読み込みます。
\r
4007 private boolean loadRecPlugins() {
\r
4009 stwin.appendMessage("【レコーダプラグイン】プラグインを読み込みます.");
\r
4011 boolean isMailPluginEnabled = false;
\r
4013 Class.forName("javax.mail.Session");
\r
4014 isMailPluginEnabled = true;
\r
4016 catch ( Exception e ) {
\r
4017 System.err.println("【レコーダプラグイン】メール系プラグイン用の外部ライブラリがみつかりません: "+e.toString());
\r
4020 boolean isCalendarPluginEnabled = false;
\r
4022 Class.forName("com.google.gdata.client.calendar.CalendarService");
\r
4023 isCalendarPluginEnabled = true;
\r
4025 catch ( Exception e ) {
\r
4026 System.err.println("【レコーダプラグイン】カレンダー系プラグイン用の外部ライブラリがみつかりません: "+e.toString());
\r
4030 ArrayList<String> recIda = new ArrayList<String>();
\r
4031 for ( File f : new File(CommonUtils.joinPath(new String[]{"bin","tainavi"})).listFiles() ) {
\r
4032 Matcher ma = Pattern.compile("^(PlugIn_Rec[^$]+)[^$]*\\.class$").matcher(f.getName());
\r
4033 if ( ma.find() ) {
\r
4034 if ( ! isMailPluginEnabled && f.getName().toLowerCase().contains("mail") ) {
\r
4035 System.out.println("【レコーダプラグイン】メール系プラグインは無効です: "+f.getName());
\r
4038 if ( ! isCalendarPluginEnabled && f.getName().toLowerCase().contains("calendar") ) {
\r
4039 System.out.println("【レコーダプラグイン】カレンダー系プラグインは無効です: "+f.getName());
\r
4043 recIda.add(ma.group(1));
\r
4046 String[] recIdd = recIda.toArray(new String[0]);
\r
4047 Arrays.sort(recIdd);
\r
4050 StringBuilder sb = new StringBuilder();
\r
4051 for ( String recId : recIdd ) {
\r
4052 sb.append("tainavi.");
\r
4056 if ( ! CommonUtils.write2file(CommonUtils.joinPath(new String[] {"bin","META-INF","services","tainavi.HDDRecorder"}), sb.toString()) ) {
\r
4057 stwin.appendError("【レコーダプラグイン】プラグインの読み込みに失敗しました: ");
\r
4061 // ここで例外が起きてもトラップできない、スレッドが落ちる
\r
4062 ServiceLoader<HDDRecorder> r = ServiceLoader.load(HDDRecorder.class);
\r
4064 recPlugins.clear();
\r
4065 for ( HDDRecorder recorder : r ) {
\r
4066 if (env.getDebug()) {
\r
4067 StdAppendMessage("+追加します: "+recorder.getRecorderId());
\r
4069 recPlugins.add(recorder.clone());
\r
4070 StdAppendMessage("+追加しました: "+recorder.getRecorderId());
\r
4077 * レコーダ設定をもとにレコーダプラグインから実レコーダのインスタンスを生成します。
\r
4079 private void initRecPluginAll() {
\r
4081 recorders.clear();
\r
4082 for ( RecorderInfo ri : recInfoList ) {
\r
4083 ArrayList<HDDRecorder> rl = recPlugins.findPlugin(ri.getRecorderId());
\r
4084 if ( rl.size() == 0 ) {
\r
4085 stwin.appendError("【レコーダプラグイン】プラグインがみつかりません: "+ri.getRecorderId()+"("+ri.getRecorderIPAddr()+":"+ri.getRecorderPortNo()+")");
\r
4088 stwin.appendMessage("【レコーダプラグイン】プラグインを初期化します: "+ri.getRecorderId()+"("+ri.getRecorderIPAddr()+":"+ri.getRecorderPortNo()+")");
\r
4089 for ( HDDRecorder rPlugin : rl ) {
\r
4090 initRecPlugin(rPlugin, ri);
\r
4095 protected HDDRecorder initRecPlugin(HDDRecorder rPlugin, RecorderInfo ri) {
\r
4096 HDDRecorder rec = rPlugin.clone();
\r
4097 recorders.add(rec);
\r
4099 rec.getChCode().load(true); // true : ログ出力あり
\r
4100 setSettingRecPluginBase(rec, ri);
\r
4101 setSettingRecPluginExt(rec,env);
\r
4102 rec.setProgressArea(stwin);
\r
4105 protected void setSettingRecPluginBase(HDDRecorder to, RecorderInfo from) {
\r
4106 to.setIPAddr(from.getRecorderIPAddr());
\r
4107 to.setPortNo(from.getRecorderPortNo());
\r
4108 to.setUser(from.getRecorderUser());
\r
4109 to.setPasswd(from.getRecorderPasswd());
\r
4110 to.setMacAddr(from.getRecorderMacAddr());
\r
4111 to.setBroadcast(from.getRecorderBroadcast());
\r
4112 to.setUseCalendar(from.getUseCalendar());
\r
4113 to.setUseChChange(from.getUseChChange());
\r
4114 to.setRecordedCheckScope(from.getRecordedCheckScope());
\r
4115 to.setTunerNum(from.getTunerNum());
\r
4116 to.setColor(from.getRecorderColor());
\r
4118 protected void setSettingRecPluginExt(HDDRecorder recorder, Env nEnv) {
\r
4119 recorder.setUserAgent(nEnv.getUserAgent());
\r
4120 recorder.setDebug(nEnv.getDebug());
\r
4121 recorder.setAdjNotRep(nEnv.getAdjoiningNotRepetition());
\r
4122 recorder.setRecordedSaveScope(nEnv.getRecordedSaveScope());
\r
4126 protected void doRecWakeup() {
\r
4127 for ( HDDRecorder rec : recorders ) {
\r
4128 if ( ! rec.getMacAddr().equals("") && ! rec.getBroadcast().equals("") ) {
\r
4137 private boolean isOLPExpired(int expire) {
\r
4138 String fname = "env"+File.separator+"olp.history";
\r
4139 if ( ! new File(fname).exists() || ! new File(fname).canWrite() ) {
\r
4140 stwin.appendError("【警告】実行履歴ファイルがないから実行させないよ!");
\r
4144 String dat = CommonUtils.read4file(fname, true);
\r
4145 if ( dat == null ) {
\r
4146 stwin.appendError("【警告】実行履歴を取得できなかったから実行させないよ!");
\r
4150 GregorianCalendar ca = null;
\r
4151 dat = EncryptPassword.dec(b64.dec(dat));
\r
4152 if ( dat != null ) {
\r
4153 ca = CommonUtils.getCalendar(dat);
\r
4155 if ( ca == null ) {
\r
4156 stwin.appendError("【警告】実行履歴の内容が不正だったから実行させないよ! "+dat);
\r
4160 if ( CommonUtils.getCompareDateTime(ca, CommonUtils.getCalendar(-expire*3600)) >= 0 ) {
\r
4161 ca.add(Calendar.HOUR,expire);
\r
4162 stwin.appendError("【警告】"+expire+"時間以内の再実行は許さないよ!"+CommonUtils.getDateTime(ca)+"まで待って!");
\r
4166 if ( ! CommonUtils.write2file(fname, b64.enc(EncryptPassword.enc(CommonUtils.getDateTime(0)))) ) {
\r
4167 stwin.appendError("【警告】実行履歴を保存できなかったから実行させないよ!");
\r
4176 * Web番組表プラグインをすべて読み込みます。
\r
4178 private boolean loadProgPlugins() {
\r
4180 final String FUNCID = "[Web番組表プラグイン組込] ";
\r
4181 final String ERRID = "[ERROR]"+FUNCID;
\r
4184 stwin.appendMessage(FUNCID+"プラグインを読み込みます.");
\r
4187 setSettingProgPluginCommon(env);
\r
4193 // TVProgramListのインスタンスは別途初期化が必要
\r
4194 progPlugins.clear();
\r
4195 tvprograms.clear();
\r
4201 ArrayList<String> prgIda = new ArrayList<String>();
\r
4202 for ( File f : new File(CommonUtils.joinPath("bin","tainavi")).listFiles() ) {
\r
4203 Matcher ma = Pattern.compile("^(PlugIn_(TV|CS|RAD)P[^$]+)\\.class$").matcher(f.getName());
\r
4205 prgIda.add(ma.group(1));
\r
4208 String[] prgIdd = prgIda.toArray(new String[0]);
\r
4209 Arrays.sort(prgIdd);
\r
4212 StringBuilder sb = new StringBuilder();
\r
4213 for ( String prgId : prgIdd ) {
\r
4214 sb.append("tainavi.");
\r
4218 if ( ! CommonUtils.write2file(CommonUtils.joinPath("bin","META-INF","services","tainavi.TVProgram"), sb.toString()) ) {
\r
4219 stwin.appendError(ERRID+"プラグインの読み込みに失敗しました: ");
\r
4223 ServiceLoader<TVProgram> p = ServiceLoader.load(TVProgram.class);
\r
4225 // 実際必要ないのだが、プラグインのインスタンスはclone()して使う
\r
4226 for ( TVProgram pg : p ) {
\r
4227 TVProgram prog = pg.clone();
\r
4229 stwin.appendMessage("+追加しました: "+prog.getTVProgramId());
\r
4231 // CH設定タブではプラグイン側のインスタンスを使うので情報を追加してやる必要があるのであった
\r
4232 setSettingProgPlugin(prog, env);
\r
4234 progPlugins.add(prog);
\r
4243 * 設定にあわせてWeb番組表プラグインを絞り込みます。
\r
4245 private void setSelectedProgPlugin() {
\r
4248 Syobocal syobo = tvprograms.getSyobo();
\r
4249 PassedProgram passed = tvprograms.getPassed();
\r
4250 PickedProgram pickup = tvprograms.getPickup();
\r
4251 SearchResult searched = tvprograms.getSearched();
\r
4253 tvprograms.clear();
\r
4256 TVProgram tvp = progPlugins.getTvProgPlugin(env.getTVProgramSite());
\r
4257 if ( tvp == null ) {
\r
4258 // デフォルトもなければ先頭にあるもの
\r
4259 tvp = progPlugins.getTvProgPlugin(null);
\r
4261 if ( tvp == null ) {
\r
4263 StdAppendError("【Web番組表選択】地上波&BS番組表が選択されていません: "+env.getTVProgramSite());
\r
4266 StdAppendMessage("【Web番組表選択】地上波&BS番組表が選択されました: "+tvp.getTVProgramId());
\r
4267 tvprograms.add(tvp.clone());
\r
4271 TVProgram tvp = progPlugins.getCsProgPlugin(env.getCSProgramSite());
\r
4272 if ( tvp == null ) {
\r
4273 tvp = progPlugins.getCsProgPlugin(null);
\r
4275 if ( tvp == null ) {
\r
4276 StdAppendError("【Web番組表選択】CS番組表[プライマリ]が選択されていません: "+env.getCSProgramSite());
\r
4279 StdAppendMessage("【Web番組表選択】CS番組表[プライマリ]が選択されました: "+tvp.getTVProgramId());
\r
4280 tvprograms.add(tvp.clone());
\r
4284 TVProgram tvp = progPlugins.getCs2ProgPlugin(env.getCS2ProgramSite());
\r
4285 if ( tvp == null ) {
\r
4286 tvp = progPlugins.getCs2ProgPlugin(null);
\r
4288 if ( tvp == null ) {
\r
4289 StdAppendError("【Web番組表選択】CS番組表[プライマリ]が選択されていません: "+env.getCS2ProgramSite());
\r
4292 StdAppendMessage("【Web番組表選択】CS番組表[プライマリ]が選択されました: "+tvp.getTVProgramId());
\r
4293 tvprograms.add(tvp.clone());
\r
4297 if ( progPlugins.getRadioProgPlugins().size() > 0 )
\r
4299 TVProgram tvp = progPlugins.getCsProgPlugin(env.getRadioProgramSite());
\r
4300 if ( tvp == null ) {
\r
4301 tvp = progPlugins.getCsProgPlugin(null);
\r
4303 if ( tvp == null ) {
\r
4304 StdAppendError("【Web番組表選択】ラジオ番組表が選択されていません: "+env.getRadioProgramSite());
\r
4307 StdAppendMessage("【Web番組表選択】ラジオ番組表が選択されました: "+tvp.getTVProgramId());
\r
4308 tvprograms.add(tvp.clone());
\r
4314 if ( syobo == null ) {
\r
4315 syobo = new Syobocal();
\r
4317 tvprograms.add(syobo);
\r
4320 if ( passed == null ) {
\r
4321 passed = new PassedProgram();
\r
4323 tvprograms.add(passed);
\r
4326 if ( pickup == null ) {
\r
4327 pickup = new PickedProgram();
\r
4328 pickup.loadProgram(null, false);
\r
4330 tvprograms.add(pickup);
\r
4333 if ( searched == null ) {
\r
4334 searched = new SearchResult();
\r
4336 tvprograms.add(searched);
\r
4341 * Web番組表設定をもとにレコーダプラグインのインスタンスを生成します。
\r
4343 private void initProgPluginAll() {
\r
4345 final String FUNCID = "[Web番組表プラグイン初期化] ";
\r
4346 final LinkedHashMap<ArrayList<TVProgram>,String> map = new LinkedHashMap<ArrayList<TVProgram>, String>();
\r
4347 map.put(tvprograms.getTvProgPlugins(), "地上波&BS番組表");
\r
4348 map.put(tvprograms.getCsProgPlugins(), "CS番組表[プライマリ]");
\r
4349 map.put(tvprograms.getCs2ProgPlugins(), "CS番組表[セカンダリ]");
\r
4350 //map.put(progPlugins.getRadioProgPlugins(), "ラジオ番組表");
\r
4352 new SwingBackgroundWorker(true) {
\r
4355 protected Object doWorks() throws Exception {
\r
4357 for ( ArrayList<TVProgram> tvpa : map.keySet() ) {
\r
4358 stwin.appendMessage(FUNCID+map.get(tvpa)+"のベース情報(放送局リストなど)を取得します.");
\r
4359 for ( TVProgram p : tvpa ) {
\r
4360 stwin.appendMessage(FUNCID+"プラグインを初期化します: "+p.getTVProgramId());
\r
4363 // 個別設定(2) …(1)と(2)の順番が逆だったので前に移動してきました(3.17.3β)
\r
4364 setSettingProgPlugin(p,env); // 他からも呼び出される部分だけ分離
\r
4367 p.setOptString(null); // フリーオプション初期化
\r
4368 p.loadAreaCode(); // 放送エリア情報取得
\r
4369 p.loadCenter(p.getSelectedCode(),false); // 放送局情報取得
\r
4370 p.setSortedCRlist(); // 有効放送局だけよりわける
\r
4372 catch (Exception e) {
\r
4373 stwin.appendError(FUNCID+"ベース情報の取得に失敗しました.");
\r
4374 e.printStackTrace();
\r
4380 //setSettingProgPluginAll(env);
\r
4382 if ( env.getUseSyobocal() ) {
\r
4383 TVProgram syobo = tvprograms.getSyobo();
\r
4384 if ( syobo != null ) {
\r
4385 stwin.appendMessage(FUNCID+"しょぼかるを初期化します.");
\r
4386 setSettingProgPlugin(syobo,env); // 他からも呼び出される部分だけ分離
\r
4387 syobo.setUserAgent("tainavi");
\r
4388 syobo.setOptString(null); // フリーオプション初期化
\r
4389 syobo.loadCenter(syobo.getSelectedCode(), false);
\r
4397 protected void doFinally() {
\r
4401 protected void setSettingProgPluginAll(Env nEnv) {
\r
4403 setSettingProgPlugin(tvprograms.getTvProgPlugin(null),nEnv);
\r
4404 setSettingProgPlugin(tvprograms.getCsProgPlugin(null),nEnv);
\r
4405 setSettingProgPlugin(tvprograms.getCs2ProgPlugin(null),nEnv);
\r
4406 //setSettingProgPlugin(tvprograms.getRadioProgPlugin(null),nEnv);
\r
4407 setSettingProgPlugin(tvprograms.getSyobo(),nEnv);
\r
4410 tvprograms.getSyobo().setUserAgent("tainavi");
\r
4412 tvprograms.getSearched().setResultBufferMax(nEnv.getSearchResultBufferMax());
\r
4414 protected void setSettingProgPlugin(TVProgram p, Env nEnv) {
\r
4415 if ( p == null ) {
\r
4418 p.setUserAgent(nEnv.getUserAgent());
\r
4419 p.setProgDir(nEnv.getProgDir());
\r
4420 p.setCacheExpired((enableWebAccess)?(nEnv.getCacheTimeLimit()):(0));
\r
4421 p.setContinueTomorrow(nEnv.getContinueTomorrow());
\r
4422 p.setExpandTo8(nEnv.getExpandTo8());
\r
4423 //p.setUseDetailCache(nEnv.getUseDetailCache());
\r
4424 p.setUseDetailCache(false);
\r
4425 p.setSplitEpno(nEnv.getSplitEpno());
\r
4429 * staticで持っている共通設定の更新
\r
4431 protected void setSettingProgPluginCommon(Env nEnv) {
\r
4433 if ( nEnv.getUseProxy() && (nEnv.getProxyAddr().length() > 0 && nEnv.getProxyPort().length() > 0) ) {
\r
4434 stwin.appendMessage("+Web番組表へのアクセスにProxyが設定されています: "+nEnv.getProxyAddr()+":"+nEnv.getProxyPort());
\r
4435 TVProgramUtils.setProxy(nEnv.getProxyAddr(),nEnv.getProxyPort());
\r
4438 TVProgramUtils.setProxy(null,null);
\r
4441 TVProgramUtils.setProgressArea(stwin);
\r
4442 TVProgramUtils.setChConv(chconv);
\r
4446 private void initMpList() {
\r
4447 //mpList = new MarkedProgramList(); // 検索結果リスト
\r
4448 mpList.setHistoryOnlyUpdateOnce(env.getHistoryOnlyUpdateOnce());
\r
4449 mpList.setShowOnlyNonrepeated(env.getShowOnlyNonrepeated());
\r
4453 private void initLookAndFeelAndFont() {
\r
4457 vwlaf = new VWLookAndFeel();
\r
4459 String lafname = vwlaf.update(env.getLookAndFeel());
\r
4460 if ( lafname != null && ! lafname.equals(env.getLookAndFeel())) {
\r
4461 env.setLookAndFeel(lafname);
\r
4464 if ( CommonUtils.isMac() ) {
\r
4465 UIManager.getDefaults().put("Table.gridColor", new Color(128,128,128));
\r
4466 //UIManager.getDefaults().put("Table.selectionBackground", new Color(182,207,229));
\r
4467 //UIManager.getDefaults().put("Table.selectionForeground", new Color(0,0,0));
\r
4472 vwfont = new VWFont();
\r
4474 String fname = vwfont.update(env.getFontName(),env.getFontSize());
\r
4475 if ( fname != null && ! fname.equals(env.getFontName())) {
\r
4476 env.setFontName(fname);
\r
4480 catch ( Exception e ) {
\r
4481 // 落ちられると困るからトラップしておこうぜ
\r
4482 e.printStackTrace();
\r
4486 // L&FやFontを変えたらコンポーネントに通知が必要
\r
4487 protected void updateComponentTreeUI() {
\r
4489 SwingUtilities.updateComponentTreeUI(this);
\r
4490 SwingUtilities.updateComponentTreeUI(stwin);
\r
4491 SwingUtilities.updateComponentTreeUI(mwin);
\r
4492 SwingUtilities.updateComponentTreeUI(pcwin);
\r
4493 SwingUtilities.updateComponentTreeUI(rdialog);
\r
4494 SwingUtilities.updateComponentTreeUI(ccwin);
\r
4496 catch ( Exception e ) {
\r
4497 // 落ちられると困るからトラップしておこうぜ
\r
4498 e.printStackTrace();
\r
4502 // ツールチップの表示遅延時間を設定する
\r
4503 private void setTooltipDelay() {
\r
4504 ToolTipManager tp = ToolTipManager.sharedInstance();
\r
4505 tp.setInitialDelay(env.getTooltipInitialDelay()*100);
\r
4506 tp.setDismissDelay(env.getTooltipDismissDelay()*100);
\r
4511 * @return true:前回終了時の設定がある場合
\r
4513 private boolean buildMainWindow() {
\r
4518 mainWindow = new VWMainWindow();
\r
4521 toolBar = new VWToolBar();
\r
4522 listed = new VWListedView();
\r
4523 paper = new VWPaperView();
\r
4524 reserved = new VWReserveListView();
\r
4525 recorded = new VWRecordedListView();
\r
4526 autores = new VWAutoReserveListView();
\r
4527 setting = new VWSettingView();
\r
4528 recsetting = new VWRecorderSettingView();
\r
4529 chsetting = new VWChannelSettingView();
\r
4530 chdatsetting = new VWChannelDatSettingView();
\r
4531 chsortsetting = new VWChannelSortView();
\r
4532 chconvsetting = new VWChannelConvertView();
\r
4538 toolBar.setDebug(env.getDebug());
\r
4539 autores.setDebug(env.getDebug());
\r
4540 rdialog.setDebug(env.getDebug());
\r
4543 toolBar.setPagerItems();
\r
4549 mainWindow.addToolBar(toolBar);
\r
4550 mainWindow.addStatusArea(mwin);
\r
4553 mainWindow.addTab(listed, MWinTab.LISTED);
\r
4554 mainWindow.addTab(paper, MWinTab.PAPER);
\r
4555 mainWindow.addTab(reserved, MWinTab.RSVED);
\r
4556 mainWindow.addTab(recorded, MWinTab.RECED);
\r
4557 mainWindow.addTab(autores, MWinTab.AUTORES);
\r
4558 mainWindow.addTab(setting, MWinTab.SETTING);
\r
4559 mainWindow.addTab(recsetting, MWinTab.RECSET);
\r
4560 mainWindow.addTab(chsetting, MWinTab.CHSET);
\r
4561 mainWindow.addTab(chsortsetting, MWinTab.CHSORT);
\r
4562 mainWindow.addTab(chconvsetting, MWinTab.CHCONV);
\r
4563 mainWindow.addTab(chdatsetting, MWinTab.CHDAT);
\r
4567 setStatusVisible(bounds.getShowStatus());
\r
4570 paper.clearPanel();
\r
4571 paper.buildMainViewByDate();
\r
4576 private void ShowInitTab() {
\r
4579 mainWindow.setSelectedTab(null);
\r
4581 if ( recInfoList.size() <= 0 ) {
\r
4583 mainWindow.setSelectedTab(MWinTab.RECSET);
\r
4587 MWinTab tab = MWinTab.getAt(bounds.getSelectedTab());
\r
4588 mainWindow.setSelectedTab(tab);
\r
4593 private void setInitBounds() {
\r
4594 // ウィンドウのサイズと表示位置を設定する
\r
4595 Rectangle window = bounds.getWinRectangle();
\r
4596 if (bounds.isLoaded()) {
\r
4597 // 設定ファイルを読み込んであったらそれを設定する
\r
4598 System.out.println(DBGID+"set bounds "+window);
\r
4599 this.setBounds(window.x, window.y, window.width, window.height);
\r
4602 // 設定ファイルがなければ自動設定する
\r
4603 Rectangle screen = this.getGraphicsConfiguration().getBounds();
\r
4605 int w = window.width;
\r
4606 if (window.width > screen.width) {
\r
4611 x = (screen.width - window.width)/2;
\r
4614 int h = window.height;
\r
4615 if (window.height > screen.height) {
\r
4617 h = screen.height;
\r
4620 y = (screen.height - window.height)/2;
\r
4622 this.setBounds(x, y, w, h);
\r
4628 * {@link VWMainWindow#setStatusVisible(boolean)}の置き換え
\r
4630 private void setStatusVisible(boolean b) {
\r
4633 listed.setDetailVisible(true);
\r
4634 paper.setDetailVisible(true);
\r
4635 MWinSetVisible(true);
\r
4638 listed.setDetailVisible(false);
\r
4639 paper.setDetailVisible(false);
\r
4640 MWinSetVisible(false);
\r
4644 // フルスクリーンモードをトグル切り替え
\r
4645 private Dimension f_dim;
\r
4646 private Point f_pnt;
\r
4647 private int divloc_l = 0;
\r
4648 private int divloc_p = 0;
\r
4650 private void setFullScreen(boolean b) {
\r
4652 if ( b == true ) {
\r
4655 this.setUndecorated(true);
\r
4656 this.setVisible(true);
\r
4659 Toolkit tk = getToolkit();
\r
4660 Insets in = tk.getScreenInsets(getGraphicsConfiguration());
\r
4661 Dimension d = tk.getScreenSize();
\r
4662 f_dim = this.getSize();
\r
4663 f_pnt = this.getLocation();
\r
4664 this.setBounds(in.left, in.top, d.width-(in.left+in.right), d.height-(in.top+in.bottom));
\r
4666 divloc_l = bounds.getTreeWidth();
\r
4667 divloc_p = bounds.getTreeWidthPaper();
\r
4670 paper.setCollapseTree();
\r
4671 listed.setCollapseTree();
\r
4674 if ( f_pnt != null && f_dim != null ) { // 起動直後などは値がないですしね
\r
4678 this.setUndecorated(false);
\r
4679 this.setVisible(true);
\r
4682 this.setBounds(f_pnt.x, f_pnt.y, f_dim.width, f_dim.height);
\r
4684 bounds.setTreeWidth(divloc_l);
\r
4685 bounds.setTreeWidthPaper(divloc_p);
\r
4688 paper.setExpandTree();
\r
4689 listed.setExpandTree();
\r
4695 private void setTitleBar() {
\r
4696 MemoryMXBean mbean = ManagementFactory.getMemoryMXBean();
\r
4697 MemoryUsage heapUsage = mbean.getHeapMemoryUsage();
\r
4701 "%s - %s - Memory Usage Max:%dM Committed:%dM Used:%dM - FrameBuffer Status:%s",
\r
4702 VersionInfo.getVersion(),
\r
4703 CommonUtils.getDateTime(0),
\r
4704 heapUsage.getMax()/(1024*1024),
\r
4705 heapUsage.getCommitted()/(1024*1024),
\r
4706 heapUsage.getUsed()/(1024*1024),
\r
4707 (paper!=null)?(paper.getFrameBufferStatus()):("N/A")
\r
4713 private void ExitOnClose() {
\r
4715 if ( ! this.toolBar.isFullScreen()) {
\r
4716 Rectangle r = this.getBounds();
\r
4717 bounds.setWinRectangle(r);
\r
4720 Rectangle r = new Rectangle();
\r
4721 r.x = this.f_pnt.x;
\r
4722 r.y = this.f_pnt.y;
\r
4723 r.width = this.f_dim.width;
\r
4724 r.height = this.f_dim.height;
\r
4725 bounds.setWinRectangle(r);
\r
4727 listed.copyColumnWidth();
\r
4728 reserved.copyColumnWidth();
\r
4730 bounds.setStatusRows(mwin.getRows());
\r
4733 bounds.setSelectedTab(mainWindow.getSelectedTab().getIndex());
\r
4734 bounds.setShowSettingTabs(mainWindow.getShowSettingTabs());
\r
4735 bounds.setSelectedRecorderId(toolBar.getSelectedRecorder());
\r
4736 bounds.setShowStatus(toolBar.isStatusShown());
\r
4742 listed.saveTreeExpansion();
\r
4743 paper.saveTreeExpansion();
\r
4747 /*******************************************************************************
\r
4749 ******************************************************************************/
\r
4752 private static boolean initialized = false;
\r
4753 private static Viewer myClass = null;
\r
4758 * @throws NoSuchAlgorithmException
\r
4759 * @version 今まで初期化を行ってからウィンドウを作成していたが<BR>
\r
4760 * 途中で例外が起こるとダンマリの上にゾンビになってたりとヒドかったので<BR>
\r
4761 * 先にウィンドウを作成してから初期化を行うように変えました
\r
4762 * @throws InterruptedException
\r
4763 * @throws InvocationTargetException
\r
4765 public static void main(final String[] args) throws NoSuchAlgorithmException, InvocationTargetException, InterruptedException {
\r
4767 if ( myClass != null ) {
\r
4768 // 既に起動していたらフォアグラウンドにする
\r
4769 SwingUtilities.invokeAndWait(new Runnable() {
\r
4771 public void run() {
\r
4773 myClass.setVisible(true);
\r
4774 myClass.setState(Frame.NORMAL);
\r
4780 SwingUtilities.invokeLater(new Runnable() {
\r
4781 public void run() {
\r
4783 final Viewer thisClass = myClass = new Viewer(args);
\r
4785 thisClass.addComponentListener(new ComponentAdapter() {
\r
4787 public void componentShown(ComponentEvent e) {
\r
4790 thisClass.removeComponentListener(this);
\r
4793 thisClass.initialize(args);
\r
4798 thisClass.setVisible(true);
\r
4805 /*******************************************************************************
\r
4807 ******************************************************************************/
\r
4812 public Viewer(final String[] args) {
\r
4817 bounds.loadText();
\r
4820 // 初期化が終わるまでは閉じられないよ → どうせステータスウィンドウにブロックされて操作できない
\r
4821 //setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
\r
4822 //setResizable(false);
\r
4824 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
\r
4829 Image image = ImageIO.read(new File(ICONFILE_TAINAVI));
\r
4830 setIconImage(image);
\r
4832 catch (IOException e) {
\r
4833 StdAppendError("[ERROR] アイコンが設定できない: "+e.toString());
\r
4836 JLabel jLabel_splash_img = new JLabel(new ImageIcon("splash.gif"));
\r
4837 jLabel_splash_img.setPreferredSize(new Dimension(400,300));
\r
4838 //getContentPane().setLayout(new BorderLayout());
\r
4839 getContentPane().add(jLabel_splash_img, BorderLayout.CENTER);
\r
4842 setLocationRelativeTo(null); // 画面の真ん中に
\r
4844 // SwingLocker共有設定
\r
4845 SwingLocker.setOwner(this);
\r
4847 // とりあえずルックアンドフィールはリセットしておかないとだめっぽいよ
\r
4848 initLookAndFeelAndFont();
\r
4849 updateComponentTreeUI();
\r
4852 // 初期化をバックグラウンドで行う
\r
4853 private void initialize(final String[] args) {
\r
4857 // 初期化処理はバックグラウンドで行う
\r
4858 new SwingBackgroundWorker(false) {
\r
4861 protected Object doWorks() throws Exception {
\r
4863 TatCount tc = new TatCount();
\r
4866 _initialize(args);
\r
4868 // 終わったら閉じられるようにするよ
\r
4869 //setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
\r
4870 //setResizable(true);
\r
4873 stwin.appendMessage(String.format("【タイニー番組ナビゲータが起動しました】 所要時間: %.2f秒",tc.end()));
\r
4878 protected void doFinally() {
\r
4879 if ( ! initialized ) System.err.println("[ERROR][鯛ナビ] 【致命的エラー】 初期化処理を行っていたスレッドが異常終了しました。");
\r
4880 stwin.setClosingEnabled(false);
\r
4881 CommonUtils.milSleep(OPENING_WIAT);
\r
4882 StWinSetVisible(false);
\r
4886 StWinSetLocationUnder(this);
\r
4887 StWinSetVisible(true);
\r
4891 private void _initialize(final String[] args) {
\r
4896 // ログ出力を設定する(Windowsの場合は文字コードをMS932にする) →DOS窓を殺したので終了
\r
4897 System.setOut(new DebugPrintStream(System.out,LOG_FILE,logging));
\r
4898 System.setErr(new DebugPrintStream(System.err,LOG_FILE,logging));
\r
4901 StdAppendMessage("================================================================================");
\r
4902 StdAppendMessage("以下のメッセージは無視してください(原因調査中)");
\r
4903 StdAppendMessage("Exception occurred during event dispatching:");
\r
4904 StdAppendMessage(" java.lang.NullPointerException");
\r
4905 StdAppendMessage(" at javax.swing.plaf.basic.BasicScrollBarUI.layoutHScrollbar(Unknown Source)");
\r
4906 StdAppendMessage(" (以下略)");
\r
4907 StdAppendMessage("================================================================================");
\r
4908 stwin.appendMessage(CommonUtils.getDateTime(0));
\r
4909 stwin.appendMessage(String.format("タイニー番組ナビゲータが起動を開始しました(VersionInfo:%s on %s)",VersionInfo.getVersion(),VersionInfo.getEnvironment()));
\r
4911 // 起動時にアップデートを確認する
\r
4915 // メインの環境設定ファイルを読み込む
\r
4921 // その他の環境設定ファイルを読み込む
\r
4924 if ( onlyLoadProgram ) {
\r
4925 if ( ! isOLPExpired(4) ) {
\r
4926 CommonUtils.milSleep(3000);
\r
4930 loadProgPlugins();
\r
4932 setSelectedProgPlugin();
\r
4933 initProgPluginAll();
\r
4934 // 検索結果リストの初期化(loadTVProgram()中で使うので)
\r
4937 loadTVProgram(true,LoadFor.ALL);
\r
4938 stwin.appendMessage("番組表を取得したので終了します");
\r
4939 CommonUtils.milSleep(3000);
\r
4944 loadProgPlugins();
\r
4948 setSelectedProgPlugin();
\r
4949 initProgPluginAll();
\r
4951 initRecPluginAll();
\r
4954 if ( runRecWakeup ) {
\r
4958 // 検索結果リストの初期化(loadTVProgram()中で使うので)
\r
4962 loadTVProgram(false,LoadFor.ALL);
\r
4967 loadRdReservesAll(runRecLoad, null);
\r
4969 catch ( Exception e ) {
\r
4970 System.err.println("【致命的エラー】設定の初期化に失敗しました");
\r
4971 e.printStackTrace();
\r
4975 // 背景色設定ダイアログにフォント名の一覧を設定する
\r
4976 pcwin.setFontList(vwfont);
\r
4978 // (新聞形式の)ツールチップの表示時間を変更する
\r
4979 setTooltipDelay();
\r
4983 buildMainWindow();
\r
4985 catch ( Exception e ) {
\r
4986 System.err.println("【致命的エラー】ウィンドウの構築に失敗しました");
\r
4987 e.printStackTrace();
\r
4992 //int x = 2/0; // サブスレッドの突然死のトラップを確認するためのコード
\r
4997 setTrayIconVisible(env.getShowSysTray());
\r
5000 setXButtonAction(env.getShowSysTray() && env.getHideToTray());
\r
5003 this.addWindowListener(new WindowAdapter() {
\r
5004 // ウィンドウを最小化したときの処理
\r
5006 public void windowIconified(WindowEvent e) {
\r
5012 public void windowClosing(WindowEvent e) {
\r
5017 // 初回起動時はレコーダの登録を促す
\r
5018 if ( recorders.size() == 0 ) {
\r
5019 Container cp = getContentPane();
\r
5020 JOptionPane.showMessageDialog(cp, "レコーダが登録されていません。\n最初に登録を行ってください。\n番組表だけを使いたい場合は、\nNULLプラグインを登録してください。");
\r
5023 // ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
\r
5025 // ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
\r
5027 // [ツールバー/共通] レコーダ情報変更
\r
5028 toolBar.addHDDRecorderChangeListener(autores);
\r
5031 toolBar.addHDDRecorderSelectionListener(this); // 新聞形式
\r
5032 toolBar.addHDDRecorderSelectionListener(paper); // 新聞形式
\r
5033 toolBar.addHDDRecorderSelectionListener(autores); // 自動予約一覧
\r
5034 toolBar.addHDDRecorderSelectionListener(rdialog); // 予約ダイアログ
\r
5036 // [タイマー] タイトルバー更新/リスト形式の現在時刻ノード/新聞形式の現在時刻ノード
\r
5037 timer_now.addTickTimerRiseListener(this);
\r
5038 timer_now.addTickTimerRiseListener(listed);
\r
5039 timer_now.addTickTimerRiseListener(paper);
\r
5041 // ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
\r
5043 // ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
\r
5044 toolBar.setSelectedRecorder(bounds.getSelectedRecorderId());
\r
5046 // ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
\r
5047 // [Fire!] サイドツリーのデフォルトを選択することで番組情報の描画を開始する
\r
5048 // ※ここ以前だとぬぽとかOOBとか出るかもよ!
\r
5049 // ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
\r
5050 paper.selectTreeDefault();
\r
5051 listed.selectTreeDefault();
\r
5053 // ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
\r
5054 // メインウィンドウをスプラッシュからコンポーネントに入れ替える
\r
5055 // ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
\r
5056 this.setVisible(false);
\r
5057 this.setContentPane(mainWindow);
\r
5059 this.setVisible(true);
\r
5061 setTitleBar(); // タイトルバー更新
\r
5063 ShowInitTab(); // 前回開いていたタブを開く
\r
5065 // ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
\r
5067 // ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
\r
5068 timer_now.start();
\r
5070 // ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
\r
5072 // ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
\r
5073 mwin.appendMessage(String.format("タイニー番組ナビゲータが起動しました (VersionInfo:%s on %s)",VersionInfo.getVersion(),VersionInfo.getEnvironment()));
\r
5074 initialized = true;
\r