3 import java.awt.BorderLayout;
\r
4 import java.awt.Color;
\r
5 import java.awt.Component;
\r
6 import java.awt.Desktop;
\r
7 import java.awt.Dimension;
\r
8 import java.awt.Point;
\r
9 import java.awt.event.ActionEvent;
\r
10 import java.awt.event.ActionListener;
\r
11 import java.awt.event.ComponentAdapter;
\r
12 import java.awt.event.ComponentEvent;
\r
13 import java.awt.event.ComponentListener;
\r
14 import java.awt.event.MouseAdapter;
\r
15 import java.awt.event.MouseEvent;
\r
16 import java.awt.event.MouseListener;
\r
17 import java.io.File;
\r
18 import java.io.IOException;
\r
19 import java.net.URI;
\r
20 import java.net.URISyntaxException;
\r
21 import java.util.ArrayList;
\r
22 import java.util.Calendar;
\r
23 import java.util.Comparator;
\r
24 import java.util.GregorianCalendar;
\r
25 import java.util.HashMap;
\r
26 import java.util.Map.Entry;
\r
27 import java.util.regex.Matcher;
\r
28 import java.util.regex.Pattern;
\r
30 import javax.swing.ButtonGroup;
\r
31 import javax.swing.JComponent;
\r
32 import javax.swing.JMenuItem;
\r
33 import javax.swing.JOptionPane;
\r
34 import javax.swing.JPanel;
\r
35 import javax.swing.JPopupMenu;
\r
36 import javax.swing.JRadioButtonMenuItem;
\r
37 import javax.swing.JScrollPane;
\r
38 import javax.swing.JSplitPane;
\r
39 import javax.swing.JTable;
\r
40 import javax.swing.JTree;
\r
41 import javax.swing.SwingConstants;
\r
42 import javax.swing.SwingUtilities;
\r
43 import javax.swing.event.ListSelectionEvent;
\r
44 import javax.swing.event.ListSelectionListener;
\r
45 import javax.swing.event.RowSorterEvent;
\r
46 import javax.swing.event.RowSorterEvent.Type;
\r
47 import javax.swing.event.RowSorterListener;
\r
48 import javax.swing.event.TableModelEvent;
\r
49 import javax.swing.event.TreeExpansionEvent;
\r
50 import javax.swing.event.TreeExpansionListener;
\r
51 import javax.swing.event.TreeSelectionEvent;
\r
52 import javax.swing.event.TreeSelectionListener;
\r
53 import javax.swing.table.DefaultTableCellRenderer;
\r
54 import javax.swing.table.DefaultTableColumnModel;
\r
55 import javax.swing.table.DefaultTableModel;
\r
56 import javax.swing.table.TableCellRenderer;
\r
57 import javax.swing.table.TableColumn;
\r
58 import javax.swing.table.TableModel;
\r
59 import javax.swing.table.TableRowSorter;
\r
60 import javax.swing.tree.DefaultMutableTreeNode;
\r
61 import javax.swing.tree.DefaultTreeModel;
\r
62 import javax.swing.tree.TreeNode;
\r
63 import javax.swing.tree.TreePath;
\r
64 import javax.swing.tree.TreeSelectionModel;
\r
66 import tainavi.TVProgram.ProgFlags;
\r
67 import tainavi.TVProgram.ProgGenre;
\r
68 import tainavi.TVProgram.ProgSubgenre;
\r
69 import tainavi.TVProgram.ProgSubtype;
\r
70 import tainavi.TVProgram.ProgType;
\r
71 import tainavi.TVProgramIterator.IterationType;
\r
72 import tainavi.VWMainWindow.MWinTab;
\r
77 * @since 3.15.4β {@link Viewer}から分離
\r
79 public abstract class AbsListedView extends JPanel implements TickTimerListener {
\r
81 private static final long serialVersionUID = 1L;
\r
83 public static String getViewName() { return "リスト形式"; }
\r
85 public void setDebug(boolean b) { debug = b; }
\r
86 private static boolean debug = false;
\r
89 /*******************************************************************************
\r
91 ******************************************************************************/
\r
93 protected abstract Env getEnv();
\r
94 protected abstract Bounds getBoundsEnv();
\r
95 protected abstract ChannelSort getChannelSort();
\r
97 protected abstract MarkedProgramList getMarkedProgramList();
\r
98 protected abstract TraceProgram getTraceProgram();
\r
99 protected abstract SearchProgram getSearchProgram();
\r
100 protected abstract SearchGroupList getSearchGroupList();
\r
101 protected abstract ExtProgram getExtProgram();
\r
103 protected abstract TVProgramList getTVProgramList();
\r
104 protected abstract HDDRecorderList getRecorderList();
\r
106 protected abstract StatusWindow getStWin();
\r
107 protected abstract StatusTextArea getMWin();
\r
108 protected abstract AbsReserveDialog getReserveDialog();
\r
110 protected abstract Component getParentComponent();
\r
112 protected abstract void ringBeep();
\r
114 // クラス内のイベントから呼び出されるもの
\r
119 protected abstract void onShown();
\r
123 protected abstract void onHidden();
\r
126 * マウス右クリックメニューを表示する
\r
128 protected abstract void showPopupForTraceProgram(
\r
129 final JComponent comp,
\r
130 final ProgDetailList tvd, final String keyword, final int threshold,
\r
131 final int x, final int y);
\r
134 * 予約マーク・予約枠を更新してほしい
\r
136 protected abstract void updateReserveDisplay(String chname);
\r
141 protected abstract void updateBangumiColumns();
\r
147 protected abstract void clearPaper();
\r
152 protected abstract void previewKeywordSearch(SearchKey search);
\r
153 //protected abstract void previewExtensionSearch(SearchKey search);
\r
157 protected abstract void jumpToPaper(String Center, String StartDateTime);
\r
162 protected abstract boolean addToPickup(final ProgDetailList tvd);
\r
164 protected abstract boolean isTabSelected(MWinTab tab);
\r
165 protected abstract void setSelectedTab(MWinTab tab);
\r
168 * @see Viewer.VWToolBar#getSelectedRecorder()
\r
170 protected abstract String getSelectedRecorderOnToolbar();
\r
171 protected abstract boolean isFullScreen();
\r
172 //protected abstract void setPagerItems(int total_page, int idx);
\r
173 protected abstract void setPagerEnabled(boolean b);
\r
174 protected abstract int getPagerCount();
\r
175 protected abstract int getSelectedPagerIndex();
\r
178 * ツリーペーンの幅の変更を保存してほしい
\r
180 protected abstract void setDividerEnvs(int loc);
\r
183 /*******************************************************************************
\r
185 ******************************************************************************/
\r
188 private final Env env = getEnv();
\r
189 private final Bounds bounds = getBoundsEnv();
\r
190 private final ChannelSort chsort = getChannelSort();
\r
192 private final MarkedProgramList mpList = getMarkedProgramList();;
\r
193 private final TraceProgram trKeys = getTraceProgram();
\r
194 private final SearchProgram srKeys = getSearchProgram();
\r
195 private final SearchGroupList srGrps = getSearchGroupList();
\r
196 private final ExtProgram extKeys = getExtProgram();
\r
198 private final TVProgramList tvprograms = getTVProgramList();
\r
199 private final HDDRecorderList recorders = getRecorderList();
\r
201 private final StatusWindow StWin = getStWin(); // これは起動時に作成されたまま変更されないオブジェクト
\r
202 private final StatusTextArea MWin = getMWin(); // これは起動時に作成されたまま変更されないオブジェクト
\r
203 private final AbsReserveDialog rD = getReserveDialog(); // これは起動時に作成されたまま変更されないオブジェクト
\r
205 private final Component parent = getParentComponent(); // これは起動時に作成されたまま変更されないオブジェクト
\r
208 private void StdAppendMessage(String message) { System.out.println(message); }
\r
209 private void StdAppendError(String message) { System.err.println(message); }
\r
210 //private void StWinSetVisible(boolean b) { StWin.setVisible(b); }
\r
211 //private void StWinSetLocationCenter(Component frame) { CommonSwingUtils.setLocationCenter(frame, (VWStatusWindow)StWin); }
\r
214 /*******************************************************************************
\r
216 ******************************************************************************/
\r
218 private static final String MSGID = "["+getViewName()+"] ";
\r
219 private static final String ERRID = "[ERROR]"+MSGID;
\r
220 private static final String DBGID = "[DEBUG]"+MSGID;
\r
226 private static final HashMap<String,Integer> lcmap = new HashMap<String, Integer>();
\r
227 public static HashMap<String,Integer> getColumnIniWidthMap() {
\r
228 if (lcmap.size() == 0 ) {
\r
229 for ( ListedColumn lc : ListedColumn.values() ) {
\r
230 lcmap.put(lc.toString(),lc.getIniWidth()); // toString()!
\r
236 private int MIN_COLUMN_WIDTH = 20;
\r
239 * テーブルのカラムの設定(名前と幅の初期値)。できれば@{link {@link ListedItem}と一体化させたかったのだが無理っぽい
\r
242 public static enum ListedColumn {
\r
243 RSVMARK ("予約", 35, false),
\r
244 PICKMARK ("ピック", 35, false),
\r
245 DUPMARK ("重複", 35, false),
\r
246 CHNAME ("チャンネル名", 100, true),
\r
247 OPTIONS ("オプション", 100, true),
\r
248 TITLE ("番組タイトル", 300, true),
\r
249 DETAIL ("番組詳細", 200, true),
\r
250 START ("開始時刻", 150, true),
\r
251 END ("終了", 50, true),
\r
252 LENGTH ("長さ", 50, true),
\r
253 GENRE ("ジャンル", 85, true),
\r
254 SITEM ("検索アイテム名", 100, true),
\r
255 STAR ("お気に入り度", 100, true),
\r
256 SCORE ("スコア", 35, false),
\r
257 THRESHOLD ("閾値", 35, false),
\r
260 private String name;
\r
261 private int iniWidth;
\r
262 private boolean resizable;
\r
264 private ListedColumn(String name, int iniWidth, boolean resizable) {
\r
266 this.iniWidth = iniWidth;
\r
267 this.resizable = resizable;
\r
270 public String getName() {
\r
274 public int getIniWidth() {
\r
278 public boolean isResizable() {
\r
283 public int getColumn() {
\r
287 public boolean equals(String s) {
\r
288 return name.equals(s);
\r
293 * 検索範囲(番組追跡か、キーワード検索か、予約待機か)
\r
295 private static enum SearchBy { TRACE, KEYWORD, BOTH } ;
\r
297 public static enum RsvMark {
\r
298 NOEXEC ( "×", "予約無効"),
\r
299 NORMAL ( "●", "ぴったり"),
\r
300 OVERRUN ( "◎", "のりしろより大きく予約時間がとられている"),
\r
301 UNDERRUN ( "○", "時間延長が考慮されていない"),
\r
302 DELAYED ( "◇", "開始時刻が一致しない"),
\r
303 CLIPPED ( "▲", "1分短縮済み"),
\r
304 CLIPPED_E ( "△", "1分短縮済み(延長警告あり)"),
\r
305 SHORTAGE ( "▼", "2分以上短かい"),
\r
306 SHORTAGE_E ( "▽", "2分以上短かい(延長警告あり)"),
\r
308 PICKUP ( "★", "ピックアップ"),
\r
309 URABAN ( "裏", "裏番組"),
\r
311 DUP_NORMAL ( "■", "時間が重なっている"),
\r
312 DUP_REP ( "□", "開始時間と終了時間が同じ"),
\r
315 private String mark;
\r
316 private String desc;
\r
318 private RsvMark(String mark, String desc) {
\r
324 private class Marker {
\r
325 RsvMark rsvmark = null;
\r
326 RsvMark pickmark = null;
\r
327 String myself = null;
\r
328 String color = null;
\r
330 public Marker(String myself, String color) {
\r
331 this.myself = myself;
\r
332 this.color = color;
\r
336 private static final String PICKUP_COLOR = CommonUtils.color2str(Color.BLACK);
\r
337 private static final String URABAN_COLOR = "#666666";
\r
338 private static final String DUPMARK_COLOR = "#FFB6C1";
\r
340 private static final String TreeExpRegFile_Listed = "env"+File.separator+"tree_expand_listed.xml";
\r
342 private final String SearchItemLabel_Passed = JTreeLabel.Nodes.PASSED.getLabel(); // 過去ログの名前
\r
346 private int vrowInFocus = -1; // マウスクリックした時のフォーカス行
\r
349 /*******************************************************************************
\r
351 ******************************************************************************/
\r
355 private JDetailPanel jTextPane_detail = null;
\r
356 private JSplitPane jSplitPane_view = null;
\r
357 private JPanel jPanel_tree = null;
\r
358 private JScrollPane jScrollPane_tree_top = null;
\r
359 private JTreeLabel jLabel_tree = null;
\r
360 private JScrollPane jScrollPane_tree = null;
\r
361 private JTree jTree_tree = null;
\r
362 private JScrollPane jScrollPane_listed = null;
\r
363 private JTableRowHeader jTable_rowheader = null;
\r
364 private ListedTable jTable_listed = null;
\r
365 private VWColorCharCellRenderer2 titleCellRenderer = null;
\r
367 private VWListedTreeNode listRootNode = null; // リスト形式のツリー
\r
369 VWListedTreeNode searchedNode = null;
\r
370 VWListedTreeNode startNode = null;
\r
371 VWListedTreeNode endNode = null;
\r
372 VWListedTreeNode nowNode = null;
\r
373 VWListedTreeNode syobocalNode = null;
\r
374 VWListedTreeNode standbyNode = null;
\r
375 VWListedTreeNode traceNode = null;
\r
376 VWListedTreeNode keywordNode = null;
\r
377 VWListedTreeNode keywordGrpNode = null;
\r
378 VWListedTreeNode genreNode = null;
\r
379 VWListedTreeNode centerListNode = null;
\r
380 VWListedTreeNode extensionNode = null;
\r
382 VWListedTreeNode defaultNode = null;
\r
384 private ListedTableModel tableModel_listed = null;
\r
386 private DefaultTableModel rowheaderModel_listed = null;
\r
391 private final RowItemList<ListedItem> rowData = new RowItemList<ListedItem>();
\r
394 TreeExpansionReg ter = null;
\r
397 private boolean timer_now_enabled = false;
\r
400 /*******************************************************************************
\r
402 ******************************************************************************/
\r
404 public AbsListedView() {
\r
409 this.setLayout(new BorderLayout());
\r
410 this.add(getJTextPane_detail(), BorderLayout.PAGE_START);
\r
411 this.add(getJSplitPane_view(), BorderLayout.CENTER);
\r
414 if ( bounds.getListedColumnSize() == null ) {
\r
415 StWin.appendError(ERRID+"なんらかの不具合によりテーブルのカラム幅設定が取得できませんでした。設定はリセットされました。申し訳ありません。");
\r
416 bounds.setListedColumnSize(lcmap);
\r
419 for ( Entry<String, Integer> en : lcmap.entrySet() ) {
\r
421 bounds.getListedColumnSize().get(en.getKey());
\r
423 catch (NullPointerException e) {
\r
424 System.err.println(ERRID+en.getKey()+", "+e.toString());
\r
425 bounds.getListedColumnSize().put(en.getKey(),en.getValue());
\r
430 // タブが開いたり閉じたりしたときの処理
\r
431 this.addComponentListener(cl_tabshownhidden);
\r
435 /*******************************************************************************
\r
437 ******************************************************************************/
\r
439 // このクラスの肝、リスト表示について。
\r
448 private class RedrawCond {
\r
449 ProgType progtype = null;
\r
450 SearchKey searchkeyword = null;
\r
451 ProgFlags flag = null;
\r
452 ProgGenre genre = null;
\r
453 ProgSubgenre subgenre = null;
\r
454 String center = null;
\r
455 String targetdate = null;
\r
459 * プレビュー表示とか(親から呼ばれるよ!)
\r
460 * @see #redrawListByKeywordDyn(SearchKey, String)
\r
461 * @see #redrawListByKeywordFilter(SearchKey, String)
\r
463 public void redrawListByPreview(SearchKey sKey) {
\r
465 jLabel_tree.setView(JTreeLabel.Nodes.SEARCHED, JTreeLabel.PREVIEW);
\r
466 redrawListByKeywordDyn(sKey);
\r
470 * キーワード検索ボックスとか(親から呼ばれるよ!)
\r
472 public void redrawListByKeywordDyn(SearchKey sKey, String target) {
\r
474 jLabel_tree.setView(JTreeLabel.Nodes.SEARCHED, target);
\r
475 redrawListByKeywordDyn(sKey);
\r
479 // キーワード検索結果に基づきリストを作成(動的)
\r
480 // (1)延長警告管理、(2)ツールバーからの検索
\r
481 private void redrawListByKeywordDyn(SearchKey sKey) {
\r
483 RedrawCond c = new RedrawCond();
\r
484 c.progtype = ProgType.PROG;
\r
485 c.searchkeyword = sKey;
\r
487 //_redrawListBy(ProgType.RADIO,sKey,null,null,null,null);
\r
488 setReservedMarks();
\r
489 tableModel_listed.fireTableDataChanged();
\r
490 rowheaderModel_listed.fireTableDataChanged();
\r
494 private void redrawListByExtkeywordAll(ArrayList<SearchKey> sKeys) {
\r
496 RedrawCond c = new RedrawCond();
\r
497 c.progtype = ProgType.PROG;
\r
498 for (SearchKey sKey : sKeys) {
\r
499 c.searchkeyword = sKey;
\r
502 setReservedMarks();
\r
503 tableModel_listed.fireTableDataChanged();
\r
504 rowheaderModel_listed.fireTableDataChanged();
\r
509 private void redrawListByFlag(ProgFlags flag) {
\r
511 RedrawCond c = new RedrawCond();
\r
512 c.progtype = ProgType.PROG;
\r
515 setReservedMarks();
\r
516 tableModel_listed.fireTableDataChanged();
\r
517 rowheaderModel_listed.fireTableDataChanged();
\r
522 private void redrawListByFlag(ProgFlags flag, ProgGenre genre) {
\r
524 RedrawCond c = new RedrawCond();
\r
525 c.progtype = ProgType.PROG;
\r
529 setReservedMarks();
\r
530 tableModel_listed.fireTableDataChanged();
\r
531 rowheaderModel_listed.fireTableDataChanged();
\r
536 private void redrawListByNow(ProgGenre genre) {
\r
537 jTable_listed.getRowSorter().setSortKeys(null); // ソーターをリセットする
\r
539 RedrawCond c = new RedrawCond();
\r
540 c.progtype = ProgType.PROG;
\r
543 _redrawListBy(c); // target == ""は現在日時しぼりこみ
\r
544 setReservedMarks();
\r
545 tableModel_listed.fireTableDataChanged();
\r
546 rowheaderModel_listed.fireTableDataChanged();
\r
550 // ジャンル検索結果に基づきリストを作成
\r
551 private void redrawListByGenre(ProgGenre genre, ProgSubgenre subgenre) {
\r
553 RedrawCond c = new RedrawCond();
\r
554 c.progtype = ProgType.PROG;
\r
556 c.subgenre = subgenre;
\r
558 setReservedMarks();
\r
559 tableModel_listed.fireTableDataChanged();
\r
560 rowheaderModel_listed.fireTableDataChanged();
\r
565 private void redrawListByCenterList(String center) {
\r
567 RedrawCond c = new RedrawCond();
\r
568 c.progtype = ProgType.PROG;
\r
571 setReservedMarks();
\r
572 tableModel_listed.fireTableDataChanged();
\r
573 rowheaderModel_listed.fireTableDataChanged();
\r
575 //setOverlapMark();
\r
581 private void redrawSyobocalAll() {
\r
583 RedrawCond c = new RedrawCond();
\r
584 c.progtype = ProgType.SYOBO;
\r
586 tableModel_listed.fireTableDataChanged();
\r
587 rowheaderModel_listed.fireTableDataChanged();
\r
588 setReservedMarks();
\r
592 * 検索総当り版の本体(全件に対して検索処理をかける)
\r
594 private void _redrawListBy(RedrawCond cond) {
\r
596 String curDateTime = CommonUtils.getDateTime(0);
\r
597 String critDateTime = CommonUtils.getCritDateTime();
\r
599 for ( TVProgram tvp : tvprograms ) {
\r
600 if (tvp.getType() != cond.progtype) {
\r
604 for ( ProgList tvpl : tvp.getCenters() ) {
\r
605 if ( ! tvpl.enabled ) {
\r
609 if (cond.center != null && ! cond.center.equals(tvpl.Center)) {
\r
615 String centerPop = TraceProgram.replacePop(tvpl.Center);
\r
617 for ( ProgDateList tvc : tvpl.pdate ) {
\r
619 for ( ProgDetailList tvd : tvc.pdetail ) {
\r
622 if (tvp.getType() != ProgType.PASSED) {
\r
623 if (tvd.endDateTime.compareTo(critDateTime) < 0) {
\r
627 // 当日過去分は表示しない(オプション)
\r
628 if ( ! env.getDisplayPassedEntry()) {
\r
629 if (tvp.getType() != ProgType.PASSED) {
\r
630 if (tvd.endDateTime.compareTo(curDateTime) <= 0) {
\r
636 // 番組情報がありませんは表示しない
\r
637 if (tvd.start.equals("")) {
\r
642 if (tvd.title.equals("放送休止") || tvd.title.equals("休止") || tvd.title.contains("放送を休止")) {
\r
649 String matched = null;
\r
650 long cur_remain = -1;
\r
652 boolean isFind = false;
\r
653 if (cond.center != null) {
\r
656 else if (cond.targetdate != null) {
\r
658 if ( cond.targetdate.length() == 0 ) {
\r
659 String cridt = CommonUtils.getDateTime(-env.getCurrentAfter());
\r
660 String curdt = CommonUtils.getDateTime(0);
\r
661 String nextdt = CommonUtils.getDateTime(env.getCurrentBefore());
\r
662 if ( tvd.endDateTime.compareTo(cridt) <= 0 ) {
\r
665 if ( tvd.startDateTime.compareTo(cridt) <= 0 && cridt.compareTo(tvd.endDateTime) <= 0 ||
\r
666 tvd.startDateTime.compareTo(curdt) <= 0 && curdt.compareTo(tvd.endDateTime) <= 0) {
\r
667 cur_remain = CommonUtils.getCompareDateTime(tvd.endDateTime, curdt);
\r
670 else if ( tvd.startDateTime.compareTo(cridt) > 0 && tvd.startDateTime.compareTo(nextdt) <= 0 ) {
\r
671 cur_wait = CommonUtils.getCompareDateTime(tvd.startDateTime, curdt);
\r
672 isFind = true; // 今後一時間以内に開始予定のものも表示
\r
674 else if ( tvd.startDateTime.compareTo(nextdt) < 0 ) {
\r
675 continue; // これ以上みても無駄
\r
678 if ( isFind && cond.genre != null && ! tvd.isEqualsGenre(cond.genre, null) ) {
\r
684 if (cond.searchkeyword != null) {
\r
685 isFind = SearchProgram.isMatchKeyword(cond.searchkeyword, ((cond.searchkeyword.getCaseSensitive()==false)?(centerPop):(tvpl.Center)), tvd);
\r
686 label = ((cond.progtype == ProgType.PASSED)?(SearchItemLabel_Passed):(cond.searchkeyword.getLabel()));
\r
687 okini = cond.searchkeyword.getOkiniiri();
\r
688 matched = SearchProgram.getMatchedString();
\r
690 else if (cond.flag != null) {
\r
691 if (tvd.flag == cond.flag) {
\r
693 label = cond.flag.toString();
\r
696 if ( isFind && cond.genre != null && ! tvd.isEqualsGenre(cond.genre, null) ) {
\r
700 else if (cond.genre != null) {
\r
701 isFind = tvd.isEqualsGenre(cond.genre, cond.subgenre);
\r
703 else if ( cond.progtype == ProgType.SYOBO && cond.searchkeyword == null ) {
\r
710 String[] tStr = new String[3];
\r
711 if (matched != null) {
\r
712 int a = tvd.title.indexOf(matched);
\r
713 tStr[0] = tvd.title.substring(0,a);
\r
715 tStr[2] = tvd.title.substring(a+matched.length());
\r
718 tStr[0] = tvd.title;
\r
723 String prefixMark = "";
\r
724 if ( cond.targetdate == "" ) {
\r
725 if ( cur_remain > 0 ) {
\r
726 prefixMark = String.format("\0終了まで%3d分",cur_remain/60000);
\r
728 else if ( cur_wait > 0 ){
\r
729 prefixMark = String.format("\0開始まで%3d分",cur_wait/60000);
\r
733 prefixMark = tvd.extension_mark+tvd.prefix_mark;
\r
736 ListedItem sa = new ListedItem();
\r
742 sa.prefix = prefixMark;
\r
743 sa.title = tvd.newlast_mark+"\0"+tStr[0]+"\0"+tStr[1]+"\0"+tStr[2]+tvd.postfix_mark;
\r
744 sa.searchlabel = label;
\r
745 sa.okiniiri = okini;
\r
749 sa.hide_rsvmarkcolor = "";
\r
760 if ( cond.targetdate == "" ) {
\r
761 // 現在放送中の終了済み番組をリストの先頭に移動する
\r
762 RowItemList<ListedItem> passed = new RowItemList<ListedItem>();
\r
763 RowItemList<ListedItem> cur = new RowItemList<ListedItem>();
\r
764 RowItemList<ListedItem> future = new RowItemList<ListedItem>();
\r
765 for ( ListedItem c : rowData ) {
\r
766 if ( c.prefix == "" ) {
\r
769 else if ( c.prefix.startsWith("\0終了まで") ){
\r
778 for ( ListedItem c : passed ) {
\r
782 int toprow = rowData.size();
\r
783 for ( ListedItem c : cur ) {
\r
785 for ( ; row<rowData.size(); row++ ) {
\r
786 ListedItem d = rowData.get(row);
\r
787 if ( c.tvd.endDateTime.compareTo(d.tvd.endDateTime) < 0 ) {
\r
791 rowData.add(row,c);
\r
794 for ( ListedItem c : future ) {
\r
801 * 検索総当り版の本体(全件に対して検索処理をかける)
\r
802 * <P><B>★将来的には、動的検索結果の表示はすべてこちらに移行する
\r
804 public boolean redrawListBySearched(ProgType typ, int index) {
\r
809 SearchResult searched = tvprograms.getSearched();
\r
811 // 検索結果の履歴数より大きい番号を指定された場合はエラー
\r
812 if ( searched.getResultBufferSize() < index ) {
\r
816 JTreeLabel.Nodes desc = ((typ == ProgType.PASSED) ? (JTreeLabel.Nodes.SEARCHHIST):(JTreeLabel.Nodes.SEARCHED));
\r
817 String label = searched.getLabel(index);
\r
819 jLabel_tree.setView(desc, label);
\r
823 for ( ProgDetailList tvd : searched.getResult(index) ) {
\r
825 String[] tStr = new String[3];
\r
827 if (tvd.dynMatched != null) {
\r
828 int a = tvd.title.indexOf(tvd.dynMatched);
\r
829 tStr[0] = tvd.title.substring(0,a);
\r
830 tStr[1] = tvd.dynMatched;
\r
831 tStr[2] = tvd.title.substring(a+tvd.dynMatched.length());
\r
834 tStr[0] = tvd.title;
\r
839 String prefixMark = tvd.extension_mark+tvd.prefix_mark;
\r
841 ListedItem sa = new ListedItem();
\r
847 sa.prefix = prefixMark;
\r
848 sa.title = tvd.newlast_mark+"\0"+tStr[0]+"\0"+tStr[1]+"\0"+tStr[2]+tvd.postfix_mark;
\r
849 sa.searchlabel = tvd.dynKey.getLabel();
\r
850 sa.okiniiri = tvd.dynKey.getOkiniiri();
\r
854 sa.hide_rsvmarkcolor = "";
\r
861 tableModel_listed.fireTableDataChanged();
\r
862 rowheaderModel_listed.fireTableDataChanged();
\r
872 private void redrawSyobocalListByTrace() {
\r
873 _redrawListByTraceAndKeyword(ProgType.SYOBO,SearchBy.TRACE,null,null,null);
\r
875 private void redrawSyobocalListByKeyword() {
\r
876 _redrawListByTraceAndKeyword(ProgType.SYOBO,SearchBy.KEYWORD,null,null,null);
\r
880 private void redrawSyobocalListByOnly() {
\r
881 _redrawListByTraceAndKeyword(ProgType.SYOBO,SearchBy.BOTH,null,null,null,true);
\r
884 private void redrawSyobocalListByTraceAndKeyword() {
\r
885 _redrawListByTraceAndKeyword(ProgType.SYOBO,SearchBy.BOTH,null,null,null);
\r
889 private void redrawListByTrace(TraceKey tKey) {
\r
890 _redrawListByTraceAndKeyword(ProgType.PROG,SearchBy.TRACE,tKey,null,null);
\r
893 // キーワード検索結果に基づきリストを作成(静的)
\r
894 private void redrawListByKeyword(SearchKey sKey) {
\r
895 _redrawListByTraceAndKeyword(ProgType.PROG,SearchBy.KEYWORD,null,sKey,null);
\r
897 // キーワードグループに基づきリストを作成(静的)
\r
898 private void redrawListByKeywordGrp(SearchGroup gr) {
\r
899 _redrawListByTraceAndKeyword(ProgType.PROG,SearchBy.KEYWORD,null,null,null,false,gr,false,false);
\r
901 // ピックアップに基づきリストを作成(静的)
\r
902 private void redrawListByPickup() {
\r
903 _redrawListByTraceAndKeyword(ProgType.PICKED,SearchBy.BOTH,null,null,null);
\r
906 // 番組追跡&キーワード検索結果に基づきリストを作成
\r
907 private void redrawListByTraceAndKeywordOkini(String oKey) {
\r
908 _redrawListByTraceAndKeyword(ProgType.PROG,SearchBy.BOTH,null,null,oKey);
\r
909 selectBatchTarget();
\r
911 private void redrawListByTraceAndKeyword() {
\r
912 _redrawListByTraceAndKeyword(ProgType.PROG,SearchBy.BOTH,null,null,null);
\r
913 selectBatchTarget();
\r
916 private void redrawListByTraceAndKeywordNewArrival() {
\r
917 _redrawListByTraceAndKeyword(ProgType.PROG,SearchBy.BOTH,null,null,null,false,null,true,false);
\r
918 selectBatchTarget();
\r
920 private void redrawListByTraceAndKeywordModified() {
\r
921 _redrawListByTraceAndKeyword(ProgType.PROG,SearchBy.BOTH,null,null,null,false,null,false,true);
\r
922 selectBatchTarget();
\r
925 private void _redrawListByTraceAndKeyword(ProgType typ, SearchBy opt, TraceKey tKey, SearchKey sKey, String oKey) {
\r
926 _redrawListByTraceAndKeyword(typ, opt, tKey, sKey, oKey, false, null, false, false);
\r
928 private void _redrawListByTraceAndKeyword(ProgType typ, SearchBy opt, TraceKey tKey, SearchKey sKey, String oKey, boolean only) {
\r
929 _redrawListByTraceAndKeyword(typ, opt, tKey, sKey, oKey, only, null, false, false);
\r
933 * 検索高速化版の本体(作成済み検索結果から必要なものを選ぶだけ、検索処理は行わない)
\r
935 private void _redrawListByTraceAndKeyword(ProgType typ, SearchBy opt, TraceKey tKey, SearchKey sKey, String oKey, boolean only, SearchGroup gr, boolean doChkNewArr, boolean doChkModify) {
\r
939 String curDateTime = CommonUtils.getDateTime(0);
\r
940 String critDateTime = CommonUtils.getCritDateTime();
\r
942 for (int n=0; n<mpList.size(); n++) {
\r
945 if (mpList.getProg(n).type != typ) {
\r
950 if (opt == SearchBy.TRACE && mpList.getTKey(n) == null) {
\r
953 if (opt == SearchBy.KEYWORD && mpList.getSKey(n) == null) {
\r
957 ProgDetailList tvd = mpList.getProg(n);
\r
960 if (tvd.endDateTime.compareTo(critDateTime) < 0) {
\r
964 if ( ! env.getDisplayPassedEntry()) {
\r
965 if (tvd.endDateTime.compareTo(curDateTime) <= 0) {
\r
971 ArrayList<TraceKey> td = mpList.getTKey(n);
\r
972 ArrayList<SearchKey> sd = mpList.getSKey(n);
\r
976 String matched = null;
\r
977 String fazScore = "";
\r
978 String threshold = "";
\r
980 if ((opt == SearchBy.BOTH || opt == SearchBy.TRACE) && td.size() > 0) {
\r
982 if (tKey != null) {
\r
983 for (i=0; i<td.size(); i++) {
\r
984 if (td.get(i) == tKey) {
\r
988 if (i >= td.size()) {
\r
989 continue; // キー指定で見つからなかったもの
\r
993 label = td.get(i)._getLabel();
\r
994 okini = td.get(i).getOkiniiri();
\r
995 threshold = String.valueOf(td.get(i).getFazzyThreshold());
\r
996 fazScore = String.valueOf(mpList.getTScore(n).get(i));
\r
998 else if ((opt == SearchBy.BOTH || opt == SearchBy.KEYWORD) && sd.size() > 0) {
\r
1000 if (sKey != null) {
\r
1001 for (i=0; i<sd.size(); i++) {
\r
1002 if (sd.get(i) == sKey) {
\r
1006 if (i >= sd.size()) {
\r
1007 continue; // キー指定で見つからなかったもの
\r
1010 else if (gr != null) {
\r
1011 for (i=0; i<sd.size(); i++) {
\r
1012 boolean f = false;
\r
1013 for ( String gmember : gr ) {
\r
1014 if (sd.get(i).getLabel().equals(gmember)) {
\r
1023 if (i >= sd.size()) {
\r
1024 continue; // キー指定で見つからなかったもの
\r
1028 if ( opt == SearchBy.BOTH && ! sd.get(i).getShowInStandby() ) {
\r
1029 continue; // 予約待機への表示はYA・DA・YO
\r
1032 label = sd.get(i).getLabel();
\r
1033 okini = sd.get(i).getOkiniiri();
\r
1034 matched = mpList.getSStr(n).get(i);
\r
1040 if ( doChkNewArr ) {
\r
1041 if ( ! tvd.newarrival ) {
\r
1046 else if ( doChkModify ) {
\r
1047 if ( ! tvd.modified ) {
\r
1052 else if (oKey != null && oKey.compareTo(okini) > 0) {
\r
1058 if ( typ == ProgType.SYOBO && (env.getSyoboFilterByCenters() || only) ) {
\r
1059 if ( only && tvd.nosyobo ) {
\r
1060 // nosyoboって名前と内容が一致していないよね…
\r
1064 boolean encr = false;
\r
1065 for ( int x=0; x<tvprograms.size() && encr == false; x++ ) {
\r
1066 TVProgram tvp = tvprograms.get(x);
\r
1067 if ( tvp.getType() != ProgType.PROG ) {
\r
1070 for ( Center cr : tvp.getSortedCRlist() ) {
\r
1071 if ( mpList.getProg(n).center.equals(cr.getCenter()) ) {
\r
1083 String[] tStr = new String[3];
\r
1084 if (matched != null) {
\r
1085 int a = tvd.title.indexOf(matched);
\r
1086 tStr[0] = tvd.title.substring(0,a);
\r
1087 tStr[1] = matched;
\r
1088 tStr[2] = tvd.title.substring(a+matched.length());
\r
1091 tStr[0] = tvd.title;
\r
1096 ListedItem sa = new ListedItem();
\r
1101 sa.dupmark = null;
\r
1102 sa.prefix = tvd.extension_mark+tvd.prefix_mark;
\r
1103 sa.title = tvd.newlast_mark+"\0"+tStr[0]+"\0"+tStr[1]+"\0"+tStr[2]+tvd.postfix_mark;
\r
1104 sa.searchlabel = label;
\r
1105 sa.okiniiri = okini;
\r
1106 sa.score = fazScore;
\r
1107 sa.threshold = threshold;
\r
1109 sa.hide_rsvmarkcolor = "";
\r
1116 // ピックアップ(予約待機(親)のみで表示)
\r
1117 if ((typ == ProgType.PROG || typ == ProgType.PICKED) && opt == SearchBy.BOTH && oKey == null) {
\r
1118 if ( ! doChkNewArr && ! doChkModify ) {
\r
1119 addPickedPrograms(curDateTime);
\r
1124 setReservedMarks();
\r
1126 tableModel_listed.fireTableDataChanged();
\r
1127 rowheaderModel_listed.fireTableDataChanged();
\r
1133 private void addPickedPrograms(String curDateTime) {
\r
1134 TVProgram tvp = tvprograms.getPickup();
\r
1135 if ( tvp != null ) {
\r
1136 for ( ProgList tPl : tvp.getCenters() ) {
\r
1137 for ( ProgDateList tPcl : tPl.pdate ) {
\r
1138 for ( ProgDetailList tvd : tPcl.pdetail ) {
\r
1140 // すでに過去になっているものは表示しない
\r
1141 if ( ! env.getDisplayPassedEntry()) {
\r
1142 if (tvd.endDateTime.compareTo(curDateTime) <= 0) {
\r
1148 ListedItem sa = new ListedItem();
\r
1153 sa.dupmark = null;
\r
1154 sa.prefix = tvd.extension_mark+tvd.prefix_mark;
\r
1155 sa.title = tvd.newlast_mark+"\0"+tvd.title+tvd.postfix_mark;
\r
1156 sa.searchlabel = "ピックアップ";
\r
1159 sa.threshold = "";
\r
1161 sa.hide_rsvmarkcolor = "";
\r
1177 * 絞り込み検索の本体(現在リストアップされているものから絞り込みを行う)(親から呼ばれるよ!)
\r
1179 public void redrawListByKeywordFilter(SearchKey keyword, String target) {
\r
1183 jLabel_tree.setView(JTreeLabel.Nodes.FILTERED, target);
\r
1185 ArrayList<ListedItem> tmpRowData = new ArrayList<ListedItem>();
\r
1187 for ( ListedItem c : rowData ) {
\r
1189 // 表示中の情報を一行ずつチェックする
\r
1190 ProgDetailList tvd = c.tvd;
\r
1193 boolean isFind = SearchProgram.isMatchKeyword(keyword, "", tvd);
\r
1195 String matched = SearchProgram.getMatchedString();
\r
1196 String[] tStr = new String[3];
\r
1197 if (matched != null) {
\r
1198 int a = tvd.title.indexOf(matched);
\r
1199 tStr[0] = tvd.title.substring(0,a);
\r
1200 tStr[1] = matched;
\r
1201 tStr[2] = tvd.title.substring(a+matched.length());
\r
1204 tStr[0] = tvd.title;
\r
1210 c.prefix = tvd.extension_mark+tvd.prefix_mark;
\r
1211 c.title = tvd.newlast_mark+"\0"+tStr[0]+"\0"+tStr[1]+"\0"+tStr[2]+tvd.postfix_mark;
\r
1213 tmpRowData.add(c);
\r
1219 for ( ListedItem a : tmpRowData ) {
\r
1224 tableModel_listed.fireTableDataChanged();
\r
1225 rowheaderModel_listed.fireTableDataChanged();
\r
1228 public boolean addRow(ListedItem data) {
\r
1231 for (; i<rowData.size(); i++) {
\r
1232 ListedItem c = rowData.get(i);
\r
1233 ProgDetailList tvd = c.tvd;
\r
1234 int x = tvd.startDateTime.compareTo(data.tvd.startDateTime);
\r
1235 int y = tvd.endDateTime.compareTo(data.tvd.endDateTime);
\r
1236 boolean isChMatched = c.tvd.center.equals(data.tvd.center);
\r
1237 boolean isTitleMatched = c.tvd.title.equals(data.tvd.title);
\r
1238 if (x == 0 && y == 0 && isChMatched ) {
\r
1239 // 日またがりで発生した重複エントリを整理 → ピックアップとかも重複するよ
\r
1240 ProgType typ = tvd.type;
\r
1242 if ( isTitleMatched ) {
\r
1243 StdAppendMessage("[重複エントリ] 省略しました: "+typ+" "+data.tvd.center+" "+data.tvd.title+" "+data.tvd.startDateTime+" "+data.tvd.endDateTime);
\r
1246 StdAppendMessage("[重複エントリ] 放送局と開始終了日時が同がじでタイトルの異なる情報がありました: "+typ+" "+data.tvd.center+" "+data.tvd.startDateTime+" "+data.tvd.title+" -> "+c.title);
\r
1257 rowData.add(i, data);
\r
1261 public void setReservedMarks() {
\r
1263 for ( ListedItem data : rowData ) {
\r
1266 Marker rm = getReservedMarkChar(data);
\r
1270 data.hide_rsvmarkcolor = rm.color;
\r
1271 data.fireChanged();
\r
1274 data.marker = null;
\r
1275 data.hide_rsvmarkcolor = "";
\r
1276 data.fireChanged();
\r
1284 private void setOverlapMark() {
\r
1286 if ( rowData.size() <= 1 ) {
\r
1287 // 1個以下ならソートの意味ないよね
\r
1292 for (int vrow=0; vrow<rowData.size(); vrow++) {
\r
1293 ListedItem rf = rowData.get(vrow);
\r
1294 rf.dupmark = null;
\r
1303 for (int vrow=0; vrow<rowData.size()-1; vrow++) {
\r
1304 ListedItem ra = rowData.get(vrow);
\r
1306 for ( int vrow2=vrow+1; vrow2<rowData.size(); vrow2++ ) {
\r
1307 ListedItem rb = rowData.get(vrow2);
\r
1309 if ( CommonUtils.getCompareDateTime(ra.tvd.endDateTime, rb.tvd.startDateTime) < 0) {
\r
1315 if ( ! sDT2.equals("")) {
\r
1322 sDT = ra.tvd.startDateTime;
\r
1323 eDT = ra.tvd.endDateTime;
\r
1327 sDT2 = rb.tvd.startDateTime;
\r
1328 eDT2 = rb.tvd.endDateTime;
\r
1331 if ( eDT.equals(sDT2) ) {
\r
1332 if ( ra.dupmark == null ) {
\r
1333 ra.dupmark = RsvMark.DUP_REP;
\r
1336 if ( rb.dupmark== null ) {
\r
1337 rb.dupmark = RsvMark.DUP_REP;
\r
1341 else if ( CommonUtils.isOverlap(sDT, eDT, sDT2, eDT2, false) ) {
\r
1342 ra.dupmark = rb.dupmark = RsvMark.DUP_NORMAL;
\r
1351 * 現在時刻追従スクロールを開始する
\r
1354 private void startTimer() {
\r
1355 timer_now_enabled = true;
\r
1359 * 現在時刻追従スクロールを停止する
\r
1361 private boolean stopTimer(boolean showmsg) {
\r
1362 return (timer_now_enabled = false);
\r
1365 // 主に他のクラスから呼び出されるメソッド
\r
1368 * サイドツリーの「予約待機」を選択する
\r
1370 public void selectTreeDefault() {
\r
1371 if ( defaultNode != null ) jTree_tree.setSelectionPath(new TreePath(defaultNode.getPath()));
\r
1375 * サイドツリーの現在選択中のノードを再度選択して描画しなおす
\r
1377 public void reselectTree() {
\r
1378 JTreeLabel.Nodes node = jLabel_tree.getNode();
\r
1379 String value = jLabel_tree.getValue();
\r
1380 String[] names = new String[] { node.getLabel(), value };
\r
1381 TreeNode[] nodes = ter.getSelectedPath(listRootNode, names, 0);
\r
1382 if (nodes != null) {
\r
1383 TreePath tp = new TreePath(nodes);
\r
1384 if ( tp != null ) {
\r
1385 jTree_tree.setSelectionPath(null);
\r
1386 jTree_tree.setSelectionPath(tp);
\r
1392 * 他から検索を実行される時にツリーの選択をはずす
\r
1394 public void clearSelection() {
\r
1395 jTree_tree.clearSelection();
\r
1401 public boolean isNodeSelected(JTreeLabel.Nodes node) {
\r
1402 return(node == jLabel_tree.getNode());
\r
1408 public void setExpandTree() {
\r
1409 jSplitPane_view.setDividerLocation(bounds.getTreeWidth());
\r
1410 jScrollPane_tree.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
\r
1411 jScrollPane_tree.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
\r
1417 public void setCollapseTree() {
\r
1418 jSplitPane_view.setDividerLocation(bounds.getMinDivLoc());
\r
1419 jScrollPane_tree.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
\r
1420 jScrollPane_tree.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
\r
1424 * サイドツリーの展開状態を設定ファイルに保存(鯛ナビ終了時に呼び出される)
\r
1426 public void saveTreeExpansion() {
\r
1431 * いまはどんな条件で表示しているのかな?
\r
1433 public String getCurrentView() {
\r
1434 return jLabel_tree.getView();
\r
1438 * 画面上部の番組詳細領域の表示のON/OFF
\r
1440 public void setDetailVisible(boolean aFlag) {
\r
1441 jTextPane_detail.setVisible(aFlag);
\r
1445 * テーブルの行番号の表示のON/OFF
\r
1447 public void setRowHeaderVisible(boolean b) {
\r
1448 jScrollPane_listed.getRowHeader().setVisible(b);
\r
1454 public Component getTableHeader() {
\r
1455 return jTable_listed.getTableHeader();
\r
1461 public Component getTableBody() {
\r
1462 return jTable_listed;
\r
1465 /*******************************************************************************
\r
1467 ******************************************************************************/
\r
1473 public void timerRised(TickTimerRiseEvent e) {
\r
1475 if ( ! timer_now_enabled ) {
\r
1481 ProgDetailList tvd = null;
\r
1483 // 更新前に選択していた行を確認する
\r
1485 int row = jTable_listed.getSelectedRow();
\r
1487 int vrow = jTable_listed.convertRowIndexToModel(row);
\r
1488 tvd = rowData.get(vrow).tvd;
\r
1492 reselectTree(); // タイマーはこの中で再開される
\r
1494 // 更新前に選択していた行を再度選択する
\r
1495 if ( tvd != null ) {
\r
1497 for ( ListedItem c : rowData ) {
\r
1499 if ( c.tvd == tvd ) {
\r
1500 int row = jTable_listed.convertRowIndexToView(vrow);
\r
1501 jTable_listed.setRowSelectionInterval(row,row);
\r
1509 * タブを開いたり閉じたりしたときに動くリスナー
\r
1510 * ★synchronized(rowData)★
\r
1511 * @see #updateReserveMark()
\r
1513 private ComponentListener cl_tabshownhidden = new ComponentAdapter() {
\r
1515 public void componentShown(ComponentEvent e) {
\r
1517 // ★★★ イベントにトリガーされた処理がかちあわないように synchronized() ★★★
\r
1518 synchronized ( rowData ) {
\r
1520 for (HDDRecorder recorder : recorders) {
\r
1521 recorder.removePassedReserves();
\r
1529 public void componentHidden(ComponentEvent e) {
\r
1539 * 行を選択すると詳細が表示されるようにする
\r
1541 private ListSelectionListener lsSelectListner = new ListSelectionListener() {
\r
1542 public void valueChanged(ListSelectionEvent e) {
\r
1543 if(e.getValueIsAdjusting()) return;
\r
1544 if (jTable_listed.getSelectedRow() >= 0) {
\r
1545 int row = jTable_listed.convertRowIndexToModel(jTable_listed.getSelectedRow());
\r
1546 ListedItem c = rowData.get(row);
\r
1547 jTextPane_detail.setLabel(
\r
1551 jTextPane_detail.setText(c.tvd.detail);
\r
1554 jTextPane_detail.setLabel("","","");
\r
1555 jTextPane_detail.setText("");
\r
1563 private MouseAdapter lsClickAdapter = new MouseAdapter() {
\r
1564 public void mouseClicked(MouseEvent e) {
\r
1566 JTable t = (JTable) e.getSource();
\r
1567 Point p = e.getPoint();
\r
1568 int vrow = t.rowAtPoint(p);
\r
1571 vrowInFocus = vrow;
\r
1573 //t.getSelectionModel().setSelectionInterval(vrow,vrow);
\r
1574 int row = t.convertRowIndexToModel(vrow);
\r
1575 ListedItem c = rowData.get(row);
\r
1577 ProgDetailList tvd = c.tvd;
\r
1579 // 番組表リストの挿入位置を決める
\r
1580 GregorianCalendar cal = CommonUtils.getCalendar(c.tvd.startDateTime);
\r
1581 if (CommonUtils.isLateNight(cal)) {
\r
1582 cal.add(Calendar.DATE,-1);
\r
1585 switch ( tvd.type ) {
\r
1593 MWin.appendError(ERRID+"未定義の番組表種別です: "+tvd.type);
\r
1597 if (e.getButton() == MouseEvent.BUTTON3) {
\r
1598 if (e.getClickCount() == 1) {
\r
1599 // 右シングルクリックでメニューの表示
\r
1600 t.getSelectionModel().setSelectionInterval(vrow,vrow);
\r
1602 int threshold = getThrValByRow(row);
\r
1603 String keyword = (threshold > 0) ? (getKeyValByRow(row)) : (tvd.title);
\r
1604 showPopupForTraceProgram(t, tvd, keyword, threshold, p.x, p.y);
\r
1607 else if (e.getButton() == MouseEvent.BUTTON1) {
\r
1608 if (e.getClickCount() == 2) {
\r
1610 if (tvd.type == ProgType.PROG && tvd.subtype == ProgSubtype.RADIO) {
\r
1613 // レコーダが選択されていない場合はなにもしない
\r
1614 if (recorders.size() == 0) {
\r
1619 switch ( env.getDblClkCmd() ) {
\r
1622 case SHOWRSVDIALOG:
\r
1623 if (tvd.type == ProgType.PASSED) {
\r
1629 String keyword = "";
\r
1630 int threshold = getThrValByRow(row);
\r
1631 if (threshold > 0) {
\r
1632 keyword = getKeyValByRow(row);
\r
1637 CommonSwingUtils.setLocationCenter(parent,rD);
\r
1638 if (rD.open(tvd, keyword, threshold)) {
\r
1639 rD.setVisible(true);
\r
1642 rD.setVisible(false);
\r
1646 if (rD.isSucceededReserve()) {
\r
1648 setReservedMarks();
\r
1649 tableModel_listed.fireTableDataChanged();
\r
1650 rowheaderModel_listed.fireTableDataChanged();
\r
1653 updateReserveDisplay(tvd.center);
\r
1659 jumpToPaper(tvd.center,tvd.startDateTime);
\r
1664 if ( tvd.link.startsWith("http") ) {
\r
1666 Desktop desktop = Desktop.getDesktop();
\r
1667 desktop.browse(new URI(tvd.link));
\r
1668 } catch (IOException e1) {
\r
1669 e1.printStackTrace();
\r
1670 } catch (URISyntaxException e1) {
\r
1671 e1.printStackTrace();
\r
1678 else if (e.getButton() == MouseEvent.BUTTON2) {
\r
1681 setReservedMarks();
\r
1682 tableModel_listed.fireTableDataChanged();
\r
1683 rowheaderModel_listed.fireTableDataChanged();
\r
1693 * サイドツリーのノードをさわると実行されるリスナー
\r
1695 private final MouseListener ml_nodeselected = new MouseAdapter() {
\r
1697 public void mouseClicked(MouseEvent e) {
\r
1698 if (SwingUtilities.isRightMouseButton(e)) {
\r
1699 int selRow = jTree_tree.getRowForLocation(e.getX(), e.getY());
\r
1700 if (selRow != -1) {
\r
1701 jTree_tree.setSelectionRow(selRow);
\r
1704 TreePath path = jTree_tree.getPathForLocation(e.getX(), e.getY());
\r
1706 if ( path != null ) {
\r
1708 JTreeLabel.Nodes node = (path.getPathCount() < 2) ? null : JTreeLabel.Nodes.getNode(path.getPathComponent(1).toString());
\r
1709 String value = path.getLastPathComponent().toString();
\r
1711 switch ( path.getPathCount() ) {
\r
1715 showPopupForSortTraceKey(e.getX(), e.getY());
\r
1718 showPopupForSortSearchKey(e.getX(), e.getY());
\r
1720 case KEYWORDGROUP:
\r
1721 showPopupForRemoveKeywordGrp(e.getX(), e.getY());
\r
1724 showPopupForSortExtension(e.getX(), e.getY());
\r
1734 showPopupForRemoveTraceKey(e.getX(), e.getY(), value);
\r
1737 showPopupForRemoveKeyword(e.getX(), e.getY(), value);
\r
1739 case KEYWORDGROUP:
\r
1740 showPopupForRemoveKeywordGrpName(e.getX(), e.getY(), value);
\r
1743 showPopupForRemoveExtension(e.getX(), e.getY(), value);
\r
1752 case KEYWORDGROUP:
\r
1753 showPopupForRemoveKeywordGrpEntry(e.getX(), e.getY(), path.getPathComponent(2).toString(), value);
\r
1766 * サイドツリーにつけるリスナー(ツリーの展開状態を記憶する)
\r
1768 private final TreeExpansionListener tel_nodeexpansion = new TreeExpansionListener() {
\r
1771 public void treeExpanded(TreeExpansionEvent event) {
\r
1776 public void treeCollapsed(TreeExpansionEvent event) {
\r
1782 * サイドツリーにつけるリスナー(クリックで描画実行)
\r
1784 private final TreeSelectionListener tsl_nodeselected = new TreeSelectionListener() {
\r
1786 public void valueChanged(TreeSelectionEvent e) {
\r
1788 TreePath path = jTree_tree.getSelectionPath();
\r
1790 if (path != null) {
\r
1794 boolean stop_timer = true;
\r
1796 JTreeLabel.Nodes node = (path.getPathCount() < 2) ? null : JTreeLabel.Nodes.getNode(path.getPathComponent(1).toString());
\r
1798 switch ( path.getPathCount() ) {
\r
1804 redrawListByFlag(ProgFlags.NEW);
\r
1807 redrawListByFlag(ProgFlags.LAST);
\r
1810 redrawListByNow(null);
\r
1811 stop_timer = false;
\r
1814 redrawSyobocalListByTraceAndKeyword();
\r
1817 redrawListByTraceAndKeyword();
\r
1820 redrawListByTrace(null);
\r
1823 redrawListByKeyword(null);
\r
1826 redrawListByExtkeywordAll(extKeys.getSearchKeys());
\r
1831 jLabel_tree.setView(node, null);
\r
1838 VWListedTreeNode inode = (VWListedTreeNode) path.getLastPathComponent();
\r
1839 VWListedTreeNode parent = (VWListedTreeNode) inode.getParent();
\r
1840 redrawListBySearched(ProgType.PASSED,parent.getIndex(inode));
\r
1844 ProgGenre genre = ProgGenre.get(path.getLastPathComponent().toString());
\r
1845 if ( genre != null ) {
\r
1846 redrawListByFlag(ProgFlags.NEW,genre);
\r
1852 ProgGenre genre = ProgGenre.get(path.getLastPathComponent().toString());
\r
1853 if ( genre != null ) {
\r
1854 redrawListByFlag(ProgFlags.LAST,genre);
\r
1860 JTreeLabel.Nodes subnode = JTreeLabel.Nodes.getNode(path.getLastPathComponent().toString());
\r
1861 switch ( subnode ) {
\r
1863 redrawSyobocalListByTrace();
\r
1866 redrawSyobocalListByKeyword();
\r
1869 redrawSyobocalAll();
\r
1878 ProgGenre genre = ProgGenre.get(path.getLastPathComponent().toString());
\r
1879 if ( genre != null ) {
\r
1880 redrawListByNow(genre);
\r
1881 stop_timer = false;
\r
1887 JTreeLabel.Nodes subnode = JTreeLabel.Nodes.getNode(path.getLastPathComponent().toString());
\r
1888 switch ( subnode ) {
\r
1890 redrawListByTraceAndKeywordNewArrival();
\r
1893 redrawListByTraceAndKeywordModified();
\r
1896 redrawSyobocalListByOnly();
\r
1899 redrawListByPickup();
\r
1902 redrawListByTraceAndKeywordOkini(path.getLastPathComponent().toString());
\r
1908 for (TraceKey trace : trKeys.getTraceKeys()) {
\r
1909 if (path.getLastPathComponent().toString().equals(trace._getLabel())) {
\r
1910 redrawListByTrace(trace);
\r
1916 for (SearchKey search : srKeys.getSearchKeys()) {
\r
1917 if (path.getLastPathComponent().toString().equals(search.getLabel())) {
\r
1918 redrawListByKeyword(search);
\r
1923 case KEYWORDGROUP:
\r
1924 for (SearchGroup gr : srGrps) {
\r
1925 if (gr.getName().equals(path.getLastPathComponent().toString())) {
\r
1926 redrawListByKeywordGrp(gr);
\r
1932 for (ProgGenre genre : ProgGenre.values()) {
\r
1933 if (path.getLastPathComponent().toString().equals(genre.toString())) {
\r
1934 redrawListByGenre(genre, null);
\r
1940 redrawListByCenterList(path.getLastPathComponent().toString());
\r
1943 for (SearchKey search : extKeys.getSearchKeys()) {
\r
1944 if (path.getLastPathComponent().toString().equals(search.getLabel())) {
\r
1945 redrawListByKeywordDyn(search);
\r
1953 jLabel_tree.setView(node, path.getLastPathComponent().toString());
\r
1954 System.out.println(jLabel_tree.getView());
\r
1960 case KEYWORDGROUP:
\r
1961 for (SearchKey search : srKeys.getSearchKeys()) {
\r
1962 if (path.getLastPathComponent().toString().equals(search.getLabel())) {
\r
1963 redrawListByKeyword(search);
\r
1969 ProgGenre genre = ProgGenre.get(path.getPathComponent(2).toString());
\r
1970 if ( genre != null ) {
\r
1971 ProgSubgenre subgenre = ProgSubgenre.get(path.getLastPathComponent().toString());
\r
1972 if ( subgenre != null ) {
\r
1973 redrawListByGenre(genre, subgenre);
\r
1980 jLabel_tree.setView(node, path.getLastPathComponent().toString());
\r
1985 stopTimer( ! (path.getPathCount() >= 2 && path.getPathComponent(1).toString().equals(JTreeLabel.Nodes.NOW.toString())));
\r
1994 private final MouseListener ml_treehide = new MouseAdapter() {
\r
1995 public void mouseEntered(MouseEvent e) {
\r
1996 if (isFullScreen()) {
\r
1998 //StdAppendMessage("Show tree (L)");
\r
2001 public void mouseExited(MouseEvent e) {
\r
2002 if (isFullScreen()) {
\r
2003 setCollapseTree();
\r
2004 //StdAppendMessage("Hide tree (L)");
\r
2013 private void stopTreeListener() {
\r
2014 jTree_tree.removeMouseListener(ml_nodeselected);
\r
2015 jTree_tree.removeTreeSelectionListener(tsl_nodeselected);
\r
2021 private void startTreeListener() {
\r
2022 jTree_tree.addMouseListener(ml_nodeselected);
\r
2023 jTree_tree.addTreeSelectionListener(tsl_nodeselected);
\r
2029 public void redrawTreeByHistory() {
\r
2031 stopTreeListener();
\r
2032 TreePath tp = jTree_tree.getSelectionPath();
\r
2034 SearchResult searched = tvprograms.getSearched();
\r
2036 searchedNode.removeAllChildren();
\r
2037 for ( int i=0; i<searched.getResultBufferSize(); i++) {
\r
2038 searchedNode.add(new VWListedTreeNode(searched.getLabel(i)));
\r
2041 jTree_tree.setSelectionPath(tp);
\r
2042 jTree_tree.updateUI();
\r
2043 startTreeListener();
\r
2049 private void redrawTreeByGenre() {
\r
2051 stopTreeListener();
\r
2052 TreePath tp = jTree_tree.getSelectionPath();
\r
2054 _redrawTreeByGenre(nowNode);
\r
2055 _redrawTreeByGenre(startNode);
\r
2056 _redrawTreeByGenre(endNode);
\r
2058 jTree_tree.setSelectionPath(tp);
\r
2059 jTree_tree.updateUI();
\r
2060 startTreeListener();
\r
2063 private void _redrawTreeByGenre(DefaultMutableTreeNode parent) {
\r
2064 parent.removeAllChildren();
\r
2065 for ( ProgGenre genre : ProgGenre.values() ) {
\r
2066 parent.add(new VWListedTreeNode(genre.toString()));
\r
2073 private void redrawTreeBySyobo() {
\r
2075 stopTreeListener();
\r
2076 TreePath tp = jTree_tree.getSelectionPath();
\r
2078 syobocalNode.removeAllChildren();
\r
2079 syobocalNode.add(new VWListedTreeNode(JTreeLabel.Nodes.TRACE.getLabel()));
\r
2080 syobocalNode.add(new VWListedTreeNode(JTreeLabel.Nodes.KEYWORD.getLabel()));
\r
2081 syobocalNode.add(new VWListedTreeNode(JTreeLabel.Nodes.SYOBOALL.getLabel()));
\r
2083 jTree_tree.setSelectionPath(tp);
\r
2084 jTree_tree.updateUI();
\r
2085 startTreeListener();
\r
2091 private void redrawTreeByStandby() {
\r
2093 stopTreeListener();
\r
2094 TreePath tp = jTree_tree.getSelectionPath();
\r
2096 standbyNode.removeAllChildren();
\r
2097 for ( String okini : TVProgram.OKINIIRI ) {
\r
2098 if ( ! "".equals(okini) ) {
\r
2099 standbyNode.add(new VWListedTreeNode(okini));
\r
2102 standbyNode.add(new VWListedTreeNode(JTreeLabel.Nodes.PICKUP.getLabel()));
\r
2103 standbyNode.add(new VWListedTreeNode(JTreeLabel.Nodes.NEWARRIVAL.getLabel()));
\r
2104 standbyNode.add(new VWListedTreeNode(JTreeLabel.Nodes.MODIFIED.getLabel()));
\r
2105 if ( env.getUseSyobocal() ) {
\r
2106 standbyNode.add(new VWListedTreeNode(JTreeLabel.Nodes.SYOBOONLY.getLabel()));
\r
2109 jTree_tree.setSelectionPath(tp);
\r
2110 jTree_tree.updateUI();
\r
2111 startTreeListener();
\r
2117 public void redrawTreeByTrace() {
\r
2119 stopTreeListener();
\r
2120 TreePath tp = jTree_tree.getSelectionPath();
\r
2122 traceNode.removeAllChildren();
\r
2123 for ( TraceKey key : trKeys.getTraceKeys() ) {
\r
2124 traceNode.add(new VWListedTreeNode(key));
\r
2127 jTree_tree.setSelectionPath(tp);
\r
2128 jTree_tree.updateUI();
\r
2129 startTreeListener();
\r
2135 public void redrawTreeByKeyword() {
\r
2137 stopTreeListener();
\r
2138 TreePath tp = jTree_tree.getSelectionPath();
\r
2140 keywordNode.removeAllChildren();
\r
2141 for ( SearchKey key : srKeys.getSearchKeys() ) {
\r
2142 keywordNode.add(new VWListedTreeNode(key));
\r
2145 jTree_tree.setSelectionPath(tp);
\r
2146 jTree_tree.updateUI();
\r
2147 startTreeListener();
\r
2153 public void redrawTreeBySubGenre() {
\r
2155 stopTreeListener();
\r
2156 TreePath tp = jTree_tree.getSelectionPath();
\r
2158 genreNode.removeAllChildren();
\r
2159 for ( ProgGenre genre : ProgGenre.values() ) {
\r
2160 VWListedTreeNode g = new VWListedTreeNode(genre.toString());
\r
2162 for ( ProgSubgenre subgenre : ProgSubgenre.values(genre) ) {
\r
2163 VWListedTreeNode sg = new VWListedTreeNode(subgenre.toString());
\r
2168 jTree_tree.setSelectionPath(tp);
\r
2169 jTree_tree.updateUI();
\r
2170 startTreeListener();
\r
2176 public void redrawTreeByCenter() {
\r
2178 stopTreeListener();
\r
2179 TreePath tp = jTree_tree.getSelectionPath();
\r
2181 centerListNode.removeAllChildren();
\r
2182 TVProgramIterator pli = tvprograms.getIterator().build(chsort.getClst(), IterationType.ALL);
\r
2183 for ( ProgList pl : pli ) {
\r
2184 centerListNode.add(new VWListedTreeNode(pl.Center));
\r
2187 jTree_tree.setSelectionPath(tp);
\r
2188 jTree_tree.updateUI();
\r
2189 startTreeListener();
\r
2193 * キーワードグループでサブノード作成
\r
2195 public void redrawTreeByKeywordGroup() {
\r
2197 stopTreeListener();
\r
2198 TreePath tp = jTree_tree.getSelectionPath();
\r
2200 keywordGrpNode.removeAllChildren();
\r
2201 for ( SearchGroup gr : srGrps ) {
\r
2202 VWListedTreeNode gn = new VWListedTreeNode(gr.getName());
\r
2203 keywordGrpNode.add(gn);
\r
2204 for ( String kw : gr ) {
\r
2205 gn.add(new VWListedTreeNode(kw));
\r
2209 jTree_tree.setSelectionPath(tp);
\r
2210 jTree_tree.updateUI();
\r
2211 startTreeListener();
\r
2217 public void redrawTreeByExtension() {
\r
2219 stopTreeListener();
\r
2220 TreePath tp = jTree_tree.getSelectionPath();
\r
2222 extensionNode.removeAllChildren();
\r
2223 for ( SearchKey key : extKeys.getSearchKeys() ) {
\r
2224 extensionNode.add(new VWListedTreeNode(key.getLabel()));
\r
2227 jTree_tree.setSelectionPath(tp);
\r
2228 jTree_tree.updateUI();
\r
2229 startTreeListener();
\r
2235 * 現時点でまだ開始していない番組を上から順に選択する。
\r
2237 public void selectBatchTarget() {
\r
2239 String dt = CommonUtils.getDateTime(0);
\r
2242 for (int row=0; row<rowData.size(); row++) {
\r
2243 ListedItem c = rowData.get(row);
\r
2244 if (dt.compareTo(c.tvd.startDateTime) > 0) {
\r
2248 if ( c.marker == null || c.marker.rsvmark == null || c.marker.rsvmark == RsvMark.URABAN ) {
\r
2249 int vrow = jTable_listed.convertRowIndexToView(row);
\r
2250 jTable_listed.getSelectionModel().addSelectionInterval(vrow, vrow);
\r
2251 if (cnt++ >= env.getRsvTargets()) {
\r
2259 * ツールバーの一括予約ボタンを押して実行される一括予約処理
\r
2261 public void doBatchReserve() {
\r
2263 boolean mod = false;
\r
2264 for (int vrow : jTable_listed.getSelectedRows()) {
\r
2266 int row = jTable_listed.convertRowIndexToModel(vrow);
\r
2267 ProgDetailList tvd = rowData.get(row).tvd;
\r
2269 //VWReserveDialog rD = new VWReserveDialog(0, 0, env, tvprograms, recorders, avs, chavs, stwin);
\r
2272 if (rD.open(tvd)) {
\r
2276 // 予約ダイアログは見せないまま更新を実行する
\r
2278 if ( ! rD.isSucceededReserve()) {
\r
2279 StdAppendError("【警告】予約の登録に失敗しました: "+rowData.get(row).tvd.title);
\r
2288 setReservedMarks();
\r
2289 tableModel_listed.fireTableDataChanged();
\r
2290 rowheaderModel_listed.fireTableDataChanged();
\r
2293 updateReserveDisplay(null);
\r
2298 * 他のクラスで発生したイベント中に呼び出されてリスト形式の予約マーク表示を更新するためのメソッド。
\r
2299 * ★synchronized(rowData)★
\r
2300 * @see #cl_tabshownhidden
\r
2302 public void updateReserveMark() {
\r
2303 // ★★★ イベントにトリガーされた処理がかちあわないように synchronized() ★★★
\r
2304 synchronized ( rowData ) {
\r
2305 setReservedMarks();
\r
2306 tableModel_listed.fireTableDataChanged();
\r
2307 rowheaderModel_listed.fireTableDataChanged();
\r
2312 * テーブルを更新した後、セレクション状態が解除されるので再度セレクションする。
\r
2314 public void refocus() {
\r
2315 if (vrowInFocus >= 0) {
\r
2316 if (vrowInFocus < jTable_listed.getRowCount()) {
\r
2317 jTable_listed.getSelectionModel().addSelectionInterval(vrowInFocus, vrowInFocus);
\r
2324 * カラム幅を保存する(鯛ナビ終了時に呼び出されるメソッド)
\r
2326 public void copyColumnWidth() {
\r
2327 //DefaultTableColumnModel columnModel = (DefaultTableColumnModel)jTable_listed.getColumnModel();
\r
2328 for ( ListedColumn lc : ListedColumn.values() ) {
\r
2329 TableColumn column = jTable_listed.getColumn(lc.getName());
\r
2330 int w = column.getWidth();
\r
2331 bounds.getListedColumnSize().put(lc.toString(), w > 0 ? w : lc.getIniWidth()); // toString()!
\r
2335 // キーワードにマッチした箇所の強調色
\r
2336 public void setMatchedKeywordColor(Color c) {
\r
2337 titleCellRenderer.setMatchedKeywordColor(c);
\r
2341 public void setRsvdLineColor(Color c) {
\r
2342 jTable_listed.setReservedColor(c);
\r
2346 public void setPickedLineColor(Color c) {
\r
2347 jTable_listed.setPickedColor(c);
\r
2351 public void setCurrentLineColor(Color c) {
\r
2352 jTable_listed.setCurrentColor(c);
\r
2356 public void setMarkColumnVisible(boolean b) {
\r
2357 _setColumnVisible(ListedColumn.OPTIONS, b);
\r
2361 public void setDetailColumnVisible(boolean b) {
\r
2362 _setColumnVisible(ListedColumn.DETAIL, b);
\r
2366 public void setPickupColumnVisible(boolean b) {
\r
2367 _setColumnVisible(ListedColumn.PICKMARK, b);
\r
2371 public void setDupColumnVisible(boolean b) {
\r
2372 _setColumnVisible(ListedColumn.DUPMARK, b);
\r
2375 private void _setColumnVisible(ListedColumn lc, boolean b) {
\r
2376 if ( lc.getIniWidth() < 0 ) {
\r
2379 TableColumn column = jTable_listed.getColumnModel().getColumn(lc.getColumn());
\r
2381 column.setMinWidth(MIN_COLUMN_WIDTH);
\r
2382 column.setPreferredWidth(lc.getIniWidth());
\r
2385 column.setMinWidth(0);
\r
2386 column.setPreferredWidth(0);
\r
2391 * 特定の項目を取得しやすくした感じ?
\r
2394 // 検索結果一覧上のIdNumをintに戻す
\r
2395 private int getThrValByRow(int row) {
\r
2397 return Integer.valueOf(rowData.get(row).threshold);
\r
2398 } catch (NumberFormatException e2) {
\r
2403 private String getKeyValByRow(int row) {
\r
2404 Matcher ma = Pattern.compile("^(.+)\\s*\\([^\\)]+?\\)$").matcher(rowData.get(row).searchlabel);
\r
2406 return ma.group(1);
\r
2420 * 引数で指定した番組を予約している、または予約に一部時間が重なっている場合に表示する予約マークを取得する。
\r
2421 * @return String [0]マーク [1]予約しているレコーダのユニークID({@link HDDRecorder#Myself()}) [2]色({@link CommonUtils#str2color(String)})
\r
2423 private Marker getReservedMarkChar(ListedItem data) {
\r
2425 // コンボボックスの指定はピックアップである
\r
2426 String myself = getSelectedRecorderOnToolbar();
\r
2427 boolean isPickupOnly = ( myself == HDDRecorder.SELECTED_PICKUP ) ;
\r
2429 Marker mark = new Marker("", "");
\r
2430 boolean marked = false;
\r
2432 if ( ! isPickupOnly ) {
\r
2433 // 「ピックアップ」が選択されていればここは通らない
\r
2436 HDDRecorderList s_recorders = recorders.findInstance(myself);
\r
2439 ArrayList<NeighborReserveList> n_reserves = findOverlapReserves(s_recorders, data);
\r
2441 for ( NeighborReserveList n_res : n_reserves ) {
\r
2442 if ( ! data.tvd.center.equals(n_res.getReserve().getCh_name()) ) {
\r
2448 mark = new Marker(n_res.getRecorder().Myself(), n_res.getRecorder().getColor(n_res.getReserve().getTuner()));
\r
2449 marked = _getReservedMarkCharNormal(mark, data, n_res);
\r
2454 if ( env.getShowRsvUra() && ! marked ) {
\r
2455 for ( NeighborReserveList n_res : n_reserves ) {
\r
2456 if ( data.tvd.center.equals(n_res.getReserve().getCh_name()) ) {
\r
2460 if ( ! n_res.getReserve().getExec() ) {
\r
2461 // 実行不可なら裏番組にはならない
\r
2466 marked = _getReservedMarkCharUra(mark, data) || marked;
\r
2474 if ( env.getShowRsvPickup() ) {
\r
2475 marked = _getReservedMarkCharPickup(mark, data) || marked;
\r
2478 return(marked ? mark : null);
\r
2482 * その番組の近傍の予約情報のリストを作成する
\r
2484 private ArrayList<NeighborReserveList> findOverlapReserves(HDDRecorderList s_recorders, ListedItem data) {
\r
2487 ArrayList<NeighborReserveList> n_reserves = new ArrayList<NeighborReserveList>();
\r
2490 String critDateTime = CommonUtils.getCritDateTime(env.getDisplayPassedReserve());
\r
2492 // 全予約をなめて、一番近い予約を探さなければならない
\r
2493 for ( HDDRecorder rec : s_recorders ) {
\r
2494 for ( ReserveList res : rec.getReserves() ) {
\r
2495 if ( env.getDisplayOnlyExecOnEntry() && ! res.getExec() ) {
\r
2496 // 実行可能な予約しかいらない場合
\r
2500 if ( res.getCh_name() == null ) {
\r
2506 ArrayList<String> starts = new ArrayList<String>();
\r
2507 ArrayList<String> ends = new ArrayList<String>();
\r
2508 CommonUtils.getStartEndList(starts, ends, res);
\r
2510 for ( int j=0; j<starts.size(); j++ ) {
\r
2511 if ( critDateTime.compareTo(ends.get(j)) > 0 ) {
\r
2515 if ( CommonUtils.isOverlap(data.tvd.startDateTime, data.tvd.endDateTime, starts.get(j), ends.get(j), true) ) {
\r
2516 // 重なってる(開始時間=終了時間は除外)
\r
2517 long df = CommonUtils.getDiffDateTime(starts.get(j), data.tvd.startDateTime);
\r
2518 NeighborReserveList n_res = new NeighborReserveList(rec, res, starts.get(j), ends.get(j), df);
\r
2522 for ( ; index < n_reserves.size(); index++ ) {
\r
2523 if ( n_res.getDiff() < n_reserves.get(index).getDiff() ) {
\r
2527 n_reserves.add(index, n_res);
\r
2535 return n_reserves;
\r
2538 private class NeighborReserveList {
\r
2539 public NeighborReserveList(HDDRecorder recorder, ReserveList reserve, String start, String end, long diff) {
\r
2540 this.recorder = recorder;
\r
2541 this.reserve = reserve;
\r
2542 this.start = start;
\r
2547 private HDDRecorder recorder;
\r
2548 public HDDRecorder getRecorder() { return recorder; }
\r
2550 private ReserveList reserve;
\r
2551 public ReserveList getReserve() { return reserve; }
\r
2553 private long diff;
\r
2554 public long getDiff() { return diff; }
\r
2556 private String start;
\r
2557 public String getStart() { return start; }
\r
2559 private String end;
\r
2560 public String getEnd() { return end; }
\r
2564 * @see #getReservedMarkChar(ListedItem)
\r
2566 private boolean _getReservedMarkCharNormal(Marker mark, ListedItem data, NeighborReserveList n_reserve) {
\r
2568 // ここに入ってくる場合は時間の重なりが確認できているものだけである
\r
2569 HDDRecorder recorder = n_reserve.getRecorder();
\r
2570 ReserveList reserve = n_reserve.getReserve();
\r
2571 String start = n_reserve.getStart();
\r
2572 String end = n_reserve.getEnd();
\r
2574 RSVMARK_COND cond = getReservedMarkCond(data, start, end);
\r
2576 if (debug) System.err.println(DBGID+data.tvd.title+" "+data.tvd.startDateTime+" "+data.tvd.endDateTime+" "+start+" "+end+" "+cond);
\r
2584 mk = RsvMark.DELAYED;
\r
2587 mk = RsvMark.UNDERRUN;
\r
2590 mk = RsvMark.OVERRUN;
\r
2593 mk = (data.tvd.extension) ? (RsvMark.CLIPPED_E) : (RsvMark.CLIPPED);
\r
2596 mk = (data.tvd.extension) ? (RsvMark.SHORTAGE_E) : (RsvMark.SHORTAGE);
\r
2599 mk = RsvMark.NORMAL;
\r
2603 mark.rsvmark = (reserve.getExec()) ? mk : RsvMark.NOEXEC;
\r
2607 private RSVMARK_COND getReservedMarkCond(ListedItem data, String start, String end) {
\r
2609 // 番組の終了日時と予約の開始日時(1分は想定内)
\r
2610 int overlap = (int) (CommonUtils.getCompareDateTime(data.tvd.endDateTime,start)/60000L);
\r
2611 if ( env.getOverlapUp() && overlap == 1 )
\r
2612 return RSVMARK_COND.PREV;
\r
2615 // 番組の開始日時と予約の開始日時(1分でも遅れちゃだめ)
\r
2616 int overlap = (int) (CommonUtils.getCompareDateTime(data.tvd.startDateTime,start)/60000L);
\r
2617 if ( overlap <= -1 )
\r
2618 return RSVMARK_COND.DELAY;
\r
2621 // 延長警告がある場合はこんだけ延びる
\r
2622 int spoex_length = (data.tvd.extension)?(Integer.valueOf(env.getSpoexLength())):(0);
\r
2625 // 番組の終了日時と予約の終了日時
\r
2626 int overlap = (int) (CommonUtils.getCompareDateTime(data.tvd.endDateTime,end)/60000L);
\r
2628 if (data.tvd.extension) {
\r
2629 // ここは、延長警告で時間が延びるはずが微妙に延びてない感じの予約を探すためのもの
\r
2631 // 通常1分短縮から~延長2分短縮まで
\r
2632 // 通常1分延長から~延長0分延長まで
\r
2633 // どちらでもなければ通常0分短縮から~延長1分短縮まで
\r
2635 (env.getOverlapDown2() && ! data.tvd.dontoverlapdown && (overlap <= 1 && (overlap+spoex_length) >= 2)) ||
\r
2636 (env.getOverlapDown() && (overlap <= -1 && (overlap+spoex_length) >= 0)) ||
\r
2637 ( ( ! env.getOverlapDown2() || env.getOverlapDown2() && data.tvd.dontoverlapdown) && ! env.getOverlapDown() && (overlap <= 0 && (overlap+spoex_length) >= 1))
\r
2639 return RSVMARK_COND.UNDER;
\r
2642 // ケツ短縮で0分以上進んでたらだめ
\r
2643 // ケツ延長で2分以上進んでたらだめ
\r
2644 // どちらでもなければ1分以上進んでたらだめ
\r
2646 (env.getOverlapDown2() && ! data.tvd.dontoverlapdown && (overlap+spoex_length) <= 0) ||
\r
2647 (env.getOverlapDown() && (overlap+spoex_length) <= -2) ||
\r
2648 ( ( ! env.getOverlapDown2() || env.getOverlapDown2() && data.tvd.dontoverlapdown) && ! env.getOverlapDown() && (overlap+spoex_length) <= -1)
\r
2650 return RSVMARK_COND.OVER;
\r
2652 if ( env.getOverlapDown2() ) {
\r
2654 if ( (overlap+spoex_length) == 1 )
\r
2655 return RSVMARK_COND.CLIP;
\r
2657 if ( (overlap+spoex_length) >= 2 )
\r
2658 return RSVMARK_COND.SHORT;
\r
2662 if ( (overlap+spoex_length) >= 2 )
\r
2663 return RSVMARK_COND.SHORT;
\r
2666 if ( env.getOverlapDown() ) {
\r
2668 if ( (overlap+spoex_length) == -1 )
\r
2669 return RSVMARK_COND.CLIP;
\r
2671 if ( (overlap+spoex_length) <= 0 )
\r
2672 return RSVMARK_COND.SHORT;
\r
2676 if ( (overlap+spoex_length) <= -1 )
\r
2677 return RSVMARK_COND.SHORT;
\r
2683 return RSVMARK_COND.NORMAL;
\r
2685 private static enum RSVMARK_COND { PREV, DELAY, UNDER, OVER, CLIP, SHORT, NORMAL };
\r
2687 private boolean _getReservedMarkCharPickup(Marker mark, ListedItem data) {
\r
2688 //return (data.hide_ispickup)?(new Marker(RSVMARK_PICKUP,"",PICKUP_COLOR)):(null);
\r
2690 PickedProgram picktvp = tvprograms.getPickup();
\r
2693 ProgDetailList picktvd = picktvp.find(data.tvd);
\r
2694 if ( picktvd == null ) {
\r
2699 mark.pickmark = RsvMark.PICKUP;
\r
2704 private boolean _getReservedMarkCharUra(Marker mark, ListedItem data) {
\r
2706 mark.rsvmark = RsvMark.URABAN;
\r
2709 if ( mark.rsvmark != null ) {
\r
2714 String myself = getSelectedRecorderOnToolbar();
\r
2715 HDDRecorderList recs = recorders.findInstance(myself);
\r
2717 for ( HDDRecorder rec : recs )
\r
2719 for ( ReserveList res : rec.getReserves() ) {
\r
2721 if ( env.getDisplayOnlyExecOnEntry() && ! res.getExec() ) {
\r
2725 if ( data.tvd.center.equals(res.getCh_name()) ) {
\r
2726 // 局が違うならいらねーよ → 裏番組だろ、逆だろJK
\r
2731 ArrayList<String> starts = new ArrayList<String>();
\r
2732 ArrayList<String> ends = new ArrayList<String>();
\r
2733 CommonUtils.getStartEndList(starts, ends, res);
\r
2734 for (int j=0; j<starts.size(); j++) {
\r
2735 if ( CommonUtils.isOverlap(data.tvd.startDateTime, data.tvd.endDateTime, starts.get(j), ends.get(j), env.getAdjoiningNotRepetition()) ) {
\r
2736 mark.rsvmark = RsvMark.URABAN;
\r
2751 * ここからノード編集系がいっぱいならんでるお!
\r
2757 private void editTraceKey(String keyword) {
\r
2759 VWTraceKeyDialog tD = new VWTraceKeyDialog(0,0);
\r
2760 CommonSwingUtils.setLocationCenter(parent,tD);
\r
2762 tD.reopen(keyword, trKeys);
\r
2763 tD.setVisible(true);
\r
2765 if (tD.isRegistered()) {
\r
2767 mpList.clear(env.getDisableFazzySearch(), env.getDisableFazzySearchReverse());
\r
2768 mpList.build(tvprograms, trKeys.getTraceKeys(), srKeys.getSearchKeys());
\r
2770 //trKeys.save(); // 保存はtDの中でやってるよ
\r
2772 // 変更したノードを選択するようにしたい
\r
2773 jLabel_tree.setView(JTreeLabel.Nodes.TRACE, tD.getNewLabel());
\r
2776 updateBangumiColumns();
\r
2779 redrawTreeByTrace();
\r
2789 private void removeTraceKey(String keyword) {
\r
2791 if (env.getShowWarnDialog()) {
\r
2792 //Container cp = frame.getContentPane();
\r
2793 int ret = JOptionPane.showConfirmDialog(parent, "削除しますか?【"+keyword+"】", "確認", JOptionPane.YES_NO_OPTION);
\r
2794 if (ret != JOptionPane.YES_OPTION) {
\r
2799 MWin.appendMessage("番組追跡が削除されました【"+keyword+"】");
\r
2802 trKeys.remove(keyword);
\r
2806 mpList.clear(env.getDisableFazzySearch(), env.getDisableFazzySearchReverse());
\r
2807 mpList.build(tvprograms, trKeys.getTraceKeys(), srKeys.getSearchKeys());
\r
2811 updateBangumiColumns();
\r
2814 redrawTreeByTrace();
\r
2818 * 番組追跡のお気に入りを変更したい
\r
2820 private void setTraceKeyOkiniiri(TraceKey tk, String okini) {
\r
2823 tk.setOkiniiri(okini);
\r
2827 mpList.clear(env.getDisableFazzySearch(), env.getDisableFazzySearchReverse());
\r
2828 mpList.build(tvprograms, trKeys.getTraceKeys(), srKeys.getSearchKeys());
\r
2837 private void sortTraceKey() {
\r
2839 ArrayList<String> oList = new ArrayList<String>();
\r
2840 for ( TraceKey key : trKeys.getTraceKeys() ) {
\r
2841 oList.add(key._getLabel());
\r
2845 int oCnt = oList.size();
\r
2848 JListSortDialog lsD = new JListSortDialog("番組追跡の並べ替え", oList);
\r
2849 CommonSwingUtils.setLocationCenter(parent,lsD);
\r
2851 lsD.setVisible(true);
\r
2853 if (lsD.isRegistered()) {
\r
2854 TraceProgram newTrKeys = new TraceProgram();
\r
2855 for ( String label : oList ) {
\r
2856 for ( TraceKey key : trKeys.getTraceKeys() ) {
\r
2857 if ( key._getLabel().equals(label) ) {
\r
2858 newTrKeys.add(key);
\r
2863 //trKeys = newTrKeys;
\r
2864 FieldUtils.deepCopy(trKeys, newTrKeys);
\r
2867 if ( oList.size() < oCnt ) {
\r
2868 // 削除があった場合のみ検索結果の再構築
\r
2869 mpList.clear(env.getDisableFazzySearch(), env.getDisableFazzySearchReverse());
\r
2870 mpList.build(tvprograms, trKeys.getTraceKeys(), srKeys.getSearchKeys());
\r
2874 redrawTreeByTrace();
\r
2881 private void editSearchKey(String keyword) {
\r
2883 AbsKeywordDialog kD = new VWKeywordDialog();
\r
2884 CommonSwingUtils.setLocationCenter(parent,kD);
\r
2886 kD.reopen(keyword, srKeys);
\r
2887 kD.setVisible(true);
\r
2889 if (kD.isRegistered()) {
\r
2891 mpList.clear(env.getDisableFazzySearch(), env.getDisableFazzySearchReverse());
\r
2892 mpList.build(tvprograms, trKeys.getTraceKeys(), srKeys.getSearchKeys());
\r
2896 if ( ! kD.getNewLabel().equals(keyword) ) {
\r
2897 if ( srGrps.rename(null, keyword, kD.getNewLabel()) ) {
\r
2902 // srKeys.save(); // 保存はkDの中でやってるよ
\r
2904 // 変更したノードを選択するようにしたい
\r
2905 jLabel_tree.setView(JTreeLabel.Nodes.KEYWORD, kD.getNewLabel());
\r
2908 updateBangumiColumns();
\r
2911 redrawTreeByKeyword();
\r
2912 redrawTreeByKeywordGroup();
\r
2922 private void removeSearchKey(String keyword) {
\r
2924 if (env.getShowWarnDialog()) {
\r
2925 //Container cp = getContentPane();
\r
2926 int ret = JOptionPane.showConfirmDialog(parent, "削除しますか?【"+keyword+"】", "確認", JOptionPane.YES_NO_OPTION);
\r
2927 if (ret != JOptionPane.YES_OPTION) {
\r
2933 srKeys.remove(keyword);
\r
2937 mpList.clear(env.getDisableFazzySearch(), env.getDisableFazzySearchReverse());
\r
2938 mpList.build(tvprograms, trKeys.getTraceKeys(), srKeys.getSearchKeys());
\r
2942 if ( srGrps.remove(null,keyword) ) {
\r
2947 updateBangumiColumns();
\r
2950 redrawTreeByKeyword();
\r
2951 redrawTreeByKeywordGroup();
\r
2955 * キーワード検索のお気に入りを変更したい
\r
2957 private void setSearchKeyOkiniiri(SearchKey sr, String okini) {
\r
2959 sr.setOkiniiri(okini);
\r
2963 mpList.clear(env.getDisableFazzySearch(), env.getDisableFazzySearchReverse());
\r
2964 mpList.build(tvprograms, trKeys.getTraceKeys(), srKeys.getSearchKeys());
\r
2973 private void sortSearchKey() {
\r
2975 ArrayList<String> oList = new ArrayList<String>();
\r
2976 for ( SearchKey key : srKeys.getSearchKeys() ) {
\r
2977 oList.add(key.getLabel());
\r
2980 JListSortDialog lsD = new JListSortDialog("キーワード検索の並べ替え", oList);
\r
2981 CommonSwingUtils.setLocationCenter(parent,lsD);
\r
2983 lsD.setVisible(true);
\r
2985 if (lsD.isRegistered()) {
\r
2986 SearchProgram newSrKeys = new SearchProgram();
\r
2987 for ( String label : oList ) {
\r
2988 for ( SearchKey key : srKeys.getSearchKeys() ) {
\r
2989 if ( key.getLabel().equals(label) ) {
\r
2990 newSrKeys.add(key);
\r
2995 //srKeys = newSrKeys;
\r
2996 FieldUtils.deepCopy(srKeys, newSrKeys);
\r
3000 redrawTreeByKeyword();
\r
3007 private void addSearchKeyGroup() {
\r
3009 VWKeywordGroupDialog kD = new VWKeywordGroupDialog();
\r
3010 CommonSwingUtils.setLocationCenter(parent,kD);
\r
3013 kD.setVisible(true);
\r
3015 if (kD.isRegistered()) {
\r
3017 srGrps.add(kD.getNewName());
\r
3021 redrawTreeByKeywordGroup();
\r
3023 // 変更したノードを選択するようにしたい
\r
3024 jLabel_tree.setView(JTreeLabel.Nodes.KEYWORDGROUP, kD.getNewName());
\r
3034 private void editSeachkeyGroup(String name) {
\r
3036 VWKeywordGroupDialog kD = new VWKeywordGroupDialog();
\r
3037 CommonSwingUtils.setLocationCenter(parent,kD);
\r
3040 kD.setVisible(true);
\r
3042 if (kD.isRegistered()) {
\r
3044 srGrps.rename(name, kD.getNewName());
\r
3048 redrawTreeByKeywordGroup();
\r
3050 // 変更したノードを選択するようにしたい
\r
3051 jLabel_tree.setView(JTreeLabel.Nodes.KEYWORDGROUP, kD.getNewName());
\r
3061 private void removeSearchKeyGroup(String name) {
\r
3062 if (env.getShowWarnDialog()) {
\r
3063 //Container cp = getContentPane();
\r
3064 int ret = JOptionPane.showConfirmDialog(parent, "キーワードグループを削除しますか?【"+name+"】", "確認", JOptionPane.YES_NO_OPTION);
\r
3065 if (ret != JOptionPane.YES_OPTION) {
\r
3069 for ( SearchGroup gr : srGrps ) {
\r
3070 if ( gr.getName().equals(name) ) {
\r
3073 redrawTreeByKeywordGroup();
\r
3080 * キーワードグループのアイテムを削除したい
\r
3081 * @param groupName : nullならグループ登録だけでなくキーワード検索アイテム自体を削除する
\r
3083 private void removeSearchKeyGroupItem(String groupName, String keyword) {
\r
3084 if (env.getShowWarnDialog()) {
\r
3085 //Container cp = getContentPane();
\r
3087 if ( groupName == null ) {
\r
3088 warn = "削除しますか?【"+keyword+"】 ※グループ登録の解除だけでなくアイテム自体が削除されます。";
\r
3091 warn = "削除しますか?【"+keyword+"】 ※グループ登録の解除のみ行います。";
\r
3093 int ret = JOptionPane.showConfirmDialog(parent, warn, "確認", JOptionPane.YES_NO_OPTION);
\r
3094 if (ret != JOptionPane.YES_OPTION) {
\r
3099 if ( groupName == null ) {
\r
3101 srKeys.remove(keyword);
\r
3106 mpList.clear(env.getDisableFazzySearch(), env.getDisableFazzySearchReverse());
\r
3107 mpList.build(tvprograms, trKeys.getTraceKeys(), srKeys.getSearchKeys());
\r
3111 if ( srGrps.remove(groupName,keyword) ) {
\r
3116 if ( groupName == null ) {
\r
3117 redrawTreeByKeyword();
\r
3120 redrawTreeByKeywordGroup();
\r
3124 * キーワードグループのアイテムを追加したい
\r
3126 private void addSearchKeyGroupItem(String groupName, String keyword) {
\r
3127 if ( srGrps.add(groupName,keyword) ) {
\r
3129 redrawTreeByKeywordGroup();
\r
3134 * キーワードグループのアイテムを編集したい
\r
3136 private void editSearchKeyGroupItem(String name, String member) {
\r
3138 AbsKeywordDialog kD = new VWKeywordDialog();
\r
3139 CommonSwingUtils.setLocationCenter(parent,kD);
\r
3141 kD.reopen(member, srKeys);
\r
3142 kD.setVisible(true);
\r
3144 if (kD.isRegistered()) {
\r
3146 mpList.clear(env.getDisableFazzySearch(), env.getDisableFazzySearchReverse());
\r
3147 mpList.build(tvprograms, trKeys.getTraceKeys(), srKeys.getSearchKeys());
\r
3151 if ( ! kD.getNewLabel().equals(member) ) {
\r
3152 if ( srGrps.rename(null, member, kD.getNewLabel()) ) {
\r
3158 redrawTreeByKeywordGroup();
\r
3160 // 変更したノードを選択するようにしたい
\r
3161 jLabel_tree.setView(JTreeLabel.Nodes.KEYWORDGROUP, name);
\r
3171 private void removeExtension(String keyword) {
\r
3172 if (env.getShowWarnDialog()) {
\r
3173 //Container cp = getContentPane();
\r
3174 int ret = JOptionPane.showConfirmDialog(parent, "削除しますか?【"+keyword+"】", "確認", JOptionPane.YES_NO_OPTION);
\r
3175 if (ret != JOptionPane.YES_OPTION) {
\r
3180 extKeys.remove(keyword);
\r
3184 redrawTreeByExtension();
\r
3187 for (TVProgram tvp : tvprograms) {
\r
3188 if (tvp.getType() == ProgType.PROG) {
\r
3189 tvp.setExtension(null, null, false, extKeys.getSearchKeys());
\r
3197 private void editExtension(String keyword) {
\r
3199 AbsExtensionDialog eD = new VWExtensionDialog();
\r
3200 CommonSwingUtils.setLocationCenter(parent,eD);
\r
3202 eD.reopen(keyword, extKeys);
\r
3203 eD.setVisible(true);
\r
3205 if (eD.isRegistered()) {
\r
3207 for (TVProgram tvp : tvprograms) {
\r
3208 if (tvp.getType() == ProgType.PROG) {
\r
3209 tvp.setExtension(null, null, false, extKeys.getSearchKeys());
\r
3214 redrawTreeByExtension();
\r
3221 private void sortExtension() {
\r
3223 ArrayList<String> oList = new ArrayList<String>();
\r
3224 for ( SearchKey key : extKeys.getSearchKeys() ) {
\r
3225 oList.add(key.getLabel());
\r
3228 JListSortDialog lsD = new JListSortDialog("延長警告の並べ替え", oList);
\r
3229 CommonSwingUtils.setLocationCenter(parent,lsD);
\r
3231 lsD.setVisible(true);
\r
3233 if (lsD.isRegistered()) {
\r
3234 ExtProgram newExtKeys = new ExtProgram();
\r
3235 for ( String label : oList ) {
\r
3236 for ( SearchKey key : extKeys.getSearchKeys() ) {
\r
3237 if ( key.getLabel().equals(label) ) {
\r
3238 newExtKeys.add(key);
\r
3243 //extKeys = newExtKeys;
\r
3244 FieldUtils.deepCopy(extKeys, newExtKeys);
\r
3248 redrawTreeByExtension();
\r
3253 private void showPopupForRemoveTraceKey(int x, int y, final String keyword)
\r
3255 JPopupMenu pop = new JPopupMenu();
\r
3258 JMenuItem menuItem = new JMenuItem("番組追跡の編集【"+keyword+"】");
\r
3259 menuItem.addActionListener(new ActionListener() {
\r
3260 public void actionPerformed(ActionEvent e) {
\r
3261 editTraceKey(keyword);
\r
3264 pop.add(menuItem);
\r
3268 JMenuItem menuItem = new JMenuItem("番組追跡の削除【"+keyword+"】");
\r
3269 menuItem.addActionListener(new ActionListener() {
\r
3270 public void actionPerformed(ActionEvent e) {
\r
3271 removeTraceKey(keyword);
\r
3274 pop.add(menuItem);
\r
3277 pop.addSeparator();
\r
3280 ButtonGroup bg = new ButtonGroup();
\r
3282 for ( TraceKey t : trKeys.getTraceKeys()) {
\r
3283 if (t._getLabel().equals(keyword)) {
\r
3284 final TraceKey tk = t;
\r
3285 for (String o : TVProgram.OKINIIRI) {
\r
3286 final String okini = o;
\r
3287 JRadioButtonMenuItem menuItem = new JRadioButtonMenuItem(okini, okini.equals(tk.getOkiniiri()));
\r
3289 menuItem.addActionListener(new ActionListener() {
\r
3290 public void actionPerformed(ActionEvent e) {
\r
3291 setTraceKeyOkiniiri(tk,okini);
\r
3294 pop.add(menuItem);
\r
3301 pop.show(jTree_tree, x, y);
\r
3305 private void showPopupForRemoveKeyword(int x, int y, final String keyword)
\r
3307 JPopupMenu pop = new JPopupMenu();
\r
3310 JMenuItem menuItem = new JMenuItem("キーワードの編集【"+keyword+"】");
\r
3311 menuItem.addActionListener(new ActionListener() {
\r
3312 public void actionPerformed(ActionEvent e) {
\r
3313 editSearchKey(keyword);
\r
3316 pop.add(menuItem);
\r
3319 JMenuItem menuItem = new JMenuItem("キーワードの削除【"+keyword+"】");
\r
3320 menuItem.addActionListener(new ActionListener() {
\r
3321 public void actionPerformed(ActionEvent e) {
\r
3322 removeSearchKey(keyword);
\r
3325 pop.add(menuItem);
\r
3328 pop.addSeparator();
\r
3331 for ( SearchGroup gr : srGrps ) {
\r
3332 final String groupName = gr.getName();
\r
3333 if (srGrps.isFind(groupName,keyword) ) {
\r
3334 JMenuItem menuItem = new JMenuItem("キーワードグループから登録解除【"+groupName+"】");
\r
3335 menuItem.setForeground(Color.RED);
\r
3336 menuItem.addActionListener(new ActionListener() {
\r
3337 public void actionPerformed(ActionEvent e) {
\r
3338 removeSearchKeyGroupItem(groupName,keyword);
\r
3341 pop.add(menuItem);
\r
3344 JMenuItem menuItem = new JMenuItem("キーワードグループに追加【"+groupName+"】");
\r
3345 menuItem.addActionListener(new ActionListener() {
\r
3346 public void actionPerformed(ActionEvent e) {
\r
3347 addSearchKeyGroupItem(groupName,keyword);
\r
3350 pop.add(menuItem);
\r
3355 pop.addSeparator();
\r
3358 ButtonGroup bg = new ButtonGroup();
\r
3360 for ( SearchKey s : srKeys.getSearchKeys()) {
\r
3361 if (s.getLabel().equals(keyword)) {
\r
3362 final SearchKey sr = s;
\r
3363 for (String o : TVProgram.OKINIIRI) {
\r
3364 final String okini = o;
\r
3365 JRadioButtonMenuItem menuItem = new JRadioButtonMenuItem(okini, okini.equals(sr.getOkiniiri()));
\r
3367 menuItem.addActionListener(new ActionListener() {
\r
3368 public void actionPerformed(ActionEvent e) {
\r
3369 setSearchKeyOkiniiri(sr,okini);
\r
3372 pop.add(menuItem);
\r
3378 pop.show(jTree_tree, x, y);
\r
3382 private void showPopupForSortTraceKey(int x, int y) {
\r
3383 JPopupMenu pop = new JPopupMenu();
\r
3385 JMenuItem menuItem = new JMenuItem("番組追跡の並べ替え");
\r
3386 menuItem.addActionListener(new ActionListener() {
\r
3387 public void actionPerformed(ActionEvent e) {
\r
3391 pop.add(menuItem);
\r
3393 pop.show(jTree_tree, x, y);
\r
3397 private void showPopupForSortSearchKey(int x, int y) {
\r
3398 JPopupMenu pop = new JPopupMenu();
\r
3400 JMenuItem menuItem = new JMenuItem("キーワード検索の並べ替え");
\r
3401 menuItem.addActionListener(new ActionListener() {
\r
3402 public void actionPerformed(ActionEvent e) {
\r
3406 pop.add(menuItem);
\r
3408 pop.show(jTree_tree, x, y);
\r
3412 private void showPopupForSortExtension(int x, int y) {
\r
3413 JPopupMenu pop = new JPopupMenu();
\r
3415 JMenuItem menuItem = new JMenuItem("延長警告の並べ替え");
\r
3416 menuItem.addActionListener(new ActionListener() {
\r
3417 public void actionPerformed(ActionEvent e) {
\r
3421 pop.add(menuItem);
\r
3423 pop.show(jTree_tree, x, y);
\r
3427 private void showPopupForRemoveKeywordGrp(int x, int y)
\r
3429 JPopupMenu pop = new JPopupMenu();
\r
3432 JMenuItem menuItem = new JMenuItem("キーワードグループの追加");
\r
3433 menuItem.addActionListener(new ActionListener() {
\r
3434 public void actionPerformed(ActionEvent e) {
\r
3435 addSearchKeyGroup();
\r
3438 pop.add(menuItem);
\r
3440 pop.show(jTree_tree, x, y);
\r
3443 private void showPopupForRemoveKeywordGrpName(int x, int y, final String name)
\r
3445 JPopupMenu pop = new JPopupMenu();
\r
3448 JMenuItem menuItem = new JMenuItem("キーワードグループの編集【"+name+"】");
\r
3449 menuItem.addActionListener(new ActionListener() {
\r
3450 public void actionPerformed(ActionEvent e) {
\r
3451 editSeachkeyGroup(name);
\r
3454 pop.add(menuItem);
\r
3457 pop.addSeparator();
\r
3460 JMenuItem menuItem = new JMenuItem("キーワードグループの削除【"+name+"】");
\r
3461 menuItem.addActionListener(new ActionListener() {
\r
3462 public void actionPerformed(ActionEvent e) {
\r
3463 removeSearchKeyGroup(name);
\r
3466 pop.add(menuItem);
\r
3468 pop.show(jTree_tree, x, y);
\r
3471 private void showPopupForRemoveKeywordGrpEntry(int x, int y, final String name, final String member)
\r
3473 JPopupMenu pop = new JPopupMenu();
\r
3476 JMenuItem menuItem = new JMenuItem("キーワードの編集【"+member+"】");
\r
3477 menuItem.addActionListener(new ActionListener() {
\r
3478 public void actionPerformed(ActionEvent e) {
\r
3479 editSearchKeyGroupItem(name,member);
\r
3482 pop.add(menuItem);
\r
3485 JMenuItem menuItem = new JMenuItem("キーワードの削除【"+member+"】");
\r
3486 menuItem.addActionListener(new ActionListener() {
\r
3487 public void actionPerformed(ActionEvent e) {
\r
3488 removeSearchKeyGroupItem(null,member);
\r
3491 pop.add(menuItem);
\r
3494 pop.addSeparator();
\r
3497 for ( SearchGroup gr : srGrps ) {
\r
3498 final String groupName = gr.getName();
\r
3499 if (srGrps.isFind(groupName,member) ) {
\r
3500 JMenuItem menuItem = new JMenuItem("キーワードグループから登録解除【"+groupName+"】");
\r
3501 menuItem.setForeground(Color.RED);
\r
3502 menuItem.addActionListener(new ActionListener() {
\r
3503 public void actionPerformed(ActionEvent e) {
\r
3504 removeSearchKeyGroupItem(groupName, member);
\r
3507 pop.add(menuItem);
\r
3510 JMenuItem menuItem = new JMenuItem("キーワードグループに追加【"+groupName+"】");
\r
3511 menuItem.addActionListener(new ActionListener() {
\r
3512 public void actionPerformed(ActionEvent e) {
\r
3513 addSearchKeyGroupItem(groupName,member);
\r
3516 pop.add(menuItem);
\r
3521 pop.show(jTree_tree, x, y);
\r
3525 private void showPopupForRemoveExtension(int x, int y, final String keyword)
\r
3527 JPopupMenu pop = new JPopupMenu();
\r
3530 JMenuItem menuItem = new JMenuItem("延長警告の編集【"+keyword+"】");
\r
3531 menuItem.addActionListener(new ActionListener() {
\r
3532 public void actionPerformed(ActionEvent e) {
\r
3533 editExtension(keyword);
\r
3536 pop.add(menuItem);
\r
3539 JMenuItem menuItem = new JMenuItem("延長警告の削除【"+keyword+"】");
\r
3540 menuItem.addActionListener(new ActionListener() {
\r
3541 public void actionPerformed(ActionEvent e) {
\r
3542 removeExtension(keyword);
\r
3545 pop.add(menuItem);
\r
3548 pop.show(jTree_tree, x, y);
\r
3553 /*******************************************************************************
\r
3555 ******************************************************************************/
\r
3562 * キーワード検索ウィンドウの内部クラス
\r
3564 private class VWKeywordDialog extends AbsKeywordDialog {
\r
3566 private static final long serialVersionUID = 1L;
\r
3569 void preview(SearchKey search) {
\r
3570 previewKeywordSearch(search);
\r
3575 * 延長警告管理ウィンドウの内部クラス
\r
3577 private class VWExtensionDialog extends AbsExtensionDialog {
\r
3579 private static final long serialVersionUID = 1L;
\r
3582 void preview(SearchKey search) {
\r
3583 previewKeywordSearch(search);
\r
3591 private JSplitPane getJSplitPane_view() {
\r
3592 if ( jSplitPane_view == null ) {
\r
3593 jSplitPane_view = new JSplitPane() {
\r
3595 private static final long serialVersionUID = 1L;
\r
3598 public void setDividerLocation(int loc) {
\r
3599 setDividerEnvs(loc);
\r
3600 super.setDividerLocation(loc);
\r
3604 jSplitPane_view.setLeftComponent(getJPanel_tree());
\r
3605 jSplitPane_view.setRightComponent(getJScrollPane_listed());
\r
3608 return jSplitPane_view;
\r
3611 private JPanel getJPanel_tree() {
\r
3612 if (jPanel_tree == null) {
\r
3613 jPanel_tree = new JPanel();
\r
3615 jPanel_tree.setLayout(new BorderLayout());
\r
3616 jPanel_tree.add(getJScrollPane_tree_top(), BorderLayout.PAGE_START);
\r
3617 jPanel_tree.add(getJScrollPane_tree(), BorderLayout.CENTER);
\r
3619 return jPanel_tree;
\r
3622 private JScrollPane getJScrollPane_tree_top() {
\r
3623 if (jScrollPane_tree_top == null) {
\r
3624 jScrollPane_tree_top = new JScrollPane();
\r
3625 jScrollPane_tree_top.setViewportView(getJLabel_tree());
\r
3626 jScrollPane_tree_top.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
\r
3627 jScrollPane_tree_top.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
\r
3629 return jScrollPane_tree_top;
\r
3632 private JTreeLabel getJLabel_tree() {
\r
3633 if (jLabel_tree == null) {
\r
3634 jLabel_tree = new JTreeLabel();
\r
3636 Dimension d = jLabel_tree.getMaximumSize();
\r
3637 d.height = bounds.getBangumiColumnHeight();
\r
3638 jLabel_tree.setPreferredSize(d);
\r
3639 //jLabel_tree.setBorder(new LineBorder(Color.BLACK));
\r
3640 jLabel_tree.setOpaque(true);
\r
3641 jLabel_tree.setBackground(Color.WHITE);
\r
3643 return jLabel_tree;
\r
3646 private JScrollPane getJScrollPane_tree() {
\r
3647 if (jScrollPane_tree == null) {
\r
3648 jScrollPane_tree = new JScrollPane();
\r
3650 jScrollPane_tree.setViewportView(getJTree_tree());
\r
3652 return jScrollPane_tree;
\r
3655 private JDetailPanel getJTextPane_detail() {
\r
3656 if (jTextPane_detail == null) {
\r
3657 jTextPane_detail = new JDetailPanel();
\r
3658 jTextPane_detail.setRows(bounds.getDetailRows());
\r
3659 //Dimension d = jTextPane_detail.getMaximumSize();
\r
3660 //d.height = bounds.getDetailAreaHeight();
\r
3661 //jTextPane_detail.setPreferredSize(d);
\r
3662 //jTextPane_detail.setVerticalAlignment(JLabel.TOP);
\r
3663 //jTextPane_detail.setHorizontalAlignment(JLabel.LEFT);
\r
3665 return jTextPane_detail;
\r
3671 private JTree getJTree_tree() {
\r
3672 if (jTree_tree == null) {
\r
3675 jTree_tree = new JTree();
\r
3676 jTree_tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
\r
3677 jTree_tree.setRootVisible(env.getRootNodeVisible());
\r
3678 jTree_tree.setCellRenderer(new VWTreeCellRenderer()); // 検索結果が存在するノードの色を変える
\r
3681 jTree_tree.setModel(new DefaultTreeModel(getTreeNodes()));
\r
3684 undoTreeExpansion();
\r
3686 // ツリーの開閉時に状態を保存する
\r
3687 jTree_tree.addTreeExpansionListener(tel_nodeexpansion);
\r
3689 // フルスクリーンの時に使う(新聞形式のツリーを自動的に隠す)
\r
3690 jTree_tree.addMouseListener(ml_treehide);
\r
3692 return jTree_tree;
\r
3698 private DefaultMutableTreeNode getTreeNodes() {
\r
3700 listRootNode = new VWListedTreeNode(JTreeLabel.Nodes.ROOT.getLabel());
\r
3702 searchedNode = new VWListedTreeNode(JTreeLabel.Nodes.SEARCHHIST.getLabel());
\r
3703 startNode = new VWListedTreeNode(JTreeLabel.Nodes.START.getLabel());
\r
3704 endNode = new VWListedTreeNode(JTreeLabel.Nodes.END.getLabel());
\r
3705 nowNode = new VWListedTreeNode(JTreeLabel.Nodes.NOW.getLabel());
\r
3706 syobocalNode = new VWListedTreeNode(JTreeLabel.Nodes.SYOBOCAL.getLabel());
\r
3707 standbyNode = new VWListedTreeNode(JTreeLabel.Nodes.STANDBY.getLabel());
\r
3708 traceNode = new VWListedTreeNode(JTreeLabel.Nodes.TRACE.getLabel());
\r
3709 keywordNode = new VWListedTreeNode(JTreeLabel.Nodes.KEYWORD.getLabel());
\r
3710 keywordGrpNode = new VWListedTreeNode(JTreeLabel.Nodes.KEYWORDGROUP.getLabel());
\r
3711 genreNode = new VWListedTreeNode(JTreeLabel.Nodes.GENRE.getLabel());
\r
3712 centerListNode = new VWListedTreeNode(JTreeLabel.Nodes.BCASTLIST.getLabel());
\r
3713 extensionNode = new VWListedTreeNode(JTreeLabel.Nodes.EXTENTION.getLabel());
\r
3715 // ★★★ でふぉるとのーど ★★★
\r
3716 defaultNode = nowNode;
\r
3718 listRootNode.add(searchedNode);
\r
3719 listRootNode.add(startNode);
\r
3720 listRootNode.add(endNode);
\r
3721 listRootNode.add(nowNode);
\r
3722 if ( env.getUseSyobocal() ) {
\r
3723 listRootNode.add(syobocalNode);
\r
3725 listRootNode.add(standbyNode);
\r
3726 listRootNode.add(traceNode);
\r
3727 listRootNode.add(keywordNode);
\r
3728 listRootNode.add(keywordGrpNode);
\r
3729 listRootNode.add(genreNode);
\r
3730 listRootNode.add(centerListNode);
\r
3731 listRootNode.add(extensionNode);
\r
3734 redrawTreeByGenre();
\r
3735 redrawTreeBySyobo();
\r
3736 redrawTreeByStandby();
\r
3737 redrawTreeByTrace();
\r
3738 redrawTreeByKeyword();
\r
3739 redrawTreeByKeywordGroup();
\r
3740 redrawTreeBySubGenre();
\r
3741 redrawTreeByCenter();
\r
3742 redrawTreeByExtension();
\r
3744 return listRootNode;
\r
3747 private void undoTreeExpansion() {
\r
3750 stopTreeListener();
\r
3753 ter = new TreeExpansionReg(jTree_tree, TreeExpRegFile_Listed);
\r
3757 catch (Exception e) {
\r
3758 MWin.appendMessage(ERRID+"ツリー展開情報の解析で問題が発生しました");
\r
3759 e.printStackTrace();
\r
3763 ArrayList<TreePath> tpa = ter.get();
\r
3764 for ( TreePath path : tpa ) {
\r
3765 jTree_tree.expandPath(path);
\r
3768 startTreeListener();
\r
3771 private JScrollPane getJScrollPane_listed() {
\r
3772 if (jScrollPane_listed == null) {
\r
3773 jScrollPane_listed = new JScrollPane();
\r
3774 jScrollPane_listed.setRowHeaderView(jTable_rowheader = new JTableRowHeader(rowData));
\r
3775 jScrollPane_listed.setViewportView(getNETable_listed());
\r
3777 Dimension d = new Dimension(jTable_rowheader.getPreferredSize().width,0);
\r
3778 jScrollPane_listed.getRowHeader().setPreferredSize(d);
\r
3780 setRowHeaderVisible(env.getRowHeaderVisible());
\r
3782 return jScrollPane_listed;
\r
3785 private JNETable getNETable_listed() {
\r
3786 if (jTable_listed == null) {
\r
3789 ArrayList<String> cola = new ArrayList<String>();
\r
3790 for ( ListedColumn lc : ListedColumn.values() ) {
\r
3791 if ( lc.getIniWidth() >= 0 ) {
\r
3792 cola.add(lc.getName());
\r
3795 final String[] colname = cola.toArray(new String[0]);
\r
3798 tableModel_listed = new ListedTableModel(colname, 0);
\r
3800 jTable_listed = new ListedTable(tableModel_listed, true);
\r
3801 jTable_listed.setAutoResizeMode(JNETable.AUTO_RESIZE_OFF);
\r
3802 //jTable_listed.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
\r
3805 rowheaderModel_listed = (DefaultTableModel) jTable_rowheader.getModel();
\r
3808 final TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(tableModel_listed);
\r
3809 jTable_listed.setRowSorter(sorter);
\r
3810 //sorter.toggleSortOrder(listedTableColumn_Sorter);
\r
3812 sorter.addRowSorterListener(new RowSorterListener() {
\r
3814 public void sorterChanged(RowSorterEvent e) {
\r
3815 if ( e.getType() == Type.SORTED ) {
\r
3816 if (rowData.size()>2) setOverlapMark();
\r
3821 // 数値でソートする項目用の計算式(番組長とか)
\r
3822 final Comparator<String> numcomp = new Comparator<String>() {
\r
3824 public int compare(String o1, String o2) {
\r
3827 if ( o1 != null ) {
\r
3828 Matcher ma = Pattern.compile("^(\\d+)").matcher(o1);
\r
3829 if ( ma.find() ) {
\r
3830 n1 = Integer.valueOf(ma.group(1));
\r
3833 if ( o2 != null ) {
\r
3834 Matcher ma = Pattern.compile("^(\\d+)").matcher(o2);
\r
3835 if ( ma.find() ) {
\r
3836 n2 = Integer.valueOf(ma.group(1));
\r
3843 // ソーターの効かない項目用の計算式(重複マーク)
\r
3844 final Comparator<String> noncomp = new Comparator<String>() {
\r
3846 public int compare(String o1, String o2) {
\r
3852 sorter.setComparator(jTable_listed.getColumn(ListedColumn.LENGTH.getName()).getModelIndex(),numcomp);
\r
3853 sorter.setComparator(jTable_listed.getColumn(ListedColumn.SCORE.getName()).getModelIndex(),numcomp);
\r
3854 sorter.setComparator(jTable_listed.getColumn(ListedColumn.THRESHOLD.getName()).getModelIndex(),numcomp);
\r
3856 sorter.setComparator(jTable_listed.getColumn(ListedColumn.DUPMARK.getName()).getModelIndex(),noncomp);
\r
3858 // 予約済みマーク/重複マークはちょっとだけ表示の仕方が違う
\r
3859 VWColorCharCellRenderer renderer = new VWColorCharCellRenderer();
\r
3860 if ( CommonUtils.isMac() ) renderer.setMacMarkFont();
\r
3861 jTable_listed.getColumn(ListedColumn.RSVMARK.getName()).setCellRenderer(renderer);
\r
3862 jTable_listed.getColumn(ListedColumn.PICKMARK.getName()).setCellRenderer(renderer);
\r
3863 jTable_listed.getColumn(ListedColumn.DUPMARK.getName()).setCellRenderer(renderer);
\r
3866 titleCellRenderer = new VWColorCharCellRenderer2();
\r
3867 jTable_listed.getColumn(ListedColumn.OPTIONS.getName()).setCellRenderer(titleCellRenderer);
\r
3868 jTable_listed.getColumn(ListedColumn.TITLE.getName()).setCellRenderer(titleCellRenderer);
\r
3870 this.setMatchedKeywordColor(env.getMatchedKeywordColor());
\r
3871 this.setRsvdLineColor((env.getRsvdLineEnhance())?(env.getRsvdLineColor()):(null));
\r
3872 this.setPickedLineColor((env.getRsvdLineEnhance())?(env.getPickedLineColor()):(null));
\r
3873 this.setCurrentLineColor((env.getCurrentLineEnhance())?(env.getCurrentLineColor()):(null));
\r
3875 // スコア・閾値はちょっとだけ表示の仕方が違う
\r
3876 DefaultTableCellRenderer renderer3 = new DefaultTableCellRenderer();
\r
3877 renderer3.setHorizontalAlignment(SwingConstants.RIGHT);
\r
3878 jTable_listed.getColumn(ListedColumn.SCORE.getName()).setCellRenderer(renderer3);
\r
3879 jTable_listed.getColumn(ListedColumn.THRESHOLD.getName()).setCellRenderer(renderer3);
\r
3882 VWDetailCellRenderer renderer4 = new VWDetailCellRenderer();
\r
3883 jTable_listed.getColumn(ListedColumn.DETAIL.getName()).setCellRenderer(renderer4);
\r
3886 DefaultTableColumnModel columnModel = (DefaultTableColumnModel)jTable_listed.getColumnModel();
\r
3887 TableColumn column = null;
\r
3888 for ( ListedColumn lc : ListedColumn.values() ) {
\r
3889 if ( lc.getIniWidth() < 0 ) {
\r
3892 column = columnModel.getColumn(lc.ordinal());
\r
3893 column.setResizable(lc.isResizable());
\r
3894 column.setMinWidth(MIN_COLUMN_WIDTH);
\r
3895 Integer w = bounds.getListedColumnSize().get(lc.toString());
\r
3896 column.setPreferredWidth(w != null ? w : lc.getIniWidth());
\r
3900 setMarkColumnVisible(env.getSplitMarkAndTitle());
\r
3903 setDetailColumnVisible(env.getShowDetailOnList());
\r
3906 setPickupColumnVisible(env.getShowRsvPickup());
\r
3909 setDupColumnVisible(env.getShowRsvDup());
\r
3911 // 行を選択すると詳細が表示されるようにする
\r
3912 jTable_listed.getSelectionModel().addListSelectionListener(lsSelectListner);
\r
3915 jTable_listed.addMouseListener(lsClickAdapter);
\r
3917 return jTable_listed;
\r
3923 /*******************************************************************************
\r
3925 ******************************************************************************/
\r
3929 * @see ListedColumn
\r
3931 private class ListedItem extends RowItem implements Cloneable {
\r
3936 String searchlabel;
\r
3941 String hide_rsvmarkcolor;
\r
3943 ProgDetailList tvd;
\r
3946 protected void myrefresh(RowItem o) {
\r
3947 ListedItem c = (ListedItem) o;
\r
3948 c.addData(marker);
\r
3949 c.addData(marker); // ピックアップ欄用のダミー
\r
3950 c.addData(dupmark);
\r
3951 c.addData(tvd.center);
\r
3952 c.addData(prefix);
\r
3953 c.addData(title); // "\0"+title or "\0"+titlebefore+"\0"+matchedkeyword+"\0"+titleafter みたいな感じで
\r
3954 c.addData(tvd.detail);
\r
3955 c.addData(tvd.start);
\r
3956 c.addData(tvd.end);
\r
3957 c.addData(tvd.recmin);
\r
3958 c.addData(tvd.genre.toString());
\r
3959 c.addData(searchlabel);
\r
3960 c.addData(okiniiri);
\r
3962 c.addData(threshold);
\r
3965 public ListedItem clone() {
\r
3966 return (ListedItem) super.clone();
\r
3971 * {@link ListedItem}を使ったJTable拡張
\r
3973 private class ListedTable extends JNETable {
\r
3975 private static final long serialVersionUID = 1L;
\r
3977 private Color passedColor = new Color(180,180,180);
\r
3980 public void setPassedColor(Color c) { passedColor = c; }
\r
3982 private Color currentColorEven = new Color(240,120,120);
\r
3983 private Color currentColorOdd = new Color(248,128,128);
\r
3985 public void setCurrentColor(Color c) {
\r
3986 if ( c == null ) {
\r
3987 currentColorEven = null;
\r
3988 currentColorOdd = null;
\r
3991 currentColorOdd = c;
\r
3992 currentColorEven = new Color(
\r
3993 ((c.getRed()>=247)?(255):(c.getRed()+8)),
\r
3994 ((c.getGreen()>=247)?(255):(c.getGreen()+8)),
\r
3995 ((c.getBlue()>=247)?(255):(c.getBlue()+8))
\r
4000 private Color nextweekFgColor = new Color(120,120,120);
\r
4003 public void setNextweekFgColor(Color c) { nextweekFgColor = c; }
\r
4005 private Color reservedColorEven = new Color(255,247,204);
\r
4006 private Color reservedColorOdd = new Color(255,255,212);
\r
4008 public void setReservedColor(Color c) {
\r
4009 if ( c == null ) {
\r
4010 reservedColorEven = null;
\r
4011 reservedColorOdd = null;
\r
4014 reservedColorOdd = c;
\r
4015 reservedColorEven = new Color(
\r
4016 ((c.getRed()>=247)?(255):(c.getRed()+8)),
\r
4017 ((c.getGreen()>=247)?(255):(c.getGreen()+8)),
\r
4018 ((c.getBlue()>=247)?(255):(c.getBlue()+8))
\r
4023 private Color pickedColorEven = new Color(51,255,0);
\r
4024 private Color pickedColorOdd = new Color(59,255,8);
\r
4026 public void setPickedColor(Color c) {
\r
4027 if ( c == null ) {
\r
4028 pickedColorEven = null;
\r
4029 pickedColorOdd = null;
\r
4032 pickedColorEven = c;
\r
4033 pickedColorOdd = new Color(
\r
4034 ((c.getRed()>=247)?(255):(c.getRed()+8)),
\r
4035 ((c.getGreen()>=247)?(255):(c.getGreen()+8)),
\r
4036 ((c.getBlue()>=247)?(255):(c.getBlue()+8))
\r
4041 private int prechkrow = -1;
\r
4042 private boolean prechkreserved = false;
\r
4043 private boolean prechkpicked = false;
\r
4044 private boolean prechkpassed = false;
\r
4045 private boolean prechkcurrent = false;
\r
4046 private boolean prechknextweek = false;
\r
4049 public Component prepareRenderer(TableCellRenderer tcr, int row, int column) {
\r
4050 Component comp = super.prepareRenderer(tcr, row, column);
\r
4051 Color fgColor = null;
\r
4052 Color bgColor = null;
\r
4053 if(isRowSelected(row)) {
\r
4054 fgColor = this.getSelectionForeground();
\r
4055 bgColor = this.getSelectionBackground();
\r
4060 fgColor = (prechknextweek)?(nextweekFgColor):(this.getForeground());
\r
4062 if( prechkpassed && passedColor != null ) {
\r
4063 bgColor = passedColor;
\r
4065 else if( prechkreserved && reservedColorEven != null ) {
\r
4066 bgColor = (isSepRowColor && row%2 == 1)?(reservedColorEven):(reservedColorOdd);
\r
4068 else if( prechkpicked && pickedColorEven != null ) {
\r
4069 bgColor = (isSepRowColor && row%2 == 1)?(pickedColorEven):(pickedColorOdd);
\r
4071 else if( prechkcurrent && currentColorEven != null ) {
\r
4072 bgColor = (isSepRowColor && row%2 == 1)?(currentColorEven):(currentColorOdd);
\r
4075 bgColor = (isSepRowColor && row%2 == 1)?(evenColor):(super.getBackground());
\r
4078 if ( tcr instanceof VWColorCharCellRenderer2 ) {
\r
4079 ((VWColorCharCellRenderer2) tcr).setForeground(fgColor);
\r
4081 else if ( ! (tcr instanceof VWColorCharCellRenderer) && ! (tcr instanceof VWColorCellRenderer)) {
\r
4083 comp.setForeground(fgColor);
\r
4085 if ( ! (tcr instanceof VWColorCellRenderer)) {
\r
4086 comp.setBackground(bgColor);
\r
4091 // 直接rowDataを見に行くようになったから、このisRowPassed()はもういらないんじゃ…
\r
4093 // 連続して同じ行へのアクセスがあったら計算を行わず前回のままにする
\r
4094 private boolean isRowPassed(int prow) {
\r
4096 if(prechkrow == prow) {
\r
4100 int row = this.convertRowIndexToModel(prow);
\r
4101 ListedItem c = rowData.get(row);
\r
4105 prechkreserved = false;
\r
4106 prechkpicked = false;
\r
4107 prechkpassed = false;
\r
4108 prechkcurrent = false;
\r
4109 prechknextweek = false;
\r
4113 if ( c.marker != null ) {
\r
4114 if ( c.marker.rsvmark != null && c.marker.rsvmark != RsvMark.NOEXEC && c.marker.rsvmark != RsvMark.URABAN ) {
\r
4115 prechkreserved = true;
\r
4117 else if ( c.marker.pickmark != null ) {
\r
4118 prechkpicked = true;
\r
4124 String cDT = CommonUtils.getDateTime(0);
\r
4125 prechkpassed = (cDT.compareTo(c.tvd.endDateTime) >= 0);
\r
4126 if ( ! prechkpassed ) {
\r
4128 prechkcurrent = (cDT.compareTo(c.tvd.startDateTime) >= 0);
\r
4130 if ( ! prechkcurrent ) {
\r
4132 String critDT = CommonUtils.getCritDateTime(7);
\r
4133 prechknextweek = (critDT.compareTo(c.tvd.startDateTime) <= 0);
\r
4141 public String getToolTipText(MouseEvent e){
\r
4142 // イベントからマウス位置を取得し、テーブル内のセルを割り出す
\r
4143 int prow = rowAtPoint(e.getPoint());
\r
4144 int row = this.convertRowIndexToModel(prow);
\r
4145 ListedItem c = rowData.get(row);
\r
4146 int col = columnAtPoint(e.getPoint());
\r
4147 if ( col == ListedColumn.RSVMARK.getColumn() && c.marker != null && c.marker.rsvmark != null ) {
\r
4148 return c.marker.rsvmark.desc;
\r
4150 else if ( col == ListedColumn.PICKMARK.getColumn() && c.marker != null && c.marker.pickmark != null ) {
\r
4151 return c.marker.pickmark.desc;
\r
4153 else if ( col == ListedColumn.DUPMARK.getColumn() && c.dupmark != null ) {
\r
4154 return c.dupmark.desc;
\r
4161 public void tableChanged(TableModelEvent e) {
\r
4163 super.tableChanged(e);
\r
4166 private void reset() {
\r
4168 prechkreserved = false;
\r
4169 prechkpicked = false;
\r
4170 prechkpassed = false;
\r
4176 public ListedTable(boolean b) {
\r
4180 public ListedTable(TableModel d, boolean b) {
\r
4187 * ソートが必要な場合はTableModelを作る。ただし、その場合Viewのrowがわからないので行の入れ替えが行えない
\r
4188 * @see ListedTable
\r
4190 private class ListedTableModel extends DefaultTableModel {
\r
4192 private static final long serialVersionUID = 1L;
\r
4195 public Object getValueAt(int row, int column) {
\r
4196 // 多少負荷があがるがこっちの方が見通しがいいだろう
\r
4197 ListedItem c = rowData.get(row);
\r
4198 if ( c.size( ) > column ) {
\r
4200 if ( column == ListedColumn.RSVMARK.getColumn() ) {
\r
4201 if ( c.marker != null && c.marker.rsvmark != null ) {
\r
4202 if ( c.marker.rsvmark != RsvMark.URABAN ) {
\r
4203 return c.marker.rsvmark.mark+"\0"+c.hide_rsvmarkcolor;
\r
4206 return c.marker.rsvmark.mark+"\0"+URABAN_COLOR;
\r
4211 else if ( column == ListedColumn.PICKMARK.getColumn() ) {
\r
4212 return (env.getShowRsvPickup() && c.marker != null && c.marker.pickmark != null) ? c.marker.pickmark.mark : "" ;
\r
4214 else if ( column == ListedColumn.DUPMARK.getColumn() ) {
\r
4215 return (env.getShowRsvDup() && c.dupmark != null) ? c.dupmark.mark+"\0"+DUPMARK_COLOR : "";
\r
4217 else if ( column == ListedColumn.START.getColumn() ) {
\r
4218 return c.tvd.accurateDate+" "+c.tvd.start;
\r
4220 else if ( column == ListedColumn.LENGTH.getColumn() ) {
\r
4221 return c.tvd.recmin+"m";
\r
4223 else if ( column == ListedColumn.GENRE.getColumn() ) {
\r
4224 if ( c.tvd.subgenre != null ) {
\r
4225 return c.tvd.genre.toString()+" - "+c.tvd.subgenre.toString();
\r
4228 // サブジャンルに非対応な番組表の場合
\r
4229 return c.tvd.genre.toString();
\r
4232 else if ( column == ListedColumn.OPTIONS.getColumn() && ! env.getSplitMarkAndTitle() ) {
\r
4236 else if ( column == ListedColumn.TITLE.getColumn() && ! env.getSplitMarkAndTitle() ) {
\r
4238 return c.prefix+c.title;
\r
4240 return c.get(column);
\r
4246 public int getRowCount() {
\r
4247 return rowData.size();
\r
4250 public ListedTableModel(String[] colname, int i) {
\r