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,VWTimerRiseListener {
\r
83 private static final long serialVersionUID = 1L;
\r
86 public void stateChanged(ChangeEvent e){
\r
87 StdAppendMessage("イベント発生");
\r
95 private void StdAppendMessage(String message) { System.out.println(message); }
\r
96 private void StdAppendError(String message) { System.err.println(message); }
\r
98 private void MWinSetVisible(boolean b) { mwin.setVisible(b); }
\r
100 private void StWinClear() { stwin.clear(); }
\r
101 private void StWinSetVisible(boolean b) { stwin.setVisible(b); }
\r
102 private void StWinSetLocationCenter(Component frame) { CommonSwingUtils.setLocationCenter(frame, (VWStatusWindow)stwin); }
\r
103 private void StWinSetLocationUnder(Component frame) { CommonSwingUtils.setLocationUnder(frame, (VWStatusWindow)stwin); }
\r
105 private void ringBeep() { if (env!=null && ! env.getDisableBeep()) { Toolkit.getDefaultToolkit().beep(); if ( env.getDebug() ) CommonUtils.printStackTrace(); } }
\r
113 private final Env env = new Env(); // 主要な設定
\r
114 private final Bounds bounds = new Bounds(); // ウィンドウサイズとか動的に変化するもの
\r
115 private final ClipboardInfoList cbitems = new ClipboardInfoList(); // クリップボード対応機能でどの項目をコピーするかとかの設定
\r
116 private final PaperColorsMap pColors = new PaperColorsMap(); // 新聞形式のジャンル別背景色の設定
\r
117 private final AVSetting avs = new AVSetting(); // ジャンル別録画画質・音質等設定
\r
118 private final CHAVSetting chavs = new CHAVSetting(); // CH別録画画質・音質等設定
\r
119 private final ChannelSort chsort = new ChannelSort(); // CHソート設定
\r
120 private final ChannelConvert chconv = new ChannelConvert(); // ChannelConvert.dat
\r
121 private final MarkChar markchar = new MarkChar(env); // タイトルにつけるマークを操作する
\r
123 private final MarkedProgramList mpList = new MarkedProgramList(); // 検索結果のキャッシュ(表示高速化用)
\r
124 private final TraceProgram trKeys = new TraceProgram(); // 番組追跡の設定
\r
125 private final SearchProgram srKeys = new SearchProgram(); // キーワード検索の設定
\r
126 private final SearchGroupList srGrps = new SearchGroupList(); // キーワード検索グループの設定
\r
127 private final ExtProgram extKeys = new ExtProgram(); // 延長警告管理の設定
\r
129 private final RecorderInfoList recInfoList = new RecorderInfoList(); // レコーダ一覧の設定
\r
131 private final HDDRecorderList recPlugins = new HDDRecorderList(); // レコーダプラグイン(テンプレート)
\r
132 private final HDDRecorderList recorders = new HDDRecorderList(); // レコーダプラグイン(実際に利用するもの)
\r
134 private final TVProgramList progPlugins = new TVProgramList(); // Web番組表プラグイン(テンプレート)
\r
135 private final TVProgramList tvprograms = new TVProgramList(); // Web番組表プラグイン(実際に利用するもの)
\r
137 private final VWTimer timer_now = new VWTimer(); // 毎分00秒に起動して処理をキックするタイマー
\r
140 private boolean logging = true; // ログ出力する
\r
141 private boolean runRecWakeup = false; // 起動時にレコーダを起こす
\r
142 private boolean runRecLoad = false; // 起動時にレコーダから予約一覧を取得する
\r
143 private boolean enableWebAccess = true; // 起動時のWeb番組表へのアクセスを禁止する
\r
144 private boolean onlyLoadProgram = false;
\r
145 private String pxaddr = null; // ProxyAddress指定
\r
146 private String pxport = null; // ProxtPort指定
\r
149 /*******************************************************************************
\r
151 ******************************************************************************/
\r
153 public static final String LOG_FILE = "log.txt"; // ログファイル名
\r
154 public static final String HISTORY_FILE = "05_history.txt"; // 更新履歴だよ
\r
156 private static final String ICONFILE_SYSTRAY = "icon"+File.separator+"tainavi16.png";
\r
157 private static final String ICONFILE_TAINAVI = "icon"+File.separator+"tainavi.png";
\r
159 public static final int TIMEBAR_START = 5; // 新聞形式の開始時刻
\r
160 private static final int OPENING_WIAT = 500; // まあ起動時しか使わないんですけども
\r
162 private static final String MSGID = "[鯛ナビ] ";
\r
163 private static final String ERRID = "[ERROR]"+MSGID;
\r
164 private static final String DBGID = "[DEBUG]"+MSGID;
\r
167 * Web番組表のどれとどれを読めばいいのか
\r
169 public static enum LoadFor {
\r
170 TERRA ("地上波&BSのみ取得"),
\r
172 CSo1 ("CS[プライマリ]のみ取得"),
\r
173 CSo2 ("CS[セカンダリ]のみ取得"),
\r
174 CSwSD ("CSのみ取得(取得後シャットダウン)"),
\r
176 SYOBO ("しょぼかるのみ取得"),
\r
179 private String name;
\r
181 private LoadFor(String name) {
\r
185 public String getName() {
\r
189 public static LoadFor get(String s) {
\r
190 for ( LoadFor lf : LoadFor.values() ) {
\r
191 if ( lf.name.equals(s) ) {
\r
200 * レコーダ情報のどれとどれを読めばいいのか
\r
202 public static enum LoadRsvedFor {
\r
203 SETTING ( "設定情報のみ取得(future use.)" ),
\r
204 RECORDED ( "録画結果のみ取得" ),
\r
207 private String name;
\r
209 private LoadRsvedFor(String name) {
\r
213 public String getName() {
\r
217 public static LoadRsvedFor get(String s) {
\r
218 for ( LoadRsvedFor lrf : LoadRsvedFor.values() ) {
\r
219 if ( lrf.name.equals(s) ) {
\r
229 * @deprecated しっぱいした 半年くらいしたら削除する
\r
231 public static enum ListedColumn {
\r
232 RSVMARK ("予約", 35),
\r
233 DUPMARK ("重複", 35),
\r
234 CHNAME ("チャンネル名", 100),
\r
235 TITLE ("番組タイトル", 300),
\r
236 DETAIL ("番組詳細", 200),
\r
237 START ("開始時刻", 150),
\r
240 GENRE ("ジャンル", 85),
\r
241 SITEM ("検索アイテム名", 100),
\r
242 STAR ("お気に入り度", 100),
\r
244 THRESHOLD ("閾値", 35),
\r
245 HID_PRGID ("PRGID", -1),
\r
246 HID_STIME ("STIME", -1),
\r
247 HID_ETIME ("ETIME", -1),
\r
248 HID_EXFLG ("EXFLG", -1),
\r
249 HID_TITLE ("TITLE", -1),
\r
252 @SuppressWarnings("unused")
\r
253 private String name;
\r
254 private int iniWidth;
\r
256 private ListedColumn(String name, int iniWidth) {
\r
258 this.iniWidth = iniWidth;
\r
263 public String toString() {
\r
268 public int getIniWidth() {
\r
272 public int getColumn() {
\r
279 * @deprecated しっぱいした 半年くらいしたら削除する
\r
281 public static enum RsvedColumn {
\r
282 PATTERN ("パタン", 110),
\r
283 DUPMARK ("重複", 35),
\r
286 NEXTSTART ("次回実行予定", 150),
\r
289 ENCODER ("エンコーダ", 50),
\r
292 TITLE ("番組タイトル", 300),
\r
293 CHNAME ("チャンネル名", 150),
\r
294 RECORDER ("レコーダ", 200),
\r
295 HID_INDEX ("INDEX", -1),
\r
296 HID_RSVID ("RSVID", -1),
\r
299 @SuppressWarnings("unused")
\r
300 private String name;
\r
301 private int iniWidth;
\r
303 private RsvedColumn(String name, int iniWidth) {
\r
305 this.iniWidth = iniWidth;
\r
310 public String toString() {
\r
315 public int getIniWidth() {
\r
319 public int getColumn() {
\r
331 private final VWStatusWindow stwin = new VWStatusWindow();
\r
332 private final VWStatusTextArea mwin = new VWStatusTextArea();
\r
333 private final VWColorChooserDialog ccwin = new VWColorChooserDialog();
\r
334 private final VWPaperColorsDialog pcwin = new VWPaperColorsDialog();
\r
335 private final VWReserveDialog rdialog = new VWReserveDialog(0, 0);
\r
337 // 初期化処理の中で生成していくもの
\r
338 private VWMainWindow mainWindow = null;
\r
339 private VWToolBar toolBar = null;
\r
340 private VWListedView listed = null;
\r
341 private VWPaperView paper = null;
\r
342 private VWReserveListView reserved = null;
\r
343 private VWRecordedListView recorded = null;
\r
344 private VWAutoReserveListView autores = null;
\r
345 private VWSettingView setting = null;
\r
346 private VWRecorderSettingView recsetting = null;
\r
347 private VWChannelSettingView chsetting = null;
\r
348 private VWChannelDatSettingView chdatsetting = null;
\r
349 private VWChannelSortView chsortsetting = null;
\r
350 private VWChannelConvertView chconvsetting = null;
\r
351 private VWLookAndFeel vwlaf = null;
\r
352 private VWFont vwfont = null;
\r
354 private TrayIcon trayicon = null;
\r
358 /*******************************************************************************
\r
359 * タブやダイアログのインスタンス作成用クラス定義
\r
360 ******************************************************************************/
\r
365 private class VWListedView extends AbsListedView {
\r
367 private static final long serialVersionUID = 1L;
\r
371 protected Env getEnv() { return env; }
\r
373 protected Bounds getBoundsEnv() { return bounds; }
\r
375 protected ChannelSort getChannelSort() { return chsort; }
\r
378 protected MarkedProgramList getMarkedProgramList() { return mpList; }
\r
380 protected TraceProgram getTraceProgram() { return trKeys; }
\r
382 protected SearchProgram getSearchProgram() { return srKeys; }
\r
384 protected SearchGroupList getSearchGroupList() { return srGrps; }
\r
386 protected ExtProgram getExtProgram() { return extKeys; }
\r
389 protected TVProgramList getTVProgramList() { return tvprograms; }
\r
391 protected HDDRecorderList getRecorderList() { return recorders; }
\r
395 protected StatusWindow getStWin() { return stwin; }
\r
397 protected StatusTextArea getMWin() { return mwin; }
\r
401 protected AbsReserveDialog getReserveDialog() { return rdialog; }
\r
403 protected Component getParentComponent() { return Viewer.this; }
\r
406 protected void ringBeep() { Viewer.this.ringBeep(); }
\r
409 * AbsListedView内でのイベントから呼び出されるメソッド群
\r
413 protected void onShown() {
\r
414 // キーワード登録ボタンはリスト形式のみ
\r
415 toolBar.setAddkeywordEnabled(true);
\r
417 toolBar.setBatchReservationEnabled(true);
\r
419 toolBar.setSnapShotEnabled(true);
\r
423 protected void onHidden() {
\r
424 // キーワード登録ボタンはリスト形式のみ
\r
425 toolBar.setAddkeywordEnabled(false);
\r
427 toolBar.setBatchReservationEnabled(false);
\r
429 toolBar.setSnapShotEnabled(false);
\r
433 protected void showPopupForTraceProgram(
\r
434 final JComponent comp,
\r
435 final ProgDetailList tvd, final String keyword, final int threshold,
\r
436 final int x, final int y, final int h) {
\r
439 Viewer.this.showPopupForTraceProgram(comp, tvd, keyword, threshold, x, y, h);
\r
444 protected void updateReserveDisplay(String chname) {
\r
446 paper.updateReserveBorder(chname);
\r
447 reserved.redrawReservedList();
\r
452 protected void updateBangumiColumns() {
\r
454 paper.updateBangumiColumns();
\r
459 protected void clearPaper() {
\r
461 paper.clearPanel();
\r
466 protected void previewKeywordSearch(SearchKey search) {
\r
467 //timer_now.pause();
\r
468 if (search.alTarget.size() > 0) {
\r
469 mainWindow.setSelectedTab(MWinTab.LISTED);
\r
470 listed.redrawListByPreview(search);
\r
472 //timer_now.start();
\r
476 protected void jumpToPaper(String Center, String StartDateTime) {
\r
477 //timer_now.pause();
\r
478 paper.jumpToBangumi(Center,StartDateTime);
\r
479 //timer_now.start();
\r
483 protected boolean addToPickup(ProgDetailList tvd) { return Viewer.this.addToPickup(tvd); }
\r
486 protected boolean isTabSelected(MWinTab tab) { return mainWindow.isTabSelected(tab); }
\r
488 protected void setSelectedTab(MWinTab tab) { mainWindow.setSelectedTab(tab); }
\r
491 protected String getSelectedRecorderOnToolbar() { return toolBar.getSelectedRecorder(); }
\r
493 protected boolean isFullScreen() { return toolBar.isFullScreen(); }
\r
495 protected void setPagerEnabled(boolean b) { toolBar.setPagerEnabled(b); }
\r
497 protected int getPagerCount() { return toolBar.getPagerCount(); }
\r
499 protected int getSelectedPagerIndex() { return toolBar.getSelectedPagerIndex(); }
\r
502 protected void setDividerEnvs(int loc) {
\r
503 if ( ! toolBar.isFullScreen() && mainWindow.isTabSelected(MWinTab.LISTED) ) {
\r
504 if (env.getSyncTreeWidth()) {
\r
505 bounds.setTreeWidth(loc);
\r
506 bounds.setTreeWidthPaper(loc);
\r
509 bounds.setTreeWidth(loc);
\r
520 private class VWPaperView extends AbsPaperView {
\r
522 private static final long serialVersionUID = 1L;
\r
526 protected Env getEnv() { return env; }
\r
528 protected Bounds getBoundsEnv() { return bounds; }
\r
530 protected PaperColorsMap getPaperColorMap() { return pColors; }
\r
532 protected ChannelSort getChannelSort() { return chsort; }
\r
535 protected TVProgramList getTVProgramList() { return tvprograms; }
\r
537 protected HDDRecorderList getRecorderList() { return recorders; }
\r
541 protected StatusWindow getStWin() { return stwin; }
\r
543 protected StatusTextArea getMWin() { return mwin; }
\r
547 protected AbsReserveDialog getReserveDialog() { return rdialog; }
\r
549 protected Component getParentComponent() { return Viewer.this; }
\r
552 protected void ringBeep() { Viewer.this.ringBeep(); }
\r
555 * AbsPaperView内でのイベントから呼び出されるメソッド群
\r
559 protected void onShown() {
\r
560 // ページャーコンボボックスを有効にする(状況次第で有効にならない場合もある)(ツリーの選択次第で変わるのでもどし)
\r
561 //toolBar.setPagerEnabled(true);
\r
563 toolBar.setSnapShotEnabled(true);
\r
565 toolBar.setPaperColorDialogEnabled(true);
\r
567 toolBar.setBorderToggleEnabled(true);
\r
571 protected void onHidden() {
\r
572 // 新聞形式以外ではページャーコンボボックスを無効にする(ツリーの選択次第で変わるのでもどし)
\r
573 //toolBar.setPagerEnabled(false);
\r
574 // 新聞形式以外ではスナップショットを無効にする
\r
575 toolBar.setSnapShotEnabled(false);
\r
576 // 新聞形式以外ではジャンル別背景色を無効にする
\r
577 toolBar.setPaperColorDialogEnabled(false);
\r
578 // 新聞形式以外ではマッチ枠を無効にする
\r
579 toolBar.setBorderToggleEnabled(false);
\r
583 protected void showPopupForTraceProgram(
\r
584 final JComponent comp,
\r
585 final ProgDetailList tvd, final String keyword, final int threshold,
\r
586 final int x, final int y, final int h) {
\r
589 Viewer.this.showPopupForTraceProgram(comp, tvd, keyword, threshold, x, y, h);
\r
594 protected void updateReserveDisplay() {
\r
596 listed.updateReserveMark();
\r
597 reserved.redrawReservedList();
\r
602 protected void addToPickup(ProgDetailList tvd) { Viewer.this.addToPickup(tvd); }
\r
605 protected boolean isTabSelected(MWinTab tab) { return mainWindow.isTabSelected(tab); }
\r
607 protected void setSelectedTab(MWinTab tab) { mainWindow.setSelectedTab(tab); }
\r
610 protected String getSelectedRecorderOnToolbar() { return toolBar.getSelectedRecorder(); }
\r
612 protected boolean isFullScreen() { return toolBar.isFullScreen(); }
\r
614 protected void setSelectedPagerIndex(int idx) {
\r
615 toolBar.setSelectedPagerIndex(idx);
\r
618 protected void setPagerEnabled(boolean b) { toolBar.setPagerEnabled(b); }
\r
620 protected int getPagerCount() { return toolBar.getPagerCount(); }
\r
622 protected int getSelectedPagerIndex() { return toolBar.getSelectedPagerIndex(); }
\r
624 protected void setPagerItems(TVProgramIterator pli, int curindex) {
\r
625 toolBar.setPagerItems(pli,curindex);
\r
629 protected String getExtensionMark(ProgDetailList tvd) { return markchar.getExtensionMark(tvd); }
\r
631 protected String getOptionMark(ProgDetailList tvd) { return markchar.getOptionMark(tvd)+markchar.getNewLastMark(tvd); }
\r
633 protected String getPostfixMark(ProgDetailList tvd) { return markchar.getPostfixMark(tvd); }
\r
636 protected void setDividerEnvs(int loc) {
\r
637 if ( ! toolBar.isFullScreen() && mainWindow.isTabSelected(MWinTab.PAPER) ) {
\r
638 if (env.getSyncTreeWidth()) {
\r
639 bounds.setTreeWidth(loc);
\r
640 bounds.setTreeWidthPaper(loc);
\r
643 bounds.setTreeWidthPaper(loc);
\r
656 private class VWReserveListView extends AbsReserveListView {
\r
658 private static final long serialVersionUID = 1L;
\r
662 protected Env getEnv() { return env; }
\r
664 protected Bounds getBoundsEnv() { return bounds; }
\r
667 protected HDDRecorderList getRecorderList() { return recorders; }
\r
673 protected AbsReserveDialog getReserveDialog() { return rdialog; }
\r
675 protected Component getParentComponent() { return Viewer.this; }
\r
678 protected void ringBeep() { Viewer.this.ringBeep(); }
\r
681 * AbsReserveListView内でのイベントから呼び出されるメソッド群
\r
685 protected void updateReserveDisplay(String chname) {
\r
687 listed.updateReserveMark();
\r
688 paper.updateReserveBorder(chname);
\r
693 protected boolean doExecOnOff(boolean fexec, String title, String chnam, String rsvId, String recId) {
\r
694 return Viewer.this.doExecOnOff(fexec, title, chnam, rsvId, recId);
\r
698 protected JMenuItem getExecOnOffMenuItem(boolean fexec, String title,
\r
699 String chnam, String rsvId, String recId) {
\r
701 return Viewer.this.getExecOnOffMenuItem(fexec, title, chnam, rsvId, recId, 0);
\r
705 protected JMenuItem getRemoveRsvMenuItem(String title, String chnam,
\r
706 String rsvId, String recId) {
\r
708 return Viewer.this.getRemoveRsvMenuItem(title, chnam, rsvId, recId, 0);
\r
712 protected JMenuItem getJumpMenuItem(String title, String chnam,
\r
715 return Viewer.this.getJumpMenuItem(title, chnam, startDT);
\r
719 protected JMenuItem getJumpToLastWeekMenuItem(String title,
\r
720 String chnam, String startDT) {
\r
722 return Viewer.this.getJumpToLastWeekMenuItem(title, chnam, startDT);
\r
726 protected String getSelectedRecorderOnToolbar() { return toolBar.getSelectedRecorder(); }
\r
735 private class VWRecordedListView extends AbsRecordedListView {
\r
737 private static final long serialVersionUID = 1L;
\r
741 protected Env getEnv() { return env; }
\r
743 protected Bounds getBoundsEnv() { return bounds; }
\r
746 protected HDDRecorderList getRecorderList() { return recorders; }
\r
752 protected Component getParentComponent() { return Viewer.this; }
\r
755 protected void ringBeep() { Viewer.this.ringBeep(); }
\r
758 * AbsReserveListView内でのイベントから呼び出されるメソッド群
\r
762 protected String getSelectedRecorderOnToolbar() { return toolBar.getSelectedRecorder(); }
\r
771 private class VWAutoReserveListView extends AbsAutoReserveListView {
\r
773 private static final long serialVersionUID = 1L;
\r
777 protected Env getEnv() { return env; }
\r
779 protected Bounds getBoundsEnv() { return bounds; }
\r
786 private class VWSettingView extends AbsSettingView {
\r
788 private static final long serialVersionUID = 1L;
\r
792 protected Env getEnv() { return env; }
\r
794 protected ClipboardInfoList getCbItemEnv() { return cbitems; }
\r
796 protected VWLookAndFeel getLAFEnv() { return vwlaf; }
\r
798 protected VWFont getFontEnv() { return vwfont; }
\r
802 protected StatusWindow getStWin() { return stwin; }
\r
804 protected StatusTextArea getMWin() { return mwin; }
\r
808 protected Component getParentComponent() { return Viewer.this; }
\r
810 protected VWColorChooserDialog getCcWin() { return ccwin; }
\r
813 * AbsSettingView内でのイベントから呼び出されるメソッド群
\r
817 protected void lafChanged(String lafname) {
\r
818 vwlaf.update(lafname);
\r
819 Viewer.this.updateComponentTreeUI();
\r
820 StdAppendMessage("Set LookAndFeel="+lafname);
\r
824 protected void fontChanged(String fn, int fontSize) {
\r
825 vwfont.update(fn, fontSize);
\r
826 Viewer.this.updateComponentTreeUI();
\r
827 StdAppendMessage("システムのフォントを変更しました: "+fn+", size="+fontSize);
\r
831 protected void setEnv(final boolean reload_prog) {
\r
833 //listed.pauseTimer();
\r
840 // CommonUtilsの設定変更
\r
841 CommonUtils.setAdjLateNight(env.getAdjLateNight());
\r
842 CommonUtils.setExpandTo8(env.getExpandTo8());
\r
843 CommonUtils.setUseRundll32(env.getUseRundll32());
\r
844 CommonUtils.setDisplayPassedReserve(env.getDisplayPassedReserve());
\r
845 CommonUtils.setDebug(env.getDebug());
\r
847 SwingBackgroundWorker.setDebug(env.getDebug());
\r
850 toolBar.setDebug(env.getDebug());
\r
851 autores.setDebug(env.getDebug());
\r
853 // PassedProgramListの設定変更
\r
854 tvprograms.getPassed().setPassedDir(env.getPassedDir());
\r
857 for ( HDDRecorder rec : recorders ) {
\r
859 setSettingRecPluginExt(rec, env);
\r
863 setSettingProgPluginCommon(env);
\r
866 setSettingProgPluginAll(env);
\r
869 toolBar.updateReloadProgramExtention();
\r
871 // ページャーコンボボックスの書き換え
\r
872 toolBar.setPagerItems();
\r
875 listed.setMarkColumnVisible(env.getSplitMarkAndTitle());
\r
876 listed.setDetailColumnVisible(env.getShowDetailOnList());
\r
877 listed.setRowHeaderVisible(env.getRowHeaderVisible());
\r
878 reserved.setRowHeaderVisible(env.getRowHeaderVisible());
\r
881 listed.setMatchedKeywordColor(env.getMatchedKeywordColor());
\r
882 listed.setRsvdLineColor((env.getRsvdLineEnhance())?(env.getRsvdLineColor()):(null));
\r
883 listed.setPickedLineColor((env.getRsvdLineEnhance())?(env.getPickedLineColor()):(null));
\r
884 listed.setCurrentLineColor((env.getCurrentLineEnhance())?(env.getCurrentLineColor()):(null));
\r
887 setTrayIconVisible(env.getShowSysTray());
\r
888 setXButtonAction(env.getShowSysTray() && env.getHideToTray());
\r
890 // 新聞形式のツールチップの表示時間を変更する
\r
894 mpList.setHistoryOnlyUpdateOnce(env.getHistoryOnlyUpdateOnce());
\r
895 mpList.setShowOnlyNonrepeated(env.getShowOnlyNonrepeated());
\r
898 if ( reload_prog ) {
\r
899 loadTVProgram(false,LoadFor.ALL); // 部品呼び出し
\r
903 paper.clearPanel();
\r
904 paper.buildMainViewByDate();
\r
907 paper.redrawTreeByDate();
\r
908 paper.redrawTreeByPassed();
\r
910 listed.redrawTreeByHistory();
\r
911 listed.redrawTreeByCenter();
\r
914 paper.reselectTree();
\r
915 listed.reselectTree();
\r
917 //listed.continueTimer(); // まあreselectTree()で再開しているはずだが
\r
924 * @see AbsRecorderSettingView
\r
926 private class VWRecorderSettingView extends AbsRecorderSettingView {
\r
928 private static final long serialVersionUID = 1L;
\r
932 protected Env getEnv() { return env; }
\r
934 protected RecorderInfoList getRecInfos() { return recInfoList; }
\r
936 protected HDDRecorderList getRecPlugins() { return recPlugins; }
\r
940 protected VWStatusWindow getStWin() { return stwin; }
\r
942 protected StatusTextArea getMWin() { return mwin; }
\r
946 protected Component getParentComponent() { return Viewer.this; }
\r
948 protected VWColorChooserDialog getCcWin() { return ccwin; }
\r
951 protected void ringBeep() { Viewer.this.ringBeep(); }
\r
954 * AbsRecorderSettingView内でのイベントから呼び出されるメソッド群
\r
958 protected void setRecInfos() {
\r
963 recInfoList.save();
\r
965 // レコーダプラグインのリフレッシュ
\r
966 initRecPluginAll();
\r
969 toolBar.updateRecorderComboBox();
\r
972 loadRdReserve(false, null); // toolBarの内容がリセットされているので recId = null で
\r
975 this.redrawRecorderEncoderEntry();
\r
977 // レコーダ一覧をCHコード設定のコンボボックスに設定
\r
978 chdatsetting.updateRecorderComboBox();
\r
980 // Web番組表の再構築(予約マークのリフレッシュ)
\r
981 paper.updateReserveBorder(null);
\r
982 listed.updateReserveMark();
\r
993 private class VWChannelSettingView extends AbsChannelSettingView {
\r
995 private static final long serialVersionUID = 1L;
\r
999 protected Env getEnv() { return Viewer.this.env; }
\r
1001 protected TVProgramList getProgPlugins() { return progPlugins; }
\r
1005 protected StatusWindow getStWin() { return stwin; }
\r
1007 protected StatusTextArea getMWin() { return mwin; }
\r
1011 protected Component getParentComponent() { return Viewer.this; }
\r
1013 protected VWColorChooserDialog getCcWin() { return ccwin; }
\r
1016 protected void ringBeep() {
\r
1017 Viewer.this.ringBeep();
\r
1020 protected void updateProgPlugin() {
\r
1022 timer_now.pause();
\r
1024 // 設定を保存(プラグイン内部の設定はChannelSettingPanel内で実施)
\r
1027 // Web番組表プラグインのリフレッシュ
\r
1028 setSelectedProgPlugin();
\r
1029 initProgPluginAll();
\r
1032 chsortsetting.updateChannelSortTable();
\r
1034 // CHコンバート設定をリフレッシュ
\r
1035 chconvsetting.updateChannelConvertTable();
\r
1038 chdatsetting.updateChannelDatTable();
\r
1041 loadTVProgram(false,LoadFor.ALL); // 部品呼び出し
\r
1044 toolBar.setPagerItems();
\r
1047 paper.clearPanel();
\r
1048 paper.buildMainViewByDate();
\r
1051 paper.redrawTreeByCenter();
\r
1053 listed.redrawTreeByCenter();
\r
1056 paper.reselectTree();
\r
1057 listed.reselectTree();
\r
1059 timer_now.start();
\r
1067 private class VWChannelDatSettingView extends AbsChannelDatSettingView {
\r
1069 private static final long serialVersionUID = 1L;
\r
1073 protected Env getEnv() { return Viewer.this.env; }
\r
1075 protected TVProgramList getTVProgramList() { return tvprograms; }
\r
1077 protected ChannelSort getChannelSort() { return chsort; }
\r
1079 protected HDDRecorderList getHDDRecorderList() { return recorders; }
\r
1083 protected StatusWindow getStWin() { return stwin; }
\r
1085 protected StatusTextArea getMWin() { return mwin; }
\r
1089 protected Component getParentComponent() { return Viewer.this; }
\r
1092 protected void ringBeep() {
\r
1093 Viewer.this.ringBeep();
\r
1101 private class VWChannelSortView extends AbsChannelSortView {
\r
1103 private static final long serialVersionUID = 1L;
\r
1106 protected Env getEnv() { return Viewer.this.env; }
\r
1108 protected TVProgramList getTVProgramList() { return tvprograms; }
\r
1110 protected ChannelSort getChannelSort() { return chsort; }
\r
1114 protected StatusTextArea getMWin() { return mwin; }
\r
1117 protected void updProc() {
\r
1119 timer_now.pause();
\r
1123 toolBar.setPagerItems();
\r
1124 toolBar.setSelectedPagerIndex(toolBar.getSelectedPagerIndex());
\r
1127 paper.clearPanel();
\r
1128 paper.buildMainViewByDate();
\r
1131 paper.redrawTreeByCenter();
\r
1133 listed.redrawTreeByCenter();
\r
1136 paper.reselectTree();
\r
1137 listed.reselectTree();
\r
1139 timer_now.start();
\r
1144 * CHコンバート設定タブの内部クラス
\r
1146 private class VWChannelConvertView extends AbsChannelConvertView {
\r
1148 private static final long serialVersionUID = 1L;
\r
1152 protected Env getEnv() { return env; }
\r
1154 protected TVProgramList getProgPlugins() { return progPlugins; }
\r
1156 protected ChannelConvert getChannelConvert() { return chconv; }
\r
1163 private class VWReserveDialog extends AbsReserveDialog {
\r
1165 private static final long serialVersionUID = 1L;
\r
1168 public VWReserveDialog(int x, int y) {
\r
1174 protected Env getEnv() { return env; }
\r
1176 protected TVProgramList getTVProgramList() { return tvprograms; }
\r
1178 protected HDDRecorderList getRecorderList() { return recorders; }
\r
1180 protected AVSetting getAVSetting() { return avs; }
\r
1182 protected CHAVSetting getCHAVSetting() { return chavs; }
\r
1186 protected StatusWindow getStWin() { return stwin; }
\r
1188 protected StatusTextArea getMWin() { return mwin; }
\r
1192 protected Component getParentComponent() { return Viewer.this; }
\r
1195 protected void ringBeep() { Viewer.this.ringBeep(); }
\r
1198 * ReserveDialog内でのイベントから呼び出されるメソッド群
\r
1202 protected void searchLikeRsv(LikeReserveList likeRsvList, ProgDetailList tvd, String keyword, int threshold) {
\r
1203 Viewer.this.searchLikeRsv(likeRsvList, tvd, keyword, threshold);
\r
1207 protected String getSelectedRecorderOnToolbar() { return toolBar.getSelectedRecorder(); }
\r
1211 * 新聞の表示形式を操作するダイアログ
\r
1213 private class VWPaperColorsDialog extends AbsPaperColorsDialog {
\r
1215 private static final long serialVersionUID = 1L;
\r
1218 protected Env getEnv() { return env; }
\r
1220 protected Bounds getBoundsEnv() { return bounds; }
\r
1222 protected PaperColorsMap getPaperColorMap() { return pColors; }
\r
1225 protected VWColorChooserDialog getCCWin() { return ccwin; }
\r
1228 * PaperColorsDialog内でのイベントから呼び出されるメソッド群
\r
1233 protected void updatePaperColors(Env ec,PaperColorsMap pc) {
\r
1234 paper.updateColors(ec,pc);
\r
1239 protected void updatePaperFonts(Env ec) {
\r
1240 paper.updateFonts(ec);
\r
1245 protected void updatePaperBounds(Env ec, Bounds bc) {
\r
1246 paper.updateBounds(ec,bc);
\r
1251 protected void updatePaperRepaint() {
\r
1252 paper.updateRepaint();
\r
1257 * キーワード検索ウィンドウの内部クラス
\r
1259 private class VWKeywordDialog extends AbsKeywordDialog {
\r
1261 private static final long serialVersionUID = 1L;
\r
1264 void preview(SearchKey search) {
\r
1266 if (search.alTarget.size() > 0) {
\r
1267 mainWindow.setSelectedTab(MWinTab.LISTED);
\r
1268 listed.redrawListByPreview(search);
\r
1274 * 延長警告管理ウィンドウの内部クラス
\r
1276 private class VWExtensionDialog extends AbsExtensionDialog {
\r
1278 private static final long serialVersionUID = 1L;
\r
1281 void preview(SearchKey search) {
\r
1283 if (search.alTarget.size() > 0) {
\r
1284 mainWindow.setSelectedTab(MWinTab.LISTED);
\r
1285 listed.redrawListByPreview(search);
\r
1295 private class VWToolBar extends AbsToolBar {
\r
1297 private static final long serialVersionUID = 1L;
\r
1300 protected Env getEnv() { return env; }
\r
1302 protected Bounds getBoundsEnv() { return bounds; }
\r
1304 protected TVProgramList getTVPrograms() { return tvprograms; }
\r
1306 protected ChannelSort getChannelSort() { return chsort; }
\r
1308 protected HDDRecorderList getHDDRecorders() { return recorders; }
\r
1311 protected StatusWindow getStWin() { return stwin; }
\r
1313 protected StatusTextArea getMWin() { return mwin; }
\r
1315 protected Component getParentComponent() { return Viewer.this; }
\r
1318 protected void ringBeep() { Viewer.this.ringBeep(); }
\r
1321 protected boolean doKeywordSerach(SearchKey search, String kStr, String sStr, boolean doFilter) {
\r
1323 timer_now.pause();
\r
1325 if ( mainWindow.getSelectedTab() == MWinTab.RSVED ) {
\r
1326 reserved.redrawListByKeywordFilter(search, kStr);
\r
1328 else if ( mainWindow.getSelectedTab() == MWinTab.RECED ) {
\r
1329 recorded.redrawListByKeywordFilter(search, kStr);
\r
1332 if ( search != null ) {
\r
1333 mainWindow.setSelectedTab(MWinTab.LISTED);
\r
1336 listed.clearSelection();
\r
1337 listed.redrawListByKeywordFilter(search, kStr);
\r
1339 else if (sStr != null) {
\r
1341 searchPassedProgram(search, sStr);
\r
1342 listed.clearSelection();
\r
1343 listed.redrawListBySearched(ProgType.PASSED, 0);
\r
1345 listed.redrawTreeByHistory();
\r
1349 listed.clearSelection();
\r
1350 listed.redrawListByKeywordDyn(search, kStr);
\r
1355 timer_now.start();
\r
1361 protected boolean doBatchReserve() {
\r
1362 timer_now.pause();
\r
1363 listed.doBatchReserve();
\r
1364 timer_now.start();
\r
1369 protected boolean jumpToNow() {
\r
1370 timer_now.pause();
\r
1371 if ( ! mainWindow.isTabSelected(MWinTab.PAPER) ) {
\r
1372 mainWindow.setSelectedTab(MWinTab.PAPER);
\r
1374 paper.jumpToNow();
\r
1375 timer_now.start();
\r
1380 protected boolean jumpToPassed(String passed) {
\r
1381 timer_now.pause();
\r
1382 boolean b = paper.jumpToBangumi(null,passed);
\r
1383 timer_now.start();
\r
1388 protected boolean redrawByPager() {
\r
1389 timer_now.pause();
\r
1390 boolean b = paper.redrawByPager();
\r
1391 timer_now.start();
\r
1396 protected void toggleMatchBorder() {
\r
1397 timer_now.pause();
\r
1398 paper.toggleMatchBorder();
\r
1399 timer_now.start();
\r
1403 protected void setPaperColorDialogVisible(boolean b) {
\r
1404 //paper.stopTimer(); xxxx
\r
1405 timer_now.pause();
\r
1406 CommonSwingUtils.setLocationCenter(Viewer.this,pcwin);
\r
1407 pcwin.setVisible(true);
\r
1408 timer_now.start();
\r
1412 protected void setPaperZoom(int n) {
\r
1413 timer_now.pause();
\r
1415 timer_now.start();
\r
1419 protected boolean recorderSelectorChanged() {
\r
1421 timer_now.pause();
\r
1423 if (mainWindow.isTabSelected(MWinTab.LISTED)) {
\r
1424 listed.updateReserveMark();
\r
1425 listed.selectBatchTarget();
\r
1427 else if (mainWindow.isTabSelected(MWinTab.RSVED)) {
\r
1428 reserved.redrawReservedList();
\r
1430 else if (mainWindow.isTabSelected(MWinTab.RECED)) {
\r
1431 recorded.redrawRecordedList();
\r
1434 // 新聞形式の予約枠を書き換えるかもよ?
\r
1435 if (env.getEffectComboToPaper()) {
\r
1436 paper.updateReserveBorder(null);
\r
1439 timer_now.start();
\r
1445 protected void takeSnapShot() {
\r
1447 timer_now.pause();
\r
1451 if ( mainWindow.isTabSelected(MWinTab.LISTED) ) {
\r
1452 fname = String.format("snapshot.%s",env.getSnapshotFmt().getExtension());
\r
1453 CommonSwingUtils.saveComponentAsJPEG(listed.getCurrentView(), listed.getTableHeader(), null, listed.getTableBody(), fname, env.getSnapshotFmt(), Viewer.this);
\r
1455 else if ( mainWindow.isTabSelected(MWinTab.PAPER) ){
\r
1456 if ( env.getDrawcacheEnable() || ! env.isPagerEnabled() ) {
\r
1457 fname = String.format("snapshot.%s",env.getSnapshotFmt().getExtension());
\r
1460 int pcur = getSelectedPagerIndex();
\r
1461 int pmax = getPagerCount();
\r
1462 if ( env.getAllPageSnapshot() ) {
\r
1463 for ( int i=0; i<pmax; i++ ) {
\r
1464 if ( i != pcur ) {
\r
1465 setSelectedPagerIndex(i);
\r
1466 fname = String.format("snapshot%02d.%s",i+1,env.getSnapshotFmt().getExtension());
\r
1467 CommonSwingUtils.saveComponentAsJPEG(paper.getCurrentView(), paper.getCenterPane(), paper.getTimebarPane(), paper.getCurrentPane(), fname, env.getSnapshotFmt(), Viewer.this);
\r
1471 fname = String.format("snapshot%02d.%s",pcur+1,env.getSnapshotFmt().getExtension());
\r
1472 setSelectedPagerIndex(pcur);
\r
1474 CommonSwingUtils.saveComponentAsJPEG(paper.getCurrentView(), paper.getCenterPane(), paper.getTimebarPane(), paper.getCurrentPane(), fname, env.getSnapshotFmt(), Viewer.this);
\r
1479 Desktop desktop = Desktop.getDesktop();
\r
1480 if (env.getPrintSnapshot()) {
\r
1481 desktop.print(new File(fname));
\r
1484 String emsg = CommonUtils.openFile(fname);
\r
1485 if (emsg != null) {
\r
1486 mwin.appendError(emsg);
\r
1489 } catch (IOException e1) {
\r
1490 e1.printStackTrace();
\r
1493 timer_now.start();
\r
1498 protected void setStatusVisible(boolean b) {
\r
1499 Viewer.this.setStatusVisible(b);
\r
1503 protected void setFullScreen(boolean b) {
\r
1504 Viewer.this.setFullScreen(b);
\r
1508 protected void toggleSettingTabVisible() {
\r
1509 mainWindow.toggleShowSettingTabs();
\r
1513 protected boolean isTabSelected(MWinTab tab) {
\r
1514 return mainWindow.isTabSelected(tab);
\r
1518 protected boolean addKeywordSearch(SearchKey search) {
\r
1520 timer_now.pause();
\r
1522 AbsKeywordDialog kD = new VWKeywordDialog();
\r
1523 CommonSwingUtils.setLocationCenter(Viewer.this,kD);
\r
1525 kD.open(search.getLabel(), search, srKeys, srGrps);
\r
1526 kD.setVisible(true);
\r
1528 if (kD.isRegistered()) {
\r
1530 mpList.clear(env.getDisableFazzySearch(), env.getDisableFazzySearchReverse());
\r
1531 mpList.build(tvprograms, trKeys.getTraceKeys(), srKeys.getSearchKeys());
\r
1534 listed.redrawTreeByKeyword();
\r
1536 mainWindow.setSelectedTab(MWinTab.LISTED);
\r
1539 timer_now.start();
\r
1545 protected boolean reLoadTVProgram(LoadFor lf) {
\r
1546 timer_now.pause();
\r
1547 boolean b = Viewer.this.reLoadTVProgram(lf);
\r
1548 timer_now.start();
\r
1553 protected boolean reLoadRdReserve(String myself) {
\r
1554 timer_now.pause();
\r
1555 boolean b = Viewer.this.reLoadRdReserve(myself);
\r
1556 timer_now.start();
\r
1561 protected boolean reLoadRdRecorded(String myself) {
\r
1562 timer_now.pause();
\r
1563 boolean b = Viewer.this.reLoadRdRecorded(myself);
\r
1564 timer_now.start();
\r
1572 /*******************************************************************************
\r
1574 ******************************************************************************/
\r
1579 private void searchLikeRsv(LikeReserveList likeRsvList, ProgDetailList tvd, String keyword, int threshold) {
\r
1581 likeRsvList.clear();
\r
1584 String keywordPop = null;
\r
1585 int thresholdVal = 0;
\r
1586 if (threshold > 0) {
\r
1588 keywordPop = TraceProgram.replacePop(keyword);
\r
1589 thresholdVal = threshold;
\r
1593 keywordPop = tvd.titlePop;
\r
1594 thresholdVal = env.getDefaultFazzyThreshold();
\r
1598 long rangeLikeRsv = env.getRangeLikeRsv()*3600000;
\r
1600 HashMap<String,Boolean> misCN = new HashMap<String, Boolean>();
\r
1601 for ( HDDRecorder recorder : recorders ) {
\r
1604 recorder.refreshReserves();
\r
1606 for ( ReserveList r : recorder.getReserves() ) {
\r
1609 boolean isExist = false;
\r
1610 if (env.getDisableFazzySearch() == false) {
\r
1612 int fazScore = TraceProgram.sumScore(keywordPop, r.getTitlePop());
\r
1613 if ( fazScore >= thresholdVal) {
\r
1616 else if ( ! env.getDisableFazzySearchReverse()) {
\r
1618 fazScore = TraceProgram.sumScore(r.getTitlePop(), keywordPop);
\r
1619 if ( fazScore >= thresholdVal) {
\r
1625 if (r.getTitlePop().equals(tvd.titlePop)) {
\r
1634 if (r.getCh_name() == null) {
\r
1635 if(r.getChannel().length() > 0) {
\r
1636 misCN.put(r.getChannel(),true);
\r
1640 if ( ! r.getCh_name().equals(tvd.center)) {
\r
1645 boolean inRange = true;
\r
1646 if (rangeLikeRsv > 0) {
\r
1650 ArrayList<String> starts = new ArrayList<String>();
\r
1651 ArrayList<String> ends = new ArrayList<String>();
\r
1652 CommonUtils.getStartEndList(starts, ends, r);
\r
1653 for (int j=0; j<starts.size(); j++) {
\r
1654 long d = CommonUtils.getDiffDateTime(tvd.startDateTime, starts.get(j));
\r
1655 //StdAppendMessage(String.format("%s %s %d", tvd.startDateTime, starts.get(j),d));
\r
1656 if (d <= rangeLikeRsv) {
\r
1667 likeRsvList.add(new LikeReserveItem(recorder, r));
\r
1682 * 番組追跡への追加とgoogle検索
\r
1684 public void showPopupForTraceProgram(
\r
1685 final JComponent comp,
\r
1686 final ProgDetailList tvd, final String keyword, final int threshold,
\r
1687 final int x, final int y, final int h)
\r
1689 JPopupMenu pop = new JPopupMenu();
\r
1692 if ( tvd.type == ProgType.PASSED ||
\r
1693 (tvd.type == ProgType.PROG && tvd.subtype == ProgSubtype.RADIO) ||
\r
1694 recorders.size() == 0 ) {
\r
1698 JMenuItem menuItem = new JMenuItem("予約する【"+tvd.title+" ("+tvd.center+")】");
\r
1700 menuItem.addActionListener(new ActionListener() {
\r
1701 public void actionPerformed(ActionEvent e) {
\r
1703 CommonSwingUtils.setLocationCenter(mainWindow,rdialog);
\r
1705 if ( rdialog.open(tvd) ) {
\r
1706 rdialog.setVisible(true);
\r
1709 rdialog.setVisible(false);
\r
1713 if (rdialog.isReserved()) {
\r
1714 listed.updateReserveMark();
\r
1715 paper.updateReserveBorder(tvd.center);
\r
1716 reserved.redrawReservedList();
\r
1720 pop.add(menuItem);
\r
1723 pop.addSeparator();
\r
1726 LikeReserveList likeRsvList = new LikeReserveList();
\r
1727 searchLikeRsv(likeRsvList, tvd, "", 0);
\r
1730 LikeReserveList overlapRsvList = new LikeReserveList();
\r
1731 searchOverlapRsv(overlapRsvList, tvd, h);
\r
1733 // 類似と重複で被るものを重複から除外
\r
1734 for ( LikeReserveItem ll : likeRsvList ) {
\r
1736 for ( ; i<overlapRsvList.size(); i++ ) {
\r
1737 if ( ll.getRsv() == overlapRsvList.getRsv(i) ) {
\r
1741 if ( i < overlapRsvList.size() ) {
\r
1742 overlapRsvList.remove(i);
\r
1747 if ( tvd.type != ProgType.PASSED )
\r
1749 for ( int n=0; n<2; n++ ) {
\r
1751 LikeReserveList rsvList = null;
\r
1753 rsvList = likeRsvList;
\r
1756 rsvList = overlapRsvList;
\r
1759 for ( int i=0; i<rsvList.size(); i++ ) {
\r
1761 final boolean fexec = rsvList.getRsv(i).getExec();
\r
1762 final String title = rsvList.getRsv(i).getTitle();
\r
1763 final String chnam = rsvList.getRsv(i).getCh_name();
\r
1764 final String rsvId = rsvList.getRsv(i).getId();
\r
1765 final String recId = rsvList.getRec(i).Myself();
\r
1767 pop.add(getExecOnOffMenuItem(fexec,title,chnam,rsvId,recId,n));
\r
1770 pop.addSeparator();
\r
1774 pop.addSeparator();
\r
1777 if ( tvd.type != ProgType.PASSED ) // 過去ログは処理対象外です
\r
1779 for ( int n=0; n<2; n++ ) {
\r
1781 LikeReserveList rsvList = null;
\r
1783 rsvList = likeRsvList;
\r
1786 rsvList = overlapRsvList;
\r
1789 for (int i=0; i<rsvList.size(); i++) {
\r
1791 final String title = rsvList.getRsv(i).getTitle();
\r
1792 final String chnam = rsvList.getRsv(i).getCh_name();
\r
1793 final String rsvId = rsvList.getRsv(i).getId();
\r
1794 final String recId = rsvList.getRec(i).Myself();
\r
1796 pop.add(getRemoveRsvMenuItem(title,chnam,rsvId,recId,n));
\r
1799 pop.addSeparator();
\r
1803 pop.addSeparator();
\r
1804 pop.addSeparator();
\r
1809 if ( mainWindow.isTabSelected(MWinTab.LISTED) ) {
\r
1810 pop.add(getJumpMenuItem(tvd.title,tvd.center,tvd.startDateTime));
\r
1812 if ( mainWindow.isTabSelected(MWinTab.LISTED) || mainWindow.isTabSelected(MWinTab.PAPER) ) {
\r
1813 JMenuItem mi = getJumpToLastWeekMenuItem(tvd.title,tvd.center,tvd.startDateTime);
\r
1814 if ( mi != null ) {
\r
1820 pop.addSeparator();
\r
1824 final String label = tvd.title+" ("+tvd.center+")";
\r
1825 JMenuItem menuItem = new JMenuItem("番組追跡への追加【"+label+"】");
\r
1826 menuItem.addActionListener(new ActionListener() {
\r
1827 public void actionPerformed(ActionEvent e) {
\r
1829 for (TraceKey tr : trKeys.getTraceKeys()) {
\r
1830 if (tr.getLabel().equals(label)) {
\r
1831 mwin.appendMessage("【警告】すでに番組追跡に登録されています:"+label);
\r
1838 trKeys.add(label, tvd.title, tvd.center, env.getDefaultFazzyThreshold());
\r
1840 VWTraceKeyDialog tD = new VWTraceKeyDialog(0,0);
\r
1841 CommonSwingUtils.setLocationCenter(mainWindow,tD);
\r
1843 tD.reopen(label, trKeys);
\r
1844 tD.setVisible(true);
\r
1846 if (tD.isRegistered()) {
\r
1851 mpList.clear(env.getDisableFazzySearch(), env.getDisableFazzySearchReverse());
\r
1852 mpList.build(tvprograms, trKeys.getTraceKeys(), srKeys.getSearchKeys());
\r
1855 listed.redrawTreeByTrace();
\r
1858 paper.updateBangumiColumns();
\r
1859 listed.reselectTree();
\r
1861 mwin.appendMessage("番組追跡へ追加しました【"+label+"】");
\r
1864 trKeys.remove(label);
\r
1868 pop.add(menuItem);
\r
1873 final String label = tvd.title+" ("+tvd.center+")";
\r
1874 JMenuItem menuItem = new JMenuItem("キーワード検索への追加【"+label+"】");
\r
1875 menuItem.addActionListener(new ActionListener(){
\r
1876 public void actionPerformed(ActionEvent e){
\r
1878 for (SearchKey sr : srKeys.getSearchKeys()) {
\r
1879 if (sr.getLabel().equals(tvd.title)) {
\r
1881 String msg = "すでにキーワード検索に登録されています: "+tvd.title;
\r
1882 mwin.appendMessage(msg);
\r
1883 JOptionPane.showConfirmDialog(null, msg, "警告", JOptionPane.CLOSED_OPTION); // キーワード検索の追加ではダイアログで修正できるので止めない
\r
1887 // 「キーワード検索の設定」ウィンドウを開く
\r
1888 SearchKey search = new SearchKey();
\r
1890 search.setCondition("0");
\r
1891 search.alTarget.add(TargetId.TITLE);
\r
1892 search.alContain.add("0");
\r
1893 search.alKeyword.add(tvd.title);
\r
1896 search.setCondition("0");
\r
1897 search.alTarget.add(TargetId.CHANNEL);
\r
1898 search.alContain.add("0");
\r
1899 search.alKeyword.add(tvd.center);
\r
1902 AbsKeywordDialog kD = new VWKeywordDialog();
\r
1903 CommonSwingUtils.setLocationCenter(mainWindow,kD);
\r
1905 kD.open(tvd.title, search, srKeys, srGrps);
\r
1906 kD.setVisible(true);
\r
1908 if (kD.isRegistered()) {
\r
1910 mpList.clear(env.getDisableFazzySearch(), env.getDisableFazzySearchReverse());
\r
1911 mpList.build(tvprograms, trKeys.getTraceKeys(), srKeys.getSearchKeys());
\r
1914 listed.redrawTreeByKeyword();
\r
1917 paper.updateBangumiColumns();
\r
1918 listed.reselectTree();
\r
1920 mwin.appendMessage("キーワード検索へ追加しました【"+label+"】");
\r
1925 pop.add(menuItem);
\r
1930 boolean isRemoveItem = false;
\r
1931 if ( mainWindow.isTabSelected(MWinTab.LISTED) && tvd.type == ProgType.PICKED ) {
\r
1932 isRemoveItem = true;
\r
1935 PickedProgram tvp = tvprograms.getPickup();
\r
1936 if ( tvp != null ) {
\r
1937 isRemoveItem = tvp.remove(tvd, tvd.center, tvd.accurateDate, false);
\r
1941 if ( ! isRemoveItem ) // 過去ログは処理対象外です
\r
1943 final String label = tvd.title+" ("+tvd.center+")";
\r
1944 JMenuItem menuItem = new JMenuItem("ピックアップへの追加【"+label+"】");
\r
1945 menuItem.addActionListener(new ActionListener() {
\r
1946 public void actionPerformed(ActionEvent e) {
\r
1948 PickedProgram tvp = tvprograms.getPickup();
\r
1949 if ( tvp != null ) {
\r
1954 if ( listed.isNodeSelected(ListedTreeNode.PICKUP) ) {
\r
1955 // ピックアップノードが選択されていたらリストを更新する
\r
1956 listed.reselectTree();
\r
1959 listed.updateReserveMark();
\r
1961 paper.updateReserveBorder(tvd.center);
\r
1962 mwin.appendMessage("【ピックアップ】追加しました: "+tvd.title+" ("+tvd.center+")");
\r
1967 pop.add(menuItem);
\r
1970 final String label = tvd.title+" ("+tvd.center+")";
\r
1971 JMenuItem menuItem = new JMenuItem("ピックアップからの削除【"+label+"】");
\r
1972 menuItem.setForeground(Color.RED);
\r
1973 menuItem.addActionListener(new ActionListener() {
\r
1974 public void actionPerformed(ActionEvent e) {
\r
1976 PickedProgram tvp = tvprograms.getPickup();
\r
1977 if ( tvp != null ) {
\r
1979 tvp.remove(tvd, tvd.center, tvd.accurateDate, true);
\r
1982 if ( listed.isNodeSelected(ListedTreeNode.PICKUP) || listed.isNodeSelected(ListedTreeNode.STANDBY) ) {
\r
1983 // ピックアップノードが選択されていたらリストを更新する
\r
1984 listed.reselectTree();
\r
1987 listed.updateReserveMark();
\r
1988 paper.updateReserveBorder(tvd.center);
\r
1989 mwin.appendMessage("【ピックアップ】削除しました: "+tvd.title+" ("+tvd.center+")");
\r
1994 pop.add(menuItem);
\r
1998 pop.addSeparator();
\r
2002 for (final TextValueSet tv : env.getTvCommand()) {
\r
2003 JMenuItem menuItem = new JMenuItem(tv.getText());
\r
2004 String escepedTitle = "";
\r
2005 String escepedChName = "";
\r
2006 String escepedDetail = "";
\r
2008 escepedTitle = URLEncoder.encode(tvd.title,"UTF-8");
\r
2009 escepedDetail = URLEncoder.encode(tvd.detail,"UTF-8");
\r
2010 escepedChName = URLEncoder.encode(tvd.center,"UTF-8");
\r
2011 } catch (UnsupportedEncodingException e2) {
\r
2015 String cmd = tv.getValue();
\r
2016 if ( cmd.matches(".*%DETAILURL%.*") ) {
\r
2017 if ( tvd.link == null || tvd.link.length() == 0 ) {
\r
2018 // このメニューは利用できません!
\r
2019 menuItem.setEnabled(false);
\r
2020 menuItem.setForeground(Color.lightGray);
\r
2023 cmd = cmd.replaceAll("%ENCTITLE%", escepedTitle);
\r
2024 cmd = cmd.replaceAll("%ENCDETAIL%", escepedDetail);
\r
2025 cmd = cmd.replaceAll("%ENCCHNAME%", escepedChName);
\r
2026 cmd = cmd.replaceAll("%TITLE%", tvd.title);
\r
2027 cmd = cmd.replaceAll("%DETAIL%", tvd.detail);
\r
2028 cmd = cmd.replaceAll("%CHNAME%", tvd.center);
\r
2029 cmd = cmd.replaceAll("%DATE%", tvd.accurateDate);
\r
2030 cmd = cmd.replaceAll("%START%", tvd.start);
\r
2031 cmd = cmd.replaceAll("%END%", tvd.end);
\r
2032 cmd = cmd.replaceAll("%DETAILURL%", tvd.link);
\r
2035 if ( cmd.matches(".*%TVKAREACODE%.*") && cmd.matches(".*%TVKPID%.*") ) {
\r
2037 for ( TVProgram tvp : progPlugins ) {
\r
2038 if ( tvp.getTVProgramId().startsWith("Gガイド.テレビ王国") ) {
\r
2039 for ( Center tempcr : tvp.getCRlist() ) {
\r
2040 // CH設定が完了している必要がある
\r
2041 if ( tvp.getSubtype() == ProgSubtype.TERRA && tvp.getSelectedCode().equals(TVProgram.allCode) && ! tempcr.getAreaCode().equals(TVProgram.bsCode) ) {
\r
2042 // 地域が全国の地デジの場合のみ、有効局かどうかを確認する必要がある
\r
2043 if ( tempcr.getCenter().equals(tvd.center) && tempcr.getOrder() > 0 ) {
\r
2050 if ( tempcr.getCenter().equals(tvd.center) ) {
\r
2058 if ( cr != null ) {
\r
2063 if ( cr != null ) {
\r
2064 String areacode = null;
\r
2065 String centercode = cr.getLink();
\r
2066 String cat = cr.getLink().substring(0,1);
\r
2067 if ( cat.equals("1") ) {
\r
2068 areacode = cr.getAreaCode();
\r
2071 if ( cat.equals("4") ) {
\r
2074 else if ( cat.equals("5") ) {
\r
2080 cmd = cmd.replaceAll("%TVKAREACODE%", areacode);
\r
2081 cmd = cmd.replaceAll("%TVKCAT%", cat);
\r
2082 cmd = cmd.replaceAll("%TVKPID%", centercode+CommonUtils.getDateTimeYMD(CommonUtils.getCalendar(tvd.startDateTime)).replaceFirst("..$", ""));
\r
2083 System.out.println("[DEBUG] "+cmd);
\r
2085 menuItem.setEnabled(true);
\r
2086 menuItem.setForeground(Color.BLACK);
\r
2089 menuItem.setEnabled(false);
\r
2090 menuItem.setForeground(Color.lightGray);
\r
2094 final String run = cmd;
\r
2096 menuItem.addActionListener(new ActionListener() {
\r
2098 public void actionPerformed(ActionEvent e) {
\r
2100 if (run.indexOf("http") == 0) {
\r
2101 Desktop desktop = Desktop.getDesktop();
\r
2102 desktop.browse(new URI(run));
\r
2105 CommonUtils.executeCommand(run);
\r
2107 } catch (IOException e1) {
\r
2108 e1.printStackTrace();
\r
2109 } catch (URISyntaxException e1) {
\r
2110 e1.printStackTrace();
\r
2115 pop.add(menuItem);
\r
2119 pop.addSeparator();
\r
2123 JMenuItem menuItem = new JMenuItem("番組名をコピー【"+tvd.title+"】");
\r
2124 menuItem.addActionListener(new ActionListener() {
\r
2125 public void actionPerformed(ActionEvent e) {
\r
2126 String msg = tvd.title;
\r
2127 Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard();
\r
2128 StringSelection s = new StringSelection(msg);
\r
2129 cb.setContents(s, null);
\r
2132 pop.add(menuItem);
\r
2135 JMenuItem menuItem = new JMenuItem("番組名と詳細をコピー【"+tvd.title+"】");
\r
2136 menuItem.addActionListener(new ActionListener() {
\r
2137 public void actionPerformed(ActionEvent e) {
\r
2138 String msg = tvd.title+System.getProperty("line.separator")+tvd.detail+"\0"+tvd.getAddedDetail();
\r
2139 Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard();
\r
2140 StringSelection s = new StringSelection(msg);
\r
2141 cb.setContents(s, null);
\r
2144 pop.add(menuItem);
\r
2147 JMenuItem menuItem = new JMenuItem("番組情報をコピー【"+tvd.title+"】");
\r
2148 menuItem.addActionListener(new ActionListener() {
\r
2149 public void actionPerformed(ActionEvent e) {
\r
2152 for (ClipboardInfo cb : cbitems) {
\r
2154 switch (cb.getId()) {
\r
2156 msg += tvd.title+"\t";
\r
2159 msg += tvd.center+"\t";
\r
2162 msg += tvd.accurateDate+"\t";
\r
2165 msg += tvd.start+"\t";
\r
2169 msg = msg.substring(0,msg.length()-1)+"-";
\r
2171 msg += tvd.end+"\t";
\r
2174 msg += tvd.genre+"\t";
\r
2177 msg += tvd.detail+"\0"+tvd.getAddedDetail()+"\t";
\r
2181 preId = cb.getId();
\r
2183 if (msg.length() > 0) {
\r
2184 msg = msg.substring(0,msg.length()-1);
\r
2186 Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard();
\r
2187 StringSelection s = new StringSelection(msg);
\r
2188 cb.setContents(s, null);
\r
2191 pop.add(menuItem);
\r
2194 pop.addSeparator();
\r
2198 tvd.type == ProgType.SYOBO ||
\r
2199 tvd.type == ProgType.PASSED ||
\r
2200 tvd.type == ProgType.PICKED ||
\r
2201 (tvd.type == ProgType.PROG && tvd.subtype != ProgSubtype.RADIO) ) // ラジオは処理対象外です
\r
2203 JMenuItem menuItem = new JMenuItem("延長感染源にしない【"+tvd.title+" ("+tvd.center+")】");
\r
2204 menuItem.addActionListener(new ActionListener() {
\r
2205 public void actionPerformed(ActionEvent e) {
\r
2207 mwin.appendMessage("延長感染源を隔離します【"+tvd.title+"("+tvd.center+")】");
\r
2209 AbsExtensionDialog eD = new VWExtensionDialog();
\r
2210 CommonSwingUtils.setLocationCenter(mainWindow,eD);
\r
2212 eD.open(tvd.title,tvd.center,false,extKeys);
\r
2213 eD.setVisible(true);
\r
2215 if (eD.isRegistered()) {
\r
2217 for (TVProgram tvp : tvprograms) {
\r
2218 if (tvp.getType() == ProgType.PROG) {
\r
2219 tvp.setExtension(null, null, false, extKeys.getSearchKeys());
\r
2224 listed.redrawTreeByExtension();
\r
2226 mainWindow.setSelectedTab(MWinTab.LISTED);
\r
2230 pop.add(menuItem);
\r
2232 if ( tvd.type == ProgType.PASSED || (tvd.type == ProgType.PROG && tvd.subtype != ProgSubtype.RADIO) ) // ラジオは処理対象外です
\r
2234 JMenuItem menuItem = new JMenuItem("延長感染源にする【"+tvd.title+" ("+tvd.center+")】");
\r
2235 menuItem.addActionListener(new ActionListener() {
\r
2236 public void actionPerformed(ActionEvent e) {
\r
2238 AbsExtensionDialog eD = new VWExtensionDialog();
\r
2239 CommonSwingUtils.setLocationCenter(mainWindow,eD);
\r
2241 eD.open(tvd.title,tvd.center,true,extKeys);
\r
2242 eD.setVisible(true);
\r
2244 if (eD.isRegistered()) {
\r
2246 for (TVProgram tvp : tvprograms) {
\r
2247 if (tvp.getType() == ProgType.PROG) {
\r
2248 tvp.setExtension(null, null, false, extKeys.getSearchKeys());
\r
2253 listed.redrawTreeByExtension();
\r
2255 mainWindow.setSelectedTab(MWinTab.LISTED);
\r
2259 pop.add(menuItem);
\r
2262 pop.addSeparator();
\r
2265 if ( tvd.type == ProgType.PROG && tvd.subtype != ProgSubtype.RADIO) // ラジオは処理対象外です
\r
2267 for (HDDRecorder recorder : recorders ) {
\r
2269 if (recorder.ChangeChannel(null) == false) {
\r
2273 final String recorderName = recorder.Myself();
\r
2274 JMenuItem menuItem = new JMenuItem("【"+recorderName+"】で【"+tvd.center+"】を視聴する");
\r
2276 menuItem.addActionListener(new ActionListener() {
\r
2277 public void actionPerformed(ActionEvent e) {
\r
2278 for (HDDRecorder recorder : recorders ) {
\r
2279 if (recorder.isMyself(recorderName)) {
\r
2280 if (recorder.ChangeChannel(tvd.center) == false) {
\r
2282 mwin.appendError("【警告】チャンネルを変更できませんでした:"+recorder.getErrmsg());
\r
2284 else if (recorder.getErrmsg() !=null && recorder.getErrmsg().length() > 0) {
\r
2285 mwin.appendError("[追加情報] "+recorder.getErrmsg());
\r
2292 menuItem.setEnabled(recorder.getUseChChange());
\r
2294 pop.add(menuItem);
\r
2298 pop.show(comp, x, y);
\r
2302 public boolean addToPickup(final ProgDetailList tvd) {
\r
2304 if (tvd.start.equals("")) {
\r
2309 PickedProgram tvp = tvprograms.getPickup();
\r
2310 if ( tvp == null ) {
\r
2316 if ( tvp.remove(tvd, tvd.center, tvd.accurateDate, true) ) {
\r
2318 if ( listed.isNodeSelected(JTreeLabel.Nodes.PICKUP) || listed.isNodeSelected(JTreeLabel.Nodes.STANDBY) ) {
\r
2319 // ピックアップノードor予約待機ノードが選択されていたらリストを更新する
\r
2320 listed.reselectTree();
\r
2321 //listed.updateReserveMark();
\r
2324 // 予約マークだけ変えておけばいいよね
\r
2325 listed.updateReserveMark();
\r
2328 paper.updateReserveBorder(tvd.center);
\r
2329 mwin.appendMessage("【ピックアップ】削除しました: "+tvd.title+" ("+tvd.center+")");
\r
2334 if ( tvd.endDateTime.compareTo(CommonUtils.getDateTime(0)) > 0 ) {
\r
2338 if ( listed.isNodeSelected(JTreeLabel.Nodes.PICKUP) ) {
\r
2339 // ピックアップノードが選択されていたらリストを更新する
\r
2340 listed.reselectTree();
\r
2341 //listed.updateReserveMark();
\r
2344 listed.updateReserveMark();
\r
2347 paper.updateReserveBorder(tvd.center);
\r
2348 mwin.appendMessage("【ピックアップ】追加しました: "+tvd.title+" ("+tvd.center+")");
\r
2353 mwin.appendMessage("【ピックアップ】過去情報はピックアップできません.");
\r
2360 private JMenuItem getRemoveRsvMenuItem(final String title, final String chnam, final String rsvId, final String recId, int n) {
\r
2362 JMenuItem menuItem = new JMenuItem(((n==0)?"予約を削除する【":"隣接予約を削除する【")+title+"("+chnam+")/"+recId+"】");
\r
2363 menuItem.setForeground(Color.RED);
\r
2364 if ( recId.equals(toolBar.getSelectedRecorder()) ) {
\r
2365 // 選択中のレコーダのものは太字に
\r
2366 Font f = menuItem.getFont();
\r
2367 menuItem.setFont(f.deriveFont(f.getStyle()|Font.BOLD));
\r
2370 menuItem.addActionListener(new ActionListener() {
\r
2371 public void actionPerformed(ActionEvent e) {
\r
2373 if (env.getShowWarnDialog()) {
\r
2374 Container cp = getContentPane();
\r
2375 int ret = JOptionPane.showConfirmDialog(cp, "削除しますか?【"+title+"("+chnam+")】("+recId+")", "確認", JOptionPane.YES_NO_OPTION);
\r
2376 if (ret != JOptionPane.YES_OPTION) {
\r
2384 new SwingBackgroundWorker(false) {
\r
2387 protected Object doWorks() throws Exception {
\r
2389 for (HDDRecorder recorder : recorders) {
\r
2390 if (recorder.isMyself(recId)) { // IPAddr:PortNo:RecorderIdで比較
\r
2392 String title = "";
\r
2393 for (ReserveList r : recorder.getReserves()) {
\r
2394 if (r.getId().equals(rsvId)) {
\r
2395 title = r.getTitle();
\r
2400 stwin.appendMessage("予約を削除します:"+title+"("+rsvId+")");
\r
2401 //recorder.setProgressArea(stwin);
\r
2402 ReserveList r = recorder.RemoveRdEntry(rsvId); // Noで検索
\r
2404 mwin.appendMessage("正常に削除できました:"+r.getTitle()+"("+r.getCh_name()+")");
\r
2406 if ( ! r.getTitle().equals(title) || ! r.getId().equals(rsvId)) {
\r
2407 mwin.appendError("【警告】削除結果が一致しません!:"+title+"/"+r.getTitle());
\r
2410 if ( recorder.getUseCalendar()) {
\r
2412 for ( HDDRecorder calendar : recorders ) {
\r
2413 if (calendar.getType() == RecType.CALENDAR) {
\r
2414 stwin.appendMessage("カレンダーから予約情報を削除します");
\r
2415 //calendar.setProgressArea(stwin);
\r
2416 if ( ! calendar.UpdateRdEntry(r, null)) {
\r
2417 mwin.appendError("【カレンダー】"+calendar.getErrmsg());
\r
2427 mwin.appendError("削除に失敗しました:"+title);
\r
2431 if ( ! recorder.getErrmsg().equals("")) {
\r
2432 mwin.appendError("【追加情報】"+recorder.getErrmsg());
\r
2442 protected void doFinally() {
\r
2443 stwin.setVisible(false);
\r
2447 CommonSwingUtils.setLocationCenter(Viewer.this, stwin);
\r
2448 stwin.setVisible(true);
\r
2451 listed.updateReserveMark();
\r
2452 paper.updateReserveBorder(chnam);
\r
2453 reserved.redrawReservedList();
\r
2464 * 他のクラスに分離できなかったというか、しなかったというか、そんなメソッド群
\r
2470 private boolean doExecOnOff(final boolean fexec, final String title, final String chnam, final String rsvId, final String recId) {
\r
2472 CommonSwingUtils.setLocationCenter(mainWindow,rdialog);
\r
2474 String mode = (fexec ? "ON" : "OFF");
\r
2476 if ( rdialog.open(recId,rsvId) ) {
\r
2477 rdialog.setOnlyUpdateExec(fexec);
\r
2478 rdialog.doUpdate();
\r
2480 if (rdialog.isReserved()) {
\r
2482 listed.updateReserveMark();
\r
2483 paper.updateReserveBorder(chnam);
\r
2484 reserved.redrawReservedList();
\r
2487 String msg = "予約を"+mode+"にしました【"+title+"("+chnam+")/"+recId+"】";
\r
2488 //StdAppendMessage(msg);
\r
2489 mwin.appendMessage(msg);
\r
2500 * 予約実行をONOFFするメニューアイテム
\r
2502 private JMenuItem getExecOnOffMenuItem(final boolean fexec, final String title, final String chnam, final String rsvId, final String recId, int n) {
\r
2504 JMenuItem menuItem = new JMenuItem();
\r
2509 menuItem.setForeground(Color.BLUE);
\r
2515 menuItem.setText(((n==0)?"予約を":"隣接予約を")+mode+"にする【"+title+"("+chnam+")/"+recId+")】");
\r
2517 if ( recId.equals(toolBar.getSelectedRecorder()) ) {
\r
2518 // 選択中のレコーダのものは太字に
\r
2519 Font f = menuItem.getFont();
\r
2520 menuItem.setFont(f.deriveFont(f.getStyle()|Font.BOLD));
\r
2523 final String xmode = mode;
\r
2524 menuItem.addActionListener(new ActionListener() {
\r
2525 public void actionPerformed(ActionEvent e) {
\r
2527 //VWReserveDialog rD = new VWReserveDialog(0, 0, env, tvprograms, recorders, avs, chavs, stwin);
\r
2528 //rdialog.clear();
\r
2529 CommonSwingUtils.setLocationCenter(mainWindow,rdialog);
\r
2531 if ( rdialog.open(recId,rsvId) ) {
\r
2532 rdialog.setOnlyUpdateExec( ! fexec);
\r
2533 rdialog.doUpdate();
\r
2535 if (rdialog.isReserved()) {
\r
2537 listed.updateReserveMark();
\r
2538 paper.updateReserveBorder(chnam);
\r
2539 reserved.redrawReservedList();
\r
2542 String msg = "予約を"+xmode+"にしました【"+title+"("+chnam+")/"+recId+"】";
\r
2543 StdAppendMessage(msg);
\r
2544 mwin.appendMessage(msg);
\r
2549 //rdialog.setVisible(false);
\r
2558 * 新聞形式へジャンプするメニューアイテム
\r
2560 private JMenuItem getJumpMenuItem(final String title, final String chnam, final String startDT) {
\r
2561 JMenuItem menuItem = new JMenuItem("番組欄へジャンプする【"+title+" ("+chnam+")】");
\r
2562 menuItem.addActionListener(new ActionListener() {
\r
2563 public void actionPerformed(ActionEvent e) {
\r
2564 paper.jumpToBangumi(chnam,startDT);
\r
2569 private JMenuItem getJumpToLastWeekMenuItem(final String title, final String chnam, final String startDT) {
\r
2570 GregorianCalendar cal = CommonUtils.getCalendar(startDT);
\r
2571 if ( cal != null ) {
\r
2572 JMenuItem menuItem = new JMenuItem("先週の番組欄へジャンプする【"+title+" ("+chnam+")】");
\r
2573 cal.add(Calendar.DATE, -7);
\r
2574 final String lastweek = CommonUtils.getDateTime(cal);
\r
2575 menuItem.addActionListener(new ActionListener() {
\r
2576 public void actionPerformed(ActionEvent e) {
\r
2577 paper.jumpToBangumi(chnam,lastweek);
\r
2585 // カーソル位置にかかる予約枠の検索
\r
2586 private void searchOverlapRsv(LikeReserveList overlapRsvList, ProgDetailList tvd, int h)
\r
2588 String clicked = "";
\r
2589 if ( h >= 0 && tvd.start.length() != 0 ) {
\r
2590 // 新聞形式ならクリック位置の日時を算出する
\r
2591 GregorianCalendar cala = CommonUtils.getCalendar(tvd.startDateTime);
\r
2592 if ( CommonUtils.isLateNight(cala.get(Calendar.HOUR_OF_DAY)) ) {
\r
2593 cala.set(Calendar.HOUR_OF_DAY, TIMEBAR_START);
\r
2594 cala.set(Calendar.MINUTE, 0);
\r
2596 cala.add(Calendar.MINUTE, Math.round(h/bounds.getPaperHeightMultiplier()));
\r
2597 clicked = CommonUtils.getDateTime(cala);
\r
2598 //StdAppendError("clicked:"+clicked);
\r
2601 HashMap<String,Boolean> misCN = new HashMap<String, Boolean>();
\r
2602 for ( HDDRecorder recorder : recorders ) {
\r
2605 recorder.refreshReserves();
\r
2607 for ( ReserveList r : recorder.getReserves() ) {
\r
2610 if (r.getCh_name() == null) {
\r
2611 if ( r.getChannel() == null ) {
\r
2612 System.err.println(ERRID+"予約情報にCHコードが設定されていません。バグの可能性があります。 recid="+recorder.Myself()+" chname="+r.getCh_name());
\r
2615 if(r.getChannel().length() > 0) {
\r
2616 misCN.put(r.getChannel(),true);
\r
2620 if ( ! r.getCh_name().equals(tvd.center)) {
\r
2625 boolean inRange = false;
\r
2627 ArrayList<String> starts = new ArrayList<String>();
\r
2628 ArrayList<String> ends = new ArrayList<String>();
\r
2629 CommonUtils.getStartEndList(starts, ends, r);
\r
2631 // 新聞形式はピンポイント(マウスポインタのある位置の時刻)
\r
2632 for (int j=0; j<starts.size(); j++) {
\r
2633 if ( clicked.compareTo(starts.get(j)) >= 0 && clicked.compareTo(ends.get(j)) <= 0 ) {
\r
2640 // リスト形式は幅がある(開始~終了までの間のいずれかの時刻)
\r
2641 for (int j=0; j<starts.size(); j++) {
\r
2642 if ( CommonUtils.isOverlap(tvd.startDateTime, tvd.endDateTime, starts.get(j), ends.get(j), false) ) {
\r
2654 overlapRsvList.add(new LikeReserveItem(recorder, r));
\r
2662 /*******************************************************************************
\r
2664 ******************************************************************************/
\r
2667 /*******************************************************************************
\r
2668 * ここからおおむね初期化処理にかかわるメソッド群
\r
2669 ******************************************************************************/
\r
2671 // レコーダから取得したエンコーダ情報で、登録済みレコーダ一覧を更新する
\r
2672 private void setEncoderInfo2RecorderList(HDDRecorder recorder) {
\r
2673 for (RecorderInfo ri : recInfoList ) {
\r
2674 //if (rl.getRecorderEncoderList().size() == 0)
\r
2676 String mySelf = ri.getRecorderIPAddr()+":"+ri.getRecorderPortNo()+":"+ri.getRecorderId();
\r
2677 String myMail = "MAIL"+":"+ri.getRecorderMacAddr()+":"+ri.getRecorderId();
\r
2678 if (recorder.isMyself(mySelf) || recorder.isMyself(myMail)) {
\r
2679 ri.clearEncoders();
\r
2680 for (TextValueSet enc : recorder.getEncoderList()) {
\r
2681 ri.addEncoder(enc.getText());
\r
2692 private boolean reLoadRdReserve(final String recId) {
\r
2696 new SwingBackgroundWorker(false) {
\r
2699 protected Object doWorks() throws Exception {
\r
2701 TatCount tc = new TatCount();
\r
2703 loadRdReserve(true, recId);
\r
2705 // エンコーダ情報が更新されるかもしれないので、一覧のエンコーダ表示にも反映する
\r
2706 recsetting.redrawRecorderEncoderEntry();
\r
2709 paper.updateReserveBorder(null);
\r
2710 listed.updateReserveMark();
\r
2711 reserved.redrawReservedList();
\r
2712 recorded.redrawRecordedList();
\r
2714 mwin.appendMessage(String.format("【予約一覧の取得処理が完了しました】 所要時間: %.2f秒",tc.end()));
\r
2719 protected void doFinally() {
\r
2720 StWinSetVisible(false);
\r
2724 StWinSetLocationCenter(this);
\r
2725 StWinSetVisible(true);
\r
2729 private void loadRdReserve(final boolean force, final String myself) {
\r
2732 new SwingBackgroundWorker(true) {
\r
2735 protected Object doWorks() throws Exception {
\r
2737 HDDRecorderList recs;
\r
2738 if ( myself != null ) {
\r
2739 recs = recorders.findInstance(myself);
\r
2744 for ( HDDRecorder recorder : recs ) {
\r
2745 switch ( recorder.getType() ) {
\r
2751 loadRdReserveOnce(recorder, force);
\r
2762 protected void doFinally() {
\r
2767 private boolean loadRdReserveOnce(HDDRecorder recorder, boolean force) {
\r
2769 mwin.appendMessage("【レコーダ情報取得】レコーダから情報を取得します: "+recorder.getRecorderId()+"("+recorder.getIPAddr()+":"+recorder.getPortNo()+")");
\r
2770 if ( recorder.isThereAdditionalDetails() && ! env.getForceGetRdReserveDetails() ) {
\r
2771 mwin.appendMessage("<<<注意!>>>このレコーダでは予約詳細の個別取得を実行しないと正確な情報を得られない場合があります。");
\r
2777 if ( ! recorder.GetRdSettings(force) ) {
\r
2779 mwin.appendError(recorder.getErrmsg()+" "+recorder.getIPAddr()+":"+recorder.getPortNo()+":"+recorder.getRecorderId());
\r
2785 if ( ! recorder.GetRdReserve(force) ) {
\r
2787 mwin.appendError(recorder.getErrmsg()+" "+recorder.getIPAddr()+":"+recorder.getPortNo()+":"+recorder.getRecorderId());
\r
2792 // レコーダから取得したエンコーダ情報で、登録済みレコーダ一覧を更新する
\r
2793 setEncoderInfo2RecorderList(recorder);
\r
2795 recInfoList.save();
\r
2799 if ( env.getNeverGetRdReserveDetails() ) {
\r
2800 mwin.appendMessage("【!】予約詳細情報の取得はスキップされました");
\r
2802 else if ( force && recorder.isThereAdditionalDetails() ) {
\r
2803 boolean getDetails = true;
\r
2804 if ( ! env.getForceGetRdReserveDetails() ) {
\r
2805 int ret = JOptOptionPane.showConfirmDialog(null, "詳細情報を取得しますか?(時間がかかります)", "今回の選択を既定の動作とする", "確認", JOptionPane.YES_NO_OPTION);
\r
2806 getDetails = (ret == JOptOptionPane.YES_OPTION);
\r
2807 if ( JOptOptionPane.isSelected() ) {
\r
2809 env.setForceGetRdReserveDetails(getDetails);
\r
2810 env.setNeverGetRdReserveDetails( ! getDetails);
\r
2812 setting.updateSelections();
\r
2815 if ( ! getDetails ) {
\r
2816 mwin.appendMessage("【!】予約詳細情報の取得はスキップされました");
\r
2819 if ( ! recorder.GetRdReserveDetails()) {
\r
2821 mwin.appendError(recorder.getErrmsg()+" "+recorder.getIPAddr()+":"+recorder.getPortNo()+":"+recorder.getRecorderId());
\r
2827 // レコーダの放送局名をWeb番組表の放送局名に置き換え
\r
2829 HashMap<String,String> misCN = new HashMap<String,String>();
\r
2830 for ( ReserveList r : recorder.getReserves() ) {
\r
2831 if ( r.getCh_name() == null ) {
\r
2832 misCN.put(r.getChannel(),recorder.getRecorderId());
\r
2835 if ( misCN.size() > 0 ) {
\r
2836 for ( String cn : misCN.keySet() ) {
\r
2837 String msg = "【警告(予約一覧)】 <"+misCN.get(cn)+"> \"レコーダの放送局名\"を\"Web番組表の放送局名\"に変換できません。CHコード設定に設定を追加してください:\"レコーダの放送局名\"="+cn;
\r
2838 mwin.appendMessage(msg);
\r
2845 if ( recorder.isEditAutoReserveSupported() ) {
\r
2846 if ( ! recorder.GetRdAutoReserve(force) ) {
\r
2848 mwin.appendError(recorder.getErrmsg()+" "+recorder.getIPAddr()+":"+recorder.getPortNo()+":"+recorder.getRecorderId());
\r
2855 if ( env.getSkipGetRdRecorded() ) {
\r
2856 mwin.appendMessage("【!】録画結果一覧の取得はスキップされました");
\r
2859 if ( ! recorder.GetRdRecorded(force) ) {
\r
2861 mwin.appendError(recorder.getErrmsg()+" "+recorder.getIPAddr()+":"+recorder.getPortNo()+":"+recorder.getRecorderId());
\r
2868 catch (Exception e) {
\r
2869 e.printStackTrace();
\r
2870 mwin.appendError("【致命的エラー】予約一覧の取得で例外が発生 "+recorder.getIPAddr()+":"+recorder.getPortNo()+":"+recorder.getRecorderId());
\r
2880 private boolean reLoadRdRecorded(final String myself) {
\r
2884 new SwingBackgroundWorker(false) {
\r
2887 protected Object doWorks() throws Exception {
\r
2889 TatCount tc = new TatCount();
\r
2891 boolean succeeded = true;
\r
2893 HDDRecorderList recs;
\r
2894 if ( myself != null ) {
\r
2895 recs = recorders.findInstance(myself);
\r
2900 for ( HDDRecorder recorder : recs ) {
\r
2901 switch ( recorder.getType() ) {
\r
2907 if ( ! recorder.GetRdSettings(true) ) {
\r
2908 succeeded = false;
\r
2910 if ( ! recorder.GetRdRecorded(true) ) {
\r
2911 succeeded = false;
\r
2919 if ( succeeded ) {
\r
2920 reserved.redrawReservedList();
\r
2921 recorded.redrawRecordedList();
\r
2923 mwin.appendMessage(String.format("【録画結果一覧の取得処理が完了しました】 所要時間: %.2f秒",tc.end()));
\r
2927 mwin.appendMessage(String.format("【録画結果一覧の取得処理に失敗しました】 所要時間: %.2f秒",tc.end()));
\r
2933 protected void doFinally() {
\r
2934 StWinSetVisible(false);
\r
2938 StWinSetLocationCenter(this);
\r
2939 StWinSetVisible(true);
\r
2946 * <P>単体実行の場合はこちらを呼び出す
\r
2947 * <P>部品実行の場合はこちらを呼び出す:{@link #loadTVProgram(boolean, LoadFor)}
\r
2949 private boolean reLoadTVProgram(final LoadFor lf) {
\r
2953 new SwingBackgroundWorker(false) {
\r
2956 protected Object doWorks() throws Exception {
\r
2958 TatCount tc = new TatCount();
\r
2960 loadTVProgram(true, lf);
\r
2963 paper.clearPanel();
\r
2964 paper.buildMainViewByDate();
\r
2967 paper.redrawTreeByPassed();
\r
2970 paper.reselectTree();
\r
2971 listed.reselectTree();
\r
2973 mwin.appendMessage(String.format("[Web番組表取得] 【完了しました】 所要時間: %.2f秒",tc.end()));
\r
2978 protected void doFinally() {
\r
2979 StWinSetVisible(false);
\r
2983 StWinSetLocationCenter(this);
\r
2984 StWinSetVisible(true);
\r
2991 * <P>単体実行の場合はこちらを呼び出す:{@link #reLoadTVProgram(LoadFor)}
\r
2992 * <P>部品実行の場合はこちらを呼び出す
\r
2994 private void loadTVProgram(final boolean b, final LoadFor lf) {
\r
2996 final String FUNCID = "[Web番組表取得] ";
\r
2997 final String ERRID = "[ERROR]"+FUNCID;
\r
2999 new SwingBackgroundWorker(true) {
\r
3002 protected Object doWorks() throws Exception {
\r
3007 tvp = tvprograms.getTvProgPlugin(null);
\r
3008 if ( tvp != null )
\r
3010 String sType = "地上波&BS番組表";
\r
3011 if (lf == LoadFor.ALL || lf == LoadFor.TERRA) {
\r
3012 loadTVProgramOnce(tvp, sType, tvp.getSelectedArea(), false, b);
\r
3015 stwin.appendMessage(FUNCID+sType+"へのアクセスはスキップされました: "+tvp.getTVProgramId());
\r
3019 tvp = tvprograms.getCsProgPlugin(null);
\r
3020 if ( tvp != null )
\r
3022 String sType = "CS番組表[プライマリ]";
\r
3023 if (lf == LoadFor.ALL || lf == LoadFor.CS || lf == LoadFor.CSo1) {
\r
3024 loadTVProgramOnce(tvp, sType, tvp.getSelectedArea(), false, b);
\r
3027 stwin.appendMessage(FUNCID+sType+"へのアクセスはスキップされました: "+tvp.getTVProgramId());
\r
3031 tvp = tvprograms.getCs2ProgPlugin(null);
\r
3032 if ( tvp != null )
\r
3034 String sType = "CS番組表[セカンダリ]";
\r
3035 if (lf == LoadFor.ALL || lf == LoadFor.CS || lf == LoadFor.CSo2) {
\r
3036 loadTVProgramOnce(tvp, sType, tvp.getSelectedArea(), false, b);
\r
3039 stwin.appendMessage(FUNCID+sType+"へのアクセスはスキップされました: "+tvp.getTVProgramId());
\r
3043 tvp = tvprograms.getSyobo();
\r
3044 if ( tvp != null ) {
\r
3045 String sType = "しょぼかる";
\r
3046 if ( (lf == LoadFor.ALL || lf == LoadFor.SYOBO) && enableWebAccess && env.getUseSyobocal()) {
\r
3047 tvp.loadCenter(tvp.getSelectedCode(), b); // しょぼかるには放送局リストを取得するイベントが他にないので
\r
3048 loadTVProgramOnce(tvp, sType, null, true, b);
\r
3051 stwin.appendMessage(FUNCID+sType+"へのアクセスはスキップされました.");
\r
3054 // しょぼかるの新番組マークを引き継ぐ
\r
3058 PickedProgram pickup = tvprograms.getPickup();
\r
3059 if ( tvp != null ) {
\r
3069 stwin.appendMessage(FUNCID+"検索結果を生成します.");
\r
3070 mpList.clear(env.getDisableFazzySearch(), env.getDisableFazzySearchReverse());
\r
3071 mpList.build(tvprograms, trKeys.getTraceKeys(), srKeys.getSearchKeys());
\r
3074 if ( env.getUsePassedProgram() ) {
\r
3075 TatCount tc = new TatCount();
\r
3076 stwin.appendMessage(FUNCID+"過去ログを生成します.");
\r
3077 if ( tvprograms.getPassed().save(tvprograms.getIterator(), chsort.getClst(), env.getPrepPassedProgramCount()) ) {
\r
3078 msg = String.format(FUNCID+"過去ログを生成しました [%.2f秒].",tc.end());
\r
3079 StdAppendMessage(msg);
\r
3081 //PassedProgramList.getDateList(env.getPassedLogLimit());
\r
3084 stwin.appendMessage(FUNCID+"過去ログは記録されません.");
\r
3087 catch (Exception e) {
\r
3088 e.printStackTrace();
\r
3089 mwin.appendError(ERRID+"番組情報の取得で例外が発生");
\r
3097 protected void doFinally() {
\r
3102 private void loadTVProgramOnce(TVProgram tvp, String sType, String aName, boolean loadonly, boolean force) {
\r
3104 final String FUNCID = "[Web番組表取得] ";
\r
3105 final String ERRID = "[ERROR]"+FUNCID;
\r
3108 String msg = FUNCID+sType+"を取得します: "+tvp.getTVProgramId();
\r
3109 stwin.appendMessage(msg);
\r
3110 if (aName!=null) stwin.appendMessage(FUNCID+"+選択されているエリア="+aName);
\r
3113 //tvp.setProgressArea(stwin);
\r
3114 tvp.loadProgram(tvp.getSelectedCode(), force);
\r
3121 tvp.setExtension(null, null, false, extKeys.getSearchKeys()); // 最初の3引数は盲腸。ダミー
\r
3123 tvp.abon(env.getNgword());
\r
3125 String errmsg = tvp.chkComplete();
\r
3126 if (errmsg != null) {
\r
3127 stwin.appendError(FUNCID+"取得した情報が不正です:"+errmsg);
\r
3128 if (mainWindow!=null) mwin.appendMessage(msg);
\r
3133 // しょぼかるの番組詳細を番組表に反映する
\r
3134 private void attachSyoboNew() {
\r
3135 TVProgram syobo = tvprograms.getSyobo();
\r
3136 if (syobo == null) {
\r
3140 for ( TVProgram tvp : tvprograms ) {
\r
3142 if ( tvp.getType() != ProgType.PROG ) {
\r
3145 if ( ! (tvp.getSubtype() == ProgSubtype.TERRA || tvp.getSubtype() == ProgSubtype.CS || tvp.getSubtype() == ProgSubtype.CS2) ) {
\r
3149 for ( ProgList tvpl : tvp.getCenters() ) {
\r
3150 if ( ! tvpl.enabled) {
\r
3153 for ( ProgList svpl : syobo.getCenters() ) {
\r
3154 if ( ! tvpl.Center.equals(svpl.Center)) {
\r
3157 for ( ProgDateList tvc : tvpl.pdate ) {
\r
3159 ProgDateList mSvc = null;
\r
3160 for ( ProgDateList svc : svpl.pdate ) {
\r
3161 if (tvc.Date.equals(svc.Date) ) {
\r
3166 if (mSvc == null) {
\r
3167 // しょぼかる側に該当する日付自体ないので全部フラグを立てっぱなしでいい
\r
3168 for ( ProgDetailList tvd : tvc.pdetail ) {
\r
3169 if ( tvd.isEqualsGenre(ProgGenre.ANIME, null) ) {
\r
3170 tvd.addOption(ProgOption.NOSYOBO);
\r
3175 // しょぼかる側に該当する日付があるのでマッチング。アニメと映画と音楽
\r
3176 for ( ProgDetailList tvd : tvc.pdetail ) {
\r
3178 // アニメはいったんフラグを立てる
\r
3179 if ( tvd.isEqualsGenre(ProgGenre.ANIME, null) ) {
\r
3180 tvd.addOption(ProgOption.NOSYOBO);
\r
3183 boolean isFind = false;
\r
3184 for ( ProgDetailList svd : mSvc.pdetail ) {
\r
3185 if ( tvd.start.equals(svd.start) ) {
\r
3189 //svd.progid = tvd.progid;
\r
3190 svd.setContentIdStr();
\r
3193 boolean isAnime = tvd.isEqualsGenre(ProgGenre.ANIME, null);
\r
3194 if ( ! isAnime && ! tvd.isEqualsGenre(ProgGenre.MOVIE, null) && ! tvd.isEqualsGenre(ProgGenre.MUSIC, null) ) {
\r
3201 // しょぼかるとWeb番組表の両方に存在する
\r
3202 svd.nosyobo = true;
\r
3206 boolean isAttached = false;
\r
3209 if ( svd.flag == ProgFlags.NEW && tvd.flag != ProgFlags.NEW ) {
\r
3210 tvd.flag = ProgFlags.NEW;
\r
3211 isAttached = true;
\r
3215 if ( svd.flag == ProgFlags.LAST && tvd.flag != ProgFlags.LAST ) {
\r
3216 tvd.flag = ProgFlags.LAST;
\r
3217 isAttached = true;
\r
3221 if ( tvd.isEqualsGenre(ProgGenre.MOVIE, null) && ! tvd.isEqualsGenre(ProgGenre.MOVIE, ProgSubgenre.MOVIE_ANIME) ) {
\r
3222 if ( tvd.genrelist == null ) {
\r
3223 tvd.genrelist = new ArrayList<ProgGenre>();
\r
3224 tvd.genrelist.add(tvd.genre);
\r
3225 tvd.genrelist.add(ProgGenre.MOVIE);
\r
3226 tvd.subgenrelist = new ArrayList<ProgSubgenre>();
\r
3227 tvd.subgenrelist.add(tvd.subgenre);
\r
3228 tvd.subgenrelist.add(ProgSubgenre.MOVIE_ANIME);
\r
3231 tvd.genrelist.add(ProgGenre.MOVIE);
\r
3232 tvd.subgenrelist.add(ProgSubgenre.MOVIE_ANIME);
\r
3234 isAttached = true;
\r
3238 for ( ProgOption sopt : svd.getOption() ) {
\r
3239 if ( tvd.addOption(sopt) && isAttached == false ) {
\r
3240 isAttached = true;
\r
3245 if (isAttached && env.getDebug()) {
\r
3246 StdAppendMessage("しょぼかるのフラグを引き継ぎました: ("+tvpl.Center+") "+tvd.title);
\r
3251 if ( tvd.detail.length() < svd.detail.length() ) {
\r
3252 tvd.detail = svd.detail;
\r
3255 int idx = svd.detail.indexOf("<!");
\r
3257 tvd.detail += svd.detail.substring(idx);
\r
3261 // 「しょぼかるにのみ存在」フラグの上げ下げ(これはアニメ限定)
\r
3264 tvd.removeOption(ProgOption.NOSYOBO); // NOSYOBOって…
\r
3267 //tvd.addOption(ProgOption.NOSYOBO);
\r
3284 private void fixTitle() {
\r
3286 if ( ! env.getFixTitle()) {
\r
3290 for ( TVProgram tvp : tvprograms ) {
\r
3291 //if ( ! (tvp.getType() == ProgType.PROG && tvp.getSubtype() == ProgSubtype.TERRA) ) {
\r
3292 if ( tvp.getType() != ProgType.PROG ) {
\r
3296 for ( ProgList pl : tvp.getCenters() ) {
\r
3297 if ( ! pl.enabled ) {
\r
3301 for ( ProgDateList pcl : pl.pdate ) {
\r
3303 for ( ProgDetailList tvd : pcl.pdetail ) {
\r
3304 if ( tvd.isEqualsGenre(ProgGenre.ANIME, null) ) {
\r
3305 if ( pl.Center.startsWith("NHK") || pl.Center.startsWith("NHK") ) {
\r
3306 // NHK系で先頭が「アニメ 」ではじまるものから「アニメ 」を削除する
\r
3307 tvd.title = tvd.title.replaceFirst("^アニメ[ ・]+","");
\r
3308 tvd.titlePop = TraceProgram.replacePop(tvd.title);
\r
3309 tvd.SearchStrKeys = TraceProgram.splitKeys(tvd.titlePop);
\r
3311 if ( (tvd.title.contains("劇場版") || tvd.detail.contains("映画")) && ! tvd.isEqualsGenre(ProgGenre.MOVIE, ProgSubgenre.MOVIE_ANIME) ) {
\r
3312 // ジャンル=アニメだがタイトルに「劇場版」が含まれるならジャンル=映画(アニメ映画)を追加する
\r
3313 if ( tvd.genrelist == null ) {
\r
3314 tvd.genrelist = new ArrayList<ProgGenre>();
\r
3315 tvd.genrelist.add(tvd.genre);
\r
3316 tvd.genrelist.add(ProgGenre.MOVIE);
\r
3317 tvd.subgenrelist = new ArrayList<ProgSubgenre>();
\r
3318 tvd.subgenrelist.add(tvd.subgenre);
\r
3319 tvd.subgenrelist.add(ProgSubgenre.MOVIE_ANIME);
\r
3322 tvd.genrelist.add(ProgGenre.MOVIE);
\r
3323 tvd.subgenrelist.add(ProgSubgenre.MOVIE_ANIME);
\r
3327 else if ( tvd.isEqualsGenre(ProgGenre.MOVIE, ProgSubgenre.MOVIE_ANIME) && tvd.subgenre != ProgSubgenre.MOVIE_ANIME ) {
\r
3328 // ジャンル=映画でサブジャンルが複数ありアニメが優先されてないものはアニメを優先する
\r
3329 tvd.subgenre = ProgSubgenre.MOVIE_ANIME;
\r
3332 // サブタイトルを番組追跡の対象から外す
\r
3333 if ( env.getTraceOnlyTitle() && tvd.title != tvd.splitted_title ) {
\r
3334 tvd.SearchStrKeys = TraceProgram.splitKeys(TraceProgram.replacePop(tvd.splitted_title)); // 番組追跡の検索用インデックスは、サブタイトルを削除したもので置き換える
\r
3343 * {@link ProgDetailList} の情報を整形する
\r
3345 private void fixDetail() {
\r
3346 for ( TVProgram tvp : tvprograms ) {
\r
3347 for ( ProgList pl : tvp.getCenters() ) {
\r
3348 if ( ! pl.enabled ) {
\r
3351 for ( ProgDateList pcl : pl.pdate ) {
\r
3352 for ( ProgDetailList tvd : pcl.pdetail ) {
\r
3353 if ( tvd.start == null || tvd.start.length() == 0 ) {
\r
3357 fixDetailSub(tvp, pl, tvd);
\r
3364 private void fixDetailSub(TVProgram tvp, ProgList pl, ProgDetailList tvd) {
\r
3365 tvd.type = tvp.getType();
\r
3366 tvd.subtype = tvp.getSubtype();
\r
3367 tvd.center = pl.Center;
\r
3369 tvd.recmin = CommonUtils.getRecMinVal(tvd.startDateTime, tvd.endDateTime);
\r
3371 tvd.extension_mark = markchar.getExtensionMark(tvd);
\r
3372 tvd.prefix_mark = markchar.getOptionMark(tvd);
\r
3373 tvd.newlast_mark = markchar.getNewLastMark(tvd);
\r
3374 tvd.postfix_mark = markchar.getPostfixMark(tvd);
\r
3376 tvd.dontoverlapdown = (tvd.center.startsWith("NHK") || tvd.center.startsWith("NHK"));
\r
3380 * <P>過去ログから検索キーワードにマッチする情報を取得する
\r
3381 * <P>全部検索がヒットした結果がかえるのだから {@link ProgDetailList} ではなく {@link MarkedProgramList} を使うべきなのだが…
\r
3383 private boolean searchPassedProgram(final SearchKey sKey, final String target) {
\r
3385 Matcher ma = Pattern.compile("^(\\d\\d\\d\\d/\\d\\d/\\d\\d)-(\\d\\d\\d\\d/\\d\\d/\\d\\d)$").matcher(target);
\r
3386 if ( ! ma.find() ) {
\r
3390 final GregorianCalendar s = CommonUtils.getCalendar(ma.group(1));
\r
3391 final GregorianCalendar e = CommonUtils.getCalendar(ma.group(2));
\r
3392 final long dDays = (e.getTimeInMillis() - s.getTimeInMillis())/86400000 + 1;
\r
3394 final ArrayList<ProgDetailList> srchpdl = tvprograms.getSearched().getResultBuffer(sKey.getLabel()) ;
\r
3398 // 検索実行(時間がかかるので状況表示する)
\r
3399 new SwingBackgroundWorker(false) {
\r
3402 protected Object doWorks() throws Exception {
\r
3404 TatCount tc = new TatCount();
\r
3407 int resultCnt = 0;
\r
3408 for (int cnt=1; cnt<=dDays; cnt++) {
\r
3410 String passdt = CommonUtils.getDate(e);
\r
3411 stwin.appendMessage(String.format("[過去ログ検索] 検索中:(%d/%d) %s", cnt, dDays, passdt));
\r
3413 PassedProgram tvp = new PassedProgram();
\r
3414 if ( tvp.loadAllCenters(passdt) ) {
\r
3415 for ( ProgList pl : tvp.getCenters() ) {
\r
3416 if ( ! pl.enabled ) {
\r
3420 for ( ProgDateList pcl : pl.pdate ) {
\r
3421 for ( ProgDetailList tvd : pcl.pdetail ) {
\r
3422 if ( tvd.start == null || tvd.start.length() == 0 ) {
\r
3426 if ( SearchProgram.isMatchKeyword(sKey, pl.Center, tvd) ) {
\r
3427 tvd.dynKey = sKey;
\r
3428 tvd.dynMatched = SearchProgram.getMatchedString();
\r
3429 fixDetailSub(tvp, pl, tvd);
\r
3431 if ( ++resultCnt >= env.getSearchResultMax() ) {
\r
3432 mwin.appendMessage(String.format("[過去ログ検索] 検索件数の上限に到達しました。所要時間: %.2f秒",tc.end()));
\r
3441 e.add(Calendar.DATE,-1);
\r
3444 mwin.appendMessage(String.format("[過去ログ検索] 検索完了。所要時間: %.2f秒",tc.end()));
\r
3449 protected void doFinally() {
\r
3450 StWinSetVisible(false);
\r
3454 StWinSetLocationCenter(this);
\r
3455 StWinSetVisible(true);
\r
3461 private void getTrayIcon() {
\r
3462 if ( trayicon != null ) {
\r
3467 Image image = ImageIO.read(new File(ICONFILE_SYSTRAY));
\r
3468 trayicon = new TrayIcon(image,"Tainavi");
\r
3470 final Viewer thisClass = this;
\r
3473 PopupMenu popup = new PopupMenu();
\r
3475 MenuItem item = new MenuItem("開く");
\r
3476 item.addActionListener(new ActionListener() {
\r
3478 public void actionPerformed(ActionEvent e) {
\r
3479 thisClass.setVisible(true);
\r
3480 thisClass.setState(Frame.NORMAL);
\r
3486 MenuItem item = new MenuItem("終了する");
\r
3487 item.addActionListener(new ActionListener() {
\r
3489 public void actionPerformed(ActionEvent e) {
\r
3496 trayicon.setPopupMenu(popup);
\r
3499 trayicon.addMouseListener(new MouseAdapter() {
\r
3501 public void mouseClicked(MouseEvent e) {
\r
3502 if (e.getButton() == MouseEvent.BUTTON1) {
\r
3503 thisClass.setVisible(true);
\r
3504 thisClass.setState(Frame.NORMAL);
\r
3509 } catch (IOException e) {
\r
3510 StdAppendError("アイコンファイルが読み込めませんでした: "+ICONFILE_SYSTRAY);
\r
3511 e.printStackTrace();
\r
3514 private void setTrayIconVisible(boolean b) {
\r
3516 if ( ! SystemTray.isSupported() || trayicon == null ) {
\r
3523 SystemTray.getSystemTray().remove(trayicon);
\r
3524 SystemTray.getSystemTray().add(trayicon);
\r
3528 SystemTray.getSystemTray().remove(trayicon);
\r
3530 } catch (AWTException e) {
\r
3531 e.printStackTrace();
\r
3534 private void HideToTray() {
\r
3535 if ( SystemTray.isSupported() && trayicon != null && (env.getShowSysTray() && env.getHideToTray()) ) {
\r
3536 this.setVisible(false);
\r
3539 private void setXButtonAction(boolean b) {
\r
3541 this.setDefaultCloseOperation(JFrame.ICONIFIED);
\r
3544 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
\r
3549 private void procArgs(String[] args) {
\r
3551 for (String arg : args) {
\r
3554 if (arg.compareTo("-L") == 0) {
\r
3556 //logging = false;
\r
3558 else if (arg.compareTo("-L") == 0) {
\r
3562 else if (arg.compareTo("-w") == 0) {
\r
3564 runRecWakeup = true;
\r
3566 else if (arg.compareTo("-nowebaccess") == 0) {
\r
3567 // -nowebaccess : 起動時のWeb番組表へのアクセス無効
\r
3568 enableWebAccess = false;
\r
3570 else if (arg.compareTo("-proxy") == 0) {
\r
3571 // -proxy : Web番組表へのアクセスにProxy経由を強制する
\r
3574 else if (arg.compareTo("-loadrec") == 0) {
\r
3575 // -loadrec : 起動時にレコーダにアクセスする
\r
3576 runRecLoad = true;
\r
3578 else if (arg.compareTo("-onlyLoadProgram") == 0) {
\r
3579 // -onlyLoadProgram : 番組表の取得だけ行う
\r
3580 onlyLoadProgram = true;
\r
3584 String[] dat = arg.split(":");
\r
3585 if (dat.length == 1 ) {
\r
3588 } if (dat.length >= 2 ) {
\r
3598 // メインの環境設定ファイルを読みだす
\r
3599 private void loadEnvfile() {
\r
3600 StdAppendMessage("【環境設定】環境設定ファイルを読み込みます.");
\r
3604 // 引き続きその他の環境設定ファイルも読みだす
\r
3605 private void procEnvs() {
\r
3607 StdAppendMessage("【環境設定】環境設定ファイル類を読み込みます.");
\r
3613 recInfoList.load();
\r
3616 if (pxaddr != null) {
\r
3617 env.setUseProxy(true);
\r
3618 env.setProxyAddr(pxaddr);
\r
3619 env.setProxyPort(pxport);
\r
3622 // Cookieの処理を入れようとしたけど無理だった
\r
3625 CookieManager manager = new CookieManager();
\r
3626 manager.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
\r
3627 CookieHandler.setDefault(manager);
\r
3634 // 深夜の帯予約の補正(一日前にずらす)
\r
3635 // 可能なら番組表を8日分取得する
\r
3636 // 【WIN】ファイルオープンにrundll32を使用する
\r
3637 CommonUtils.setAdjLateNight(env.getAdjLateNight());
\r
3638 CommonUtils.setExpandTo8(env.getExpandTo8());
\r
3639 CommonUtils.setUseRundll32(env.getUseRundll32());
\r
3640 CommonUtils.setDisplayPassedReserve(env.getDisplayPassedReserve());
\r
3641 CommonUtils.setDebug(env.getDebug());
\r
3643 SwingBackgroundWorker.setDebug(env.getDebug());
\r
3649 bounds.setLoaded(bounds.load());
\r
3667 // スポーツ延長警告のデフォルト設定のコードはもういらないので削除(3.15.4β)
\r
3669 // 簡易描画はもういらないので削除
\r
3676 private void chkDualBoot() {
\r
3677 if ( ! env.getOnlyOneInstance() ) {
\r
3681 if ( ! CommonUtils.getLock() ) {
\r
3687 Runtime.getRuntime().addShutdownHook(new Thread() {
\r
3688 public void run() {
\r
3689 // 鯛ナビ終了時にロックを解除する
\r
3690 CommonUtils.getUnlock();
\r
3696 private void chkVerUp() {
\r
3697 if ( ! enableWebAccess || onlyLoadProgram ) {
\r
3698 stwin.appendError("【オンラインアップデート】オンラインアップデートは無効です");
\r
3702 VWUpdate vu = new VWUpdate(stwin);
\r
3703 if ( ! vu.isExpired(env.getUpdateMethod()) ) {
\r
3704 // メッセージはVWUpdate内で出力されます
\r
3707 if ( doVerUp(vu) ) {
\r
3712 private boolean doVerUp(VWUpdate vu) {
\r
3713 UpdateResult res = vu.checkUpdate(VersionInfo.getVersion());
\r
3717 // 履歴は更新しない(連続アップデートがあるかも知れないので)
\r
3718 LogViewer lv = new LogViewer(HISTORY_FILE);
\r
3719 lv.setModal(true);
\r
3720 lv.setCaretPosition(0);
\r
3721 lv.setVisible(true);
\r
3725 // 履歴は更新しない(次回に持ち越し)
\r
3729 vu.updateHistory();
\r
3733 // 履歴は更新しない(次回再挑戦)
\r
3740 * レコーダプラグインをすべて読み込みます。
\r
3742 private boolean loadRecPlugins() {
\r
3744 stwin.appendMessage("【レコーダプラグイン】プラグインを読み込みます.");
\r
3746 boolean isMailPluginEnabled = false;
\r
3748 Class.forName("javax.mail.Session");
\r
3749 isMailPluginEnabled = true;
\r
3751 catch ( Exception e ) {
\r
3752 System.err.println("【レコーダプラグイン】メール系プラグイン用の外部ライブラリがみつかりません: "+e.toString());
\r
3755 boolean isCalendarPluginEnabled = false;
\r
3757 Class.forName("com.google.gdata.client.calendar.CalendarService");
\r
3758 isCalendarPluginEnabled = true;
\r
3760 catch ( Exception e ) {
\r
3761 System.err.println("【レコーダプラグイン】カレンダー系プラグイン用の外部ライブラリがみつかりません: "+e.toString());
\r
3765 ArrayList<String> recIda = new ArrayList<String>();
\r
3766 for ( File f : new File(CommonUtils.joinPath(new String[]{"bin","tainavi"})).listFiles() ) {
\r
3767 Matcher ma = Pattern.compile("^(PlugIn_Rec[^$]+)[^$]*\\.class$").matcher(f.getName());
\r
3768 if ( ma.find() ) {
\r
3769 if ( ! isMailPluginEnabled && f.getName().toLowerCase().contains("mail") ) {
\r
3770 System.out.println("【レコーダプラグイン】メール系プラグインは無効です: "+f.getName());
\r
3773 if ( ! isCalendarPluginEnabled && f.getName().toLowerCase().contains("calendar") ) {
\r
3774 System.out.println("【レコーダプラグイン】カレンダー系プラグインは無効です: "+f.getName());
\r
3778 recIda.add(ma.group(1));
\r
3781 String[] recIdd = recIda.toArray(new String[0]);
\r
3782 Arrays.sort(recIdd);
\r
3785 StringBuilder sb = new StringBuilder();
\r
3786 for ( String recId : recIdd ) {
\r
3787 sb.append("tainavi.");
\r
3791 if ( ! CommonUtils.write2file(CommonUtils.joinPath(new String[] {"bin","META-INF","services","tainavi.HDDRecorder"}), sb.toString()) ) {
\r
3792 stwin.appendError("【レコーダプラグイン】プラグインの読み込みに失敗しました: ");
\r
3796 // ここで例外が起きてもトラップできない、スレッドが落ちる
\r
3797 ServiceLoader<HDDRecorder> r = ServiceLoader.load(HDDRecorder.class);
\r
3799 recPlugins.clear();
\r
3800 for ( HDDRecorder recorder : r ) {
\r
3801 if (env.getDebug()) StdAppendMessage("+追加します: "+recorder.getRecorderId());
\r
3802 recPlugins.add(recorder.clone());
\r
3803 StdAppendMessage("+追加しました: "+recorder.getRecorderId());
\r
3810 * レコーダ設定をもとにレコーダプラグインから実レコーダのインスタンスを生成します。
\r
3812 private void initRecPluginAll() {
\r
3814 recorders.clear();
\r
3815 for ( RecorderInfo ri : recInfoList ) {
\r
3816 ArrayList<HDDRecorder> rl = recPlugins.findPlugin(ri.getRecorderId());
\r
3817 if ( rl.size() == 0 ) {
\r
3818 stwin.appendError("【レコーダプラグイン】プラグインがみつかりません: "+ri.getRecorderId()+"("+ri.getRecorderIPAddr()+":"+ri.getRecorderPortNo()+")");
\r
3821 stwin.appendMessage("【レコーダプラグイン】プラグインを初期化します: "+ri.getRecorderId()+"("+ri.getRecorderIPAddr()+":"+ri.getRecorderPortNo()+")");
\r
3822 for ( HDDRecorder rPlugin : rl ) {
\r
3823 initRecPlugin(rPlugin, ri);
\r
3828 protected HDDRecorder initRecPlugin(HDDRecorder rPlugin, RecorderInfo ri) {
\r
3829 HDDRecorder rec = rPlugin.clone();
\r
3830 recorders.add(rec);
\r
3832 rec.getChCode().load(true); // true : ログ出力あり
\r
3833 setSettingRecPluginBase(rec, ri);
\r
3834 setSettingRecPluginExt(rec,env);
\r
3835 rec.setProgressArea(stwin);
\r
3838 protected void setSettingRecPluginBase(HDDRecorder to, RecorderInfo from) {
\r
3839 to.setIPAddr(from.getRecorderIPAddr());
\r
3840 to.setPortNo(from.getRecorderPortNo());
\r
3841 to.setUser(from.getRecorderUser());
\r
3842 to.setPasswd(from.getRecorderPasswd());
\r
3843 to.setMacAddr(from.getRecorderMacAddr());
\r
3844 to.setBroadcast(from.getRecorderBroadcast());
\r
3845 to.setUseCalendar(from.getUseCalendar());
\r
3846 to.setUseChChange(from.getUseChChange());
\r
3847 to.setRecordedCheckScope(from.getRecordedCheckScope());
\r
3848 to.setTunerNum(from.getTunerNum());
\r
3849 to.setColor(from.getRecorderColor());
\r
3851 protected void setSettingRecPluginExt(HDDRecorder recorder, Env nEnv) {
\r
3852 recorder.setUserAgent(nEnv.getUserAgent());
\r
3853 recorder.setDebug(nEnv.getDebug());
\r
3854 recorder.setAdjNotRep(nEnv.getAdjoiningNotRepetition());
\r
3855 recorder.setRecordedSaveScope(nEnv.getRecordedSaveScope());
\r
3859 protected void doRecWakeup() {
\r
3860 for ( HDDRecorder rec : recorders ) {
\r
3861 if ( ! rec.getMacAddr().equals("") && ! rec.getBroadcast().equals("") ) {
\r
3870 private boolean isOLPExpired(int expire) {
\r
3871 String fname = "env"+File.separator+"olp.history";
\r
3872 if ( ! new File(fname).exists() || ! new File(fname).canWrite() ) {
\r
3873 stwin.appendError("【警告】実行履歴ファイルがないから実行させないよ!");
\r
3877 String dat = CommonUtils.read4file(fname, true);
\r
3878 if ( dat == null ) {
\r
3879 stwin.appendError("【警告】実行履歴を取得できなかったから実行させないよ!");
\r
3883 GregorianCalendar ca = null;
\r
3884 dat = EncryptPassword.dec(b64.dec(dat));
\r
3885 if ( dat != null ) {
\r
3886 ca = CommonUtils.getCalendar(dat);
\r
3888 if ( ca == null ) {
\r
3889 stwin.appendError("【警告】実行履歴の内容が不正だったから実行させないよ! "+dat);
\r
3893 if ( CommonUtils.getCompareDateTime(ca, CommonUtils.getCalendar(-expire*3600)) >= 0 ) {
\r
3894 ca.add(Calendar.HOUR,expire);
\r
3895 stwin.appendError("【警告】"+expire+"時間以内の再実行は許さないよ!"+CommonUtils.getDateTime(ca)+"まで待って!");
\r
3899 if ( ! CommonUtils.write2file(fname, b64.enc(EncryptPassword.enc(CommonUtils.getDateTime(0)))) ) {
\r
3900 stwin.appendError("【警告】実行履歴を保存できなかったから実行させないよ!");
\r
3909 * Web番組表プラグインをすべて読み込みます。
\r
3911 private boolean loadProgPlugins() {
\r
3913 final String FUNCID = "[Web番組表プラグイン組込] ";
\r
3914 final String ERRID = "[ERROR]"+FUNCID;
\r
3917 stwin.appendMessage(FUNCID+"プラグインを読み込みます.");
\r
3920 setSettingProgPluginCommon(env);
\r
3926 // TVProgramListのインスタンスは別途初期化が必要
\r
3927 progPlugins.clear();
\r
3928 tvprograms.clear();
\r
3934 ArrayList<String> prgIda = new ArrayList<String>();
\r
3935 for ( File f : new File(CommonUtils.joinPath("bin","tainavi")).listFiles() ) {
\r
3936 Matcher ma = Pattern.compile("^(PlugIn_(TV|CS|RAD)P[^$]+)\\.class$").matcher(f.getName());
\r
3938 prgIda.add(ma.group(1));
\r
3941 String[] prgIdd = prgIda.toArray(new String[0]);
\r
3942 Arrays.sort(prgIdd);
\r
3945 StringBuilder sb = new StringBuilder();
\r
3946 for ( String prgId : prgIdd ) {
\r
3947 sb.append("tainavi.");
\r
3951 if ( ! CommonUtils.write2file(CommonUtils.joinPath("bin","META-INF","services","tainavi.TVProgram"), sb.toString()) ) {
\r
3952 stwin.appendError(ERRID+"プラグインの読み込みに失敗しました: ");
\r
3956 ServiceLoader<TVProgram> p = ServiceLoader.load(TVProgram.class);
\r
3958 // 実際必要ないのだが、プラグインのインスタンスはclone()して使う
\r
3959 for ( TVProgram pg : p ) {
\r
3960 TVProgram prog = pg.clone();
\r
3962 stwin.appendMessage("+追加しました: "+prog.getTVProgramId());
\r
3964 // CH設定タブではプラグイン側のインスタンスを使うので情報を追加してやる必要があるのであった
\r
3965 setSettingProgPlugin(prog, env);
\r
3967 progPlugins.add(prog);
\r
3976 * 設定にあわせてWeb番組表プラグインを絞り込みます。
\r
3978 private void setSelectedProgPlugin() {
\r
3981 Syobocal syobo = tvprograms.getSyobo();
\r
3982 PassedProgram passed = tvprograms.getPassed();
\r
3983 PickedProgram pickup = tvprograms.getPickup();
\r
3984 SearchResult searched = tvprograms.getSearched();
\r
3986 tvprograms.clear();
\r
3989 TVProgram tvp = progPlugins.getTvProgPlugin(env.getTVProgramSite());
\r
3990 if ( tvp == null ) {
\r
3991 // デフォルトもなければ先頭にあるもの
\r
3992 tvp = progPlugins.getTvProgPlugin(null);
\r
3994 if ( tvp == null ) {
\r
3996 StdAppendError("【Web番組表選択】地上波&BS番組表が選択されていません: "+env.getTVProgramSite());
\r
3999 StdAppendMessage("【Web番組表選択】地上波&BS番組表が選択されました: "+tvp.getTVProgramId());
\r
4000 tvprograms.add(tvp.clone());
\r
4004 TVProgram tvp = progPlugins.getCsProgPlugin(env.getCSProgramSite());
\r
4005 if ( tvp == null ) {
\r
4006 tvp = progPlugins.getCsProgPlugin(null);
\r
4008 if ( tvp == null ) {
\r
4009 StdAppendError("【Web番組表選択】CS番組表[プライマリ]が選択されていません: "+env.getCSProgramSite());
\r
4012 StdAppendMessage("【Web番組表選択】CS番組表[プライマリ]が選択されました: "+tvp.getTVProgramId());
\r
4013 tvprograms.add(tvp.clone());
\r
4017 TVProgram tvp = progPlugins.getCs2ProgPlugin(env.getCS2ProgramSite());
\r
4018 if ( tvp == null ) {
\r
4019 tvp = progPlugins.getCs2ProgPlugin(null);
\r
4021 if ( tvp == null ) {
\r
4022 StdAppendError("【Web番組表選択】CS番組表[プライマリ]が選択されていません: "+env.getCS2ProgramSite());
\r
4025 StdAppendMessage("【Web番組表選択】CS番組表[プライマリ]が選択されました: "+tvp.getTVProgramId());
\r
4026 tvprograms.add(tvp.clone());
\r
4030 if ( progPlugins.getRadioProgPlugins().size() > 0 )
\r
4032 TVProgram tvp = progPlugins.getCsProgPlugin(env.getRadioProgramSite());
\r
4033 if ( tvp == null ) {
\r
4034 tvp = progPlugins.getCsProgPlugin(null);
\r
4036 if ( tvp == null ) {
\r
4037 StdAppendError("【Web番組表選択】ラジオ番組表が選択されていません: "+env.getRadioProgramSite());
\r
4040 StdAppendMessage("【Web番組表選択】ラジオ番組表が選択されました: "+tvp.getTVProgramId());
\r
4041 tvprograms.add(tvp.clone());
\r
4047 if ( syobo == null ) {
\r
4048 syobo = new Syobocal();
\r
4050 tvprograms.add(syobo);
\r
4053 if ( passed == null ) {
\r
4054 passed = new PassedProgram();
\r
4056 tvprograms.add(passed);
\r
4059 if ( pickup == null ) {
\r
4060 pickup = new PickedProgram();
\r
4061 pickup.loadProgram(null, false);
\r
4063 tvprograms.add(pickup);
\r
4066 if ( searched == null ) {
\r
4067 searched = new SearchResult();
\r
4069 tvprograms.add(searched);
\r
4074 * Web番組表設定をもとにレコーダプラグインのインスタンスを生成します。
\r
4076 private void initProgPluginAll() {
\r
4078 final String FUNCID = "[Web番組表プラグイン初期化] ";
\r
4079 final LinkedHashMap<ArrayList<TVProgram>,String> map = new LinkedHashMap<ArrayList<TVProgram>, String>();
\r
4080 map.put(tvprograms.getTvProgPlugins(), "地上波&BS番組表");
\r
4081 map.put(tvprograms.getCsProgPlugins(), "CS番組表[プライマリ]");
\r
4082 map.put(tvprograms.getCs2ProgPlugins(), "CS番組表[セカンダリ]");
\r
4083 //map.put(progPlugins.getRadioProgPlugins(), "ラジオ番組表");
\r
4085 new SwingBackgroundWorker(true) {
\r
4088 protected Object doWorks() throws Exception {
\r
4090 for ( ArrayList<TVProgram> tvpa : map.keySet() ) {
\r
4091 stwin.appendMessage(FUNCID+map.get(tvpa)+"のベース情報(放送局リストなど)を取得します.");
\r
4092 for ( TVProgram p : tvpa ) {
\r
4093 stwin.appendMessage(FUNCID+"プラグインを初期化します: "+p.getTVProgramId());
\r
4096 // 個別設定(2) …(1)と(2)の順番が逆だったので前に移動してきました(3.17.3β)
\r
4097 setSettingProgPlugin(p,env); // 他からも呼び出される部分だけ分離
\r
4100 p.setOptString(null); // フリーオプション初期化
\r
4101 p.loadAreaCode(); // 放送エリア情報取得
\r
4102 p.loadCenter(p.getSelectedCode(),false); // 放送局情報取得
\r
4103 p.setSortedCRlist(); // 有効放送局だけよりわける
\r
4105 catch (Exception e) {
\r
4106 stwin.appendError(FUNCID+"ベース情報の取得に失敗しました.");
\r
4107 e.printStackTrace();
\r
4113 //setSettingProgPluginAll(env);
\r
4115 if ( env.getUseSyobocal() ) {
\r
4116 TVProgram syobo = tvprograms.getSyobo();
\r
4117 if ( syobo != null ) {
\r
4118 stwin.appendMessage(FUNCID+"しょぼかるを初期化します.");
\r
4119 setSettingProgPlugin(syobo,env); // 他からも呼び出される部分だけ分離
\r
4120 syobo.setUserAgent("tainavi");
\r
4121 syobo.setOptString(null); // フリーオプション初期化
\r
4122 syobo.loadCenter(syobo.getSelectedCode(), false);
\r
4130 protected void doFinally() {
\r
4134 protected void setSettingProgPluginAll(Env nEnv) {
\r
4136 setSettingProgPlugin(tvprograms.getTvProgPlugin(null),nEnv);
\r
4137 setSettingProgPlugin(tvprograms.getCsProgPlugin(null),nEnv);
\r
4138 setSettingProgPlugin(tvprograms.getCs2ProgPlugin(null),nEnv);
\r
4139 //setSettingProgPlugin(tvprograms.getRadioProgPlugin(null),nEnv);
\r
4140 setSettingProgPlugin(tvprograms.getSyobo(),nEnv);
\r
4143 tvprograms.getSyobo().setUserAgent("tainavi");
\r
4145 tvprograms.getSearched().setResultBufferMax(nEnv.getSearchResultBufferMax());
\r
4147 protected void setSettingProgPlugin(TVProgram p, Env nEnv) {
\r
4148 if ( p == null ) {
\r
4151 p.setUserAgent(nEnv.getUserAgent());
\r
4152 p.setProgDir(nEnv.getProgDir());
\r
4153 p.setCacheExpired((enableWebAccess)?(nEnv.getCacheTimeLimit()):(0));
\r
4154 p.setContinueTomorrow(nEnv.getContinueTomorrow());
\r
4155 p.setExpandTo8(nEnv.getExpandTo8());
\r
4156 //p.setUseDetailCache(nEnv.getUseDetailCache());
\r
4157 p.setUseDetailCache(false);
\r
4158 p.setSplitEpno(nEnv.getSplitEpno());
\r
4162 * staticで持っている共通設定の更新
\r
4164 protected void setSettingProgPluginCommon(Env nEnv) {
\r
4166 if ( nEnv.getUseProxy() && (nEnv.getProxyAddr().length() > 0 && nEnv.getProxyPort().length() > 0) ) {
\r
4167 stwin.appendMessage("+Web番組表へのアクセスにProxyが設定されています: "+nEnv.getProxyAddr()+":"+nEnv.getProxyPort());
\r
4168 TVProgramUtils.setProxy(nEnv.getProxyAddr(),nEnv.getProxyPort());
\r
4171 TVProgramUtils.setProxy(null,null);
\r
4174 TVProgramUtils.setProgressArea(stwin);
\r
4175 TVProgramUtils.setChConv(chconv);
\r
4179 private void initMpList() {
\r
4180 //mpList = new MarkedProgramList(); // 検索結果リスト
\r
4181 mpList.setHistoryOnlyUpdateOnce(env.getHistoryOnlyUpdateOnce());
\r
4182 mpList.setShowOnlyNonrepeated(env.getShowOnlyNonrepeated());
\r
4186 private void initLookAndFeelAndFont() {
\r
4190 vwlaf = new VWLookAndFeel();
\r
4192 String lafname = vwlaf.update(env.getLookAndFeel());
\r
4193 if ( lafname != null && ! lafname.equals(env.getLookAndFeel())) {
\r
4194 env.setLookAndFeel(lafname);
\r
4197 if ( CommonUtils.isMac() ) {
\r
4198 UIManager.getDefaults().put("Table.gridColor", new Color(128,128,128));
\r
4199 //UIManager.getDefaults().put("Table.selectionBackground", new Color(182,207,229));
\r
4200 //UIManager.getDefaults().put("Table.selectionForeground", new Color(0,0,0));
\r
4205 vwfont = new VWFont();
\r
4207 String fname = vwfont.update(env.getFontName(),env.getFontSize());
\r
4208 if ( fname != null && ! fname.equals(env.getFontName())) {
\r
4209 env.setFontName(fname);
\r
4213 catch ( Exception e ) {
\r
4214 // 落ちられると困るからトラップしておこうぜ
\r
4215 e.printStackTrace();
\r
4219 // L&FやFontを変えたらコンポーネントに通知が必要
\r
4220 protected void updateComponentTreeUI() {
\r
4222 SwingUtilities.updateComponentTreeUI(this);
\r
4223 SwingUtilities.updateComponentTreeUI(stwin);
\r
4224 SwingUtilities.updateComponentTreeUI(mwin);
\r
4225 SwingUtilities.updateComponentTreeUI(pcwin);
\r
4226 SwingUtilities.updateComponentTreeUI(rdialog);
\r
4227 SwingUtilities.updateComponentTreeUI(ccwin);
\r
4229 catch ( Exception e ) {
\r
4230 // 落ちられると困るからトラップしておこうぜ
\r
4231 e.printStackTrace();
\r
4235 // ツールチップの表示遅延時間を設定する
\r
4236 private void setTooltipDelay() {
\r
4237 ToolTipManager tp = ToolTipManager.sharedInstance();
\r
4238 tp.setInitialDelay(env.getTooltipInitialDelay()*100);
\r
4239 tp.setDismissDelay(env.getTooltipDismissDelay()*100);
\r
4244 * @return true:前回終了時の設定がある場合
\r
4246 private boolean buildMainWindow() {
\r
4248 mainWindow.addToolBar(toolBar);
\r
4249 mainWindow.addStatusArea(mwin);
\r
4251 mainWindow.addTab(listed, MWinTab.LISTED);
\r
4252 mainWindow.addTab(paper, MWinTab.PAPER);
\r
4253 mainWindow.addTab(reserved, MWinTab.RSVED);
\r
4254 mainWindow.addTab(recorded, MWinTab.RECED);
\r
4255 mainWindow.addTab(autores, MWinTab.AUTORES);
\r
4256 mainWindow.addTab(setting, MWinTab.SETTING);
\r
4257 mainWindow.addTab(recsetting, MWinTab.RECSET);
\r
4258 mainWindow.addTab(chsetting, MWinTab.CHSET);
\r
4259 mainWindow.addTab(chsortsetting, MWinTab.CHSORT);
\r
4260 mainWindow.addTab(chconvsetting, MWinTab.CHCONV);
\r
4261 mainWindow.addTab(chdatsetting, MWinTab.CHDAT);
\r
4264 paper.clearPanel();
\r
4265 paper.buildMainViewByDate();
\r
4267 // サイドツリーのデフォルトノードの選択
\r
4268 paper.selectTreeDefault();
\r
4269 listed.selectTreeDefault();
\r
4271 if ( recInfoList.size() > 0 ) {
\r
4275 mainWindow.setShowSettingTabs(bounds.getShowSettingTabs());
\r
4278 mwin.setRows(bounds.getStatusRows());
\r
4283 // 前回終了時設定が存在しない場合
\r
4287 private void ShowInitTab() {
\r
4290 mainWindow.setSelectedTab(null);
\r
4292 if ( recInfoList.size() <= 0 ) {
\r
4294 mainWindow.setSelectedTab(MWinTab.RECSET);
\r
4298 mainWindow.setSelectedTab(MWinTab.getAt(bounds.getSelectedTab()));
\r
4303 private void setInitBounds() {
\r
4304 // ウィンドウのサイズと表示位置を設定する
\r
4305 Rectangle window = bounds.getWinRectangle();
\r
4306 if (bounds.isLoaded()) {
\r
4307 // 設定ファイルを読み込んであったらそれを設定する
\r
4308 System.out.println(DBGID+"set bounds "+window);
\r
4309 this.setBounds(window.x, window.y, window.width, window.height);
\r
4312 // 設定ファイルがなければ自動設定する
\r
4313 Rectangle screen = this.getGraphicsConfiguration().getBounds();
\r
4315 int w = window.width;
\r
4316 if (window.width > screen.width) {
\r
4321 x = (screen.width - window.width)/2;
\r
4324 int h = window.height;
\r
4325 if (window.height > screen.height) {
\r
4327 h = screen.height;
\r
4330 y = (screen.height - window.height)/2;
\r
4332 this.setBounds(x, y, w, h);
\r
4338 * {@link VWMainWindow#setStatusVisible(boolean)}の置き換え
\r
4340 private void setStatusVisible(boolean b) {
\r
4343 listed.setDetailVisible(true);
\r
4344 paper.setDetailVisible(true);
\r
4345 MWinSetVisible(true);
\r
4348 listed.setDetailVisible(false);
\r
4349 paper.setDetailVisible(false);
\r
4350 MWinSetVisible(false);
\r
4354 // フルスクリーンモードをトグル切り替え
\r
4355 private Dimension f_dim;
\r
4356 private Point f_pnt;
\r
4357 private int divloc_l = 0;
\r
4358 private int divloc_p = 0;
\r
4360 private void setFullScreen(boolean b) {
\r
4362 if ( b == true ) {
\r
4365 this.setUndecorated(true);
\r
4366 this.setVisible(true);
\r
4369 Toolkit tk = getToolkit();
\r
4370 Insets in = tk.getScreenInsets(getGraphicsConfiguration());
\r
4371 Dimension d = tk.getScreenSize();
\r
4372 f_dim = this.getSize();
\r
4373 f_pnt = this.getLocation();
\r
4374 this.setBounds(in.left, in.top, d.width-(in.left+in.right), d.height-(in.top+in.bottom));
\r
4376 divloc_l = bounds.getTreeWidth();
\r
4377 divloc_p = bounds.getTreeWidthPaper();
\r
4380 paper.setCollapseTree();
\r
4381 listed.setCollapseTree();
\r
4384 if ( f_pnt != null && f_dim != null ) { // 起動直後などは値がないですしね
\r
4388 this.setUndecorated(false);
\r
4389 this.setVisible(true);
\r
4392 this.setBounds(f_pnt.x, f_pnt.y, f_dim.width, f_dim.height);
\r
4394 bounds.setTreeWidth(divloc_l);
\r
4395 bounds.setTreeWidthPaper(divloc_p);
\r
4398 paper.setExpandTree();
\r
4399 listed.setExpandTree();
\r
4405 private void setTitleBar() {
\r
4406 MemoryMXBean mbean = ManagementFactory.getMemoryMXBean();
\r
4407 MemoryUsage heapUsage = mbean.getHeapMemoryUsage();
\r
4411 "%s - %s - Memory Usage Max:%dM Committed:%dM Used:%dM - FrameBuffer Status:%s",
\r
4412 VersionInfo.getVersion(),
\r
4413 CommonUtils.getDateTime(0),
\r
4414 heapUsage.getMax()/(1024*1024),
\r
4415 heapUsage.getCommitted()/(1024*1024),
\r
4416 heapUsage.getUsed()/(1024*1024),
\r
4417 (paper!=null)?(paper.getFrameBufferStatus()):("N/A")
\r
4423 public void timerRised(VWTimerRiseEvent e) {
\r
4424 if (env.getDebug()) System.out.println("Timer Rised: now="+CommonUtils.getDateTimeYMDx(e.getCalendar()));
\r
4429 private void ExitOnClose() {
\r
4431 if ( ! this.toolBar.isFullScreen()) {
\r
4432 Rectangle r = this.getBounds();
\r
4433 bounds.setWinRectangle(r);
\r
4436 Rectangle r = new Rectangle();
\r
4437 r.x = this.f_pnt.x;
\r
4438 r.y = this.f_pnt.y;
\r
4439 r.width = this.f_dim.width;
\r
4440 r.height = this.f_dim.height;
\r
4441 bounds.setWinRectangle(r);
\r
4443 listed.copyColumnWidth();
\r
4444 reserved.copyColumnWidth();
\r
4446 bounds.setStatusRows(mwin.getRows());
\r
4449 bounds.setSelectedTab(mainWindow.getSelectedTab().getIndex());
\r
4450 bounds.setShowSettingTabs(mainWindow.getShowSettingTabs());
\r
4451 bounds.setSelectedRecorderId(toolBar.getSelectedRecorder());
\r
4452 bounds.setShowStatus(toolBar.isStatusShown());
\r
4458 listed.saveTreeExpansion();
\r
4459 paper.saveTreeExpansion();
\r
4463 /*******************************************************************************
\r
4465 ******************************************************************************/
\r
4468 private static boolean initialized = false;
\r
4469 private static Viewer myClass = null;
\r
4474 * @throws NoSuchAlgorithmException
\r
4475 * @version 今まで初期化を行ってからウィンドウを作成していたが<BR>
\r
4476 * 途中で例外が起こるとダンマリの上にゾンビになってたりとヒドかったので<BR>
\r
4477 * 先にウィンドウを作成してから初期化を行うように変えました
\r
4478 * @throws InterruptedException
\r
4479 * @throws InvocationTargetException
\r
4481 public static void main(final String[] args) throws NoSuchAlgorithmException, InvocationTargetException, InterruptedException {
\r
4483 if ( myClass != null ) {
\r
4484 // 既に起動していたらフォアグラウンドにする
\r
4485 SwingUtilities.invokeAndWait(new Runnable() {
\r
4487 public void run() {
\r
4489 myClass.setVisible(true);
\r
4490 myClass.setState(Frame.NORMAL);
\r
4496 SwingUtilities.invokeLater(new Runnable() {
\r
4497 public void run() {
\r
4499 final Viewer thisClass = myClass = new Viewer(args);
\r
4501 thisClass.addComponentListener(new ComponentAdapter() {
\r
4503 public void componentShown(ComponentEvent e) {
\r
4506 thisClass.removeComponentListener(this);
\r
4509 thisClass.initialize(args);
\r
4514 thisClass.setVisible(true);
\r
4521 /*******************************************************************************
\r
4523 ******************************************************************************/
\r
4528 public Viewer(final String[] args) {
\r
4533 bounds.loadText();
\r
4536 // 初期化が終わるまでは閉じられないよ → どうせステータスウィンドウにブロックされて操作できない
\r
4537 //setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
\r
4538 //setResizable(false);
\r
4540 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
\r
4545 Image image = ImageIO.read(new File(ICONFILE_TAINAVI));
\r
4546 setIconImage(image);
\r
4548 catch (IOException e) {
\r
4549 StdAppendError("[ERROR] アイコンが設定できない: "+e.toString());
\r
4552 JLabel jLabel_splash_img = new JLabel(new ImageIcon("splash.gif"));
\r
4553 jLabel_splash_img.setPreferredSize(new Dimension(400,300));
\r
4554 //getContentPane().setLayout(new BorderLayout());
\r
4555 getContentPane().add(jLabel_splash_img, BorderLayout.CENTER);
\r
4558 setLocationRelativeTo(null); // 画面の真ん中に
\r
4560 // SwingLocker共有設定
\r
4561 SwingLocker.setOwner(this);
\r
4563 // とりあえずルックアンドフィールはリセットしておかないとだめっぽいよ
\r
4564 initLookAndFeelAndFont();
\r
4565 updateComponentTreeUI();
\r
4568 // 初期化をバックグラウンドで行う
\r
4569 private void initialize(final String[] args) {
\r
4573 // 初期化処理はバックグラウンドで行う
\r
4574 new SwingBackgroundWorker(false) {
\r
4577 protected Object doWorks() throws Exception {
\r
4579 TatCount tc = new TatCount();
\r
4582 _initialize(args);
\r
4584 // 終わったら閉じられるようにするよ
\r
4585 //setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
\r
4586 //setResizable(true);
\r
4589 stwin.appendMessage(String.format("【タイニー番組ナビゲータが起動しました】 所要時間: %.2f秒",tc.end()));
\r
4594 protected void doFinally() {
\r
4595 if ( ! initialized ) System.err.println("[ERROR][鯛ナビ] 【致命的エラー】 初期化処理を行っていたスレッドが異常終了しました。");
\r
4596 stwin.setClosingEnabled(false);
\r
4597 CommonUtils.milSleep(OPENING_WIAT);
\r
4598 StWinSetVisible(false);
\r
4602 StWinSetLocationUnder(this);
\r
4603 StWinSetVisible(true);
\r
4607 private void _initialize(final String[] args) {
\r
4612 // ログ出力を設定する(Windowsの場合は文字コードをMS932にする) →DOS窓を殺したので終了
\r
4613 System.setOut(new DebugPrintStream(System.out,LOG_FILE,logging));
\r
4614 System.setErr(new DebugPrintStream(System.err,LOG_FILE,logging));
\r
4617 StdAppendMessage("================================================================================");
\r
4618 StdAppendMessage("以下のメッセージは無視してください(原因調査中)");
\r
4619 StdAppendMessage("Exception occurred during event dispatching:");
\r
4620 StdAppendMessage(" java.lang.NullPointerException");
\r
4621 StdAppendMessage(" at javax.swing.plaf.basic.BasicScrollBarUI.layoutHScrollbar(Unknown Source)");
\r
4622 StdAppendMessage(" (以下略)");
\r
4623 StdAppendMessage("================================================================================");
\r
4624 stwin.appendMessage(CommonUtils.getDateTime(0));
\r
4625 stwin.appendMessage(String.format("タイニー番組ナビゲータが起動を開始しました(VersionInfo:%s on %s)",VersionInfo.getVersion(),VersionInfo.getEnvironment()));
\r
4627 // 起動時にアップデートを確認する
\r
4631 // メインの環境設定ファイルを読み込む
\r
4637 // その他の環境設定ファイルを読み込む
\r
4640 if ( onlyLoadProgram ) {
\r
4641 if ( ! isOLPExpired(4) ) {
\r
4642 CommonUtils.milSleep(3000);
\r
4646 loadProgPlugins();
\r
4648 setSelectedProgPlugin();
\r
4649 initProgPluginAll();
\r
4650 // 検索結果リストの初期化(loadTVProgram()中で使うので)
\r
4653 loadTVProgram(true,LoadFor.ALL);
\r
4654 stwin.appendMessage("番組表を取得したので終了します");
\r
4655 CommonUtils.milSleep(3000);
\r
4660 loadProgPlugins();
\r
4664 setSelectedProgPlugin();
\r
4665 initProgPluginAll();
\r
4667 initRecPluginAll();
\r
4670 if ( runRecWakeup ) {
\r
4674 // 検索結果リストの初期化(loadTVProgram()中で使うので)
\r
4678 loadTVProgram(false,LoadFor.ALL);
\r
4683 loadRdReserve(runRecLoad, null);
\r
4685 catch ( Exception e ) {
\r
4686 System.err.println("【致命的エラー】設定の初期化に失敗しました");
\r
4687 e.printStackTrace();
\r
4691 // 背景色設定ダイアログにフォント名の一覧を設定する
\r
4692 pcwin.setFontList(vwfont);
\r
4694 // (新聞形式の)ツールチップの表示時間を変更する
\r
4695 setTooltipDelay();
\r
4697 boolean firstRun = true;
\r
4700 mainWindow = new VWMainWindow();
\r
4703 toolBar = new VWToolBar();
\r
4704 listed = new VWListedView();
\r
4705 paper = new VWPaperView();
\r
4706 reserved = new VWReserveListView();
\r
4707 recorded = new VWRecordedListView();
\r
4708 autores = new VWAutoReserveListView();
\r
4709 setting = new VWSettingView();
\r
4710 recsetting = new VWRecorderSettingView();
\r
4711 chsetting = new VWChannelSettingView();
\r
4712 chdatsetting = new VWChannelDatSettingView();
\r
4713 chsortsetting = new VWChannelSortView();
\r
4714 chconvsetting = new VWChannelConvertView();
\r
4717 toolBar.setDebug(env.getDebug());
\r
4718 autores.setDebug(env.getDebug());
\r
4721 toolBar.setPagerItems();
\r
4724 firstRun = buildMainWindow();
\r
4727 setStatusVisible(bounds.getShowStatus());
\r
4729 catch ( Exception e ) {
\r
4730 System.err.println("【致命的エラー】ウィンドウの構築に失敗しました");
\r
4731 e.printStackTrace();
\r
4736 //int x = 2/0; // サブスレッドの突然死のトラップを確認するためのコード
\r
4741 setTrayIconVisible(env.getShowSysTray());
\r
4744 setXButtonAction(env.getShowSysTray() && env.getHideToTray());
\r
4747 this.addWindowListener(new WindowAdapter() {
\r
4748 // ウィンドウを最小化したときの処理
\r
4750 public void windowIconified(WindowEvent e) {
\r
4756 public void windowClosing(WindowEvent e) {
\r
4764 // 初回起動時はレコーダの登録を促す
\r
4766 Container cp = getContentPane();
\r
4767 JOptionPane.showMessageDialog(cp, "レコーダが登録されていません。\n最初に登録を行ってください。\n番組表だけを使いたい場合は、\nNULLプラグインを登録してください。");
\r
4770 // メインウィンドウをスプラッシュからコンポーネントに入れ替える
\r
4771 this.setVisible(false);
\r
4772 this.setContentPane(mainWindow);
\r
4774 this.setVisible(true);
\r
4779 // [ツールバー/共通] レコーダ情報変更
\r
4780 toolBar.addHDDRecorderChangeListener(autores);
\r
4782 // [ツールバー/レコーダ選択] 自動予約一覧
\r
4783 toolBar.addHDDRecorderSelectionListener(autores);
\r
4787 toolBar.setSelectedRecorder(bounds.getSelectedRecorderId());
\r
4789 // [タイマー] タイトルバー更新/リスト形式の現在時刻ノード/新聞形式の現在時刻ノード
\r
4790 timer_now.addVWTimerRiseListener(this);
\r
4791 timer_now.addVWTimerRiseListener(listed);
\r
4792 timer_now.addVWTimerRiseListener(paper);
\r
4795 timer_now.start();
\r
4798 mwin.appendMessage(String.format("タイニー番組ナビゲータが起動しました (VersionInfo:%s on %s)",VersionInfo.getVersion(),VersionInfo.getEnvironment()));
\r
4800 initialized = true;
\r