/*
* Geotoolkit - An Open Source Java GIS Toolkit
* http://www.geotoolkit.org
*
* (C) 2007 - 2008, Open Source Geospatial Foundation (OSGeo)
* (C) 2008 - 2009, Johann Sorel
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
package org.geotoolkit.gui.swing.filter;
import java.awt.Component;
import java.awt.image.BufferedImage;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.Collection;
import javax.swing.DefaultListCellRenderer;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import org.geotoolkit.cql.CQLException;
import org.geotoolkit.gui.swing.util.JOptionDialog;
import org.geotoolkit.font.FontAwesomeIcons;
import org.geotoolkit.font.IconBuilder;
import org.geotoolkit.gui.swing.resource.MessageBundle;
import org.geotoolkit.map.FeatureMapLayer;
import org.geotoolkit.map.MapLayer;
import org.jdesktop.swingx.combobox.ListComboBoxModel;
import org.opengis.feature.PropertyType;
import org.opengis.filter.Filter;
import org.opengis.filter.expression.Expression;
import org.opengis.util.InternationalString;
/**
* CQL filter panel
*
* @author Johann Sorel (Puzzle-GIS)
* @module
*/
public class JCQLEditor extends javax.swing.JPanel{
public static volatile boolean DEFAULT_SIMPLE = true;
private static final ImageIcon ICON_FILTER = IconBuilder.createIcon(FontAwesomeIcons.ICON_FILTER, 16, FontAwesomeIcons.DEFAULT_COLOR);
private MapLayer layer;
private boolean isFilter = false;
/** Creates new form JCQLPropertyPanel */
public JCQLEditor() {
initComponents();
guiProperties.addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
Object ob = guiProperties.getSelectedValue();
if(ob != null){
final String name = ((PropertyType)ob).getName().tip().toString();
guiCQL.insertText(" "+name);
guiProperties.clearSelection();
}
}
});
guiProperties.setCellRenderer(new PropertyRenderer());
guiPropertiesPane.setVisible(false);
guiCQL.addPropertyChangeListener("content", new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
try {
final Expression exp = guiCQL.getExpression();
final BufferedImage img = MathMLVisitor.toImage(MathMLVisitor.toMathML(exp));
lblFormula.setIcon(new ImageIcon(img));
} catch (Exception ex) {
//happens very often
lblFormula.setIcon(null);
}
}
});
guiShortcuts.addPropertyChangeListener(JCQLShortcutPanel.KEY_SELECTION, new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
guiCQL.insertText(""+evt.getNewValue());
}
});
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
setLayout(new java.awt.BorderLayout());
guiTextPropertySplit.setDividerSize(2);
guiTextPropertySplit.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);
guiProperties.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
guiScroll.setViewportView(guiProperties);
jXTitledSeparator6.setTitle(MessageBundle.format("properties")); // NOI18N
javax.swing.GroupLayout guiPropertiesPaneLayout = new javax.swing.GroupLayout(guiPropertiesPane);
guiPropertiesPane.setLayout(guiPropertiesPaneLayout);
guiPropertiesPaneLayout.setHorizontalGroup(
guiPropertiesPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(guiPropertiesPaneLayout.createSequentialGroup()
.addContainerGap()
.addComponent(jXTitledSeparator6, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addComponent(guiScroll, javax.swing.GroupLayout.DEFAULT_SIZE, 515, Short.MAX_VALUE)
);
guiPropertiesPaneLayout.setVerticalGroup(
guiPropertiesPaneLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(guiPropertiesPaneLayout.createSequentialGroup()
.addContainerGap()
.addComponent(jXTitledSeparator6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(guiScroll, javax.swing.GroupLayout.DEFAULT_SIZE, 92, Short.MAX_VALUE))
);
guiTextPropertySplit.setLeftComponent(guiPropertiesPane);
jPanel7.setLayout(new java.awt.BorderLayout());
jPanel7.add(guiCQL, java.awt.BorderLayout.CENTER);
lblFormula.setBackground(new java.awt.Color(255, 255, 255));
lblFormula.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
lblFormula.setBorder(javax.swing.BorderFactory.createEmptyBorder(4, 4, 4, 4));
lblFormula.setOpaque(true);
jPanel7.add(lblFormula, java.awt.BorderLayout.PAGE_END);
guiTextPropertySplit.setBottomComponent(jPanel7);
add(guiTextPropertySplit, java.awt.BorderLayout.CENTER);
add(guiShortcuts, java.awt.BorderLayout.WEST);
}// </editor-fold>//GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables
private final javax.swing.ButtonGroup groupType = new javax.swing.ButtonGroup();
private final org.geotoolkit.cql.JCQLTextPane guiCQL = new org.geotoolkit.cql.JCQLTextPane();
private final javax.swing.JList guiProperties = new javax.swing.JList();
private final javax.swing.JPanel guiPropertiesPane = new javax.swing.JPanel();
private final javax.swing.JScrollPane guiScroll = new javax.swing.JScrollPane();
private final org.geotoolkit.gui.swing.filter.JCQLShortcutPanel guiShortcuts = new org.geotoolkit.gui.swing.filter.JCQLShortcutPanel();
private final javax.swing.JSplitPane guiTextPropertySplit = new javax.swing.JSplitPane();
private final javax.swing.JPanel jPanel7 = new javax.swing.JPanel();
private final org.jdesktop.swingx.JXTitledSeparator jXTitledSeparator6 = new org.jdesktop.swingx.JXTitledSeparator();
private final javax.swing.JLabel lblFormula = new javax.swing.JLabel();
// End of variables declaration//GEN-END:variables
public void setExpression(final Expression exp){
isFilter = false;
guiCQL.setExpression(exp);
guiShortcuts.setFilterOpVisible(isFilter);
}
public Expression getExpression() throws CQLException{
return guiCQL.getExpression();
}
public void setFilter(final Filter filter) {
isFilter = true;
guiCQL.setFilter(filter);
guiShortcuts.setFilterOpVisible(isFilter);
}
public Filter getFilter() throws CQLException {
return guiCQL.getFilter();
}
public void setLayer(final MapLayer layer) {
this.layer = layer;
if (layer instanceof FeatureMapLayer) {
final FeatureMapLayer fml = (FeatureMapLayer) layer;
final Collection<? extends PropertyType> col = fml.getCollection().getFeatureType().getProperties(true);
guiProperties.setModel(new ListComboBoxModel(new ArrayList(col)));
guiPropertiesPane.setVisible(true);
guiTextPropertySplit.setDividerLocation(120);
}else{
guiPropertiesPane.setVisible(false);
guiTextPropertySplit.setDividerLocation(0);
}
guiTextPropertySplit.revalidate();
guiTextPropertySplit.repaint();
}
public MapLayer getLayer() {
return layer;
}
public String getTitle() {
return MessageBundle.format("property_cql_filter");
}
public ImageIcon getIcon() {
return ICON_FILTER;
}
public String getToolTip() {
return null;
}
public JComponent getComponent() {
return this;
}
public static Filter showDialog(Component parent, final MapLayer layer, final Filter filter) throws CQLException{
final JCQLEditor editor = new JCQLEditor();
editor.setLayer(layer);
editor.setFilter(filter);
final int res = JOptionDialog.show(parent, editor, JOptionPane.OK_CANCEL_OPTION);
if(res == JOptionPane.OK_OPTION){
return editor.getFilter();
}else{
return filter;
}
}
public static Expression showDialog(Component parent, final MapLayer layer, final Expression expression) throws CQLException{
final JCQLEditor editor = new JCQLEditor();
editor.setLayer(layer);
editor.setExpression(expression);
final int res = JOptionDialog.show(parent, editor, JOptionPane.OK_CANCEL_OPTION);
if(res == JOptionPane.OK_OPTION){
return editor.getExpression();
}else{
return expression;
}
}
private static final class PropertyRenderer extends DefaultListCellRenderer{
@Override
public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
final JLabel lbl = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if(value instanceof PropertyType){
final PropertyType desc = (PropertyType) value;
String text = desc.getName().tip().toString().toString();
final InternationalString is = desc.getDescription();
if(is!=null && !is.toString().isEmpty()){
text += " ("+is.toString()+")";
}
lbl.setText(text);
}
return lbl;
}
}
}