package org.openstreetmap.josm.data.osm;
import static org.openstreetmap.josm.tools.I18n.tr;
import static org.openstreetmap.josm.tools.I18n.trc;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.table.AbstractTableModel;
import org.openstreetmap.josm.Main;
import org.openstreetmap.josm.actions.search.SearchAction;
import org.openstreetmap.josm.actions.search.SearchAction.Function;
/**
*
* @author Petr_DlouhĂ˝
*/
public class Filters extends AbstractTableModel{
public int disabledCount, hiddenCount;
public Filters(){
loadPrefs();
}
private List<Filter> filters = new LinkedList<Filter>();
public void executeFilters(){
Collection<OsmPrimitive> seld = new LinkedList<OsmPrimitive> ();
Collection<OsmPrimitive> self = new LinkedList<OsmPrimitive> ();
DataSet ds = Main.main.getCurrentDataSet();
if(ds == null)return;
ds.setFiltered();
ds.setDisabled();
for (Filter flt : filters){
if(flt.enable){
SearchAction.getSelection(flt, seld, new Function(){
public Boolean isSomething(OsmPrimitive o){
return o.isDisabled();
}
});
if(flt.hide) {
SearchAction.getSelection(flt, self, new Function(){
public Boolean isSomething(OsmPrimitive o){
return o.isFiltered();
}
});
}
}
}
disabledCount = seld.size() - self.size();
hiddenCount = self.size();
ds.setFiltered(self);
ds.setDisabled(seld);
ds.clearSelection(seld);
Main.map.mapView.repaint();
}
public void clearFilterFlags() {
DataSet ds = Main.main.getCurrentDataSet();
if (ds != null) {
ds.setFiltered();
ds.setDisabled();
}
disabledCount = 0;
hiddenCount = 0;
Main.map.mapView.repaint();
}
private void loadPrefs() {
Map<String,String> prefs = Main.pref.getAllPrefix("filters.filter");
for (String value : prefs.values()) {
filters.add(new Filter(value));
}
}
private void savePrefs(){
Map<String,String> prefs = Main.pref.getAllPrefix("filters.filter");
for (String key : prefs.keySet()) {
String[] sts = key.split("\\.");
if (sts.length != 3)throw new Error("Incompatible filter preferences");
Main.pref.put("filters.filter." + sts[2], null);
}
int i = 0;
for (Filter flt : filters){
Main.pref.put("filters.filter." + i++, flt.getPrefString());
}
}
private void savePref(int i){
if(i >= filters.size()) {
Main.pref.put("filters.filter." + i, null);
} else {
Main.pref.put("filters.filter." + i, filters.get(i).getPrefString());
}
}
public void addFilter(Filter f){
filters.add(f);
savePref(filters.size()-1);
executeFilters();
fireTableRowsInserted(filters.size()-1, filters.size()-1);
}
public void moveDownFilter(int i){
if(i >= filters.size()-1) return;
filters.add(i+1, filters.remove(i));
savePref(i);
savePref(i+1);
executeFilters();
fireTableRowsUpdated(i, i+1);
}
public void moveUpFilter(int i){
if(i == 0) return;
filters.add(i-1, filters.remove(i));
savePref(i);
savePref(i-1);
executeFilters();
fireTableRowsUpdated(i-1, i);
}
public void removeFilter(int i){
filters.remove(i);
savePrefs();
executeFilters();
fireTableRowsDeleted(i, i);
}
public void setFilter(int i, Filter f){
filters.set(i, f);
savePref(i);
executeFilters();
fireTableRowsUpdated(i, i);
}
public Filter getFilter(int i){
return filters.get(i);
}
public int getRowCount(){
return filters.size();
}
public int getColumnCount(){
return 6;
}
@Override
public String getColumnName(int column){
String[] names = { /* translators notes must be in front */
/* column header: enable filter */ trc("filter","E"),
/* column header: hide filter */ trc("filter", "H"),
/* column header: filter text */ trc("filter", "Text"),
/* column header: apply filter for children */ trc("filter", "C"),
/* column header: inverted filter */ trc("filter", "I"),
/* column header: filter mode */ trc("filter", "M")
};
return names[column];
}
@Override
public Class<?> getColumnClass(int column){
Class<?>[] classes = { Boolean.class, Boolean.class, String.class, Boolean.class, Boolean.class, String.class };
return classes[column];
}
public boolean isCellEnabled(int row, int column){
if(!filters.get(row).enable && column!=0) return false;
return true;
}
@Override
public boolean isCellEditable(int row, int column){
if(!filters.get(row).enable && column!=0) return false;
if(column < 5)return true;
return false;
}
@Override
public void setValueAt(Object aValue, int row, int column){
Filter f = filters.get(row);
switch(column){
case 0:
f.enable = (Boolean)aValue;
savePref(row);
executeFilters();
fireTableRowsUpdated(row, row);
break;
case 1:
f.hide = (Boolean)aValue;
savePref(row);
executeFilters();
break;
case 2:
f.text = (String)aValue;
savePref(row);
break;
case 3:
f.applyForChildren = (Boolean)aValue;
savePref(row);
executeFilters();
break;
case 4:
f.inverted = (Boolean)aValue;
savePref(row);
executeFilters();
break;
}
if(column!=0) {
fireTableCellUpdated(row, column);
}
}
public Object getValueAt(int row, int column){
Filter f = filters.get(row);
switch(column){
case 0: return f.enable;
case 1: return f.hide;
case 2: return f.text;
case 3: return f.applyForChildren;
case 4: return f.inverted;
case 5:
switch(f.mode){ /* translators notes must be in front */
case replace: /* filter mode: replace */ return trc("filter", "R");
case add: /* filter mode: add */ return trc("filter", "A");
case remove: /* filter mode: remove */ return trc("filter", "D");
case in_selection: /* filter mode: in selection */ return trc("filter", "F");
}
}
return null;
}
private static class OSDLabel extends JLabel {
public OSDLabel(String text) {
super(text);
setOpaque(true);
setForeground(Color.black);
setBackground(new Color(0,0,0,0));
setFont(getFont().deriveFont(Font.PLAIN));
setBorder(BorderFactory.createEmptyBorder(0, 10, 10, 10));
}
@Override
public void paintComponent(Graphics g) {
g.setColor(new Color(255, 255, 255, 140));
g.fillRoundRect(getX(), getY(), getWidth(), getHeight(), 10, 10);
super.paintComponent(g);
}
}
private OSDLabel lblOSD = new OSDLabel("");
public void drawOSDText(Graphics2D g) {
String message = "<html>"+tr("<h2>Filter active</h2>");
if (disabledCount == 0 && hiddenCount == 0)
return;
if (hiddenCount != 0) {
message += tr("<p><b>{0}</b> objects hidden", hiddenCount);
}
if (hiddenCount != 0 && disabledCount != 0) {
message += "<br>";
}
if (disabledCount != 0) {
message += tr("<b>{0}</b> objects disabled", disabledCount);
}
message += tr("</p><p>Close the filter dialog to see all objects.<p></html>");
lblOSD.setText(message);
lblOSD.setSize(lblOSD.getPreferredSize());
int dx = Main.map.mapView.getWidth() - lblOSD.getPreferredSize().width - 15;
int dy = 15;
g.translate(dx, dy);
lblOSD.paintComponent(g);
g.translate(-dx, -dy);
}
}