• 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

Revision29e0e0454d3e205732c2a95533c33696517608fe (tree)
Time2021-01-15 22:02:03
AuthorMasahiko Kimura <mkimura@u01....>
CommiterMasahiko Kimura

Log Message

Ver.1.12.18 (2021/1/15)
1.[ツールバー]検索設定画面の追加(検索ボタン右の▼ボタンをクリックするか、Ctrl+Shift+K)
2.[予約ダイアログ]レコーダを切り替えた時もジャンル別あるいはデフォルトの画質設定を取得し直す
3.[新聞形式]ツリービューの選択が外れていても、ヘッダーのダブルクリックで日付別と放送局別を切り替えられる
4.[その他]番組表データの不要なフラグをログに出力しないようにする

Change Summary

Incremental Difference

--- a/TinyBannavi/src/tainavi/AbsPaperView.java
+++ b/TinyBannavi/src/tainavi/AbsPaperView.java
@@ -111,7 +111,7 @@ public abstract class AbsPaperView extends JPanel implements TickTimerListener,H
111111 * マウス右クリックメニューを表示する
112112 */
113113 protected abstract void showPopupMenu(
114- final JComponent comp, final ProgDetailList tvd, final int x, final int y);
114+ final JComponent comp, final ProgDetailList tvd, final int x, final int y, final String clickedDateTime);
115115
116116 /**
117117 * 予約マーク・予約枠を更新してほしい
@@ -632,11 +632,9 @@ public abstract class AbsPaperView extends JPanel implements TickTimerListener,H
632632 */
633633 public void redrawByPager() {
634634 Point vp = vport.getViewPosition();
635-// Dimension vs = vport.getSize();
636635
637636 redrawByCurrentSelection();
638637
639-// jLayeredPane_space_main_view.scrollRectToVisible(new Rectangle(vp, vs));
640638 vport.setViewPosition(vp);
641639 }
642640
@@ -644,88 +642,59 @@ public abstract class AbsPaperView extends JPanel implements TickTimerListener,H
644642 * 現在の選択状態で再描画する
645643 */
646644 public void redrawByCurrentSelection() {
647- TreePath path = jTree_tree.getSelectionPath();
648- // 何も選択されていない場合
649- if (path == null)
650- return;
651-
652- if ( path.getPathCount() == 2 ) {
653- // 親ノードとか触られても…
645+ JTreeLabel.Nodes node = jLabel_tree.getNode();
646+ String value = jLabel_tree.getValue();
647+ if (node == null || value == null)
654648 return;
655- }
656-
657- if ( path.getPathCount() == 3 ) {
658-
659- if (env.getDebug()) System.out.println(DBGID+"SELECTED treeSelListner "+path);
660-
661- stopTimer();
662649
663- JTreeLabel.Nodes node = JTreeLabel.Nodes.getNode(path.getPathComponent(1).toString());
664- String value = path.getLastPathComponent().toString();
650+ stopTimer();
665651
666- switch ( node ) {
652+ switch ( node ) {
653+ case DATE:
654+ case TERRA:
655+ case BS:
656+ case CS:
657+ IterationType type = IterationType.ALL;
658+ switch( node ){
667659 case DATE:
668- if ( JTreeLabel.Nodes.NOW.getLabel().equals(value) ) {
669- // 現在日時に移動する
670- redrawByNow(IterationType.ALL);
671- }
672- else {
673- redrawByDate(value,IterationType.ALL);
674- }
660+ type = IterationType.ALL;
675661 break;
676662 case TERRA:
677- if ( JTreeLabel.Nodes.NOW.getLabel().equals(value) ) {
678- redrawByNow(IterationType.TERRA);
679- }
680- else {
681- redrawByDate(value,IterationType.TERRA);
682- }
663+ type = IterationType.TERRA;
683664 break;
684665 case BS:
685- if ( JTreeLabel.Nodes.NOW.getLabel().equals(value) ) {
686- redrawByNow(IterationType.BS);
687- }
688- else {
689- redrawByDate(path.getLastPathComponent().toString(),IterationType.BS);
690- }
666+ type = IterationType.BS;
691667 break;
692668 case CS:
693- if ( JTreeLabel.Nodes.NOW.getLabel().equals(value) ) {
694- redrawByNow(IterationType.CS);
695- }
696- else {
697- redrawByDate(path.getLastPathComponent().toString(),IterationType.CS);
698- }
699- break;
700- case BCAST:
701- redrawByCenter(value);
702- break;
703- case PASSED:
704- PassedProgram passed = tvprograms.getPassed();
705- if ( passed.loadAllCenters(value) ) {
706- redrawByDate(value, IterationType.PASSED);
707- }
708- else {
709- MWin.appendError(ERRID+"過去ログが存在しません: "+value);
710- ringBeep();
711- }
669+ type = IterationType.CS;
712670 break;
713671 default:
714672 break;
715673 }
716-
717- updatePagerEnabled();
718-
719- jLabel_tree.setView(node, value);
720- return;
674+ // 現在日時に移動する
675+ if ( JTreeLabel.Nodes.NOW.getLabel().equals(value) )
676+ redrawByNow(type);
677+ else
678+ redrawByDate(value, type);
679+ break;
680+ case BCAST:
681+ redrawByCenter(value);
682+ break;
683+ case PASSED:
684+ PassedProgram passed = tvprograms.getPassed();
685+ if ( passed.loadAllCenters(value) ) {
686+ redrawByDate(value, IterationType.PASSED);
687+ }
688+ else {
689+ MWin.appendError(ERRID+"過去ログが存在しません: "+value);
690+ ringBeep();
691+ }
692+ break;
693+ default:
694+ break;
721695 }
722696
723- // なんかおかしいのでデフォルト選択にまわす
724- CommonUtils.printStackTrace();
725- MWin.appendError(DBGID+"デバッグまで仮置き");
726- //redrawByNow(IterationType.ALL);
727- //jLabel_tree.setView(JTreeLabel.Nodes.DATE, JTreeLabel.Nodes.NOW.getLabel());
728-
697+ updatePagerEnabled();
729698 }
730699
731700 /**
@@ -1382,12 +1351,11 @@ public abstract class AbsPaperView extends JPanel implements TickTimerListener,H
13821351 if (jLabel_timeline == null | jLabel_timeline_tb == null || vport == null)
13831352 return;
13841353
1385- // 表示中のパスを取得する
1386- TreePath path = jTree_tree.getSelectionPath();
1387-
13881354 // 第1階層のノード、第2階層のノード名を取得する
1389- JTreeLabel.Nodes node1 = JTreeLabel.Nodes.getNode(path.getPathComponent(1).toString());
1390- String node2 = path.getPathCount() > 2 ? path.getPathComponent(2).toString() : "";
1355+ JTreeLabel.Nodes node1 = jLabel_tree.getNode();
1356+ String node2 = jLabel_tree.getValue();
1357+ if (node2 == null)
1358+ node2 = "";
13911359
13921360 // 当日の日付を計算する
13931361 int correct = 0; // 24:00-28:59迄は前日の日付になる
@@ -2616,13 +2584,14 @@ public abstract class AbsPaperView extends JPanel implements TickTimerListener,H
26162584
26172585 if ( timer_now_enabled ) {
26182586 // 表示中のノード
2619- TreePath path = jTree_tree.getSelectionPath();
2620- JTreeLabel.Nodes node = JTreeLabel.Nodes.getNode(path.getPathComponent(1).toString());
2621- String date = path.getPathCount() > 2 ? path.getPathComponent(2).toString() : "";
2587+ JTreeLabel.Nodes node = jLabel_tree.getNode();
2588+ String value = jLabel_tree.getValue();
2589+ if (node == null || value == null)
2590+ return;
26222591
2623- boolean now = (node == JTreeLabel.Nodes.DATE || node == JTreeLabel.Nodes.BS ||
2624- node == JTreeLabel.Nodes.CS || node == JTreeLabel.Nodes.TERRA) &&
2625- dateNode.getChildAt(0).toString().equals(date);
2592+ boolean byCenter = (node == JTreeLabel.Nodes.DATE || node == JTreeLabel.Nodes.BS ||
2593+ node == JTreeLabel.Nodes.CS || node == JTreeLabel.Nodes.TERRA);
2594+ boolean now = byCenter && dateNode.getChildAt(0).toString().equals(value);
26262595
26272596 if (prevDT4Now != null && ! prevDT4Now.equals(curDT)){
26282597 // 日付切り替え
@@ -2640,6 +2609,11 @@ public abstract class AbsPaperView extends JPanel implements TickTimerListener,H
26402609
26412610 if (now)
26422611 redrawByNow(cur_tuner);
2612+ else if (byCenter && !value.equals("")){
2613+ c = CommonUtils.getCalendar(value, 3600*24);
2614+ if (c != null)
2615+ redrawByDateWithCenter(node.getLabel(), CommonUtils.getDate(c));
2616+ }
26432617 else
26442618 redrawByCurrentSelection();
26452619 }
@@ -2719,7 +2693,7 @@ public abstract class AbsPaperView extends JPanel implements TickTimerListener,H
27192693 if (e.getClickCount() == 1) {
27202694 // 右シングルクリックでメニューの表示
27212695 String clicked = getClickedDateTime(tvd, e.getY());
2722- showPopupMenu(b, tvd, p.x, p.y);
2696+ showPopupMenu(b, tvd, p.x, p.y, clicked);
27232697 }
27242698 }
27252699 else if (e.getButton() == MouseEvent.BUTTON1) {
@@ -2856,13 +2830,14 @@ public abstract class AbsPaperView extends JPanel implements TickTimerListener,H
28562830 */
28572831 private final TreePath getNextDatePath(boolean next){
28582832 // 表示中のノード
2859- TreePath path = jTree_tree.getSelectionPath();
2833+ JTreeLabel.Nodes node = jLabel_tree.getNode();
2834+ String value = jLabel_tree.getValue();
2835+ if (node == null || value == null)
2836+ return null;
28602837
28612838 DefaultMutableTreeNode pnode = null;
28622839 int offset = next ? 1 : -1;
28632840
2864- JTreeLabel.Nodes node = JTreeLabel.Nodes.getNode(path.getPathComponent(1).toString());
2865-
28662841 switch(node){
28672842 case DATE:
28682843 pnode = dateNode;
@@ -2888,10 +2863,7 @@ public abstract class AbsPaperView extends JPanel implements TickTimerListener,H
28882863 return null;
28892864 }
28902865
2891- if (path.getPathCount() < 3)
2892- return null;
2893-
2894- String date = path.getPathComponent(2).toString();
2866+ String date = value;
28952867 String today = JTreeLabel.Nodes.NOW.getLabel();
28962868
28972869 // 特殊なケース(今日⇔昨日)
@@ -3022,7 +2994,23 @@ public abstract class AbsPaperView extends JPanel implements TickTimerListener,H
30222994 private final TreeSelectionListener tsl_nodeselected = new TreeSelectionListener() {
30232995 @Override
30242996 public void valueChanged(TreeSelectionEvent e){
2997+ TreePath path = jTree_tree.getSelectionPath();
2998+ if (path == null)
2999+ return;
30253000
3001+ if (env.getDebug()) System.out.println(DBGID+"SELECTED treeSelListner "+path);
3002+
3003+ // 3層目が選択されていない場合は無視する
3004+ if (path.getPathCount() != 3)
3005+ return;
3006+
3007+ // 2層目と3層目を取得してラベルにセットする
3008+ JTreeLabel.Nodes node = JTreeLabel.Nodes.getNode(path.getPathComponent(1).toString());
3009+ String value = path.getLastPathComponent().toString();
3010+
3011+ jLabel_tree.setView(node, value);
3012+
3013+ // セットした選択状態で再描画する
30263014 redrawByCurrentSelection();
30273015 }
30283016 };
@@ -3063,13 +3051,14 @@ public abstract class AbsPaperView extends JPanel implements TickTimerListener,H
30633051 public void mouseClicked(MouseEvent e) {
30643052 if (e.getButton() == MouseEvent.BUTTON1) {
30653053 if (e.getClickCount() == 2) {
3066- TreePath path = jTree_tree.getSelectionPath();
3067- if (path == null || path.getPathCount() != 3)
3054+ JTreeLabel.Nodes node = jLabel_tree.getNode();
3055+ String value = jLabel_tree.getValue();
3056+ if (node == null || value == null)
30683057 return;
30693058
30703059 // 過去ログノードの場合、選択されているノードを開始日とする
3071- if (path.getPathComponent(1) == passedNode)
3072- startDate = path.getPathComponent(2).toString();
3060+ if (node == JTreeLabel.Nodes.PASSED)
3061+ startDate = value;
30733062 else
30743063 startDate = CommonUtils.getDate529(0, true);
30753064
@@ -3102,13 +3091,12 @@ public abstract class AbsPaperView extends JPanel implements TickTimerListener,H
31023091 public void mouseClicked(MouseEvent e) {
31033092 if (e.getButton() == MouseEvent.BUTTON1) {
31043093 if (e.getClickCount() == 2) {
3105- // 右ダブルクリックで日付表示に切り替え
3106-
3107- TreePath path = jTree_tree.getSelectionPath();
3108- if (path == null || path.getPathCount() != 3)
3094+ JTreeLabel.Nodes node = jLabel_tree.getNode();
3095+ String value = jLabel_tree.getValue();
3096+ if (node == null || value == null)
31093097 return;
31103098
3111- String center = path.getPathComponent(2).toString();
3099+ String center = value;
31123100 String date = ((JTXTLabel)e.getSource()).getValue();
31133101
31143102 StdAppendMessage(MSGID+"日付表示に切り替え:"+date);
--- a/TinyBannavi/src/tainavi/AbsToolBar.java
+++ b/TinyBannavi/src/tainavi/AbsToolBar.java
@@ -59,7 +59,7 @@ public abstract class AbsToolBar extends JToolBar implements HDDRecorderSelectab
5959 public void setDebug(boolean b) {debug = b; }
6060 private boolean debug = false;
6161
62- private SearchWordList swlist = new SearchWordList();
62+ protected SearchWordList swlist = new SearchWordList();
6363
6464 /*******************************************************************************
6565 * 抽象メソッド
@@ -109,6 +109,7 @@ public abstract class AbsToolBar extends JToolBar implements HDDRecorderSelectab
109109 // 共通
110110 protected abstract boolean recorderSelectorChanged();
111111 protected abstract void takeSnapShot();
112+ protected abstract void openSearchDialog(JButton button);
112113 // メインウィンドウ
113114 /**
114115 * 親から呼ばないでくださいね!
@@ -177,6 +178,7 @@ public abstract class AbsToolBar extends JToolBar implements HDDRecorderSelectab
177178
178179 private static final String TIPS_KEYWORD = "<HTML><B>検索ボックスの書式</B><BR>検索:(オプション1) (オプション2) キーワード <BR>過去ログ検索:開始日[(YYYY/)MM/DD] 終了日[(YYYY/)MM/DD] (オプション2) キーワード<BR>過去ログ閲覧:日付[YYYY/MM/DD]<BR>※オプション1:@filter..絞込検索(過去ログは対象外)<BR>※オプション2:#title..番組名一致、#detail..番組詳細一致、なし..番組名&番組詳細一致<BR><B>Ctrl+D:キーワードをコンボボックスから削除する</B><BR></HTML>";
179180 private static final String TIPS_SEARCH = "キーワード検索 or 過去ログ閲覧";
181+ private static final String TIPS_SEARCH_MENU = "検索設定画面(Ctrl+Shift+K)";
180182 private static final String TIPS_ADDKEYWORD = "キーワードリストに登録(Ctrl+K)";
181183 private static final String TIPS_PAGER = "ページャー";
182184 private static final String TIPS_RELOADPROG = "Webから番組情報を再取得(Ctrl+W)";
@@ -223,8 +225,9 @@ public abstract class AbsToolBar extends JToolBar implements HDDRecorderSelectab
223225 // ツールバーのコンポーネント
224226
225227 private JComboBoxWithPopup jComboBox_keyword = null;
226- private JTextField jTextField_keyword = null;
228+ protected JTextField jTextField_keyword = null;
227229 private JButton jButton_search = null;
230+ private JButton jButton_searchmenu = null;
228231 private JButton jButton_addkeyword = null;
229232 private JWideComboBox jComboBox_select_recorder = null;
230233 private JWideComboBox jComboBox_pager = null;
@@ -284,6 +287,7 @@ public abstract class AbsToolBar extends JToolBar implements HDDRecorderSelectab
284287 private void createComponents(){
285288 getJComboBox_keyword();
286289 getJButton_search("キーワード検索");
290+ getJButton_searchmenu("キーワード検索メニュー");
287291 getJButton_addkeyword("キーワード一覧に登録");
288292
289293 getJButton_reloadprogs("番組情報再取得");
@@ -352,6 +356,7 @@ public abstract class AbsToolBar extends JToolBar implements HDDRecorderSelectab
352356 break;
353357 case SEARCH:
354358 this.add(jButton_search);
359+ this.add(jButton_searchmenu);
355360 break;
356361 case ADDKEYWORD:
357362 this.add(jButton_addkeyword);
@@ -501,12 +506,20 @@ public abstract class AbsToolBar extends JToolBar implements HDDRecorderSelectab
501506 /**
502507 * キーワード検索ボックスからの検索の実行
503508 */
504- private void toolbarSearch() {
509+ protected void toolbarSearch(String keywordArg) {
505510 // 入力形式による分岐
506511 boolean doFilter = false;
507512 String sStr = null;
508513 String kStr = null;
509- String keywordStr = jTextField_keyword.getText().trim();
514+ String keywordStr = keywordArg != null ? keywordArg : jTextField_keyword.getText().trim();
515+
516+ // 過去ログ閲覧
517+ if (keywordStr.matches("^\\d\\d\\d\\d/\\d\\d/\\d\\d$")) {
518+ if ( ! jumpToPassed(keywordStr)) {
519+ JOptionPane.showConfirmDialog(null, keywordStr+"はみつからなかったでゲソ!", "警告", JOptionPane.CLOSED_OPTION);
520+ }
521+ return;
522+ }
510523
511524 if (swlist.add(keywordStr)){
512525 swlist.save();
@@ -661,6 +674,13 @@ public abstract class AbsToolBar extends JToolBar implements HDDRecorderSelectab
661674 jTextField_keyword.requestFocusInWindow();
662675 }
663676
677+ /*
678+ * 「検索設定画面」を表示する
679+ */
680+ public void openSearchDialog() {
681+ openSearchDialog(jButton_searchmenu);
682+ }
683+
664684 /**
665685 *
666686 */
@@ -1304,14 +1324,17 @@ public abstract class AbsToolBar extends JToolBar implements HDDRecorderSelectab
13041324 private final ActionListener al_keywordEntered = new ActionListener() {
13051325 @Override
13061326 public void actionPerformed(ActionEvent e) {
1307- if (jTextField_keyword.getText().matches("^\\d\\d\\d\\d/\\d\\d/\\d\\d$")) {
1308- if ( ! jumpToPassed(jTextField_keyword.getText())) {
1309- JOptionPane.showConfirmDialog(null, jTextField_keyword.getText()+"はみつからなかったでゲソ!", "警告", JOptionPane.CLOSED_OPTION);
1310- }
1311- }
1312- else {
1313- toolbarSearch();
1314- }
1327+ toolbarSearch(null);
1328+ }
1329+ };
1330+
1331+ /*
1332+ * 「キーワード検索メニュー」ボタンが押された
1333+ */
1334+ private final MouseAdapter ma_searchMenu = new MouseAdapter() {
1335+ @Override
1336+ public void mousePressed(MouseEvent e) {
1337+ openSearchDialog();
13151338 }
13161339 };
13171340
@@ -1696,6 +1719,18 @@ public abstract class AbsToolBar extends JToolBar implements HDDRecorderSelectab
16961719 return jButton_search;
16971720 }
16981721
1722+ // 「検索拡張メニュー」ボタン
1723+ private JButton getJButton_searchmenu(String s) {
1724+ if (jButton_searchmenu == null) {
1725+ ImageIcon arrow = new ImageIcon(ICONFILE_PULLDOWNMENU);
1726+ jButton_searchmenu = new JButton(arrow);
1727+ jButton_searchmenu.setToolTipText(TIPS_SEARCH_MENU);
1728+
1729+ jButton_searchmenu.addMouseListener(ma_searchMenu);
1730+ }
1731+ return jButton_searchmenu;
1732+ }
1733+
16991734 // 「キーワード検索に登録」
17001735 private JButton getJButton_addkeyword(String s) {
17011736 if (jButton_addkeyword == null) {
--- a/TinyBannavi/src/tainavi/RecSettingEditorPanel.java
+++ b/TinyBannavi/src/tainavi/RecSettingEditorPanel.java
@@ -1011,6 +1011,8 @@ public class RecSettingEditorPanel extends JPanel {
10111011
10121012 recsetsel.doSelectRecorder(getSelectedRecorderId());
10131013
1014+ recsetsel.doSetAVSettings();
1015+
10141016 setEnabledListenerAll(true); // 再開
10151017 }
10161018 }
--- /dev/null
+++ b/TinyBannavi/src/tainavi/VWSearchWordDialog.java
@@ -0,0 +1,928 @@
1+package tainavi;
2+
3+import java.awt.Color;
4+import java.awt.Dimension;
5+import java.awt.Font;
6+import java.awt.Point;
7+import java.awt.Rectangle;
8+import java.awt.event.ActionEvent;
9+import java.awt.event.ActionListener;
10+import java.awt.event.ItemEvent;
11+import java.awt.event.ItemListener;
12+import java.awt.event.KeyEvent;
13+import java.awt.event.KeyListener;
14+import java.awt.event.MouseAdapter;
15+import java.awt.event.MouseEvent;
16+import java.awt.event.WindowEvent;
17+import java.awt.event.WindowListener;
18+import java.text.SimpleDateFormat;
19+import java.time.Instant;
20+import java.util.GregorianCalendar;
21+import java.util.regex.Matcher;
22+import java.util.regex.Pattern;
23+
24+import javax.swing.AbstractAction;
25+import javax.swing.InputMap;
26+import javax.swing.JButton;
27+import javax.swing.JCheckBox;
28+import javax.swing.JComponent;
29+import javax.swing.JLabel;
30+import javax.swing.JOptionPane;
31+import javax.swing.JPanel;
32+import javax.swing.JTextField;
33+import javax.swing.KeyStroke;
34+import javax.swing.SpringLayout;
35+import javax.swing.border.LineBorder;
36+import javax.swing.event.DocumentEvent;
37+import javax.swing.event.DocumentListener;
38+
39+/*
40+ * 検索文字列入力画面
41+ *
42+ */
43+public class VWSearchWordDialog extends JEscCancelDialog {
44+
45+ private static final long serialVersionUID = 1L;
46+
47+ /*******************************************************************************
48+ * 定数
49+ ******************************************************************************/
50+
51+ // レイアウト関連
52+
53+ private static final int PARTS_HEIGHT = 30;
54+ private static final int SEP_WIDTH = 10;
55+ private static final int SEP_HEIGHT = 10;
56+ private static final int SEARCH_HEIGHT = 45;
57+
58+ private static final int LABEL_WIDTH = 120;
59+
60+ private static final int TEXT_WIDTH = 500;
61+ private static final int CHECKBOX_WIDTH = 150;
62+ private static final int DATE_WIDTH = 120;
63+ private static final int AMONG_WIDTH = 30;
64+ private static final int NOTE_WIDTH = 600;
65+ private static final int NOTE_HEIGHT = PARTS_HEIGHT*2;
66+
67+ private static final int BUTTON_WIDTH = 120;
68+
69+ private static final int PANEL_WIDTH = SEP_WIDTH+LABEL_WIDTH+SEP_WIDTH+TEXT_WIDTH+SEP_WIDTH*2+BUTTON_WIDTH+SEP_WIDTH;
70+
71+ // その他
72+ private static final int MAX_SEARCH_WORDS = 32;
73+
74+ /*******************************************************************************
75+ * 部品
76+ ******************************************************************************/
77+
78+ private JPanel jPanel = null;
79+
80+ private JLabel jLabel_swlist = null;
81+ private JComboBoxWithPopup jComboBox_swlist = null;
82+// private JTextField jTextField_swlist = null;
83+
84+ private JLabel jLabel_keyword = null;
85+ private JTextField jTextField_keyword = null;
86+
87+ private JLabel jLabel_options = null;
88+ private JCheckBox jCheckBox_title = null;
89+ private JCheckBox jCheckBox_detail = null;
90+ private JCheckBox jCheckBox_filter = null;
91+
92+ private JLabel jLabel_period = null;
93+ private JTextField jTextField_from = null;
94+ private JLabel jLabel_among = null;
95+ private JTextField jTextField_to = null;
96+ private JButton jButton_same = null;
97+
98+ private JButton jButton_delete = null;
99+ private JButton jButton_search = null;
100+// private JButton jButton_cancel = null;
101+ private JButton jButton_clear = null;
102+ private JLabel jLabel_note = null;
103+
104+ private JButton jButton_menu = null;
105+ private AbsToolBar jToolbar = null;
106+
107+ // コンポーネント以外
108+ private Instant last_shown = null;
109+ private SearchWordList swlist = null;
110+ private boolean autoclose_enabled = true;
111+
112+ /*******************************************************************************
113+ * コンストラクタ
114+ ******************************************************************************/
115+
116+ public VWSearchWordDialog() {
117+
118+ super();
119+
120+// this.setModal(true);
121+// this.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); // 閉じるときはキャンセルボタンを使ってクレ
122+ this.addWindowListener(wl_panel);
123+ this.setAlwaysOnTop(true);
124+ this.setContentPane(getJPanel());
125+ this.setUndecorated(true);
126+ this.pack();
127+ this.setTitle("検索条件の編集");
128+ this.setResizable(false);
129+ }
130+
131+ /*******************************************************************************
132+ * 公開メソッド
133+ ******************************************************************************/
134+ /*
135+ * ダイアログを表示する
136+ */
137+ public void open(AbsToolBar jtoolbar, JButton jbutton, SearchWordList list, String s){
138+ jToolbar = jtoolbar;
139+ jButton_menu = jbutton;
140+ swlist = list;
141+
142+ Instant now = Instant.now();
143+ if (last_shown != null && now.minusMillis(100).isBefore(last_shown))
144+ return;
145+
146+ updateKeywordComboBox();
147+ if (s != null){
148+ jComboBox_swlist.setSelectedItem(s);
149+
150+ if (s.isEmpty()){
151+ doClear();
152+ }
153+ else{
154+ decodeKeyword(s);
155+ }
156+ }
157+
158+ updateControlStatus();
159+ setVisible(true);
160+ }
161+
162+ /*
163+ * 表示・非表示を切り替える
164+ *
165+ * @see java.awt.Dialog#setVisible(boolean)
166+ */
167+ @Override
168+ public void setVisible(boolean b) {
169+ if (b){
170+ setLocation();
171+ jTextField_keyword.requestFocusInWindow();
172+ }
173+ else{
174+ last_shown = Instant.now();
175+ }
176+
177+ super.setVisible(b);
178+ }
179+
180+ /*
181+ * ダイアログを▼ボタンの下、ツールバーの左端に位置決めする
182+ */
183+ public void setLocation(){
184+ Point pf = jToolbar.getLocationOnScreen();
185+// Rectangle rf = jToolbar.getBounds();
186+
187+ Point pm = jButton_menu.getLocationOnScreen();
188+ Rectangle rm = jButton_menu.getBounds();
189+
190+ setPosition(pf.x, pm.y + rm.height);
191+ }
192+
193+ /*
194+ * ダイアログを位置決めする
195+ */
196+ public void setPosition(int x, int y) {
197+ Rectangle r = this.getBounds();
198+ r.x = x;
199+ r.y = y;
200+ this.setBounds(r);
201+ }
202+
203+ /*******************************************************************************
204+ * コンポーネント
205+ ******************************************************************************/
206+ /*
207+ * パネル全体
208+ */
209+ private JPanel getJPanel() {
210+ if (jPanel == null) {
211+ jPanel = new JPanel();
212+
213+ jPanel.setLayout(new SpringLayout());
214+
215+ // 1行目
216+ int y = SEP_HEIGHT;
217+ int x = SEP_WIDTH;
218+ CommonSwingUtils.putComponentOn(jPanel, getJLabel_swlist("検索履歴"), LABEL_WIDTH, PARTS_HEIGHT, x, y);
219+ x += LABEL_WIDTH + SEP_WIDTH;
220+ CommonSwingUtils.putComponentOn(jPanel, getJComboBox_swlist(), TEXT_WIDTH, PARTS_HEIGHT, x, y);
221+ x += TEXT_WIDTH + SEP_WIDTH*2;
222+ int xb = x;
223+ CommonSwingUtils.putComponentOn(jPanel, getJButton_delete("削除"), BUTTON_WIDTH, PARTS_HEIGHT, xb, y);
224+
225+ // 2行目
226+ y += PARTS_HEIGHT + SEP_HEIGHT;
227+ x = SEP_WIDTH;
228+ CommonSwingUtils.putComponentOn(jPanel, getJLabel_keyword("キーワード"), LABEL_WIDTH, PARTS_HEIGHT, x, y);
229+ x += LABEL_WIDTH + SEP_WIDTH;
230+ CommonSwingUtils.putComponentOn(jPanel, getJTextField_keyword(), TEXT_WIDTH, PARTS_HEIGHT, x, y);
231+ CommonSwingUtils.putComponentOn(jPanel, getJButton_search("検索"), BUTTON_WIDTH, SEARCH_HEIGHT, xb, y);
232+
233+ // 3行目
234+ y += PARTS_HEIGHT + SEP_HEIGHT;
235+ x = SEP_WIDTH;
236+ CommonSwingUtils.putComponentOn(jPanel, getJLabel_options("オプション"), LABEL_WIDTH, PARTS_HEIGHT, x, y);
237+ x += LABEL_WIDTH + SEP_WIDTH;
238+ CommonSwingUtils.putComponentOn(jPanel, getJCheckBox_title("番組名一致"), CHECKBOX_WIDTH, PARTS_HEIGHT, x, y);
239+ x += CHECKBOX_WIDTH;
240+ CommonSwingUtils.putComponentOn(jPanel, getJCheckBox_detail("番組詳細一致"), CHECKBOX_WIDTH, PARTS_HEIGHT, x, y);
241+ x += CHECKBOX_WIDTH;
242+ CommonSwingUtils.putComponentOn(jPanel, getJCheckBox_filter("絞り込み"), CHECKBOX_WIDTH, PARTS_HEIGHT, x, y);
243+ x += SEP_WIDTH;
244+// int yb2 = y;
245+// CommonSwingUtils.putComponentOn(jPanel, getJButton_cancel("閉じる"), BUTTON_WIDTH, PARTS_HEIGHT, xb, yb2);
246+
247+ // 4行目
248+ y += PARTS_HEIGHT + SEP_HEIGHT;
249+ x = SEP_WIDTH;
250+ CommonSwingUtils.putComponentOn(jPanel, getJLabel_period("過去ログ期間※"), LABEL_WIDTH, PARTS_HEIGHT, x, y);
251+ x += LABEL_WIDTH + SEP_WIDTH;
252+ CommonSwingUtils.putComponentOn(jPanel, getJTextField_from(), DATE_WIDTH, PARTS_HEIGHT, x, y);
253+ x += DATE_WIDTH;
254+ CommonSwingUtils.putComponentOn(jPanel, getJLabel_among("~"), AMONG_WIDTH, PARTS_HEIGHT, x, y);
255+ x += AMONG_WIDTH;
256+ CommonSwingUtils.putComponentOn(jPanel, getJTextField_to(), DATE_WIDTH, PARTS_HEIGHT, x, y);
257+ x += DATE_WIDTH;
258+ CommonSwingUtils.putComponentOn(jPanel, getJButton_same("同値"), BUTTON_WIDTH, PARTS_HEIGHT, x, y);
259+ x += BUTTON_WIDTH + SEP_WIDTH;
260+ CommonSwingUtils.putComponentOn(jPanel, getJButton_clear("クリア"), BUTTON_WIDTH, PARTS_HEIGHT, xb, y);
261+
262+ // 5行目
263+ y += PARTS_HEIGHT-5;
264+ x = SEP_WIDTH;
265+ CommonSwingUtils.putComponentOn(jPanel, getJLabel_note(), NOTE_WIDTH, NOTE_HEIGHT, x, y);
266+ y += NOTE_HEIGHT+SEP_HEIGHT;
267+
268+
269+ jPanel.setPreferredSize(new Dimension(PANEL_WIDTH, y));
270+ jPanel.setBorder(new LineBorder(Color.BLACK, 1));
271+
272+ // ESCキーをショートカットに登録する(が何故か効かない)
273+ String ESCKEYACTION = "escape";
274+ InputMap imap = getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
275+ imap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), ESCKEYACTION);
276+ getRootPane().getActionMap().put(ESCKEYACTION, new AbstractAction() {
277+ private static final long serialVersionUID = 1L;
278+ @Override
279+ public void actionPerformed(ActionEvent e) {
280+ doCancel();
281+ }
282+ });
283+ }
284+
285+ return jPanel;
286+ }
287+
288+ /*
289+ * 「検索履歴」ラベル
290+ */
291+ private JLabel getJLabel_swlist(String s) {
292+ if (jLabel_swlist == null) {
293+ jLabel_swlist = new JLabel(s);
294+ }
295+ return(jLabel_swlist);
296+ }
297+
298+ /*
299+ * 「検索履歴」コンボボックス
300+ */
301+ private JComboBoxWithPopup getJComboBox_swlist() {
302+ if (jComboBox_swlist == null) {
303+ jComboBox_swlist = new JComboBoxWithPopup();
304+ jComboBox_swlist.setMaximumRowCount(32);
305+ jComboBox_swlist.addItemListener(il_swlistSelected);
306+
307+// jTextField_swlist = ((JTextField)jComboBox_swlist.getEditor().getEditorComponent());
308+ }
309+
310+ return(jComboBox_swlist);
311+ }
312+
313+ /*
314+ * 「削除」ボタン
315+ */
316+ private JButton getJButton_delete(String s) {
317+ if (jButton_delete == null) {
318+ jButton_delete = new JButton();
319+ jButton_delete.setText(s);
320+ jButton_delete.setForeground(Color.RED);
321+
322+ jButton_delete.addMouseListener(new MouseAdapter() {
323+ @Override
324+ public void mouseClicked(MouseEvent e) {
325+ doDelete();
326+ jTextField_keyword.requestFocusInWindow();
327+ updateControlStatus();
328+ }
329+ });
330+ }
331+ return(jButton_delete);
332+ }
333+
334+ /*
335+ * 「キーワード」ラベル
336+ */
337+ private JLabel getJLabel_keyword(String s) {
338+ if (jLabel_keyword == null) {
339+ jLabel_keyword = new JLabel(s);
340+ }
341+ return(jLabel_keyword);
342+ }
343+
344+ /*
345+ * 「キーワード」テキストフィールド
346+ */
347+ private JTextField getJTextField_keyword() {
348+ if (jTextField_keyword == null) {
349+ jTextField_keyword = new JTextField();
350+ jTextField_keyword.addActionListener(al_search);
351+ jTextField_keyword.addKeyListener(kl_escape);
352+ jTextField_keyword.getDocument().addDocumentListener(dl_documentChanged);
353+ }
354+
355+ return(jTextField_keyword);
356+ }
357+
358+ /*
359+ * 「検索」ボタン
360+ */
361+ private JButton getJButton_search(String s) {
362+ if (jButton_search == null) {
363+ jButton_search = new JButton();
364+ jButton_search.setText(s);
365+
366+ Font f = jButton_search.getFont();
367+ jButton_search.setFont(f.deriveFont(f.getStyle() | Font.BOLD, f.getSize()));
368+
369+ jButton_search.addMouseListener(new MouseAdapter() {
370+ @Override
371+ public void mouseClicked(MouseEvent e) {
372+ doSearch();
373+ }
374+ });
375+ }
376+ return(jButton_search);
377+ }
378+
379+ /*
380+ * 「オプション」ラベル
381+ */
382+ private JLabel getJLabel_options(String s) {
383+ if (jLabel_options == null) {
384+ jLabel_options = new JLabel(s);
385+ }
386+ return(jLabel_options);
387+ }
388+
389+ /*
390+ * 「番組名一致」チェックボックス
391+ */
392+ private JCheckBox getJCheckBox_title(String s) {
393+ if (jCheckBox_title == null) {
394+ jCheckBox_title = new JCheckBox();
395+ jCheckBox_title.setText(s);
396+ jCheckBox_title.setSelected(true);
397+ }
398+ return(jCheckBox_title);
399+ }
400+
401+ /*
402+ * 「番組詳細一致」チェックボックス
403+ */
404+ private JCheckBox getJCheckBox_detail(String s) {
405+ if (jCheckBox_detail == null) {
406+ jCheckBox_detail = new JCheckBox();
407+ jCheckBox_detail.setText(s);
408+ jCheckBox_detail.setSelected(true);
409+ }
410+ return(jCheckBox_detail);
411+ }
412+
413+ /*
414+ * 「絞り込み」チェックボックス
415+ */
416+ private JCheckBox getJCheckBox_filter(String s) {
417+ if (jCheckBox_filter == null) {
418+ jCheckBox_filter = new JCheckBox();
419+ jCheckBox_filter.setText(s);
420+ }
421+ return(jCheckBox_filter);
422+ }
423+
424+ /*
425+ * 「キャンセル」ボタン
426+ */
427+// private JButton getJButton_cancel(String s) {
428+// if (jButton_cancel == null) {
429+// jButton_cancel = new JButton(s);
430+// jButton_cancel.addMouseListener(new MouseAdapter() {
431+// @Override
432+// public void mouseClicked(MouseEvent e) {
433+// doCancel();
434+// }
435+// });
436+// }
437+//
438+// return(jButton_cancel);
439+// }
440+
441+ /*
442+ * 「過去ログ期間」ラベル
443+ */
444+ private JLabel getJLabel_period(String s) {
445+ if (jLabel_period == null) {
446+ jLabel_period = new JLabel(s);
447+ }
448+ return(jLabel_period);
449+ }
450+
451+ /*
452+ * 「過去ログ期間開始」テキストフィールド
453+ */
454+ private JTextField getJTextField_from() {
455+ if (jTextField_from == null) {
456+ jTextField_from = new JTextFieldWithPopup();
457+
458+ jTextField_from.addActionListener(al_search);
459+ jTextField_from.addKeyListener(kl_escape);
460+ jTextField_from.getDocument().addDocumentListener(dl_documentChanged);
461+ }
462+
463+ return(jTextField_from);
464+ }
465+
466+ /*
467+ * 「~」ラベル
468+ */
469+ private JLabel getJLabel_among(String s) {
470+ if (jLabel_among == null) {
471+ jLabel_among = new JLabel(s);
472+ jLabel_among.setHorizontalAlignment(JLabel.CENTER);
473+ }
474+ return(jLabel_among);
475+ }
476+
477+ /*
478+ * 「過去ログ期間終了」テキストフィールド
479+ */
480+ private JTextField getJTextField_to() {
481+ if (jTextField_to == null) {
482+ jTextField_to = new JTextFieldWithPopup();
483+
484+ jTextField_to.addActionListener(al_search);
485+ jTextField_to.addKeyListener(kl_escape);
486+ jTextField_to.getDocument().addDocumentListener(dl_documentChanged);
487+ }
488+
489+ return(jTextField_to);
490+ }
491+
492+ /*
493+ * 「同日」ボタン
494+ */
495+ private JButton getJButton_same(String s) {
496+ if (jButton_same == null) {
497+ jButton_same = new JButton();
498+ jButton_same.setText(s);
499+
500+ jButton_same.addMouseListener(new MouseAdapter() {
501+ @Override
502+ public void mouseClicked(MouseEvent e) {
503+ jTextField_to.setText(jTextField_from.getText());
504+ }
505+ });
506+ }
507+ return(jButton_same);
508+ }
509+
510+ /*
511+ * 注釈ラベル
512+ */
513+ private JLabel getJLabel_note() {
514+ if (jLabel_note == null) {
515+ String s = "<html>※YYYY/MM/DDかMM/DDの形式で指定してください。<br>※YYYY/MM/DDで開始日のみ指定するとその日の過去ログが閲覧できます。</html>";
516+ jLabel_note = new JLabel(s);
517+
518+ }
519+ return(jLabel_note);
520+ }
521+
522+ /*
523+ * 「クリア」ボタン
524+ */
525+ private JButton getJButton_clear(String s) {
526+ if (jButton_clear == null) {
527+ jButton_clear = new JButton();
528+ jButton_clear.setText(s);
529+
530+ jButton_clear.addMouseListener(new MouseAdapter() {
531+ @Override
532+ public void mouseClicked(MouseEvent e) {
533+ doClear();
534+ jComboBox_swlist.setSelectedItem("");
535+ jTextField_keyword.requestFocusInWindow();
536+ }
537+ });
538+ }
539+ return(jButton_clear);
540+ }
541+
542+ /*******************************************************************************
543+ * アクション
544+ ******************************************************************************/
545+ /*
546+ * クリアする
547+ */
548+ protected void doClear(){
549+ jTextField_keyword.setText("");
550+ jTextField_from.setText("");
551+ jTextField_to.setText("");
552+
553+ jCheckBox_title.setSelected(true);
554+ jCheckBox_detail.setSelected(true);
555+ jCheckBox_filter.setSelected(false);
556+ }
557+
558+ /*
559+ * 履歴を削除する
560+ */
561+ protected void doDelete(){
562+ int no = jComboBox_swlist.getSelectedIndex();
563+ if (no < 1)
564+ return;
565+
566+ swlist.getWordList().remove(no-1);
567+ swlist.save();
568+ updateKeywordComboBox();
569+
570+ if (jComboBox_swlist.getItemCount() > no){
571+ jComboBox_swlist.setSelectedIndex(no);
572+ decodeKeyword((String)jComboBox_swlist.getSelectedItem());
573+ }
574+ else
575+ doClear();
576+ }
577+
578+ /*
579+ * キャンセルする
580+ *
581+ * @see tainavi.JEscCancelDialog#doCancel()
582+ */
583+ @Override
584+ protected void doCancel() {
585+ setVisible(false);
586+ }
587+
588+ /*
589+ * 検索する
590+ */
591+ protected boolean doSearch(){
592+ StringBuilder sb = new StringBuilder("");
593+
594+ String keyword = jTextField_keyword.getText();
595+
596+ String from = jTextField_from.getText();
597+ if (from.length() > 0){
598+ if (!checkDateFormat(from, true))
599+ return false;
600+
601+ sb.append(from);
602+ }
603+
604+ String to = jTextField_to.getText();
605+ if (to.length() > 0){
606+ if (!checkDateFormat(to, true))
607+ return false;
608+
609+ if (sb.length() > 0)
610+ sb.append(" ");
611+ sb.append(to);
612+ }
613+
614+ if (sb.length() == 0 && jCheckBox_filter.isSelected())
615+ sb.append("@filter");
616+
617+ if (keyword.length() > 0){
618+ if (jCheckBox_title.isSelected() && jCheckBox_detail.isSelected())
619+ ;
620+ else if (jCheckBox_title.isSelected()){
621+ if (sb.length() > 0)
622+ sb.append(" ");
623+ sb.append("#title");
624+ }
625+ else if (jCheckBox_detail.isSelected()){
626+ if (sb.length() > 0)
627+ sb.append(" ");
628+ sb.append("#detail");
629+ }
630+
631+ if (sb.length() > 0)
632+ sb.append(" ");
633+ sb.append(keyword);
634+ }
635+
636+ jToolbar.toolbarSearch(sb.toString());
637+
638+ setVisible(false);
639+
640+ return true;
641+ }
642+
643+ /*
644+ * 「検索履歴」コンボボックスを更新する
645+ */
646+ protected void updateKeywordComboBox(){
647+ String str = (String)jComboBox_swlist.getSelectedItem();
648+
649+ jComboBox_swlist.removeAllItems();
650+
651+ jComboBox_swlist.addItem("");
652+
653+ int num=0;
654+ for (SearchWordItem item : swlist.getWordList()){
655+ if (num >= MAX_SEARCH_WORDS)
656+ break;
657+
658+ jComboBox_swlist.addItem(item.getKeyword());
659+ num++;
660+ }
661+
662+ jComboBox_swlist.setSelectedItem(str);
663+ }
664+
665+ /*
666+ * 部品のステータスを更新する
667+ */
668+ protected void updateControlStatus(){
669+ String keyword = jTextField_keyword.getText();
670+ String from = jTextField_from.getText();
671+ String to = jTextField_to.getText();
672+ boolean isSelected = jComboBox_swlist.getSelectedIndex() > 0;
673+ boolean haskey = keyword.length() > 0;
674+ boolean hasrange = from.length() > 0 || to.length() > 0;
675+ boolean hasfrom = from.length() == 10 && to.length() == 0;
676+ boolean passlog = !haskey && hasfrom;
677+ boolean passkey = hasrange;
678+
679+ jButton_delete.setEnabled(isSelected);
680+ jButton_search.setEnabled(haskey || hasfrom);
681+ jButton_search.setText(passlog ? "過去ログ閲覧" : passkey ? "過去ログ検索" : "検索");
682+ jButton_same.setEnabled(hasrange);
683+
684+ jCheckBox_filter.setEnabled(!hasrange);
685+ jTextField_to.setEnabled(from.length() > 0);
686+
687+ jTextField_from.setForeground(checkDateFormat(from, false) ? Color.BLACK : Color.RED);
688+ jTextField_to.setForeground(checkDateFormat(to, false) ? Color.BLACK : Color.RED);
689+ }
690+
691+ /*
692+ * 過去日の年月日をチェックする
693+ */
694+ private boolean checkPassedDate(String syear, String smonth, String sday, boolean msg){
695+ int month = Integer.parseInt(smonth);
696+ int day = Integer.parseInt(sday);
697+
698+ if (month < 1 || month > 12 || day < 1 || day > 31)
699+ throw new NumberFormatException();
700+
701+ String today = null;
702+ String date = null;
703+ GregorianCalendar c = new GregorianCalendar();
704+ if (syear == null){
705+ today = new SimpleDateFormat("MM/dd").format(c.getTime());
706+ date = String.format("%02d/%02d", month, day);
707+ }
708+ else{
709+ int year = Integer.parseInt(syear);
710+ today = new SimpleDateFormat("yyyy/MM/dd").format(c.getTime());
711+ date = String.format("%04d/%02d/%02d", year, month, day);
712+ }
713+
714+ if (date.compareTo(today) >= 0){
715+ if (msg)
716+ showWarnMessage(date + ":過去日を指定してください。");
717+ return false;
718+ }
719+
720+ return true;
721+ }
722+
723+ /*
724+ * 日付のフォーマットをチェックする
725+ */
726+ private boolean checkDateFormat(String str, boolean msg){
727+ if (str.length() == 0)
728+ return true;
729+
730+ Matcher ma = Pattern.compile("^([0-9]{4})/([0-9]{2})/([0-9]{2})$").matcher(str);
731+ Matcher mb = Pattern.compile("^([0-9]{2})/([0-9]{2})$").matcher(str);
732+
733+ try{
734+ if (ma.find()){
735+ if (!checkPassedDate(ma.group(1), ma.group(2), ma.group(3), msg))
736+ return false;
737+ }
738+ else if (mb.find()){
739+ if (!checkPassedDate(null, mb.group(1), mb.group(2), msg))
740+ return false;
741+ }
742+ else{
743+ throw new NumberFormatException();
744+ }
745+ }
746+ catch(NumberFormatException e){
747+ if (msg){
748+ showWarnMessage(str+":不正な日付です!「YYYY/MM/DD」ないし「MM/DD」で指定してください。");
749+ }
750+ return false;
751+ }
752+
753+ return true;
754+ }
755+
756+ /*
757+ * 警告メッセージを表示する
758+ */
759+ private void showWarnMessage(String msg){
760+ autoclose_enabled = false;
761+ JOptionPane.showConfirmDialog(null, msg, "警告", JOptionPane.CLOSED_OPTION);
762+ autoclose_enabled = true;
763+ }
764+
765+ /*
766+ * キーワードをデコードする
767+ */
768+ private void decodeKeyword(String str){
769+ if (str == null || str.isEmpty())
770+ return;
771+
772+ _decodeKeyword(str);
773+ updateControlStatus();
774+
775+ jPanel.updateUI();
776+ }
777+
778+ /*
779+ * キーワードのデコードを実行する
780+ */
781+ private void _decodeKeyword(String str){
782+ doClear();
783+
784+ // 過去ログ閲覧
785+ if (str.matches("^\\d\\d\\d\\d/\\d\\d/\\d\\d$")) {
786+ jTextField_keyword.setText(str);
787+ return;
788+ }
789+
790+ // 過去ログ検索
791+ Matcher ma = Pattern.compile("^(\\d\\d\\d\\d/)?(\\d\\d/\\d\\d)([  ]+((\\d\\d\\d\\d/)?\\d\\d/\\d\\d))?[  ]+(.*)$").matcher(str);
792+ if (ma.find()) {
793+ String from = (ma.group(1) != null ? ma.group(1) : "") + ma.group(2);
794+ String to = ma.group(4);
795+ str = ma.group(6);
796+
797+ jTextField_from.setText(from);
798+ jTextField_to.setText(to);
799+ }
800+
801+ // 絞り込みあり
802+ Matcher mb = Pattern.compile("^@filter[  ]+(.*)$").matcher(str);
803+ if ( mb.find() ) {
804+ str = mb.group(1);
805+ jCheckBox_filter.setSelected(true);
806+ }
807+
808+ // オプションあり
809+ Matcher mc = Pattern.compile("^(#title|#detail)?[  ]+(.*)$").matcher(str);
810+ if (mc.find()){
811+ jCheckBox_title.setSelected(!mc.group(1).equals("#detail"));
812+ jCheckBox_detail.setSelected(!mc.group(1).equals("#title"));
813+ jTextField_keyword.setText(mc.group(2));
814+ }
815+ // オプションなし
816+ else{
817+ jTextField_keyword.setText(str);
818+ }
819+
820+ updateControlStatus();
821+ jTextField_keyword.requestFocusInWindow();
822+ }
823+
824+ /*******************************************************************************
825+ * リスナー
826+ ******************************************************************************/
827+ /*
828+ * ウインドウのオープン/クローズ等の変化
829+ */
830+ private final WindowListener wl_panel = new WindowListener(){
831+ @Override
832+ public void windowOpened(WindowEvent e) {
833+ }
834+
835+ @Override
836+ public void windowClosing(WindowEvent e) {
837+ }
838+
839+ @Override
840+ public void windowClosed(WindowEvent e) {
841+ }
842+
843+ @Override
844+ public void windowIconified(WindowEvent e) {
845+ if (autoclose_enabled)
846+ doCancel();
847+ }
848+
849+ @Override
850+ public void windowDeiconified(WindowEvent e) {
851+ }
852+
853+ @Override
854+ public void windowActivated(WindowEvent e) {
855+ }
856+
857+ @Override
858+ public void windowDeactivated(WindowEvent e) {
859+ if (autoclose_enabled)
860+ doCancel();
861+ }
862+ };
863+
864+ /*
865+ * 「検索履歴」コンボボックスの項目変更
866+ */
867+ private final ItemListener il_swlistSelected = new ItemListener() {
868+
869+ @Override
870+ public void itemStateChanged(ItemEvent e) {
871+ switch (e.getStateChange()) {
872+ case ItemEvent.SELECTED:
873+ decodeKeyword((String)jComboBox_swlist.getSelectedItem());
874+ break;
875+ }
876+ }
877+ };
878+
879+ /*
880+ * テキストフィールドでのEnterキー
881+ */
882+ private final ActionListener al_search = new ActionListener() {
883+ @Override
884+ public void actionPerformed(ActionEvent e) {
885+ if (jButton_search.isEnabled())
886+ doSearch();
887+ }
888+ };
889+
890+ /**
891+ * テキストフィールドでの文書変更
892+ */
893+ private final DocumentListener dl_documentChanged = new DocumentListener(){
894+ @Override
895+ public void insertUpdate(DocumentEvent e) {
896+ updateControlStatus();
897+ }
898+
899+ @Override
900+ public void removeUpdate(DocumentEvent e) {
901+ updateControlStatus();
902+ }
903+
904+ @Override
905+ public void changedUpdate(DocumentEvent e) {
906+ updateControlStatus();
907+ }
908+ };
909+
910+ /*
911+ * テキストフィールドでのESCキー押下
912+ */
913+ private final KeyListener kl_escape = new KeyListener(){
914+ @Override
915+ public void keyTyped(KeyEvent e) {
916+ }
917+
918+ @Override
919+ public void keyPressed(KeyEvent e) {
920+ if (e.getKeyCode() == KeyEvent.VK_ESCAPE)
921+ doCancel();
922+ }
923+
924+ @Override
925+ public void keyReleased(KeyEvent e) {
926+ }
927+ };
928+}
--- 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.17";
8+ private static final String Version = "タイニー番組ナビゲータ for DBR-T2007 3.22.18β+1.12.18";
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
@@ -57,6 +57,7 @@ import javax.swing.AbstractAction;
5757 import javax.swing.Action;
5858 import javax.swing.ImageIcon;
5959 import javax.swing.InputMap;
60+import javax.swing.JButton;
6061 import javax.swing.JComponent;
6162 import javax.swing.JFrame;
6263 import javax.swing.JLabel;
@@ -372,6 +373,7 @@ public class Viewer extends JFrame implements ChangeListener,TickTimerListener,H
372373 private VWChannelConvertView chconvsetting = null;
373374 private VWLookAndFeel vwlaf = null;
374375 private VWFont vwfont = null;
376+ private VWSearchWordDialog swdialog = null;
375377
376378 private TrayIcon trayicon = null;
377379
@@ -475,7 +477,7 @@ public class Viewer extends JFrame implements ChangeListener,TickTimerListener,H
475477
476478 timer_now.pause(); // 停止
477479
478- Viewer.this.showPopupMenuForProgram(comp, tvd, x, y);
480+ Viewer.this.showPopupMenuForProgram(comp, tvd, x, y, null);
479481
480482 timer_now.start(); // 再開
481483 }
@@ -623,11 +625,11 @@ public class Viewer extends JFrame implements ChangeListener,TickTimerListener,H
623625
624626 @Override
625627 protected void showPopupMenu(
626- final JComponent comp, final ProgDetailList tvd, final int x, final int y) {
628+ final JComponent comp, final ProgDetailList tvd, final int x, final int y, final String clickedDateTime) {
627629
628630 timer_now.pause(); // 停止
629631
630- Viewer.this.showPopupMenuForProgram(comp, tvd, x, y);
632+ Viewer.this.showPopupMenuForProgram(comp, tvd, x, y, clickedDateTime);
631633
632634 timer_now.start(); // 再開
633635 }
@@ -1984,6 +1986,27 @@ public class Viewer extends JFrame implements ChangeListener,TickTimerListener,H
19841986 return true;
19851987 }
19861988
1989+ /*
1990+ * 検索ダイアログを表示する
1991+ *
1992+ * @see tainavi.AbsToolBar#openSearchDialog()
1993+ */
1994+ @Override
1995+ protected void openSearchDialog(JButton jbutton) {
1996+ timer_now.pause();
1997+
1998+ if (swdialog == null)
1999+ swdialog = new VWSearchWordDialog();
2000+
2001+ if (swdialog.isVisible()){
2002+ swdialog.setVisible(false);
2003+ }
2004+ else
2005+ swdialog.open(this, jbutton, swlist, jTextField_keyword.getText());
2006+
2007+ timer_now.start();
2008+ }
2009+
19872010 @Override
19882011 protected boolean doBatchReserve() {
19892012 timer_now.pause();
@@ -2312,14 +2335,14 @@ public class Viewer extends JFrame implements ChangeListener,TickTimerListener,H
23122335 * 番組追跡への追加とgoogle検索
23132336 */
23142337 public void showPopupMenuForProgram(
2315- final JComponent comp, final ProgDetailList tvd, final int x, final int y)
2338+ final JComponent comp, final ProgDetailList tvd, final int x, final int y, final String clickedDateTime)
23162339 {
23172340 JPopupMenu pop = new JPopupMenu();
23182341
23192342 String myself = toolBar.getSelectedRecorder();
23202343
23212344 // 予約関係のメニューを追加する
2322- addReserveMenuToPopup(pop, tvd, myself);
2345+ addReserveMenuToPopup(pop, tvd, myself, clickedDateTime);
23232346
23242347 // ジャンプする
23252348 if (pop.getComponentCount() > 0)
@@ -2361,7 +2384,7 @@ public class Viewer extends JFrame implements ChangeListener,TickTimerListener,H
23612384 /*
23622385 * 予約メニューを追加する
23632386 */
2364- public void addReserveMenuToPopup( JPopupMenu pop, final ProgDetailList tvd, final String myself ){
2387+ public void addReserveMenuToPopup( JPopupMenu pop, final ProgDetailList tvd, final String myself, final String clickedDateTime ){
23652388 // 類似予約検索
23662389 LikeReserveList likeRsvList;
23672390 if ( env.getDisableFazzySearch() ) {
@@ -2372,7 +2395,7 @@ public class Viewer extends JFrame implements ChangeListener,TickTimerListener,H
23722395 }
23732396
23742397 // 重複予約検索
2375- LikeReserveList overlapRsvList = recorders.findOverlapReserves(tvd, null, true, env.getOverlapUp());
2398+ LikeReserveList overlapRsvList = recorders.findOverlapReserves(tvd, clickedDateTime, true, env.getOverlapUp());
23762399
23772400 // 類似と重複で被るものを重複から除外
23782401 for ( LikeReserveItem item : likeRsvList ) {
@@ -5978,6 +6001,7 @@ public class Viewer extends JFrame implements ChangeListener,TickTimerListener,H
59786001
59796002 final String BUTTON_ACTION_KEYWORD_ADDED = "keyword_added";
59806003 final String BUTTON_ACTION_KEYWORD_DELETED = "keyword_deleted";
6004+ final String BUTTON_ACTION_SEARCH_DIALOG = "search_dialog";
59816005 final String BUTTON_ACTION_RELOAD_PROGRAM = "reload_program";
59826006 final String BUTTON_ACTION_SHOW_BORDER = "show_border";
59836007 final String BUTTON_ACTION_JUMP_TO_NOW = "jump_to_now";
@@ -6062,6 +6086,12 @@ public class Viewer extends JFrame implements ChangeListener,TickTimerListener,H
60626086 toolBar.doKeywordDeleted();
60636087 }
60646088 };
6089+ final Action sc_search_dialog = new AbstractAction() {
6090+ @Override
6091+ public void actionPerformed(ActionEvent e) {
6092+ toolBar.openSearchDialog();
6093+ }
6094+ };
60656095 final Action sc_reload_program = new AbstractAction() {
60666096 @Override
60676097 public void actionPerformed(ActionEvent e) {
@@ -6223,6 +6253,7 @@ public class Viewer extends JFrame implements ChangeListener,TickTimerListener,H
62236253
62246254 sca.add(new ShortCut(BUTTON_ACTION_KEYWORD_ADDED, KeyEvent.VK_K, KeyEvent.CTRL_DOWN_MASK, sc_keyword_added));
62256255 sca.add(new ShortCut(BUTTON_ACTION_KEYWORD_DELETED, KeyEvent.VK_D, KeyEvent.CTRL_DOWN_MASK, sc_keyword_deleted));
6256+ sca.add(new ShortCut(BUTTON_ACTION_SEARCH_DIALOG, KeyEvent.VK_K, KeyEvent.CTRL_DOWN_MASK + KeyEvent.SHIFT_DOWN_MASK, sc_search_dialog));
62266257
62276258 sca.add(new ShortCut(BUTTON_ACTION_RELOAD_PROGRAM, KeyEvent.VK_W, KeyEvent.CTRL_DOWN_MASK, sc_reload_program));
62286259 sca.add(new ShortCut(BUTTON_ACTION_RELOAD_PROGRAM, KeyEvent.VK_F2, 0, sc_reload_program));
--- a/TinyBannavi/src/tainavi/plugintv/PlugIn_CSPTVKingdom110.java
+++ b/TinyBannavi/src/tainavi/plugintv/PlugIn_CSPTVKingdom110.java
@@ -104,7 +104,7 @@ public class PlugIn_CSPTVKingdom110 extends PlugIn_TVPTVKingdom implements TVPro
104104 }
105105 }
106106
107- debugNF();
107+// debugNF();
108108
109109 // 古い番組データを置き換える
110110 if (pcenter != null)
--- a/TinyBannavi/src/tainavi/plugintv/PlugIn_TVPDimora.java
+++ b/TinyBannavi/src/tainavi/plugintv/PlugIn_TVPDimora.java
@@ -236,12 +236,12 @@ public class PlugIn_TVPDimora extends TVProgramUtils implements TVProgram,Clonea
236236 // 古いデータから補完できないかな?
237237 CompensatesPrograms(newplist);
238238
239- // 解析用
240- {
241- for ( String f : nf.keySet() ) {
242- System.out.println(String.format(DBGID+"未定義のフラグです: [%s]",f));
243- }
244- }
239+// // 解析用
240+// {
241+// for ( String f : nf.keySet() ) {
242+// System.out.println(String.format(DBGID+"未定義のフラグです: [%s]",f));
243+// }
244+// }
245245
246246 // 古い番組データを置き換える
247247 if (pcenter != null)
--- a/TinyBannavi/src/tainavi/plugintv/PlugIn_TVPTVKingdom.java
+++ b/TinyBannavi/src/tainavi/plugintv/PlugIn_TVPTVKingdom.java
@@ -246,7 +246,7 @@ public class PlugIn_TVPTVKingdom extends TVProgramUtils implements TVProgram,Clo
246246 }
247247
248248 // 解析用
249- debugNF();
249+// debugNF();
250250
251251 // 古い番組データを置き換える
252252 if (pcenter != null)