• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

タイニー番組ナビゲータ本体


Commit MetaInfo

Révision533fc32f972cfc7fcfcc916be62e0e029a32902f (tree)
l'heure2019-06-30 22:23:46
AuteurMasahiko Kimura <mkimura@u01....>
CommiterMasahiko Kimura

Message de Log

Ver.1.12.1 (2019/06/30):

  1. [その他]ピックアップした番組でも始まる前にメッセージを通知できるようにする
  2. [リスト形式]キーワードグループの並べ替えができるようにする
  3. [リスト形式]ピックアップノード選択中にピックアップへ追加してもすぐに反映されない問題の対応
  4. [新聞形式]ツリービューの選択ノードが変わったら、それが見えるようスクロールする
  5. [新聞形式]過去ログにない過去日を検索した時にページ切替ができない問題の対応
  6. [テレビ王国]BS4K/8Kの放送局に対応する
  7. [タイトル一覧]「コピー」欄のコピー回数表示をネットでナビに合わせる

Change Summary

Modification

--- a/TinyBannavi/src/tainavi/AbsListedView.java
+++ b/TinyBannavi/src/tainavi/AbsListedView.java
@@ -391,7 +391,7 @@ public abstract class AbsListedView extends JPanel implements TickTimerListener
391391 private JTree jTree_tree = null;
392392 private JScrollPane jScrollPane_listed = null;
393393 private JTableRowHeader jTable_rowheader = null;
394- private ListedTable jTable_listed = null;
394+ protected ListedTable jTable_listed = null;
395395 private VWColorCharCellRenderer2 titleCellRenderer = null;
396396
397397 private VWListedTreeNode listRootNode = null; // リスト形式のツリー
@@ -1204,6 +1204,58 @@ public abstract class AbsListedView extends JPanel implements TickTimerListener
12041204 }
12051205 }
12061206
1207+ /**
1208+ * 通知すべきピックアップ情報を取得する
1209+ */
1210+ public boolean getPickupsToNotify(ArrayList<String>list) {
1211+ list.clear();
1212+
1213+ TVProgram tvp = tvprograms.getPickup();
1214+ if ( tvp == null )
1215+ return false;
1216+
1217+ String os = System.getProperty("os.name");
1218+ boolean isWin10 = os != null && os.contains("Windows 10");
1219+
1220+ // 現在日時
1221+ int min = env.getMinsBeforeProgStart();
1222+ String dtmin = CommonUtils.getDateTime(min*60);
1223+ String dtmax = CommonUtils.getDateTime((min+1)*60);
1224+
1225+ String bodyAll = "";
1226+ String head = "" + min + "分後にピックアップの番組が始まります\n";
1227+
1228+ for ( ProgList tPl : tvp.getCenters() ) {
1229+ for ( ProgDateList tPcl : tPl.pdate ) {
1230+ for ( ProgDetailList tvd : tPcl.pdetail ) {
1231+ // 予約開始まで規定時間以内の場合
1232+ String nextstart = tvd.startDateTime;
1233+
1234+ if ( nextstart.compareTo(dtmin) >= 0 && nextstart.compareTo(dtmax) < 0 ) {
1235+ String title = tvd.title;
1236+ String stime = tvd.start;
1237+ String etime = tvd.end;
1238+ String body =
1239+ "「" + title + "」\n" +
1240+ "(" + stime + "~" + etime + ")\n";
1241+
1242+ if (isWin10){
1243+ list.add(head + body);
1244+ }
1245+ else{
1246+ bodyAll += body;
1247+ }
1248+ }
1249+ }
1250+ }
1251+ }
1252+
1253+ if (!isWin10 && !bodyAll.isEmpty())
1254+ list.add(head + bodyAll);
1255+
1256+ return list.size() > 0;
1257+ }
1258+
12071259 /*
12081260 * 絞り込み検索
12091261 */
@@ -1867,7 +1919,7 @@ public abstract class AbsListedView extends JPanel implements TickTimerListener
18671919 showPopupForSortSearchKey(e.getX(), e.getY());
18681920 break;
18691921 case KEYWORDGROUP:
1870- showPopupForRemoveKeywordGrp(e.getX(), e.getY());
1922+ showPopupForKeywordGroup(e.getX(), e.getY());
18711923 break;
18721924 case EXTENTION:
18731925 showPopupForSortExtension(e.getX(), e.getY());
@@ -3207,6 +3259,44 @@ public abstract class AbsListedView extends JPanel implements TickTimerListener
32073259 }
32083260
32093261 /**
3262+ * キーワードグループを並べ替える
3263+ */
3264+ private void sortSearchKeyGroup() {
3265+ //
3266+ ArrayList<String> oList = new ArrayList<String>();
3267+ for ( SearchGroup gr : srGrps ) {
3268+ final String name = gr.getName();
3269+ oList.add(name);
3270+ }
3271+ //
3272+ JListSortDialog lsD = new JListSortDialog("キーワードグループの並べ替え", oList);
3273+ CommonSwingUtils.setLocationCenter(parent,lsD);
3274+
3275+ lsD.setVisible(true);
3276+
3277+ if (lsD.isRegistered()) {
3278+ SearchGroupList newSrGrps = new SearchGroupList();
3279+ for ( String label : oList ) {
3280+ for ( SearchGroup gr : srGrps ) {
3281+ if ( gr.getName().equals(label) ) {
3282+ newSrGrps.add(gr);
3283+ break;
3284+ }
3285+ }
3286+ }
3287+
3288+ srGrps.clear();
3289+ for (SearchGroup gr : newSrGrps){
3290+ srGrps.add(gr);
3291+ }
3292+ srGrps.save();
3293+
3294+ // ツリーを更新
3295+ redrawTreeByKeywordGroup();
3296+ }
3297+ }
3298+
3299+ /**
32103300 * キーワードグループを編集したい
32113301 */
32123302 private void editSeachkeyGroup(String name) {
@@ -3613,7 +3703,7 @@ public abstract class AbsListedView extends JPanel implements TickTimerListener
36133703 }
36143704
36153705 // キーワードグループの処理
3616- private void showPopupForRemoveKeywordGrp(int x, int y)
3706+ private void showPopupForKeywordGroup(int x, int y)
36173707 {
36183708 JPopupMenu pop = new JPopupMenu();
36193709
@@ -3626,6 +3716,15 @@ public abstract class AbsListedView extends JPanel implements TickTimerListener
36263716 }
36273717 });
36283718 pop.add(menuItem);
3719+
3720+ menuItem = new JMenuItemWithShortcut("キーワードグループの並べ替え");
3721+ menuItem.setMnemonic(KeyEvent.VK_S);
3722+ menuItem.addActionListener(new ActionListener() {
3723+ public void actionPerformed(ActionEvent e) {
3724+ sortSearchKeyGroup();
3725+ }
3726+ });
3727+ pop.add(menuItem);
36293728 }
36303729 pop.show(jTree_tree, x, y);
36313730 }
--- a/TinyBannavi/src/tainavi/AbsPaperView.java
+++ b/TinyBannavi/src/tainavi/AbsPaperView.java
@@ -444,8 +444,8 @@ public abstract class AbsPaperView extends JPanel implements TickTimerListener,H
444444 public void jumpToNow() {
445445 if ( nowNode != null ) {
446446 TreePath tp = new TreePath(nowNode.getPath());
447- jTree_tree.setSelectionPath(null);
448- jTree_tree.setSelectionPath(tp);
447+ setSelectionPath(null);
448+ setSelectionPath(tp);
449449 }
450450 }
451451
@@ -871,7 +871,7 @@ public abstract class AbsPaperView extends JPanel implements TickTimerListener,H
871871 return;
872872
873873 // 前後のノードに移動する
874- jTree_tree.setSelectionPath(path);
874+ setSelectionPath(path);
875875 jLayeredPane_space_main_view.scrollRectToVisible(new Rectangle(vp, vs));
876876 }
877877 /*
@@ -893,7 +893,7 @@ public abstract class AbsPaperView extends JPanel implements TickTimerListener,H
893893 return;
894894
895895 // 前日のノードに移動して一番下にスクロールする
896- jTree_tree.setSelectionPath(path);
896+ setSelectionPath(path);
897897 vp.y = ps.height - vs.height;
898898 }
899899 // 一番下でかつプラス方向にスクロールしたら
@@ -907,7 +907,7 @@ public abstract class AbsPaperView extends JPanel implements TickTimerListener,H
907907 return;
908908
909909 // 翌日のノードに移動して一番上にスクロールする
910- jTree_tree.setSelectionPath(path);
910+ setSelectionPath(path);
911911 vp.y = 0;
912912 }
913913 // それ以外の場合はホイール量に応じてスクロールする
@@ -1014,7 +1014,7 @@ public abstract class AbsPaperView extends JPanel implements TickTimerListener,H
10141014 * サイドツリーの「現在日時」を選択する
10151015 */
10161016 public void selectTreeDefault() {
1017- if ( defaultNode != null ) jTree_tree.setSelectionPath(new TreePath(defaultNode.getPath()));
1017+ if ( defaultNode != null ) setSelectionPath(new TreePath(defaultNode.getPath()));
10181018 }
10191019
10201020 /**
@@ -1029,8 +1029,8 @@ public abstract class AbsPaperView extends JPanel implements TickTimerListener,H
10291029 // 表示位置を記憶
10301030 Point vp = vport.getViewPosition(); //= SwingUtilities.convertPoint(vport,0,0,label);
10311031 // ツリー再選択
1032- jTree_tree.setSelectionPath(null);
1033- jTree_tree.setSelectionPath(tp);
1032+ setSelectionPath(null);
1033+ setSelectionPath(tp);
10341034 // 表示位置を復帰
10351035 if (vp.x != 0 && vp.y != 0) {
10361036 jLayeredPane_space_main_view.scrollRectToVisible(new Rectangle(vp, vport.getSize()));
@@ -1184,7 +1184,7 @@ public abstract class AbsPaperView extends JPanel implements TickTimerListener,H
11841184 _redrawTreeByDate(bsNode);
11851185 _redrawTreeByDate(csNode);
11861186
1187- jTree_tree.setSelectionPath(tp);
1187+ setSelectionPath(tp);
11881188 jTree_tree.updateUI();
11891189 startTreeListener();
11901190 }
@@ -1221,7 +1221,7 @@ public abstract class AbsPaperView extends JPanel implements TickTimerListener,H
12211221 centerNode.add(new DefaultMutableTreeNode(pl.Center));
12221222 }
12231223
1224- jTree_tree.setSelectionPath(tp);
1224+ setSelectionPath(tp);
12251225 jTree_tree.updateUI();
12261226 startTreeListener();
12271227 }
@@ -1242,7 +1242,7 @@ public abstract class AbsPaperView extends JPanel implements TickTimerListener,H
12421242 }
12431243 }
12441244
1245- jTree_tree.setSelectionPath(tp);
1245+ setSelectionPath(tp);
12461246 jTree_tree.updateUI();
12471247 startTreeListener();
12481248 }
@@ -1484,6 +1484,9 @@ public abstract class AbsPaperView extends JPanel implements TickTimerListener,H
14841484 System.err.println(ERRID+"過去ログの取得に失敗しました: "+date);
14851485 return null;
14861486 }
1487+
1488+ // 指定した日付のノードがツリーになければ作成する
1489+ addPassedNodeIfNotExist(date);
14871490 }
14881491
14891492 // 番組枠描画
@@ -1495,6 +1498,35 @@ public abstract class AbsPaperView extends JPanel implements TickTimerListener,H
14951498 return pli;
14961499 }
14971500
1501+ /*
1502+ * 表示対象の過去日のノードがなければ追加する
1503+ */
1504+ private boolean addPassedNodeIfNotExist(String date){
1505+ if (date == null)
1506+ return false;
1507+
1508+ // 過去日ノードを順にチェックする
1509+ int num = passedNode.getChildCount();
1510+ for (int n=0; n<num; n++){
1511+ DefaultMutableTreeNode cnode = (DefaultMutableTreeNode) passedNode.getChildAt(n);
1512+
1513+ // ラベルが一致したら
1514+ if (cnode.toString().equals(date))
1515+ return true;
1516+ // 追加する日より過去の日付だったらその前にインサートする
1517+ else if (cnode.toString().compareTo(date) < 0){
1518+ passedNode.insert(new DefaultMutableTreeNode(date), n);
1519+ jTree_tree.updateUI();
1520+ return true;
1521+ }
1522+ }
1523+
1524+ // 過去日ノードになかったら追加する
1525+ passedNode.add(new DefaultMutableTreeNode(date));
1526+ jTree_tree.updateUI();
1527+ return true;
1528+ }
1529+
14981530 /**
14991531 * 日付別に表を作成する、の本体
15001532 * @see #redrawByDate(String, IterationType)
@@ -2563,6 +2595,16 @@ public abstract class AbsPaperView extends JPanel implements TickTimerListener,H
25632595 };
25642596
25652597 /*
2598+ * ツリービューでパスを選択する
2599+ */
2600+ private void setSelectionPath(TreePath path){
2601+ if (jTree_tree != null){
2602+ jTree_tree.setSelectionPath(path);
2603+ if (path != null)
2604+ jTree_tree.scrollPathToVisible(path);
2605+ }
2606+ }
2607+ /*
25662608 * 表示中の日付の前後の日付のパスを取得する
25672609 */
25682610 private final TreePath getNextDatePath(boolean next){
@@ -2599,6 +2641,9 @@ public abstract class AbsPaperView extends JPanel implements TickTimerListener,H
25992641 return null;
26002642 }
26012643
2644+ if (path.getPathCount() < 3)
2645+ return null;
2646+
26022647 String date = path.getPathComponent(2).toString();
26032648 String today = JTreeLabel.Nodes.NOW.getLabel();
26042649
@@ -2672,7 +2717,7 @@ public abstract class AbsPaperView extends JPanel implements TickTimerListener,H
26722717 return;
26732718
26742719 // 前後のノードに移動する
2675- jTree_tree.setSelectionPath(path);
2720+ setSelectionPath(path);
26762721 }
26772722 // データの高さがビューポートより小さい場合は何もしない
26782723 else if (ps.height <= vs.height)
@@ -2685,7 +2730,7 @@ public abstract class AbsPaperView extends JPanel implements TickTimerListener,H
26852730 return;
26862731
26872732 // 前日のノードに移動して一番下にスクロールする
2688- jTree_tree.setSelectionPath(path);
2733+ setSelectionPath(path);
26892734 vp.y = ps.height - vs.height;
26902735 }
26912736 // 一番下でかつプラス方向にホイールを回したら
@@ -2696,7 +2741,7 @@ public abstract class AbsPaperView extends JPanel implements TickTimerListener,H
26962741 return;
26972742
26982743 // 翌日のノードに移動して一番上にスクロールする
2699- jTree_tree.setSelectionPath(path);
2744+ setSelectionPath(path);
27002745 vp.y = 0;
27012746 }
27022747 // それ以外の場合はホイール量に応じてスクロールする
--- a/TinyBannavi/src/tainavi/AbsReserveListView.java
+++ b/TinyBannavi/src/tainavi/AbsReserveListView.java
@@ -769,7 +769,7 @@ public abstract class AbsReserveListView extends JScrollPane implements TickTime
769769 HDDRecorderList recs = recorders.findInstance(getSelectedRecorderOnToolbar());
770770
771771 String bodyAll = "";
772- String head = "予約済の番組が" + min + "分後に始まります\n";
772+ String head = "" + min + "分後に予約した番組が始まります\n";
773773
774774 for ( HDDRecorder recorder : recs ) {
775775 if ( recorder.isBackgroundOnly() ) {
--- a/TinyBannavi/src/tainavi/AbsSettingView.java
+++ b/TinyBannavi/src/tainavi/AbsSettingView.java
@@ -308,6 +308,7 @@ public abstract class AbsSettingView extends JScrollPane {
308308 private JCCLabel jCCL_rsv_recedcolor = null;
309309 private JCheckBoxPanel jCBP_useAutocomplete = null;
310310 private JCheckBoxPanel jCBP_notifyBeforeProgStart = null;
311+ private JCheckBoxPanel jCBP_notifyBeforePickProgStart = null;
311312 private JSliderPanel jSP_minsBeforeProgStart = null;
312313
313314 // タイトル一覧
@@ -1076,15 +1077,21 @@ public abstract class AbsSettingView extends JScrollPane {
10761077 // RELOADリスナー不要
10771078 y+=(PARTS_HEIGHT+SEP_HEIGHT);
10781079
1079- CommonSwingUtils.putComponentOn(jPanel_setting, jCBP_notifyBeforeProgStart = new JCheckBoxPanel("予約番組が開始する前に通知する(Windows 10のみ)",LABEL_WIDTH), PARTS_WIDTH, PARTS_HEIGHT, SEP_WIDTH, y);
1080+ CommonSwingUtils.putComponentOn(jPanel_setting, jCBP_notifyBeforeProgStart = new JCheckBoxPanel("予約した番組が開始する前に通知する",LABEL_WIDTH), PARTS_WIDTH, PARTS_HEIGHT, SEP_WIDTH, y);
10801081 jCBP_notifyBeforeProgStart.setSelected(env.getNotifyBeforeProgStart());
10811082 jCBP_notifyBeforeProgStart.addItemListener(il_notifyBeforeProgStart);
10821083 // RELOADリスナー不要
10831084 y+=(PARTS_HEIGHT+SEP_HEIGHT);
10841085
1085- CommonSwingUtils.putComponentOn(jPanel_setting, jSP_minsBeforeProgStart = new JSliderPanel("┗ 開始何分前に通知するか",LABEL_WIDTH,0,72,200), PARTS_WIDTH, PARTS_HEIGHT, SEP_WIDTH, y);
1086+ CommonSwingUtils.putComponentOn(jPanel_setting, jCBP_notifyBeforePickProgStart = new JCheckBoxPanel("ピックアップした番組が開始する前に通知する",LABEL_WIDTH), PARTS_WIDTH, PARTS_HEIGHT, SEP_WIDTH, y);
1087+ jCBP_notifyBeforePickProgStart.setSelected(env.getNotifyBeforePickProgStart());
1088+ jCBP_notifyBeforePickProgStart.addItemListener(il_notifyBeforeProgStart);
1089+ // RELOADリスナー不要
1090+ y+=(PARTS_HEIGHT+SEP_HEIGHT);
1091+
1092+ CommonSwingUtils.putComponentOn(jPanel_setting, jSP_minsBeforeProgStart = new JSliderPanel("┗ 番組開始の何分前に通知するか",LABEL_WIDTH,0,60,200), PARTS_WIDTH, PARTS_HEIGHT, SEP_WIDTH, y);
10861093 jSP_minsBeforeProgStart.setValue(env.getMinsBeforeProgStart());
1087- jSP_minsBeforeProgStart.setEnabled(jCBP_notifyBeforeProgStart.isSelected());
1094+ jSP_minsBeforeProgStart.setEnabled(jCBP_notifyBeforeProgStart.isSelected() || jCBP_notifyBeforePickProgStart.isSelected());
10881095 // RELOADリスナー不要
10891096 y+=(PARTS_HEIGHT+SEP_HEIGHT);
10901097
@@ -1436,6 +1443,7 @@ public abstract class AbsSettingView extends JScrollPane {
14361443 env.setRecordedColor(jCCL_rsv_recedcolor.getChoosed());
14371444 env.setUseAutocomplete(jCBP_useAutocomplete.isSelected());
14381445 env.setNotifyBeforeProgStart(jCBP_notifyBeforeProgStart.isSelected());
1446+ env.setNotifyBeforePickProgStart(jCBP_notifyBeforePickProgStart.isSelected());
14391447 env.setMinsBeforeProgStart(jSP_minsBeforeProgStart.getValue());
14401448
14411449 // タイトル一覧関係
@@ -1817,7 +1825,7 @@ public abstract class AbsSettingView extends JScrollPane {
18171825 private final ItemListener il_notifyBeforeProgStart = new ItemListener() {
18181826 @Override
18191827 public void itemStateChanged(ItemEvent e) {
1820- jSP_minsBeforeProgStart.setEnabled(jCBP_notifyBeforeProgStart.isSelected());
1828+ jSP_minsBeforeProgStart.setEnabled(jCBP_notifyBeforeProgStart.isSelected() || jCBP_notifyBeforePickProgStart.isSelected());
18211829 }
18221830 };
18231831
--- a/TinyBannavi/src/tainavi/AbsTitleListView.java
+++ b/TinyBannavi/src/tainavi/AbsTitleListView.java
@@ -163,8 +163,6 @@ public abstract class AbsTitleListView extends JPanel {
163163
164164 private static final String ICONFILE_PULLDOWNMENU = "icon/down-arrow.png";
165165
166- public static final String MOVEONLY = "移動のみ";
167-
168166 /*******************************************************************************
169167 * 部品
170168 ******************************************************************************/
@@ -269,7 +267,7 @@ public abstract class AbsTitleListView extends JPanel {
269267 c.addData(folder);
270268 c.addData(genre);
271269 c.addData(recname);
272- c.addData(copycount.equals("1") ? MOVEONLY : copycount + "回");
270+ c.addData(copycount);
273271 c.addData(dlna_oid);
274272 c.addData(recorder);
275273
@@ -506,11 +504,15 @@ public abstract class AbsTitleListView extends JPanel {
506504 String devId = getSelectedDeviceId();
507505 if (titles && devId != null){
508506 StWin.appendMessage(MSGID+"レコーダからタイトル一覧を取得します(force=" + String.valueOf(force) + ",details=" + String.valueOf(details) + "):"+devId);
507+ TatCount tc = new TatCount();
509508 if (rec.GetRdTitles(devId, force, details, devId.equals(HDDRecorder.DEVICE_ALL))){
510- MWin.appendMessage(MSGID+"レコーダからタイトル一覧が正常に取得できました:"+devId);
509+ String time = String.format(" [%.2f秒]", tc.end());
510+ MWin.appendMessage(MSGID+"レコーダからタイトル一覧が正常に取得できました:"+devId + time);
511+ }
512+ else{
513+ String time = String.format("[%.2f秒]", tc.end());
514+ MWin.appendError(ERRID+"レコーダからのタイトル一覧の取得に失敗しました:"+devId + time);
511515 }
512- else
513- MWin.appendError(ERRID+"レコーダからのタイトル一覧の取得に失敗しました:"+devId);
514516
515517 if ( ! rec.getErrmsg().equals("")) {
516518 MWin.appendMessage(MSGID+"[追加情報] "+rec.getErrmsg());
@@ -890,11 +892,11 @@ public abstract class AbsTitleListView extends JPanel {
890892 sa.genre = ro.getGenreNameList();
891893 sa.recname = rec.getDispName();
892894 sa.recorder = rec.Myself();
893- sa.copycount = ro.getHidden_params().get("copycount");
895+ sa.copycount = ro.formatCopyCount();
894896 sa.dlna_oid = ro.getHidden_params().get("dlnaObjectID");
895897
896898 sa.hide_ttlid = ro.getId();
897- sa.hide_detail = ro.getDetail();
899+ sa.hide_detail = ro.formatDetail();
898900 sa.hide_recording = ro.getRecording();
899901
900902 sa.fireChanged();
@@ -1696,10 +1698,28 @@ public abstract class AbsTitleListView extends JPanel {
16961698
16971699 @Override
16981700 public int compare(String str1, String str2) {
1699- int num1 = str1.equals(MOVEONLY) ? 1 : Integer.parseInt(str1.substring(0, str1.length()-1));
1700- int num2 = str2.equals(MOVEONLY) ? 1 : Integer.parseInt(str2.substring(0, str2.length()-1));
1701+ int num1 = parseCopyCount(str1);
1702+ int num2 = parseCopyCount(str2);
17011703 return num1 - num2;
17021704 }
1705+
1706+ // 整形されたコピー回数から回数を取得する
1707+ int parseCopyCount(String str){
1708+ try{
1709+ // 「移動のみ」の場合
1710+ if (str.equals(TitleInfo.MOVEONLY))
1711+ return 0;
1712+ // 「録画中」の場合
1713+ else if (str.equals(TitleInfo.RECORDING))
1714+ return -1;
1715+ // 「n回」の場合
1716+ else
1717+ return Integer.parseInt(str.substring(0, str.length()-1));
1718+ }
1719+ catch(NumberFormatException e){
1720+ return -2;
1721+ }
1722+ }
17031723 };
17041724
17051725 col = getColumn(TitleColumn.COPYCOUNT);
--- a/TinyBannavi/src/tainavi/Env.java
+++ b/TinyBannavi/src/tainavi/Env.java
@@ -887,11 +887,16 @@ public class Env {
887887 public void setUseAutocomplete(boolean b) { useAutocomplete = b; }
888888 private boolean useAutocomplete = false;
889889
890- // 予約番組の開始を通知するか(Windows10のみ)
890+ // 予約番組の開始を通知するか
891891 public boolean getNotifyBeforeProgStart(){ return notifyBeforeProgStart; }
892892 public void setNotifyBeforeProgStart(boolean b){ notifyBeforeProgStart = b; }
893893 private boolean notifyBeforeProgStart = false;
894894
895+ // ピックアップ番組の開始を通知するか
896+ public boolean getNotifyBeforePickProgStart(){ return notifyBeforePickProgStart; }
897+ public void setNotifyBeforePickProgStart(boolean b){ notifyBeforePickProgStart = b; }
898+ private boolean notifyBeforePickProgStart = false;
899+
895900 // 開始何分前に通知するか
896901 public int getMinsBeforeProgStart(){ return minsBeforeProgStart; }
897902 public void setMinsBeforeProgStart(int n){ minsBeforeProgStart = n; }
--- a/TinyBannavi/src/tainavi/SearchGroupList.java
+++ b/TinyBannavi/src/tainavi/SearchGroupList.java
@@ -5,20 +5,20 @@ import java.util.ArrayList;
55 import java.util.Iterator;
66
77 public class SearchGroupList implements Iterator<SearchGroup>, Iterable<SearchGroup>{
8-
8+
99 private final ArrayList<SearchGroup> gList = new ArrayList<SearchGroup>();
10-
10+
1111 private int idx;
12-
12+
1313 private String gFile = "env"+File.separator+"keywordgroup.xml";
14-
15-
14+
15+
1616 // コンストラクタ
1717 public SearchGroupList() {
1818 //
1919 }
20-
21-
20+
21+
2222 // 検索系
2323 @Override
2424 public Iterator<SearchGroup> iterator() {
@@ -37,11 +37,11 @@ public class SearchGroupList implements Iterator<SearchGroup>, Iterable<SearchGr
3737 public void remove() {
3838 gList.remove(idx);
3939 }
40-
40+
4141 public int size() {
4242 return gList.size();
4343 }
44-
44+
4545 // グループ・メンバー追加
4646 public boolean add(String name) {
4747 for ( SearchGroup gl : gList ) {
@@ -55,13 +55,30 @@ public class SearchGroupList implements Iterator<SearchGroup>, Iterable<SearchGr
5555 gList.add(gl);
5656 return true;
5757 }
58+
59+ public boolean add(SearchGroup gr){
60+ if (gr == null || gr.getName() == null)
61+ return false;
62+
63+ for ( SearchGroup gl : gList ) {
64+ if ( gl.getName().equals(gr.getName()) ) {
65+ // 既に存在している
66+ return false;
67+ }
68+ }
69+
70+ gList.add(gr);
71+
72+ return true;
73+ }
74+
5875 public boolean add(String name, String member) {
59-
76+
6077 if ( name == null || member == null ) {
6178 // グループとメンバーの指定は必須
6279 return false;
6380 }
64-
81+
6582 for ( SearchGroup gl : gList ) {
6683 if ( gl.getName().equals(name) ) {
6784 gList.iterator();
@@ -82,7 +99,7 @@ public class SearchGroupList implements Iterator<SearchGroup>, Iterable<SearchGr
8299 gl.add(member);
83100 return true;
84101 }
85-
102+
86103 // 削除する
87104 public boolean remove(String name) {
88105 for ( SearchGroup gl : gList ) {
@@ -95,12 +112,12 @@ public class SearchGroupList implements Iterator<SearchGroup>, Iterable<SearchGr
95112 return false;
96113 }
97114 public boolean remove(String name, String member) {
98-
115+
99116 if ( member == null ) {
100117 // グループ指定は必須
101118 return false;
102119 }
103-
120+
104121 if ( name == null ) {
105122 // グループ横断削除
106123 for ( SearchGroup gl : gList ) {
@@ -134,14 +151,19 @@ public class SearchGroupList implements Iterator<SearchGroup>, Iterable<SearchGr
134151 return false;
135152 }
136153 }
137-
154+
155+ // クリアする
156+ public void clear(){
157+ gList.clear();
158+ }
159+
138160 // 検索する
139161 public boolean isFind(String name, String member) {
140-
162+
141163 if ( name == null || member == null ) {
142164 return false;
143165 }
144-
166+
145167 for ( SearchGroup gl : gList ) {
146168 if ( gl.getName().equals(name) ) {
147169 for ( String gmember : gl ) {
@@ -154,7 +176,7 @@ public class SearchGroupList implements Iterator<SearchGroup>, Iterable<SearchGr
154176 }
155177 return false;
156178 }
157-
179+
158180 // 改名する
159181 public boolean rename(String oldName, String newName) {
160182 for ( SearchGroup gl : gList ) {
@@ -186,7 +208,7 @@ public class SearchGroupList implements Iterator<SearchGroup>, Iterable<SearchGr
186208 }
187209 return false;
188210 }
189-
211+
190212 // セーブ・ロード
191213 public boolean save() {
192214 System.out.println("検索キーワードグループ設定を保存します: "+gFile);
@@ -196,7 +218,7 @@ public class SearchGroupList implements Iterator<SearchGroup>, Iterable<SearchGr
196218 }
197219 return true;
198220 }
199-
221+
200222 public boolean load() {
201223 System.out.println("検索キーワードグループ設定を読み込みます: "+gFile);
202224 if ( new File(gFile).exists() ) {
@@ -207,7 +229,7 @@ public class SearchGroupList implements Iterator<SearchGroup>, Iterable<SearchGr
207229 return true;
208230 }
209231 }
210-
232+
211233 System.err.println("検索キーワードグループ設定が読み込みに失敗しました: "+gFile);
212234 return false;
213235 }
--- a/TinyBannavi/src/tainavi/TVProgramUtils.java
+++ b/TinyBannavi/src/tainavi/TVProgramUtils.java
@@ -1569,6 +1569,8 @@ public class TVProgramUtils implements Cloneable {
15691569 * 番組情報をキャッシュファイルから読み込む
15701570 */
15711571 public boolean loadFromProgCache(String prefix){
1572+ TatCount tc = new TatCount();
1573+
15721574 if (!useProgCache){
15731575 System.out.println("高速キャッシュファイルは使用しません");
15741576 return false;
@@ -1623,7 +1625,8 @@ public class TVProgramUtils implements Cloneable {
16231625
16241626 pcenter = pcl;
16251627
1626- System.out.println("高速キャッシュファイルの読み込みに成功しました");
1628+ String tm = String.format(" [%.2f秒]", tc.end());
1629+ System.out.println("高速キャッシュファイルの読み込みに成功しました" + tm);
16271630 return true;
16281631 }
16291632 }
--- a/TinyBannavi/src/tainavi/TitleInfo.java
+++ b/TinyBannavi/src/tainavi/TitleInfo.java
@@ -9,6 +9,9 @@ import java.util.regex.Pattern;
99 * <P>個々のタイトルの情報を保持します。
1010 */
1111 public class TitleInfo implements Cloneable {
12+ public static final String MOVEONLY = "移動のみ";
13+ public static final String RECORDING = "録画中";
14+
1215 private int serial=0;
1316 private String id=null;
1417 private String rec_mode="";
@@ -22,8 +25,6 @@ public class TitleInfo implements Cloneable {
2225 private String channel="";
2326 private String ch_name="";
2427
25- private String detail="";
26-
2728 private String content_id="";
2829
2930 private String rec_device=null;
@@ -83,8 +84,7 @@ public class TitleInfo implements Cloneable {
8384 public String getCh_name() {return ch_name;}
8485 public void setCh_name(String s) { ch_name=s;}
8586
86- public String getDetail() {return detail;}
87- public void setDetail(String s) { detail=s;}
87+ public void setDetail(String s) {}
8888
8989 public String getContentId() {return content_id;}
9090 public void setContentId(String s) { content_id=s;}
@@ -165,4 +165,49 @@ public class TitleInfo implements Cloneable {
165165 public HashMap<String,String> getHidden_params() { return hidden_params; }
166166 public void setHidden_params(HashMap<String,String> a) { hidden_params = a; }
167167
168+ // コピー回数を整形する
169+ public String formatCopyCount(){
170+ String copycount = getHidden_params().get("copycount");
171+ if (copycount == null)
172+ return "";
173+ else if (copycount.equals("1"))
174+ return MOVEONLY;
175+ else if (copycount.equals("238"))
176+ return RECORDING;
177+ else{
178+ try{
179+ int count = Integer.parseInt(copycount);
180+ return String.format("%d回", count-1);
181+ }
182+ catch(NumberFormatException e){
183+ }
184+
185+ return copycount + "回";
186+ }
187+ }
188+
189+ // 詳細情報を整形する
190+ public String formatDetail(){
191+ String detail =
192+ "番組タイトル:" + getTitle() + "\n" +
193+ "録画モード:" + getRec_mode() + "\n" +
194+ "フォルダ:" + getFolderNameList() + "\n";
195+
196+ String g = "";
197+ for (TextValueSet ts : getRec_genre()){
198+ if (!g.equals(""))
199+ g += ",";
200+ g += ts.getValue() + ":" + ts.getText();
201+ }
202+
203+ detail += "ジャンル:" + g + "\n";
204+ detail += "コピー回数:" + formatCopyCount() + "\n";
205+// detail += "CONTENT ID:" + getContentId() + "\n";
206+
207+ String dlnaObjectID = getHidden_params().get("dlnaObjectID");
208+ if (dlnaObjectID != null)
209+ detail += "DLNA OID:" + dlnaObjectID + "\n";
210+
211+ return detail;
212+ }
168213 }
--- a/TinyBannavi/src/tainavi/VersionInfo.java
+++ b/TinyBannavi/src/tainavi/VersionInfo.java
@@ -5,7 +5,7 @@ import java.util.regex.Pattern;
55
66
77 public class VersionInfo {
8- private static final String Version = "タイニー番組ナビゲータ for DBR-T2007 3.22.18β+1.12";
8+ private static final String Version = "タイニー番組ナビゲータ for DBR-T2007 3.22.18β+1.12.1";
99
1010 private static final String OSname = System.getProperty("os.name");
1111 private static final String OSvers = System.getProperty("os.version");
--- a/TinyBannavi/src/tainavi/Viewer.java
+++ b/TinyBannavi/src/tainavi/Viewer.java
@@ -2116,6 +2116,7 @@ public class Viewer extends JFrame implements ChangeListener,TickTimerListener,H
21162116 if (env.getDebug()) System.out.println("Timer Rised: now="+CommonUtils.getDateTimeYMDx(e.getCalendar()));
21172117 setTitleBar();
21182118 checkReservesForNotify();
2119+ checkPickProgsForNotify();
21192120 checkDownloadProgramTime(e.getCalendar());
21202121 }
21212122
@@ -2127,12 +2128,29 @@ public class Viewer extends JFrame implements ChangeListener,TickTimerListener,H
21272128 return;
21282129 if (reserved == null)
21292130 return;
2130-
21312131 ArrayList<String> list = new ArrayList<String>();
21322132 reserved.getReservesToNotify(list);
21332133
21342134 for (String s : list){
2135- trayicon.displayMessage("TinyBannavi", s, MessageType.INFO);
2135+ trayicon.displayMessage("TinyBannaviからのお知らせ", s, MessageType.INFO);
2136+ }
2137+ }
2138+
2139+ /*
2140+ * 開始間もなくのピックアップ番組を通知する
2141+ */
2142+ private void checkPickProgsForNotify(){
2143+ if (!env.getNotifyBeforePickProgStart())
2144+ return;
2145+
2146+ if (listed == null)
2147+ return;
2148+
2149+ ArrayList<String> list = new ArrayList<String>();
2150+ listed.getPickupsToNotify(list);
2151+
2152+ for (String s : list){
2153+ trayicon.displayMessage("TinyBannaviからのお知らせ", s, MessageType.INFO);
21362154 }
21372155 }
21382156
@@ -2461,12 +2479,12 @@ public class Viewer extends JFrame implements ChangeListener,TickTimerListener,H
24612479 tvp.refresh();
24622480 tvp.add(tvd);
24632481 tvp.save();
2464- /*
2465- if ( listed.isNodeSelected(ListedTreeNode.PICKUP) ) {
2482+
2483+ if ( listed.isNodeSelected(JTreeLabel.Nodes.PICKUP) || listed.isNodeSelected(JTreeLabel.Nodes.STANDBY) ) {
24662484 // ピックアップノードが選択されていたらリストを更新する
24672485 listed.reselectTree();
24682486 }
2469- */
2487+
24702488 listed.updateReserveMark();
24712489 listed.refocus();
24722490 paper.updateReserveBorder(tvd.center);
@@ -5079,7 +5097,7 @@ public class Viewer extends JFrame implements ChangeListener,TickTimerListener,H
50795097 HDDRecorder rec = rPlugin.clone();
50805098 recorders.add(rec);
50815099
5082- rec.getChCode().load(true); // true : ログ出力あり
5100+ rec.getChCode().load(env.getDebug()); // true : ログ出力あり
50835101 setSettingRecPluginBase(rec, ri);
50845102 setSettingRecPluginExt(rec,env);
50855103 rec.setProgressArea(stwin);
--- a/TinyBannavi/src/tainavi/pluginrec/PlugIn_RecDBR_T2007.java
+++ b/TinyBannavi/src/tainavi/pluginrec/PlugIn_RecDBR_T2007.java
@@ -14,7 +14,6 @@ import java.util.Locale;
1414 import java.util.regex.Matcher;
1515 import java.util.regex.Pattern;
1616
17-import tainavi.AbsTitleListView;
1817 import tainavi.AribCharMap;
1918 import tainavi.ChannelCode;
2019 import tainavi.ChapterInfo;
@@ -406,7 +405,6 @@ public class PlugIn_RecDBR_T2007 extends HDDRecorderUtils implements HDDRecorder
406405 ReservesToFile(getReserves(), rsvedFile);
407406
408407 reportProgress(MSGID+"正常に登録できました。");
409- System.out.printf("\n<<< Message from RD >>> \"%s\"\n\n", "正常に登録できました。");
410408
411409 return(true);
412410 }
@@ -457,7 +455,6 @@ public class PlugIn_RecDBR_T2007 extends HDDRecorderUtils implements HDDRecorder
457455 ReservesToFile(getReserves(), rsvedFile);
458456
459457 reportProgress(MSGID+"正常に更新できました。");
460- System.out.printf("\n<<< Message from RD >>> \"%s\"\n\n", "正常に更新できました。");
461458
462459 return(true);
463460 }
@@ -767,8 +764,6 @@ public class PlugIn_RecDBR_T2007 extends HDDRecorderUtils implements HDDRecorder
767764 return(false);
768765 }
769766
770- updateTitleDetail(t);
771-
772767 // 録画タイトルリストを更新
773768 ArrayList<TitleInfo> list = getTitles();
774769 list.remove(o);
@@ -904,7 +899,6 @@ public class PlugIn_RecDBR_T2007 extends HDDRecorderUtils implements HDDRecorder
904899 }
905900
906901 reportProgress(MSGID+"正常に" + action + "できました。");
907-// System.out.printf("\n<<< Message from RD >>> \"%s\"\n\n", "正常に" + action + "できました。");
908902
909903 return(true);
910904 }
@@ -1792,9 +1786,6 @@ public class PlugIn_RecDBR_T2007 extends HDDRecorderUtils implements HDDRecorder
17921786 entry.setSerial(++serial);
17931787 setTitleBasicInfo(entry, titlename, ch, datetime, duration, device_id, folders, genres);
17941788
1795- // 詳細情報のテキストを更新する
1796- updateTitleDetail(entry);
1797-
17981789 // 予約情報を保存
17991790 list.add(entry.clone());
18001791 }
@@ -1975,47 +1966,12 @@ public class PlugIn_RecDBR_T2007 extends HDDRecorderUtils implements HDDRecorder
19751966
19761967 t.setRecording(recording);
19771968
1978- // 詳細情報のテキストを更新する
1979- updateTitleDetail(t);
1980-
19811969 t.setDetailLoaded(true);
19821970
19831971 return(true);
19841972 }
19851973
19861974 /**
1987- * タイトルの詳細情報のテキストを更新する
1988- *
1989- */
1990- protected void updateTitleDetail(TitleInfo t) {
1991- String detail =
1992- "番組タイトル:" + t.getTitle() + "\n" +
1993- "録画モード:" + t.getRec_mode() + "\n" +
1994- "フォルダ:" + t.getFolderNameList() + "\n";
1995-
1996- String g = "";
1997- for (TextValueSet ts : t.getRec_genre()){
1998- if (!g.equals(""))
1999- g += ",";
2000- g += ts.getValue() + ":" + ts.getText();
2001- }
2002-
2003- detail += "ジャンル:" + g + "\n";
2004-
2005- String copycount = t.getHidden_params().get("copycount");
2006- if (copycount != null)
2007- detail += "コピー回数:" + (copycount.equals("1") ? AbsTitleListView.MOVEONLY : copycount + "回") + "\n";
2008-
2009-// detail += "CONTENT ID:" + t.getContentId() + "\n";
2010-
2011- String dlnaObjectID = t.getHidden_params().get("dlnaObjectID");
2012- if (dlnaObjectID != null)
2013- detail += "DLNA OID:" + dlnaObjectID + "\n";
2014-
2015- t.setDetail(detail);
2016- }
2017-
2018- /**
20191975 * フォルダーのJSONテキストを解析する
20201976 */
20211977 protected ArrayList<TextValueSet> parseFolders(String device_id, String s) {
--- a/TinyBannavi/src/tainavi/plugintv/PlugIn_TVPTVKingdom.java
+++ b/TinyBannavi/src/tainavi/plugintv/PlugIn_TVPTVKingdom.java
@@ -188,8 +188,14 @@ public class PlugIn_TVPTVKingdom extends TVProgramUtils implements TVProgram,Clo
188188 String url = null;
189189 String cookie = null;
190190 if (ac.equals(bsCode)) {
191+ // BS4K8K
192+ if (d>bscnt){
193+ int d4k = d-bscnt;
194+ url = "https://tv.so-net.ne.jp/chart/bs4k8k_"+d4k+".action?head="+date+"&span=24";
195+ }
191196 // BS
192- url = "https://tv.so-net.ne.jp/chart/bs"+d+".action?head="+date+"&span=24";
197+ else
198+ url = "https://tv.so-net.ne.jp/chart/bs"+d+".action?head="+date+"&span=24";
193199 cookie = null;
194200 }
195201 else {
@@ -666,7 +672,8 @@ public class PlugIn_TVPTVKingdom extends TVProgramUtils implements TVProgram,Clo
666672
667673 // 地上派・UHFは地域別に扱う
668674
669- int cntMax = ((code.equals(allCode))?(aclist.size()-2):(1))+bscnt;
675+ int bs4kcnt = 2; // BS4K8Kのページ数は現状固定
676+ int cntMax = ((code.equals(allCode))?(aclist.size()-2):(1))+bscnt+bs4kcnt;
670677 int cnt = 1;
671678 for (AreaCode ac : aclist) {
672679 if (ac.getCode().equals(bsCode)) {
@@ -703,6 +710,15 @@ public class PlugIn_TVPTVKingdom extends TVProgramUtils implements TVProgram,Clo
703710 cnt++;
704711 }
705712
713+ // BS4K&8Kは共通にする(ページ数はとりあえず固定)
714+ for ( int d=1; d<=bs4kcnt; d++ ){
715+ String url = "https://tv.so-net.ne.jp/chart/bs4k8k_"+d+".action?group=4"+d;
716+ if ( _loadCenter(newcrlist, bsCode, String.valueOf(bscnt+d), url) ) {
717+ reportProgress("放送局情報を取得しました: ("+cnt+"/"+cntMax+") "+url);
718+ }
719+ cnt++;
720+ }
721+
706722 // BSのページ数を記録する
707723
708724 if ( bscntTmp < bscnt ) {