source: josm/trunk/src/org/openstreetmap/josm/gui/dialogs/FilterDialog.java@ 4363

Last change on this file since 4363 was 4363, checked in by stoecker, 13 years ago

use createLayout() in all internal ToggleDialog's

  • Property svn:eol-style set to native
File size: 10.5 KB
Line 
1// License: GPL. Copyright 2007 by Immanuel Scholz and others
2package org.openstreetmap.josm.gui.dialogs;
3
4import static org.openstreetmap.josm.tools.I18n.marktr;
5import static org.openstreetmap.josm.tools.I18n.tr;
6
7import java.awt.Component;
8import java.awt.Graphics2D;
9import java.awt.event.ActionEvent;
10import java.awt.event.ActionListener;
11import java.awt.event.KeyEvent;
12import java.awt.event.MouseEvent;
13import java.util.Arrays;
14import java.util.Collection;
15import java.util.HashSet;
16import java.util.Set;
17import java.util.Stack;
18
19import javax.swing.JCheckBox;
20import javax.swing.JTable;
21import javax.swing.ListSelectionModel;
22import javax.swing.SwingUtilities;
23import javax.swing.table.DefaultTableCellRenderer;
24import javax.swing.table.JTableHeader;
25import javax.swing.table.TableCellRenderer;
26
27import org.openstreetmap.josm.Main;
28import org.openstreetmap.josm.actions.search.SearchAction;
29import org.openstreetmap.josm.data.osm.Filter;
30import org.openstreetmap.josm.data.osm.OsmPrimitive;
31import org.openstreetmap.josm.data.osm.Relation;
32import org.openstreetmap.josm.data.osm.RelationMember;
33import org.openstreetmap.josm.data.osm.Way;
34import org.openstreetmap.josm.data.osm.event.AbstractDatasetChangedEvent;
35import org.openstreetmap.josm.data.osm.event.DataChangedEvent;
36import org.openstreetmap.josm.data.osm.event.DataSetListener;
37import org.openstreetmap.josm.data.osm.event.DatasetEventManager;
38import org.openstreetmap.josm.data.osm.event.DatasetEventManager.FireMode;
39import org.openstreetmap.josm.data.osm.event.NodeMovedEvent;
40import org.openstreetmap.josm.data.osm.event.PrimitivesAddedEvent;
41import org.openstreetmap.josm.data.osm.event.PrimitivesRemovedEvent;
42import org.openstreetmap.josm.data.osm.event.RelationMembersChangedEvent;
43import org.openstreetmap.josm.data.osm.event.TagsChangedEvent;
44import org.openstreetmap.josm.data.osm.event.WayNodesChangedEvent;
45import org.openstreetmap.josm.gui.SideButton;
46import org.openstreetmap.josm.tools.Shortcut;
47
48/**
49 *
50 * @author Petr_Dlouhý
51 */
52public class FilterDialog extends ToggleDialog implements DataSetListener {
53
54 private JTable userTable;
55 private FilterTableModel filterModel = new FilterTableModel();
56 private SideButton addButton;
57 private SideButton editButton;
58 private SideButton deleteButton;
59 private SideButton upButton;
60 private SideButton downButton;
61
62
63 public FilterDialog(){
64 super(tr("Filter"), "filter", tr("Filter objects and hide/disable them."),
65 Shortcut.registerShortcut("subwindow:filter", tr("Toggle: {0}", tr("Filter")), KeyEvent.VK_F, Shortcut.GROUP_LAYER, Shortcut.SHIFT_DEFAULT), 162);
66 build();
67 }
68
69 @Override
70 public void showNotify() {
71 DatasetEventManager.getInstance().addDatasetListener(this, FireMode.IN_EDT_CONSOLIDATED);
72 filterModel.executeFilters();
73 }
74
75 @Override
76 public void hideNotify() {
77 DatasetEventManager.getInstance().removeDatasetListener(this);
78 filterModel.clearFilterFlags();
79 Main.map.mapView.repaint();
80 }
81
82 protected String[] columnToolTips = {
83 tr("Enable filter"),
84 tr("Hide elements"),
85 null,
86 tr("Inverse filter"),
87 tr("Filter mode")
88 };
89
90 protected void build() {
91 userTable = new JTable(filterModel){
92 @Override
93 protected JTableHeader createDefaultTableHeader() {
94 return new JTableHeader(columnModel) {
95 @Override
96 public String getToolTipText(MouseEvent e) {
97 java.awt.Point p = e.getPoint();
98 int index = columnModel.getColumnIndexAtX(p.x);
99 int realIndex = columnModel.getColumn(index).getModelIndex();
100 return columnToolTips[realIndex];
101 }
102 };
103 }
104 };
105
106 userTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
107
108 userTable.getColumnModel().getColumn(0).setMaxWidth(1);
109 userTable.getColumnModel().getColumn(1).setMaxWidth(1);
110 userTable.getColumnModel().getColumn(3).setMaxWidth(1);
111 userTable.getColumnModel().getColumn(4).setMaxWidth(1);
112
113 userTable.getColumnModel().getColumn(0).setResizable(false);
114 userTable.getColumnModel().getColumn(1).setResizable(false);
115 userTable.getColumnModel().getColumn(3).setResizable(false);
116 userTable.getColumnModel().getColumn(4).setResizable(false);
117
118 userTable.setDefaultRenderer(Boolean.class, new BooleanRenderer());
119 userTable.setDefaultRenderer(String.class, new StringRenderer());
120
121 addButton = new SideButton(marktr("Add"), "add", "SelectionList", tr("Add filter."),
122 new ActionListener(){
123 public void actionPerformed(ActionEvent evt){
124 Filter filter = (Filter)SearchAction.showSearchDialog(new Filter());
125 if(filter != null){
126 filterModel.addFilter(filter);
127 }
128 }
129 });
130
131 editButton = new SideButton(marktr("Edit"), "edit", "SelectionList", tr("Edit filter."),
132 new ActionListener(){
133 public void actionPerformed(ActionEvent evt){
134 int index = userTable.getSelectionModel().getMinSelectionIndex();
135 if(index < 0) return;
136 Filter f = filterModel.getFilter(index);
137 Filter filter = (Filter)SearchAction.showSearchDialog(f);
138 if(filter != null){
139 filterModel.setFilter(index, filter);
140 }
141 }
142 });
143
144 deleteButton = new SideButton(marktr("Delete"), "delete", "SelectionList", tr("Delete filter."),
145 new ActionListener(){
146 public void actionPerformed(ActionEvent evt){
147 int index = userTable.getSelectionModel().getMinSelectionIndex();
148 if(index < 0) return;
149 filterModel.removeFilter(index);
150 }
151 });
152
153 upButton = new SideButton(marktr("Up"), "up", "SelectionList", tr("Move filter up."),
154 new ActionListener(){
155 public void actionPerformed(ActionEvent evt){
156 int index = userTable.getSelectionModel().getMinSelectionIndex();
157 if(index < 0) return;
158 filterModel.moveUpFilter(index);
159 userTable.getSelectionModel().setSelectionInterval(index-1, index-1);
160 }
161 });
162
163 downButton = new SideButton(marktr("Down"), "down", "SelectionList", tr("Move filter down."),
164 new ActionListener(){
165 public void actionPerformed(ActionEvent evt){
166 int index = userTable.getSelectionModel().getMinSelectionIndex();
167 if(index < 0) return;
168 filterModel.moveDownFilter(index);
169 userTable.getSelectionModel().setSelectionInterval(index+1, index+1);
170 }
171 });
172
173 createLayout(userTable, true, Arrays.asList(new SideButton[] {
174 addButton, editButton, deleteButton, upButton, downButton
175 }));
176 }
177
178 static class StringRenderer extends DefaultTableCellRenderer {
179 @Override
180 public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,int row,int column) {
181 FilterTableModel model = (FilterTableModel)table.getModel();
182 Component cell = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
183 cell.setEnabled(model.isCellEnabled(row, column));
184 return cell;
185 }
186 }
187
188 static class BooleanRenderer extends JCheckBox implements TableCellRenderer {
189 public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,int row,int column) {
190 FilterTableModel model = (FilterTableModel)table.getModel();
191 setSelected(value != null && (Boolean)value);
192 setEnabled(model.isCellEnabled(row, column));
193 setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
194 return this;
195 }
196 }
197
198 public void updateDialogHeader() {
199 SwingUtilities.invokeLater(new Runnable() {
200 public void run() {
201 setTitle(tr("Filter Hidden:{0} Disabled:{1}", filterModel.disabledAndHiddenCount, filterModel.disabledCount));
202 }
203 });
204 }
205
206 public void drawOSDText(Graphics2D g) {
207 filterModel.drawOSDText(g);
208 }
209
210 /**
211 *
212 * @param primitive
213 * @return List of primitives whose filtering can be affected by change in primitive
214 */
215 private Collection<OsmPrimitive> getAffectedPrimitives(Collection<? extends OsmPrimitive> primitives) {
216 // Filters can use nested parent/child expression so complete tree is necessary
217 Set<OsmPrimitive> result = new HashSet<OsmPrimitive>();
218 Stack<OsmPrimitive> stack = new Stack<OsmPrimitive>();
219 stack.addAll(primitives);
220
221 while (!stack.isEmpty()) {
222 OsmPrimitive p = stack.pop();
223
224 if (result.contains(p)) {
225 continue;
226 }
227
228 result.add(p);
229
230 if (p instanceof Way) {
231 for (OsmPrimitive n: ((Way)p).getNodes()) {
232 stack.push(n);
233 }
234 } else if (p instanceof Relation) {
235 for (RelationMember rm: ((Relation)p).getMembers()) {
236 stack.push(rm.getMember());
237 }
238 }
239
240 for (OsmPrimitive ref: p.getReferrers()) {
241 stack.push(ref);
242 }
243 }
244
245 return result;
246 }
247
248 public void dataChanged(DataChangedEvent event) {
249 filterModel.executeFilters();
250 }
251
252 public void nodeMoved(NodeMovedEvent event) {
253 // Do nothing
254 }
255
256 public void otherDatasetChange(AbstractDatasetChangedEvent event) {
257 filterModel.executeFilters();
258 }
259
260 public void primitivesAdded(PrimitivesAddedEvent event) {
261 filterModel.executeFilters(event.getPrimitives());
262 }
263
264 public void primitivesRemoved(PrimitivesRemovedEvent event) {
265 filterModel.executeFilters();
266 }
267
268 public void relationMembersChanged(RelationMembersChangedEvent event) {
269 filterModel.executeFilters(getAffectedPrimitives(event.getPrimitives()));
270 }
271
272 public void tagsChanged(TagsChangedEvent event) {
273 filterModel.executeFilters(getAffectedPrimitives(event.getPrimitives()));
274 }
275
276 public void wayNodesChanged(WayNodesChangedEvent event) {
277 filterModel.executeFilters(getAffectedPrimitives(event.getPrimitives()));
278 }
279}
Note: See TracBrowser for help on using the repository browser.