OSDN Git Service

不具合修正
[tainavi/TinyBannavi.git] / TinyBannavi / src / tainavi / AbsReserveDialog.java
1 package tainavi;\r
2 \r
3 import java.awt.BorderLayout;\r
4 import java.awt.Color;\r
5 import java.awt.Component;\r
6 import java.awt.Dimension;\r
7 import java.awt.event.WindowAdapter;\r
8 import java.awt.event.WindowEvent;\r
9 import java.awt.event.WindowListener;\r
10 import java.util.ArrayList;\r
11 import java.util.Calendar;\r
12 import java.util.GregorianCalendar;\r
13 \r
14 import javax.swing.JOptionPane;\r
15 import javax.swing.JPanel;\r
16 import javax.swing.JScrollPane;\r
17 import javax.swing.border.LineBorder;\r
18 \r
19 import tainavi.TitleEditorPanel.TimeVal;\r
20 import tainavi.HDDRecorder.RecType;\r
21 import tainavi.TVProgram.ProgGenre;\r
22 import tainavi.TVProgram.ProgOption;\r
23 import tainavi.TVProgram.ProgSubgenre;\r
24 \r
25 \r
26 // ソースがもうグチャグチャでございます.\r
27 \r
28 /**\r
29  * 予約ダイアログのクラス\r
30  * @since 3.15.4β ReserveDialogからクラス名変更\r
31  * @version 3.22.2β コンポーネントを、番組情報部・録画設定部、類似予約部の3つに分離(このまま突き進めばロジックとSwingコンポーネントを分離できるんじゃないかしら?)\r
32  */\r
33 abstract class AbsReserveDialog extends JEscCancelDialog implements HDDRecorderListener,RecordExecutable,RecSettingSelectable,LikeReserveSelectable {\r
34 \r
35         private static final long serialVersionUID = 1L;\r
36 \r
37         public static String getViewName() { return "予約ダイアログ"; }\r
38         \r
39         public void setDebug(boolean b) { debug = b; }\r
40         private static boolean debug = false;\r
41         \r
42         \r
43         /*******************************************************************************\r
44          * 抽象メソッド\r
45          ******************************************************************************/\r
46 \r
47         protected abstract Env getEnv();\r
48         protected abstract TVProgramList getTVProgramList();\r
49         protected abstract HDDRecorderList getRecorderList();\r
50 \r
51         protected abstract AVSetting getAVSetting();\r
52         protected abstract CHAVSetting getCHAVSetting();\r
53 \r
54         protected abstract StatusWindow getStWin(); \r
55         protected abstract StatusTextArea getMWin();\r
56 \r
57         protected abstract Component getParentComponent();\r
58         \r
59         protected abstract void ringBeep();\r
60 \r
61         // クラス内のイベントから呼び出されるもの\r
62         protected abstract LikeReserveList findLikeReserves(ProgDetailList tvd, String keyword, int threshold);\r
63         \r
64         \r
65         /*******************************************************************************\r
66          * 呼び出し元から引き継いだもの\r
67          ******************************************************************************/\r
68         \r
69         private final Env env = getEnv();\r
70         private final HDDRecorderList recorders = getRecorderList();\r
71         \r
72         private final AVSetting avslist = getAVSetting();\r
73         private final CHAVSetting chavslist = getCHAVSetting();\r
74         \r
75         private final StatusWindow StWin = getStWin();                  // これは起動時に作成されたまま変更されないオブジェクト\r
76         private final StatusTextArea MWin = getMWin();                  // これは起動時に作成されたまま変更されないオブジェクト\r
77         \r
78         private final Component parent = getParentComponent();  // これは起動時に作成されたまま変更されないオブジェクト\r
79         \r
80         private final GetEventId geteventid = new GetEventId(); // 番組IDの取得\r
81         \r
82         \r
83         /*******************************************************************************\r
84          * 定数\r
85          ******************************************************************************/\r
86         \r
87         // ログ関連\r
88         \r
89         private static final String MSGID = "["+getViewName()+"] ";\r
90         private static final String ERRID = "[ERROR]"+MSGID;\r
91         private static final String DBGID = "[DEBUG]"+MSGID;\r
92         \r
93         \r
94         /*******************************************************************************\r
95          * 部品\r
96          ******************************************************************************/\r
97         \r
98         // コンポーネント\r
99         \r
100         private JPanel jContentPane_rsv = null;\r
101 \r
102         private TitleEditorPanel jPane_title = null;                            // 番組設定\r
103         private RecSettingEditorPanel jPane_recsetting = null;          // 録画設定\r
104         private LikeReserveEditorPanel  jPane_likersv = null;           // 類似予約\r
105         private OverlapReserveViewPanel jPane_overlap = null;\r
106         \r
107         \r
108         /*\r
109          * その他\r
110          */\r
111         \r
112         /**\r
113          * 初期化漏れが怖いのでまとめて内部クラスとした。\r
114          */\r
115         private class Vals {\r
116                 \r
117                 // 検索した類似予約を保持する\r
118                 LikeReserveList hide_likersvlist = null;\r
119                 \r
120                 // 類似予約抽出条件(タイトル)\r
121                 String keyword = "";\r
122                 \r
123                 // 類似予約抽出条件(あいまい度)\r
124                 int threshold = 0;\r
125                 \r
126                 // 実行のON/OFFのみの更新かどうか\r
127                 boolean isUpdateOnlyExec = false;\r
128         \r
129                 // 予約する番組情報\r
130                 HDDRecorder hide_recorder = null;\r
131                 ProgDetailList hide_tvd = null;\r
132                 AVs hide_avs = null;\r
133                 \r
134                 // 録画設定の選択イベントにより設定される値\r
135                 HDDRecorder selected_recorder = null;\r
136         }\r
137         \r
138         private Vals vals = null;\r
139         \r
140         /**\r
141          * 予約操作が成功したかどうかを返す。\r
142          */\r
143         public boolean isSucceededReserve() { return doneReserve; }\r
144 \r
145         private boolean doneReserve = false;\r
146 \r
147         \r
148         /*******************************************************************************\r
149          * コンストラクタ\r
150          ******************************************************************************/\r
151         \r
152         public AbsReserveDialog(int x, int y) {\r
153                 \r
154                 super();\r
155                 \r
156                 setModal(true);\r
157                 setContentPane(getJContentPane_rsv());\r
158                 \r
159                 // タイトルバーの高さも考慮する必要がある\r
160                 Dimension d = getJContentPane_rsv().getPreferredSize();\r
161                 pack();\r
162                 setBounds(\r
163                                 x,\r
164                                 y,\r
165                                 d.width+(this.getInsets().left+this.getInsets().right),\r
166                                 d.height+(this.getInsets().top+this.getInsets().bottom));\r
167                 setResizable(false);\r
168                 \r
169                 setTitle(getViewName());\r
170                 \r
171                 // とりあえず起動時のみ設定可能\r
172                 jPane_recsetting.setDebug(env.getDebug());\r
173                 \r
174                 addWindowListener(wl_opened);\r
175         }\r
176         \r
177         \r
178         /*******************************************************************************\r
179          * ダイアログオープン\r
180          ******************************************************************************/\r
181 \r
182         /***************************************\r
183          * 番組情報からのオープン2種+α\r
184          **************************************/\r
185         \r
186         /**\r
187          * 類似予約抽出条件なしオープン\r
188          * @see #doSelectLikeReserve(int)\r
189          */\r
190         public boolean open(ProgDetailList tvd) {\r
191                 return open(tvd,null,0);\r
192         }\r
193         \r
194         /**\r
195          *  類似予約抽出条件ありオープン\r
196          * @see #doSelectLikeReserve(int)\r
197          */\r
198         public boolean open(ProgDetailList tvd, String keywordVal, int thresholdVal) {\r
199                 \r
200                 // 予約は行われてないよー\r
201                 doneReserve = false;\r
202                 \r
203                 if (recorders.size() == 0) {\r
204                         return false;   // レコーダがひとつもないのはやばい\r
205                 }\r
206                 if (tvd.start.equals("")) {\r
207                         return false;   // これは「番組情報がありません」だろう\r
208                 }\r
209                 \r
210                 // 初期パラメータの保存場所\r
211                 if (vals == null) vals = new Vals();\r
212                 \r
213                 // 選択中のレコーダ\r
214                 String myself = getSelectedMySelf();                            // ツールバーで選択されているのはどれかな?\r
215                 HDDRecorder myrec = getSelectedRecorderList().get(0);   // 先頭を選んでおけばおけ\r
216                 \r
217                 vals.hide_recorder = myrec;     // 隠しパラメータ\r
218                 vals.hide_tvd = tvd;            // 隠しパラメータ\r
219                 \r
220                 // ダイアログオープン時に自動で取得する\r
221                 if ( env.getAutoEventIdComplete() ) {\r
222                         tvd.progid = getEventIdOnOpen(tvd);\r
223                 }\r
224                 \r
225                 // 類似予約抽出条件\r
226                 if ( thresholdVal > 0 ) {\r
227                         vals.keyword = keywordVal;              // 隠しパラメータ\r
228                         vals.threshold = thresholdVal;  // 隠しパラメータ\r
229                 }\r
230 \r
231                 // 類似予約情報\r
232                 ReserveList myrsv = null;\r
233                 int myrsvidx = -1;\r
234                 LikeReserveList likersvlist = findLikeReserves(tvd, vals.keyword, vals.threshold);      // 類似予約リストの作成\r
235                 if ( env.getGivePriorityToReserved() ) {\r
236                         // 類似予約が優先される\r
237                         LikeReserveItem likersv = findClosestLikeReserve(likersvlist, myself);          // 類似予約の絞り込み\r
238                         if ( likersv != null ) {\r
239                                 myrsvidx = likersvlist.getClosestIndex();\r
240                                 myrsv = likersv.getRsv();\r
241                                 myrec = likersv.getRec();\r
242                         }\r
243                 }\r
244                 \r
245                 vals.hide_likersvlist = likersvlist;    // 隠しパラメータ\r
246                 \r
247                 // ジャンル別AV設定の確認(該当するものがあれば)\r
248                 AVs myavs = null;\r
249                 if ( myrsv == null ) {\r
250                         // 類似予約がないか、あっても優先されない場合\r
251                         myavs = findAVs(tvd.genre.toString(), tvd.center, myrec.getRecorderId());\r
252                 }\r
253                 else {\r
254                         MWin.appendMessage(MSGID+"画質・音質を類似予約から継承します.");\r
255                 }\r
256                 \r
257                 vals.hide_avs = myavs;  // 隠しパラメータ\r
258 \r
259                 // 類似予約リストのアイテム設定\r
260                 setLikeRsvItems(likersvlist);\r
261                 \r
262                 // 初期値の選択\r
263                 if ( env.getGivePriorityToReserved() && myrsv != null ) {\r
264                         // それっぽい類似予約を選択する\r
265                         jPane_likersv.setRowSelection(myrsvidx);\r
266                 }\r
267                 else {\r
268                         // 番組情報から選択する\r
269                         jPane_likersv.setRowSelection(LikeReserveEditorPanel.LIKERSVTABLE_NONE);\r
270                 }\r
271                 \r
272                 return true;\r
273         }\r
274         \r
275         /**\r
276          * 隣接予約の編集\r
277          */\r
278         public boolean open(ProgDetailList tvd, LikeReserveItem likersv) {\r
279                 \r
280                 // 予約は行われてないよー\r
281                 doneReserve = false;\r
282                 \r
283                 if (recorders.size() == 0) {\r
284                         return false;   // レコーダがひとつもないのはやばい\r
285                 }\r
286                 if (tvd.start.equals("")) {\r
287                         return false;   // これは「番組情報がありません」だろう\r
288                 }\r
289                 \r
290                 // 初期パラメータの保存場所\r
291                 if (vals == null) vals = new Vals();\r
292                 \r
293                 // 選択中のレコーダ\r
294                 HDDRecorder myrec = likersv.getRec();\r
295 //              String myself = myrec.Myself();\r
296                 \r
297                 vals.hide_recorder = myrec;     // 隠しパラメータ\r
298                 vals.hide_tvd = tvd;            // 隠しパラメータ\r
299                 \r
300                 // ダイアログオープン時に自動で取得する\r
301                 if ( env.getAutoEventIdComplete() ) {\r
302                         tvd.progid = getEventIdOnOpen(tvd);\r
303                 }\r
304                 \r
305                 LikeReserveList likersvlist = new LikeReserveList();\r
306                 likersvlist.add(likersv);\r
307                 \r
308                 vals.hide_likersvlist = likersvlist;    // 隠しパラメータ\r
309                 \r
310                 MWin.appendMessage(MSGID+"画質・音質を類似予約から継承します.");\r
311                 \r
312                 // 類似予約リストのアイテム設定\r
313                 setLikeRsvItems(likersvlist);\r
314                 \r
315                 // 初期値の選択(類似予約の一個目を選択)\r
316                 jPane_likersv.setRowSelection(LikeReserveEditorPanel.LIKERSVTABLE_DEFAULT);\r
317                 \r
318                 // 番組情報は番組情報から得た情報を優先する ←変な日本語\r
319                 jPane_title.setSelectedValues(tvd);\r
320                 \r
321                 // 各コンポーネントの強制状態変更\r
322                 jPane_title.setEnabledRecordButton(false);      // 新規ボタンは操作不能に\r
323                 jPane_likersv.setEnabledTable(false);           // 類似予約は選択不能に\r
324                 \r
325                 return true;\r
326         }\r
327         \r
328         /***************************************\r
329          * 予約情報からのオープン1種\r
330          **************************************/\r
331         \r
332         /**\r
333          * 実行のON/OFFだけしか操作しない場合に呼び出す(画面にウィンドウは表示しない)\r
334          * ※これがあるので、各openでは vals != null チェックの必要がある\r
335          */\r
336         public boolean open(String myself, String rsvId) {\r
337                 \r
338                 return open(myself, rsvId, null);\r
339                 \r
340         }\r
341         \r
342         /**\r
343          * 本体予約一覧からのオープン、または予約ON/OFFメニュー\r
344          * @see #doSelectLikeReserve(int)\r
345          */\r
346         public boolean open(String myself, String rsvId, Boolean onlyupdateexec) {\r
347                 \r
348                 // 予約は行われてないよー\r
349                 doneReserve = false;\r
350                 \r
351                 HDDRecorderList myrecs = recorders.findInstance(myself);\r
352                 if ( myrecs.size() == 0 ) {\r
353                         return false;   // ここに来たらバグ\r
354                 }\r
355                 HDDRecorder myrec = myrecs.get(0);\r
356 \r
357                 ReserveList myrsv = myrec.getReserveList(rsvId);\r
358                 if ( myrsv == null ) {\r
359                         MWin.appendMessage(ERRID+"更新すべき予約情報が見つかりません: "+myself+", "+rsvId);\r
360                         ringBeep();\r
361                         return false;   // ここに来たらバグ\r
362                 }\r
363                 if ( myrsv.getCh_name() == null ) {\r
364                         MWin.appendMessage(ERRID+"予約情報の放送局名が不正です: "+myrsv.getStartDateTime()+", "+myrsv.getTitle());\r
365                         ringBeep();\r
366                         return false;\r
367                 }\r
368 \r
369                 // 初期パラメータの保存場所\r
370                 if (vals == null) vals = new Vals();\r
371                 \r
372                 // 予約情報から番組情報を組み立てる\r
373                 ProgDetailList tvd = getProgDetails(myrsv);\r
374                 \r
375                 vals.hide_recorder = myrec;     // 隠しパラメータ\r
376                 vals.hide_tvd = tvd;            // 隠しパラメータ\r
377 \r
378                 // 予約情報(類似予約の一個目として設定)\r
379                 LikeReserveList likersvlist = new LikeReserveList();\r
380                 likersvlist.add(new LikeReserveItem(myrec, myrsv, 0));\r
381                 \r
382                 vals.hide_likersvlist = likersvlist;    // 隠しパラメータ\r
383                 \r
384                 // 類似予約リストのアイテム設定\r
385                 setLikeRsvItems(likersvlist);\r
386                 \r
387                 // 初期値の選択(類似予約の一個目を選択)\r
388                 jPane_likersv.setRowSelection(LikeReserveEditorPanel.LIKERSVTABLE_DEFAULT);\r
389 \r
390                 // 各コンポーネントの強制状態変更\r
391                 jPane_title.setEnabledRecordButton(false);      // 新規ボタンは操作不能に\r
392                 jPane_likersv.setEnabledTable(false);           // 類似予約は選択不能に\r
393                 \r
394                 /*\r
395                  *  予約ON・OFFのみの実行かなー?\r
396                  */\r
397                 if ( onlyupdateexec != null ) {\r
398                         vals.isUpdateOnlyExec = true;\r
399                         jPane_recsetting.setExecValue(onlyupdateexec);\r
400                 }\r
401                 \r
402                 return true;\r
403         }\r
404         \r
405         /***************************************\r
406          * オープン用部品\r
407          **************************************/\r
408         \r
409         /**\r
410          * 類似予約リストの取得\r
411          */\r
412         private LikeReserveItem findClosestLikeReserve(LikeReserveList lrl, String myself) {\r
413                 \r
414                 if ( lrl.size() == 0 ) {\r
415                         // 類似予約がない\r
416                         return null;\r
417                 }\r
418                 \r
419                 LikeReserveItem lr = lrl.getClosest(myself);\r
420                 if ( lr == null ) {\r
421                         // 類似予約があってもコンボボックスで選択したレコーダのものがない\r
422                         if (debug) System.out.println(DBGID+"類似予約に選択中のレコーダのものはなかった: "+myself);\r
423                         return null;\r
424                 }\r
425                 \r
426                 // 選択中のレコーダの類似予約があった\r
427                 return lr;\r
428         }\r
429         \r
430         /**\r
431          * ジャンル別AV設定の取得\r
432          */\r
433         private AVs findAVs(String key_genre, String key_webChName, String recId) {\r
434                 \r
435                 String selected_key = key_genre;\r
436                 AVSetting xavslist = avslist;\r
437                 if ( env.getEnableCHAVsetting() ) {\r
438                         selected_key = key_webChName;\r
439                         xavslist = chavslist;\r
440                 }\r
441                 \r
442                 AVs myavs = xavslist.getSelectedAVs(selected_key, recId);\r
443                 if ( myavs != null ) {\r
444                         if ( myavs.getGenre() != null ) {\r
445                                 MWin.appendMessage(MSGID+"画質・音質を自動設定します: "+recId+" & "+myavs.getGenre());\r
446                         }\r
447                         else {\r
448                                 MWin.appendMessage(MSGID+"画質・音質にデフォルト設定を適用します: "+recId);\r
449                         }\r
450                 }\r
451                 else {\r
452                         MWin.appendMessage(MSGID+"画質・音質の自動設定候補がありません: "+recId+" & "+selected_key);\r
453                 }\r
454                 \r
455                 return myavs;\r
456         }\r
457         \r
458         /**\r
459          * 番組情報から予約情報を生成する\r
460          */\r
461         private ReserveList getReserveList(HDDRecorder recorder, ProgDetailList tvd, TimeVal tVal, String enc) {\r
462                 \r
463                 ReserveList r = new ReserveList();\r
464                 \r
465                 // 開始・終了時刻\r
466                 if ( tvd != null ) {\r
467                         r.setTitle(tvd.title);\r
468                         r.setCh_name(tvd.center);\r
469                         GregorianCalendar ca = CommonUtils.getCalendar(tVal!=null ? tVal.startDateTime : tvd.startDateTime);\r
470                         GregorianCalendar cz = CommonUtils.getCalendar(tVal!=null ? tVal.endDateTime : tvd.endDateTime);\r
471                         r.setAhh(String.format("%02d",ca.get(Calendar.HOUR_OF_DAY)));\r
472                         r.setAmm(String.format("%02d",ca.get(Calendar.MINUTE)));\r
473                         r.setZhh(String.format("%02d",cz.get(Calendar.HOUR_OF_DAY)));\r
474                         r.setZmm(String.format("%02d",cz.get(Calendar.MINUTE)));\r
475                 }\r
476                 \r
477                 // チューナー\r
478                 r.setTuner(enc);\r
479                 \r
480                 // 画質・音質\r
481                 r.setRec_mode(getDefaultText(recorder, recorder.getVideoRateList()));\r
482                 r.setRec_audio(getDefaultText(recorder, recorder.getAudioRateList()));\r
483                 r.setRec_folder(getDefaultText(recorder, recorder.getFolderList()));\r
484 \r
485                 r.setRec_dvdcompat(getDefaultText(recorder, recorder.getDVDCompatList()));\r
486                 r.setRec_device(getDefaultText(recorder, recorder.getDeviceList()));\r
487                 \r
488                 // 自動チャプタ関連\r
489                 r.setRec_xchapter(getDefaultText(recorder, recorder.getXChapter()));\r
490                 r.setRec_mschapter(getDefaultText(recorder, recorder.getMsChapter()));\r
491                 r.setRec_mvchapter(getDefaultText(recorder, recorder.getMvChapter()));\r
492                 \r
493                 // その他\r
494                 r.setRec_aspect(getDefaultText(recorder, recorder.getAspect()));\r
495                 r.setRec_bvperf(getDefaultText(recorder, recorder.getBVperf()));\r
496                 r.setRec_lvoice(getDefaultText(recorder, recorder.getLVoice()));\r
497                 r.setRec_autodel(getDefaultText(recorder, recorder.getAutodel()));\r
498                 \r
499                 r.setExec(true);\r
500                 \r
501                 return r;\r
502         }\r
503         \r
504         private String getDefaultText(HDDRecorder myrec, ArrayList<TextValueSet> tvs) {\r
505                 TextValueSet t = myrec.getDefaultSet(tvs);\r
506                 if ( t != null ) {\r
507                         return t.getText();\r
508                 }\r
509                 if ( tvs.size() > 0 ) {\r
510                         return tvs.get(0).getText();\r
511                 }\r
512                 return null;\r
513         }\r
514         \r
515         /**\r
516          * 予約情報から番組情報を生成する\r
517          */\r
518         private ProgDetailList getProgDetails(ReserveList myrsv) {\r
519                 \r
520                 ProgDetailList tvd = new ProgDetailList();\r
521                 \r
522                 tvd.title = myrsv.getTitle();\r
523                 tvd.detail = myrsv.getDetail();\r
524                 \r
525                 tvd.center = myrsv.getCh_name();\r
526                 \r
527                 {\r
528                         String nextdate = CommonUtils.getNextDate(myrsv);\r
529                         GregorianCalendar ca = CommonUtils.getCalendar(nextdate);\r
530                         \r
531                         ca.add(Calendar.HOUR_OF_DAY, Integer.valueOf(myrsv.getAhh())-ca.get(Calendar.HOUR_OF_DAY));\r
532                         ca.add(Calendar.MINUTE, Integer.valueOf(myrsv.getAmm())-ca.get(Calendar.MINUTE));\r
533                         tvd.startDateTime = CommonUtils.getDateTime(ca);\r
534                         tvd.start = CommonUtils.getTime(ca);\r
535 \r
536                         ca.add(Calendar.MINUTE, Integer.valueOf(myrsv.getRec_min()));\r
537                         tvd.endDateTime = CommonUtils.getDateTime(ca);\r
538                         tvd.end = CommonUtils.getTime(ca);\r
539                 }\r
540                 \r
541                 tvd.progid = myrsv.getContentId();\r
542                 \r
543                 tvd.genre = ProgGenre.get(myrsv.getRec_genre());\r
544                 tvd.subgenre = ProgSubgenre.get(tvd.genre,myrsv.getRec_subgenre());\r
545                 \r
546                 // 特殊\r
547                 tvd.accurateDate = null;\r
548                 tvd.dontoverlapdown = true;\r
549                 \r
550                 return tvd;\r
551         }\r
552         \r
553         /***************************************\r
554          * 番組情報部の設定\r
555          **************************************/\r
556         \r
557         private TimeVal setTitleItems(HDDRecorder myrec, ProgDetailList tvd, LikeReserveList lrl, boolean atrsvlst) {\r
558                 \r
559                 jPane_title.setContentIdValue(tvd.progid, ! atrsvlst);\r
560                 jPane_title.setTitleItems(tvd, lrl, env.getUseAutocomplete());\r
561                 jPane_title.setChItem(myrec, tvd);\r
562                 \r
563                 TimeVal tVal = getTimeValue(tvd);\r
564                 jPane_title.setTimeValue(tVal);\r
565                 jPane_title.setDateItems(tvd, tVal);\r
566                 \r
567                 return tVal;\r
568         }\r
569         \r
570         /***************************************\r
571          * 録画設定部の設定\r
572          **************************************/\r
573         \r
574         private void setRecSettingItems(HDDRecorderList reclst, HDDRecorder myrec, ProgDetailList tvd) {\r
575                 \r
576                 jPane_recsetting.setLabels(myrec);                                      // 項目ラベル\r
577                 jPane_recsetting.setFixedItems(reclst);                         // 固定アイテム\r
578                 jPane_recsetting.setFlexItems(myrec,tvd.center);        // 可変アイテム\r
579         }\r
580         \r
581         /***************************************\r
582          * 類似予約部の設定\r
583          **************************************/\r
584         \r
585         private void setLikeRsvItems(LikeReserveList lrl) {\r
586                 jPane_likersv.setListItems(lrl);\r
587         }\r
588         \r
589         \r
590         /*******************************************************************************\r
591          * ほげほげ\r
592          ******************************************************************************/\r
593         \r
594         /**\r
595          * 延長警告などを加味した録画開始・終了日時を算出する\r
596          */\r
597         private TimeVal getTimeValue(ProgDetailList tvd) {\r
598                 \r
599                 TimeVal tVal = new TimeVal();\r
600                 \r
601                 GregorianCalendar ca = CommonUtils.getCalendar(tvd.startDateTime);\r
602                 GregorianCalendar cz = CommonUtils.getCalendar(tvd.endDateTime);\r
603                 \r
604                 if ( tvd.accurateDate != null ) {\r
605                         // のりしろ処理(開始時刻)\r
606                         if ( env.getOverlapUp() ) {\r
607                                 // 開始1分前倒し\r
608                                 ca.add(Calendar.MINUTE, -1);\r
609                                 \r
610                                 tVal.margined = true;\r
611                         }\r
612                         \r
613                         // のりしろ処理(終了時刻)\r
614                         if ( env.getOverlapDown() ) {\r
615                                 // 終了1分延長\r
616                                 cz.add(Calendar.MINUTE, +1);\r
617                         }\r
618                         else if (\r
619                                         env.getOverlapDown2() &&\r
620                                         ! tvd.dontoverlapdown &&                        // NHKは縮めない\r
621                                         ! (env.getNoOverlapDown2Sp() && tvd.option.contains(ProgOption.SPECIAL))        // OVAとかは縮めない \r
622                                         ) {\r
623                                 // 終了1分前倒し\r
624                                 cz.add(Calendar.MINUTE, -1);\r
625                                 \r
626                                 tVal.clipped = true;\r
627                         }\r
628                         \r
629                         // 延長警告処理\r
630                         int spoexlen = Integer.valueOf(env.getSpoexLength());\r
631                         if ( tvd.extension == true && spoexlen > 0 ) {\r
632                                 // 指定時間分延長\r
633                                 cz.add(Calendar.MINUTE, +spoexlen);\r
634                                 \r
635                                 tVal.spoex = true;\r
636                                 tVal.spoexlen = spoexlen;\r
637                         }\r
638                 }\r
639                 \r
640                 tVal.date = CommonUtils.getDate(ca);\r
641                 \r
642                 tVal.ahh = ca.get(Calendar.HOUR_OF_DAY);\r
643                 tVal.amm = ca.get(Calendar.MINUTE);\r
644                 tVal.zhh = cz.get(Calendar.HOUR_OF_DAY);\r
645                 tVal.zmm = cz.get(Calendar.MINUTE);\r
646                 \r
647                 tVal.startDateTime = CommonUtils.getDateTime(ca);\r
648                 tVal.endDateTime = CommonUtils.getDateTime(cz);\r
649 \r
650                 return tVal;\r
651         }\r
652         \r
653         \r
654         /*******************************************************************************\r
655          * ネットから番組IDを取得する\r
656          ******************************************************************************/\r
657         \r
658         /**\r
659          * ダイアログオープン時の番組ID取得処理\r
660          */\r
661         private String getEventIdOnOpen(ProgDetailList tvd) {\r
662                 \r
663                 if (debug) System.err.println(DBGID+"ダイアログ表示時の自動番組ID取得 id=\""+tvd.progid+"\"");\r
664                 \r
665                 if ( ContentIdEDCB.isValid(tvd.progid) ) {\r
666                         if (debug) System.err.println(DBGID+"番組ID取得済み");\r
667                         return tvd.progid;\r
668                 }\r
669                 if ( ! env.getAutoEventIdComplete() ) {\r
670                         if (debug) System.err.println(DBGID+"番組ID自動取得OFF");\r
671                         return tvd.progid;      // 有効な値かもしれないし、nullかもしれない\r
672                 }\r
673                 \r
674                 // キャッシュに情報を持っていないか探す\r
675                 String content_id = getContentId(tvd, false);\r
676                 if ( content_id != null ) {\r
677                         if (debug) System.err.println(DBGID+"番組IDキャッシュ有効");\r
678                         return content_id;\r
679                 }\r
680                 \r
681                 // ネットに探しに行く\r
682                 return doGetEventId();\r
683         }\r
684         \r
685 \r
686         /*******************************************************************************\r
687          * 自動エンコーダ選択と裏番組抽出\r
688          ******************************************************************************/\r
689 \r
690         /**\r
691          * これはグラフで描画するようになるまでの仮置き\r
692          * @param urabanlist\r
693          */\r
694         private void showUrabanList(ReserveList myrsv, ArrayList<ReserveList> urabanlist) {\r
695                 \r
696                 jPane_overlap.putOverlap(myrsv, urabanlist);\r
697                 \r
698                 if ( ! debug ) {\r
699                         return;\r
700                 }\r
701                 \r
702                 if ( urabanlist == null ) {\r
703                         return;\r
704                 }\r
705                 String MID = MSGID+"[裏番組チェック] ";\r
706                 System.out.println(MID+"----------");\r
707                 if ( urabanlist.size() > 0 ) {\r
708                         for ( ReserveList ura : urabanlist ) {\r
709                                 System.out.println(String.format("%s裏番組あり: %s:%s-%s:%s, %-10s, %-12s, %s", MID, ura.getAhh(), ura.getAmm(), ura.getZhh(), ura.getZmm(), ura.getTuner(), ura.getCh_name(), ura.getTitle()));\r
710                         }\r
711                 }\r
712                 else {\r
713                         // 裏番組がない場合に分かりにくかったので追加\r
714                         System.out.println(MID+"裏番組はありません");\r
715                 }\r
716         }\r
717         \r
718         \r
719         /*******************************************************************************\r
720          * リスナー\r
721          ******************************************************************************/\r
722         \r
723         /**\r
724          * ダイアログを開いたときは\r
725          */\r
726         private final WindowListener wl_opened = new WindowAdapter() {\r
727                 @Override\r
728                 public void windowClosing(WindowEvent e) {\r
729                         \r
730                         if (debug) System.out.println(DBGID+"wl_opened/windowClosing "+((vals!=null)?(vals.toString()):("")));\r
731                         \r
732                         resetWhenWindowClosed();\r
733                         \r
734                         ((AbsReserveDialog) e.getSource()).dispose();\r
735                 }\r
736                 \r
737                 @Override\r
738                 public void windowOpened(WindowEvent e) {\r
739                         if (debug) System.out.println(DBGID+"wl_opened/windowOpened");\r
740                         // 開いたときは、タイトル入力エリアにフォーカスを移します\r
741 //                      jComboBox_title.requestFocusInWindow();\r
742                 }\r
743         };\r
744         \r
745         private void resetWhenWindowClosed() {\r
746                 \r
747                 if (debug) System.out.println(DBGID+"resetWhenWindowClosed "+((vals!=null)?(vals.toString()):("")));\r
748                 \r
749                 if (vals == null) return;\r
750                 \r
751                 // リセット\r
752                 vals = null;\r
753         }\r
754         \r
755         \r
756         /*******************************************************************************\r
757          * コンポーネント\r
758          ******************************************************************************/\r
759         \r
760         private JPanel getJContentPane_rsv() {\r
761                 if (jContentPane_rsv == null) {\r
762                         jContentPane_rsv = new JPanel();\r
763                         \r
764                         jContentPane_rsv.setLayout(new BorderLayout());\r
765 \r
766                         JPanel panel = new JPanel();\r
767                         panel.setLayout(new BorderLayout());\r
768                         jContentPane_rsv.add(panel,BorderLayout.CENTER);\r
769                         jContentPane_rsv.add(getJPane_overlap(),BorderLayout.EAST);\r
770                         \r
771                         panel.add(getJPane_title(),BorderLayout.NORTH);\r
772                         panel.add(getJPane_recsetting(),BorderLayout.CENTER);\r
773                         panel.add(getJPane_likersv(),BorderLayout.SOUTH);\r
774                 }\r
775                 return jContentPane_rsv;\r
776         }\r
777         \r
778         /**\r
779          * 番組情報のエリア\r
780          */\r
781         private JPanel getJPane_title() {\r
782                 if ( jPane_title == null ) {\r
783                         jPane_title = new TitleEditorPanel();\r
784                         \r
785                         jPane_title.setRecordExecuter(this);    // 予約実行ボタン押下時のコールバックの設定\r
786                 }\r
787                 return jPane_title;\r
788         }\r
789         \r
790         /**\r
791          * 録画設定のエリア\r
792          */\r
793         private JPanel getJPane_recsetting() {\r
794                 if ( jPane_recsetting == null ) {\r
795                         jPane_recsetting = new RecSettingEditorPanel();\r
796                         \r
797                         jPane_recsetting.setRecSettingSelector(this);   // アイテム選択時のコールバックの設定\r
798                 }\r
799                 return jPane_recsetting;\r
800         }\r
801 \r
802         /**\r
803          * 類似予約のエリア\r
804          */\r
805         private JScrollPane getJPane_likersv() {\r
806                 if ( jPane_likersv == null ) {\r
807                         jPane_likersv = new LikeReserveEditorPanel();\r
808                         \r
809                         jPane_likersv.setLikeReserveSelector(this);     // 予約実行ボタン押下時のコールバックの設定\r
810                 }\r
811                 return jPane_likersv;\r
812         }\r
813         \r
814         /**\r
815          * 重複予約のエリア\r
816          */\r
817         private JScrollPane getJPane_overlap() {\r
818                 if ( jPane_overlap == null ) {\r
819                         jPane_overlap = new OverlapReserveViewPanel();\r
820                         jPane_overlap.setBorder(new LineBorder(Color.BLACK));\r
821                 }\r
822                 return jPane_overlap;\r
823         }\r
824         \r
825         /*******************************************************************************\r
826          * ハンドラ―メソッドの実装\r
827          ******************************************************************************/\r
828         \r
829         /**\r
830          * ツールバーでレコーダの選択イベントが発生\r
831          */\r
832         @Override\r
833         public void valueChanged(HDDRecorderSelectionEvent e) {\r
834                 if (debug) System.out.println(DBGID+"recorder selection rised");\r
835                 \r
836                 // 選択中のレコーダ情報を保存する\r
837                 src_recsel = (HDDRecorderSelectable) e.getSource();\r
838         }\r
839         \r
840         /**\r
841          * ツールバーの操作によって選択されたレコーダのIDを取得する\r
842          */\r
843         private String getSelectedMySelf() {\r
844                 return ( src_recsel!=null ? src_recsel.getSelectedMySelf() : null );\r
845         }\r
846         \r
847         /**\r
848          * ツールバーの操作によって選択されたレコーダのプラグインインスタンスリストを取得する\r
849          */\r
850         private HDDRecorderList getSelectedRecorderList() {\r
851                 return ( src_recsel!=null ? src_recsel.getSelectedList() : null );\r
852         }\r
853         \r
854         private HDDRecorderSelectable src_recsel;\r
855         \r
856         \r
857         /**\r
858          * ツールバーでレコーダ情報の変更イベントが発生\r
859          */\r
860         @Override\r
861         public void stateChanged(HDDRecorderChangeEvent e) {\r
862                 // 処理はいらんな…\r
863         }\r
864         \r
865         \r
866         /*******************************************************************************\r
867          * コールバックメソッドの実装(番組情報)\r
868          ******************************************************************************/\r
869 \r
870         /***************************************\r
871          * 予約ボタンが押された時の処理\r
872          **************************************/\r
873 \r
874         /**\r
875          * 新規登録を行う\r
876          */\r
877         @Override\r
878         public void doRecord() {\r
879                 \r
880                 if (debug) System.out.println(DBGID+"doRecord "+vals.toString());\r
881                 \r
882                 // 新規処理\r
883                 final ReserveList newRsv = new ReserveList();\r
884                 \r
885                 jPane_title.getSelectedValues(newRsv);                  // タイトル\r
886                 jPane_recsetting.getSelectedValues(newRsv);             // 録画設定\r
887                 \r
888                 if ( newRsv.getRec_audio() == HDDRecorder.ITEM_REC_TYPE_EPG &&\r
889                                 (newRsv.getContentId() == null || newRsv.getContentId().length() == 0) ) {\r
890                         ringBeep();\r
891                         JOptionPane.showConfirmDialog(this, "EPG予約では番組IDが必要になります。", "警告", JOptionPane.CLOSED_OPTION);\r
892                         return;\r
893                 }\r
894                 \r
895                 newRsv.setId(null);                                                             // PostRdEntry()中で取得するのでここはダミー\r
896                 newRsv.setUpdateOnlyExec(false);                                // 新規ONLYなのでfalse固定\r
897 \r
898                 final HDDRecorder recorder = vals.selected_recorder;\r
899                 \r
900                 // 予約実行\r
901                 StWin.clear();\r
902                 new SwingBackgroundWorker(false) {\r
903                         \r
904                         @Override\r
905                         protected Object doWorks() throws Exception {\r
906                                 \r
907                                 StWin.appendMessage(MSGID+"予約を登録します:"+newRsv.getTitle());\r
908                                 \r
909                                 if ( recorder.PostRdEntry(newRsv) ) {\r
910                                         \r
911                                         MWin.appendMessage(MSGID+"正常に登録できました:"+newRsv.getTitle()+"("+newRsv.getCh_name()+")");\r
912                                         doneReserve = true;\r
913                                         \r
914                                         // カレンダーに登録する\r
915                                         if ( recorder.getUseCalendar() && newRsv.getExec() ) {\r
916                                                 \r
917                                                 for ( HDDRecorder calendar : recorders.findInstance(RecType.CALENDAR) ) {\r
918                                                         \r
919                                                         StWin.appendMessage(MSGID+"カレンダーに予約情報を登録します");\r
920                                                         \r
921                                                         if ( ! calendar.PostRdEntry(newRsv)) {\r
922                                                                 MWin.appendError(ERRID+"[カレンダー] "+calendar.getErrmsg());\r
923                                                                 ringBeep();\r
924                                                         }\r
925                                                 }\r
926                                         }\r
927                                 }\r
928                                 else {\r
929                                         MWin.appendError(ERRID+"登録に失敗しました:"+newRsv.getTitle()+"("+newRsv.getCh_name()+")");\r
930                                 }\r
931                                 \r
932                                 if ( ! recorder.getErrmsg().equals("")) {\r
933                                         MWin.appendMessage(MSGID+"[追加情報] "+recorder.getErrmsg());\r
934                                         ringBeep();\r
935                                 }\r
936                                         \r
937                                 return null;\r
938                         }\r
939                         \r
940                         @Override\r
941                         protected void doFinally() {\r
942                                 //CommonUtils.milSleep(0);\r
943                                 StWin.setVisible(false);\r
944                         }\r
945                 }.execute();\r
946                 \r
947                 CommonSwingUtils.setLocationCenter(parent, (Component)StWin);\r
948                 StWin.setVisible(true);\r
949                 \r
950                 resetWhenWindowClosed();\r
951                 dispose();\r
952         }\r
953         \r
954         /**\r
955          * 更新を行う\r
956          */\r
957         @Override\r
958         public void doUpdate() {\r
959                 \r
960                 if (debug) System.out.println(DBGID+"doUpdate "+vals.toString());\r
961                 \r
962                 LikeReserveItem likersv = vals.hide_likersvlist.getSelected();\r
963                 if ( likersv == null ) {\r
964                         // ==0なら更新対象の予約情報がないっつーことで処理できない\r
965                         return;\r
966                 }\r
967                 \r
968                 // 更新処理\r
969                 final ReserveList oldRsv = likersv.getRsv();\r
970                 final ReserveList newRsv = oldRsv.clone();\r
971                 final HDDRecorder recorder = likersv.getRec();\r
972 \r
973                 jPane_title.getSelectedValues(newRsv);                          // タイトル\r
974                 jPane_recsetting.getSelectedValues(newRsv);                     // 録画設定\r
975                 \r
976                 if ( (newRsv.getRec_audio() == HDDRecorder.ITEM_REC_TYPE_EPG || newRsv.getRec_audio() == HDDRecorder.ITEM_REC_TYPE_PROG) &&\r
977                                 (newRsv.getRec_audio() != oldRsv.getRec_audio()) ) {\r
978                         ringBeep();\r
979                         JOptionPane.showConfirmDialog(this, String.format("%s予約を%s予約には変更できません。",oldRsv.getRec_audio(),newRsv.getRec_audio()), "警告", JOptionPane.CLOSED_OPTION);\r
980                         return;\r
981                 }\r
982                 \r
983                 newRsv.setId(oldRsv.getId());                                           // 更新では引き継ぐ\r
984                 newRsv.setUpdateOnlyExec(vals.isUpdateOnlyExec);        // 実行ON・OFFのみかもしんない\r
985 \r
986                 // 更新実行\r
987                 StWin.clear();\r
988                 new SwingBackgroundWorker(false) {\r
989                         \r
990                         @Override\r
991                         protected Object doWorks() throws Exception {\r
992                                 \r
993                                 StWin.appendMessage(MSGID+"予約を更新します:"+newRsv.getTitle());\r
994                                 \r
995                                 if ( recorder.UpdateRdEntry(oldRsv, newRsv) ) {\r
996                                         \r
997                                         // 成功したよ\r
998                                         MWin.appendMessage(MSGID+"正常に更新できました:"+oldRsv.getTitle()+"("+oldRsv.getCh_name()+")");\r
999                                         doneReserve = true;\r
1000                                         \r
1001                                         // カレンダーを更新する\r
1002                                         if ( recorder.getUseCalendar() ) {\r
1003                                                 for ( HDDRecorder calendar : recorders.findInstance(RecType.CALENDAR) ) {\r
1004                                                         \r
1005                                                         StWin.appendMessage(MSGID+"カレンダーの予約情報を更新します");\r
1006                                                         \r
1007                                                         if ( ! calendar.UpdateRdEntry(oldRsv, (newRsv.getExec())?(newRsv):(null))) {\r
1008                                                                 MWin.appendError(ERRID+"[カレンダー] "+calendar.getErrmsg());\r
1009                                                                 ringBeep();\r
1010                                                         }\r
1011                                                 }\r
1012                                         }\r
1013                                 }\r
1014                                 else {\r
1015                                         MWin.appendError(ERRID+"更新に失敗しました:"+oldRsv.getTitle()+"("+oldRsv.getCh_name()+")");\r
1016                                 }\r
1017                                 \r
1018                                 if ( ! recorder.getErrmsg().equals("")) {\r
1019                                         MWin.appendMessage(MSGID+"[追加情報] "+recorder.getErrmsg());\r
1020                                         ringBeep();\r
1021                                 }\r
1022                                 return null;\r
1023                         }\r
1024                         \r
1025                         @Override\r
1026                         protected void doFinally() {\r
1027                                 StWin.setVisible(false);\r
1028                         }\r
1029                 }.execute();\r
1030 \r
1031                 StWin.setVisible(true);\r
1032 \r
1033                 resetWhenWindowClosed();\r
1034                 dispose();\r
1035         }\r
1036         \r
1037         /**\r
1038          * ダイアログを閉じる\r
1039          */\r
1040         @Override\r
1041         public void doCancel() {\r
1042                 resetWhenWindowClosed();\r
1043                 dispose();\r
1044         }\r
1045 \r
1046         /***************************************\r
1047          * 番組ID取得ボタンが押された時の処理\r
1048          **************************************/\r
1049 \r
1050         /**\r
1051          * 番組IDを取得する\r
1052          */\r
1053         public String doGetEventId() {\r
1054                 \r
1055                 final ProgDetailList tvd = vals.hide_tvd;\r
1056                 \r
1057                 StWin.clear();\r
1058                 \r
1059                 new SwingBackgroundWorker(false) {\r
1060                         \r
1061                         @Override\r
1062                         protected Object doWorks() throws Exception {\r
1063                                 TatCount tc = new TatCount();\r
1064                                 StWin.appendMessage(MSGID+"番組IDを取得します");\r
1065                                 \r
1066                                 String content_id = getContentId(tvd, true);\r
1067                                 if ( content_id == null ) {\r
1068                                         StWin.appendError(ERRID+String.format("番組IDの取得に失敗しました。所要時間: %.2f秒",tc.end()));\r
1069                                 }\r
1070                                 else {\r
1071                                         StWin.appendMessage(MSGID+String.format("番組IDを取得しました。所要時間: %.2f秒",tc.end()));\r
1072                                 }\r
1073                                 \r
1074                                 return null;\r
1075                         }\r
1076                         \r
1077                         @Override\r
1078                         protected void doFinally() {\r
1079                                 StWin.setVisible(false);\r
1080                         }\r
1081                 }.execute();\r
1082                 \r
1083                 CommonSwingUtils.setLocationCenter(AbsReserveDialog.this, (Component) StWin);\r
1084                 StWin.setVisible(true);\r
1085                 \r
1086                 return tvd.progid;\r
1087         }\r
1088         \r
1089         private String getContentId(ProgDetailList tvd, boolean force) {\r
1090                 \r
1091                 String content_id = null;\r
1092                 \r
1093                 if ( ContentIdDIMORA.isValid(tvd.progid) ) {\r
1094                         ContentIdDIMORA.decodeContentId(tvd.progid);\r
1095                         String chid = ContentIdDIMORA.getChId();\r
1096                         content_id = getContentIdById(chid, tvd.startDateTime, force);\r
1097                 }\r
1098                 else {\r
1099                         content_id = getContentIdByName(tvd.center, tvd.startDateTime, force);\r
1100                 }\r
1101                 if ( content_id != null ) {\r
1102                         tvd.progid = content_id;\r
1103                         tvd.setContentIdStr();\r
1104                 }\r
1105 \r
1106                 return content_id;\r
1107         }\r
1108 \r
1109         /**\r
1110          * 番組表に存在する放送局IDで\r
1111          */\r
1112         private String getContentIdById(String chid, String startdatetime, boolean force) {\r
1113                 \r
1114                 Integer evid = geteventid.getEvId(chid, startdatetime, force);\r
1115                 \r
1116                 if ( force && evid == null ) {\r
1117                         MWin.appendError(ERRID+"番組ID取得でエラーが発生しました: "+chid+", "+startdatetime);\r
1118                         ringBeep();\r
1119                         return null;    // 一発死に\r
1120                 }\r
1121                 else if ( ! force && evid == null ) {\r
1122                         System.out.println(MSGID+"キャッシュにヒットしませんでした: "+chid+", "+startdatetime);\r
1123                         return null;\r
1124                 }\r
1125                 else if ( evid == -1 ) {\r
1126                         MWin.appendError(ERRID+"番組IDが取得できませんでした: "+chid+", "+startdatetime);\r
1127                         return null;\r
1128                 }\r
1129                 \r
1130                 ContentIdDIMORA.decodeChId(chid);\r
1131                 String content_id = ContentIdDIMORA.getContentId(evid);\r
1132 \r
1133                 MWin.appendMessage(MSGID+"番組IDを取得しました(byId): "+content_id);\r
1134                 \r
1135                 return content_id;\r
1136         }\r
1137         \r
1138         /**\r
1139          * レコーダに登録された放送局IDで\r
1140          */\r
1141         private String getContentIdByName(String chname, String startdatetime, boolean force) {\r
1142                 \r
1143                 String chid = null;\r
1144                 String chidEDCB = null;\r
1145                 String chidREGZA = null;\r
1146                 \r
1147                 Integer evid = null;\r
1148                 \r
1149                 // 登録済みのレコーダプラグインを全部チェックしてみる\r
1150                 for ( HDDRecorder rec : recorders ) {\r
1151                         if ( rec.isBackgroundOnly() ) {\r
1152                                 continue;\r
1153                         }\r
1154 \r
1155                         chidEDCB = chidREGZA = chid = null;\r
1156                         Integer tmpEvid = null;\r
1157                         \r
1158                         String chcode = rec.getChCode().getCH_WEB2CODE(chname);\r
1159                         if ( chcode == null ) {\r
1160                                 System.err.println(ERRID+"「Web番組表の放送局名」を「放送局コード」に変換できません: "+rec.getRecorderId()+" "+chname);\r
1161                                 continue;\r
1162                         }\r
1163                         \r
1164                         chidEDCB = chid = ContentIdEDCB.getChId(chcode);\r
1165                         if ( chid == null ) {\r
1166                                 chidREGZA = chid = ContentIdREGZA.getChId(chcode);\r
1167                                 if ( chid == null ) {\r
1168                                         System.err.println(ERRID+"番組IDの取得に未対応のレコーダです: "+rec.getRecorderId());\r
1169                                         continue;\r
1170                                 }\r
1171                         }\r
1172                         \r
1173                         if (debug) System.out.println(MSGID+"番組IDを取得します: "+rec.getRecorderId());\r
1174                         \r
1175                         tmpEvid = geteventid.getEvId(chid, startdatetime, force);\r
1176                         \r
1177                         if (evid == null) evid = tmpEvid;\r
1178                         \r
1179                         if ( force && tmpEvid == null ) {\r
1180                                 MWin.appendError(ERRID+"番組ID取得でエラーが発生しました: "+chid+", "+startdatetime);\r
1181                                 ringBeep();\r
1182                                 return null;    // 一発死に\r
1183                         }\r
1184                         else if ( ! force && tmpEvid == null ) {\r
1185                                 System.out.println(MSGID+"キャッシュにヒットしませんでした: "+chid+", "+startdatetime);\r
1186                                 return null;\r
1187                         }\r
1188                         else if ( tmpEvid == -1 ) {\r
1189                                 System.err.println(ERRID+"番組IDが取得できませんでした: "+chid+", "+startdatetime);\r
1190                                 continue;\r
1191                         }\r
1192                         \r
1193                         break;\r
1194                 }\r
1195                 \r
1196                 if ( evid == null ) {\r
1197                         MWin.appendError(ERRID+"【致命的エラー】放送局IDを持つレコーダプラグインが存在しません");\r
1198                         ringBeep();\r
1199                         return null;\r
1200                 }\r
1201                 else if ( evid == -1 ) {\r
1202                         MWin.appendError(ERRID+"【警告】番組IDの取得に失敗しました。開始時刻の移動や、まだ番組表サイトに情報が用意されていない場合などが考えられます。");\r
1203                         ringBeep();\r
1204                         return null;\r
1205                 }\r
1206                 \r
1207                 String content_id;\r
1208                 if ( chidREGZA != null ) {\r
1209                         content_id = ContentIdREGZA.getContentId(chidREGZA, evid);\r
1210                 }\r
1211                 else {\r
1212                         content_id = ContentIdEDCB.getContentId(chidEDCB, evid);\r
1213                 }               \r
1214                 \r
1215                 MWin.appendMessage(MSGID+"番組IDを取得しました(byName): "+content_id);\r
1216                 \r
1217                 return content_id;\r
1218         }\r
1219 \r
1220         /*******************************************************************************\r
1221          * コールバックメソッドの実装(録画設定)\r
1222          ******************************************************************************/\r
1223         \r
1224         /***************************************\r
1225          * 選択系\r
1226          **************************************/\r
1227         \r
1228         /**\r
1229          * レコーダが選択されたのでテキトーな録画設定を選ぶ\r
1230          */\r
1231         public boolean doSelectRecorder(String myself) {\r
1232                 \r
1233                 System.out.println(DBGID+"選択されたレコーダ: "+myself);\r
1234                 \r
1235                 HDDRecorderList myrecs = recorders.findInstance(myself);\r
1236                 if ( myrecs.size() == 0 ) {\r
1237                         return false;\r
1238                 }\r
1239                 HDDRecorder myrec = myrecs.get(0);\r
1240                 \r
1241                 // 今回選択されたレコーダを保存する\r
1242                 vals.selected_recorder = myrec;\r
1243                 \r
1244                 // 番組情報のアイテム設定\r
1245                 ProgDetailList tvd = vals.hide_tvd;\r
1246                 TimeVal tVal = getTimeValue(tvd);\r
1247                 jPane_title.setTimeValue(tVal);\r
1248                 jPane_title.setDateItems(tvd, tVal);\r
1249                 \r
1250                 // 録画設定のアイテム設定\r
1251                 setRecSettingItems(recorders, myrec, tvd);\r
1252                 \r
1253                 // 選択\r
1254                 String enc = myrec.getEmptyEncorder(tvd.center, tVal.startDateTime, tVal.endDateTime, null, null);\r
1255                 ReserveList myrsv = getReserveList(myrec, tvd, tVal, enc);\r
1256                 jPane_recsetting.setSelectedValues(tvd, myrsv);\r
1257                 \r
1258                 showUrabanList(myrsv, myrec.getUrabanList());\r
1259                 \r
1260                 return true;\r
1261         }\r
1262         \r
1263         /**\r
1264          * エンコーダが選択されたのでテキトーな録画設定を選ぶ(RD用)\r
1265          */\r
1266         public boolean doSelectEncoder(String encoder) {\r
1267                 \r
1268                 if ( encoder == null ) {\r
1269                         return false;\r
1270                 }\r
1271                 \r
1272                 HDDRecorder myrec = vals.hide_recorder;\r
1273                 if ( myrec == null ) {\r
1274                         return false;\r
1275                 }\r
1276                 \r
1277                 // チューナーにあった画質を探そう\r
1278                 String vrate = myrec.getPreferredVrate_VARDIA(encoder);\r
1279                 if ( vrate == null ) {\r
1280                         // 対象外だわ\r
1281                         return true;\r
1282                 }\r
1283                 \r
1284                 jPane_recsetting.setSelectedVrateValue(vrate);\r
1285                 return true;\r
1286         }\r
1287         \r
1288         /**\r
1289          * 画質が選択されたのでテキトーな録画設定を選ぶ()\r
1290          */\r
1291         public boolean doSelectVrate(String vrate) {\r
1292                 \r
1293                 if ( vrate == null ) {\r
1294                         return false;\r
1295                 }\r
1296                 \r
1297                 HDDRecorder myrec = vals.hide_recorder;\r
1298                 if ( myrec == null ) {\r
1299                         return false;\r
1300                 }\r
1301                 \r
1302                 // 画質にあったチューナーのリストを探してコンボボックスを並べ替える\r
1303                 ArrayList<TextValueSet> tuners = myrec.getPreferredTuners_VARDIA(vrate);\r
1304                 if ( tuners == null ) {\r
1305                         // 対象外だわ\r
1306                         return true;\r
1307                 }\r
1308                 jPane_recsetting.sortEncoderItems(tuners);\r
1309                 \r
1310                 // 画質にあったチューナーを探そう\r
1311                 ReserveList myrsv = jPane_title.getSelectedValues();\r
1312                 String tuner = myrec.getEmptyEncorder(myrsv.getCh_name(), myrsv.getStartDateTime(), myrsv.getEndDateTime(), null, vrate);\r
1313                                 \r
1314                 jPane_recsetting.setSelectedEncoderValue(tuner);\r
1315                 return true;\r
1316         }\r
1317         \r
1318         /***************************************\r
1319          * ボタン系\r
1320          **************************************/\r
1321         \r
1322         /**\r
1323          * \r
1324          */\r
1325         public boolean doSetAVSettings() {\r
1326 \r
1327                 ReserveList r = jPane_title.getSelectedValues();        // 放送局名の取得\r
1328                 String webChName = r.getCh_name();\r
1329                 if ( webChName == null ) {\r
1330                         System.out.println(ERRID+"放送局名が不正.");\r
1331                         return false;\r
1332                 }\r
1333                 \r
1334                 jPane_recsetting.getSelectedValues(r);                          // ジャンルの取得\r
1335                 ProgGenre genre = ProgGenre.get(r.getRec_genre());\r
1336                 if ( genre == null ) {\r
1337                         return false;\r
1338                 }\r
1339                 \r
1340                 HDDRecorder myrec = vals.selected_recorder;                     // レコーダ情報の取得\r
1341                 if ( myrec == null ) {\r
1342                         System.out.println(ERRID+"レコーダが未選択.");\r
1343                         return false;\r
1344                 }\r
1345                 String recid = myrec.getRecorderId();\r
1346                 \r
1347                 // ジャンル別AV設定の取得\r
1348                 AVs myavs = findAVs(genre.toString(), webChName, recid);\r
1349                 if ( myavs == null ) {\r
1350                         return false;\r
1351                 }\r
1352                 \r
1353                 // ジャンル別AV設定から追加で選択する\r
1354                 jPane_recsetting.setSelectedValues(myavs);\r
1355                 \r
1356                 return true;\r
1357         }\r
1358 \r
1359         /**\r
1360          * \r
1361          */\r
1362         public boolean doSaveAVSettings(boolean savedefault) {\r
1363 \r
1364                 ReserveList r = jPane_title.getSelectedValues();        // 放送局名の取得\r
1365                 String webChName = r.getCh_name();\r
1366                 if ( webChName == null ) {\r
1367                         System.out.println(ERRID+"放送局名が不正.");\r
1368                         return false;\r
1369                 }\r
1370                 \r
1371                 HDDRecorder myrec = vals.selected_recorder;                     // レコーダ情報の取得\r
1372                 if ( myrec == null ) {\r
1373                         System.out.println(ERRID+"レコーダが未選択.");\r
1374                         return false;\r
1375                 }\r
1376                 String recid = myrec.getRecorderId();\r
1377                 \r
1378                 AVs c = jPane_recsetting.getSelectedSetting();          // AV設定の取得\r
1379                 c.setRecorderId(recid);\r
1380                 \r
1381                 String key_item = c.getGenre();\r
1382                 AVSetting xavslist = avslist;\r
1383                 if ( env.getEnableCHAVsetting() ) {\r
1384                         key_item = webChName;\r
1385                         xavslist = chavslist;   // CHをキーに\r
1386                 }\r
1387                 \r
1388                 if ( savedefault ) {\r
1389                         key_item = null;                // デフォルトだよう\r
1390                 }\r
1391                 \r
1392                 c.setGenre(key_item);           // 入れなおしだよう\r
1393                 \r
1394                 xavslist.add(recid, key_item, c);\r
1395                 xavslist.save();\r
1396                 \r
1397                 MWin.appendMessage(MSGID+"画質・音質等の設定を保存しました:"+recid+" & "+((key_item!=null)?(key_item):("デフォルト")));\r
1398                 \r
1399                 return true;\r
1400         }\r
1401 \r
1402         \r
1403         /*******************************************************************************\r
1404          * コールバックメソッドの実装(類似予約)\r
1405          ******************************************************************************/\r
1406         \r
1407         /***************************************\r
1408          * 類似予約が選択された時の処理\r
1409          **************************************/\r
1410         \r
1411         /**\r
1412          * 類似予約が選択されたので処理をしてほしい\r
1413          */\r
1414         @Override\r
1415         public void doSelectLikeReserve(int row) {\r
1416                 if ( row == LikeReserveEditorPanel.LIKERSVTABLE_NONE ) {\r
1417                         doSelectLikeReserveByProg();\r
1418                 }\r
1419                 else {\r
1420                         doSelectLikeReserveByReserve(row);\r
1421                 }\r
1422         }\r
1423         \r
1424         // 番組情報で置き換え\r
1425         private boolean doSelectLikeReserveByProg() {\r
1426                 \r
1427                 HDDRecorder myrec = vals.hide_recorder;\r
1428                 ProgDetailList tvd = vals.hide_tvd;\r
1429                 LikeReserveList likersvlist = vals.hide_likersvlist;\r
1430                 AVs myavs = vals.hide_avs;\r
1431                 TimeVal tVal = getTimeValue(tvd);\r
1432                 \r
1433                 // 初期化\r
1434                 setTitleItems(myrec, tvd, likersvlist, false);\r
1435                 setRecSettingItems(recorders, myrec, tvd);\r
1436                 jPane_title.setDateItems(tvd, tVal);\r
1437 \r
1438                 // 選択\r
1439                 {\r
1440                         // 番組情報の選択\r
1441                         jPane_title.setSelectedValues(tvd);\r
1442         \r
1443                         jPane_title.setTimeValue(tVal);\r
1444                         \r
1445                         // RDだと画質でエンコーダの種類が絞られちまうンですよ\r
1446                         String vrate = myavs != null ? myavs.getVideorate() : null;\r
1447                         \r
1448                         // 録画設定の選択\r
1449                         setSelectedRecorder(myrec);\r
1450                         jPane_recsetting.setFlexItems(myrec, tvd.center);\r
1451                         \r
1452                         String enc = myrec.getEmptyEncorder(tvd.center, tVal.startDateTime, tVal.endDateTime, null, vrate);\r
1453                         ReserveList myrsv = getReserveList(myrec, tvd, tVal, enc);\r
1454                         jPane_recsetting.setSelectedValues(tvd, myrsv);\r
1455                         showUrabanList(myrsv, myrec.getUrabanList());\r
1456                                                 \r
1457                         if ( myavs != null ) {\r
1458                                 // ジャンル別AV設定から追加で選択する\r
1459                                 jPane_recsetting.setSelectedValues(myavs);\r
1460                         }\r
1461                 }\r
1462                 \r
1463                 // 予約ボタンの状態設定\r
1464                 jPane_title.setEnabledRecordButton(true);\r
1465                 jPane_title.setEnabledUpdateButton(false);\r
1466                 \r
1467                 return true;\r
1468         }\r
1469         \r
1470         // 類似予約情報で置き換え\r
1471         private boolean doSelectLikeReserveByReserve(int row) {\r
1472                 \r
1473                 LikeReserveList likersvlist = vals.hide_likersvlist;\r
1474                 LikeReserveItem likersv = likersvlist.setSelectedIndex(row);\r
1475                 ReserveList myrsv = likersv.getRsv();\r
1476 \r
1477                 HDDRecorderList myrecs = new HDDRecorderList();\r
1478                 HDDRecorder myrec = likersv.getRec();\r
1479                 myrecs.add(myrec);\r
1480                 \r
1481                 ProgDetailList tvd = vals.hide_tvd;\r
1482                 TimeVal tVal = getTimeValue(tvd);\r
1483                 \r
1484                 // 初期化\r
1485                 setTitleItems(myrec, tvd, likersvlist, true);\r
1486                 setRecSettingItems(myrecs, myrec, tvd);\r
1487                 jPane_title.setDateItems(tvd, tVal);\r
1488                 //jPane_recsetting.setFlexItems(myrec, tvd.center);\r
1489 \r
1490                 // 選択\r
1491                 {\r
1492                         // 番組情報の選択\r
1493                         jPane_title.setSelectedValues(myrsv);\r
1494                         jPane_title.setTimeValue(tVal);\r
1495                         \r
1496                         // 録画設定の選択\r
1497                         myrec.getEmptyEncorder(tvd.center, myrsv.getStartDateTime(), myrsv.getEndDateTime(), myrsv, null);      // 裏番組チェックのみ\r
1498                         setSelectedRecorder(myrec);\r
1499                         \r
1500                         ReserveList modrsv = getReserveList(myrec, tvd, tVal, myrsv.getTuner());\r
1501                         showUrabanList(modrsv, myrec.getUrabanList());\r
1502                         \r
1503                         jPane_recsetting.setSelectedValues(myrsv);\r
1504                 }\r
1505 \r
1506                 // 予約ボタンの状態設定\r
1507                 jPane_title.setEnabledRecordButton(true);\r
1508                 jPane_title.setEnabledUpdateButton(true);\r
1509                 \r
1510                 return true;\r
1511         }\r
1512         \r
1513         \r
1514         /*******************************************************************************\r
1515          * 直し残し\r
1516          ******************************************************************************/\r
1517         \r
1518         /**\r
1519          * レコーダの選択をしなおしたらコンボボックスアイテムの入れ替えも実行すること\r
1520          * @see RecSettingEditorPanel#setFlexItems(HDDRecorder, String)\r
1521          */\r
1522         private HDDRecorder setSelectedRecorder(HDDRecorder myrec) {\r
1523                 if ( jPane_recsetting.setSelectedRecorderValue(myrec.Myself()) != null ) {\r
1524                         vals.selected_recorder = myrec;\r
1525                         return myrec;\r
1526                 }\r
1527                 return null;\r
1528         }\r
1529         \r
1530         /**\r
1531          *  <P>指定したレコーダによってフォルダを変える\r
1532          *  <P>うーん、folderを他の用途に転用してるけど問題おきないかな?\r
1533          */\r
1534         private void setSelectedFolder() {\r
1535 /*\r
1536                 // タイトルに連動\r
1537                 if ( env.getAutoFolderSelect() ) {\r
1538                         String titlePop = TraceProgram.replacePop((String) jComboBox_title.getSelectedItem());\r
1539                         for (int i=0; i<jCBXPanel_folder.getItemCount(); i++) {\r
1540                                 String folderPop = TraceProgram.replacePop(((String) jCBXPanel_folder.getItemAt(i)).replaceFirst("^\\[(HDD|USB)\\] ",""));\r
1541                                 if (folderPop.equals(titlePop)) {\r
1542                                         jCBXPanel_folder.setSelectedIndex(i);\r
1543                                         return;\r
1544                                 }\r
1545                         }\r
1546                 }\r
1547                 \r
1548                 // デバイス名に連動\r
1549                 int defaultFolderIdx = -1;\r
1550                 int defaultHDDFolderIdx = -1;\r
1551                 int defaultDVDFolderIdx = -1;\r
1552                 for (int i=0; i<jCBXPanel_folder.getItemCount(); i++ ) {\r
1553                         String folderName = (String) jCBXPanel_folder.getItemAt(i);\r
1554                         if (folderName.indexOf("指定なし") != -1) {\r
1555                                 if (defaultFolderIdx == -1) {\r
1556                                         defaultFolderIdx = i;\r
1557                                 }\r
1558                                 if (folderName.startsWith("[HDD] ")) {\r
1559                                         defaultHDDFolderIdx = i;\r
1560                                 }\r
1561                                 else if (folderName.startsWith("[USB] ")) {\r
1562                                         defaultDVDFolderIdx = i;\r
1563                                 }\r
1564                         }\r
1565                 }\r
1566                 if (jCBXPanel_device.getItemCount() > 0) {\r
1567                         if (((String) jCBXPanel_device.getSelectedItem()).equals("HDD")) {\r
1568                                 if (defaultHDDFolderIdx != -1) {\r
1569                                         jCBXPanel_folder.setSelectedIndex(defaultHDDFolderIdx);\r
1570                                         return;\r
1571                                 }\r
1572                         }\r
1573                         else {\r
1574                                 if (defaultDVDFolderIdx != -1) {\r
1575                                         jCBXPanel_folder.setSelectedIndex(defaultDVDFolderIdx);\r
1576                                         return;\r
1577                                 }\r
1578                         }\r
1579                 }\r
1580                 if (defaultFolderIdx != -1) {\r
1581                         jCBXPanel_folder.setSelectedIndex(defaultFolderIdx);\r
1582                 }\r
1583 */\r
1584         }\r
1585         \r
1586 }\r