001// License: GPL. See LICENSE file for details. 002package org.openstreetmap.josm.gui.layer.gpx; 003 004import static org.openstreetmap.josm.tools.I18n.tr; 005 006import java.awt.Component; 007import java.awt.GridBagLayout; 008import java.awt.event.ActionEvent; 009import java.awt.event.ActionListener; 010import java.util.Date; 011import java.util.GregorianCalendar; 012 013import javax.swing.JCheckBox; 014import javax.swing.JPanel; 015import javax.swing.Timer; 016import javax.swing.event.ChangeEvent; 017import javax.swing.event.ChangeListener; 018 019import org.openstreetmap.josm.Main; 020import org.openstreetmap.josm.gui.layer.GpxLayer; 021import org.openstreetmap.josm.gui.widgets.DateEditorWithSlider; 022import org.openstreetmap.josm.tools.GBC; 023 024public class DateFilterPanel extends JPanel { 025 DateEditorWithSlider dateFrom = new DateEditorWithSlider(tr("From")); 026 DateEditorWithSlider dateTo = new DateEditorWithSlider(tr("To")); 027 JCheckBox noTimestampCb = new JCheckBox(tr("No timestamp")); 028 GpxLayer layer; 029 030 ActionListener filterAppliedListener; 031 032 final String PREF_DATE_0; 033 final String PREF_DATE_MIN; 034 final String PREF_DATE_MAX; 035 036 /** 037 * Create the panel to filter tracks on GPX layer @param layer by date 038 * Preferences will be stored in @param preferencePrefix 039 * If @param enabled = true, the the panel is created as active and filtering occurs immediately. 040 */ 041 public DateFilterPanel(GpxLayer layer, String preferencePrefix, boolean enabled) { 042 super(new GridBagLayout()); 043 PREF_DATE_0 = preferencePrefix+".showzerotimestamp"; 044 PREF_DATE_MIN = preferencePrefix+".mintime"; 045 PREF_DATE_MAX = preferencePrefix+".maxtime"; 046 this.layer = layer; 047 048 final Date startTime, endTime; 049 Date[] bounds = layer.getMinMaxTimeForAllTracks(); 050 startTime = (bounds==null) ? new GregorianCalendar(2000, 1, 1).getTime():bounds[0]; 051 endTime = (bounds==null) ? new Date() : bounds[1]; 052 053 dateFrom.setDate(startTime); 054 dateTo.setDate(endTime); 055 dateFrom.setRange(startTime, endTime); 056 dateTo.setRange(startTime, endTime); 057 058 add(noTimestampCb, GBC.std().grid(1,1).insets(0, 0, 5, 0)); 059 add(dateFrom, GBC.std().grid(2,1).fill(GBC.HORIZONTAL)); 060 add(dateTo, GBC.eol().grid(3,1).fill(GBC.HORIZONTAL)); 061 062 setEnabled(enabled); 063 064 dateFrom.addDateListener(changeListener); 065 dateTo.addDateListener(changeListener); 066 noTimestampCb.addChangeListener(changeListener); 067 } 068 069 private ChangeListener changeListener = new ChangeListener() { 070 @Override public void stateChanged(ChangeEvent e) { 071 if (isEnabled()) applyFilterWithDelay(); 072 } 073 }; 074 075 private Timer t = new Timer(200 , new ActionListener() { 076 @Override public void actionPerformed(ActionEvent e) { 077 applyFilter(); 078 } 079 }); 080 081 /** 082 * Do filtering but little bit later (to reduce cpu load) 083 */ 084 public void applyFilterWithDelay() { 085 if (t.isRunning()) { 086 t.restart(); 087 } else { 088 t.start(); 089 } 090 } 091 092 public void applyFilter() { 093 t.stop(); 094 filterTracksByDate(); 095 if (filterAppliedListener!=null) 096 filterAppliedListener.actionPerformed(null); 097 } 098 099 /** 100 * Called by other components when it is correct time to save date filtering parameters 101 */ 102 public void saveInPrefs() { 103 Main.pref.putLong(PREF_DATE_MIN, dateFrom.getDate().getTime()); 104 Main.pref.putLong(PREF_DATE_MAX, dateTo.getDate().getTime()); 105 Main.pref.put(PREF_DATE_0, noTimestampCb.isSelected()); 106 } 107 108 /** 109 * If possible, load date ragne and "zero timestamp" option from preferences 110 * Called by other components when it is needed. 111 */ 112 public void loadFromPrefs() { 113 long t1 =Main.pref.getLong(PREF_DATE_MIN, 0); 114 if (t1!=0) dateFrom.setDate(new Date(t1)); 115 long t2 =Main.pref.getLong(PREF_DATE_MAX, 0); 116 if (t2!=0) dateTo.setDate(new Date(t2)); 117 noTimestampCb.setSelected(Main.pref.getBoolean(PREF_DATE_0, false)); 118 } 119 120 public void setFilterAppliedListener(ActionListener filterAppliedListener) { 121 this.filterAppliedListener = filterAppliedListener; 122 } 123 124 private void filterTracksByDate() { 125 Date from = dateFrom.getDate(); 126 Date to = dateTo.getDate(); 127 layer.filterTracksByDate(from, to, noTimestampCb.isSelected()); 128 } 129 130 @Override 131 public void setEnabled(boolean enabled) { 132 super.setEnabled(enabled); 133 for (Component c: getComponents()) { 134 c.setEnabled(enabled); 135 } 136 } 137 138 139 140 141}