/* Copyright (c) 2001 - 2007 TOPP - www.openplans.org. All rights reserved.
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.web.data.layergroup;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.apache.wicket.AttributeModifier;
import org.apache.wicket.Component;
import org.apache.wicket.ResourceReference;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.form.OnChangeAjaxBehavior;
import org.apache.wicket.ajax.markup.html.AjaxLink;
import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.CheckBox;
import org.apache.wicket.markup.html.panel.Fragment;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.geoserver.catalog.LayerGroupInfo;
import org.geoserver.catalog.LayerInfo;
import org.geoserver.catalog.StyleInfo;
import org.geoserver.web.data.layergroup.AbstractLayerGroupPage.LayerListPanel;
import org.geoserver.web.data.layergroup.AbstractLayerGroupPage.StyleListPanel;
import org.geoserver.web.wicket.GeoServerDataProvider;
import org.geoserver.web.wicket.GeoServerTablePanel;
import org.geoserver.web.wicket.ImageAjaxLink;
import org.geoserver.web.wicket.ParamResourceModel;
import org.geoserver.web.wicket.SimpleAjaxLink;
import org.geoserver.web.wicket.GeoServerDataProvider.Property;
/**
* Allows to edit the list of layers contained in a layer group
*/
@SuppressWarnings("serial")
public class LayerGroupEntryPanel extends Panel {
ModalWindow popupWindow;
LayerGroupEntryProvider entryProvider;
GeoServerTablePanel<LayerGroupEntry> layerTable;
List<LayerGroupEntry> items;
public LayerGroupEntryPanel( String id, LayerGroupInfo layerGroup ) {
super( id );
items = new ArrayList();
for ( int i = 0; i < layerGroup.getLayers().size(); i++ ) {
LayerInfo layer = layerGroup.getLayers().get( i );
StyleInfo style = layerGroup.getStyles().get( i );
items.add( new LayerGroupEntry( layer, style ) );
}
add( popupWindow = new ModalWindow( "popup" ) );
//layers
entryProvider = new LayerGroupEntryProvider( items );
add( layerTable = new GeoServerTablePanel<LayerGroupEntry>("layers",entryProvider) {
@Override
protected Component getComponentForProperty(String id, IModel itemModel,
Property<LayerGroupEntry> property) {
if ( property == LayerGroupEntryProvider.LAYER ) {
return layerLink( id, itemModel );
}
if ( property == LayerGroupEntryProvider.DEFAULT_STYLE) {
return defaultStyleCheckbox( id, itemModel );
}
if ( property == LayerGroupEntryProvider.STYLE ) {
return styleLink( id, itemModel );
}
if ( property == LayerGroupEntryProvider.REMOVE ) {
return removeLink( id, itemModel );
}
if ( property == LayerGroupEntryProvider.POSITION ) {
return positionPanel( id, itemModel );
}
return null;
}
}.setFilterable( false ));
layerTable.setOutputMarkupId( true );
add( new AjaxLink( "add" ) {
@Override
public void onClick(AjaxRequestTarget target) {
popupWindow.setInitialHeight( 375 );
popupWindow.setInitialWidth( 525 );
popupWindow.setTitle(new ParamResourceModel("chooseLayer", this));
popupWindow.setContent( new LayerListPanel(popupWindow.getContentId()) {
@Override
protected void handleLayer(LayerInfo layer, AjaxRequestTarget target) {
popupWindow.close( target );
entryProvider.getItems().add(
new LayerGroupEntry( layer, layer.getDefaultStyle() ) );
//getCatalog().save( lg );
target.addComponent( layerTable );
}
});
popupWindow.show(target);
}
});
}
public List<LayerGroupEntry> getEntries() {
return items;
}
Component layerLink(String id, IModel itemModel) {
LayerGroupEntry entry = (LayerGroupEntry) itemModel.getObject();
return new Label( id, entry.getLayer().getResource().getPrefixedName() );
}
Component defaultStyleCheckbox(String id, IModel itemModel) {
final LayerGroupEntry entry = (LayerGroupEntry) itemModel.getObject();
Fragment f = new Fragment(id, "defaultStyle", this);
CheckBox ds = new CheckBox("checkbox", new Model(entry.isDefaultStyle()));
ds.add(new OnChangeAjaxBehavior() {
@Override
protected void onUpdate(AjaxRequestTarget target) {
Boolean useDefault = (Boolean) getComponent().getDefaultModelObject();
entry.setDefaultStyle(useDefault);
target.addComponent(layerTable);
}
});
f.add(ds);
return f;
}
Component styleLink(String id, final IModel itemModel) {
// decide if the style is the default and the current style name
LayerGroupEntry entry = (LayerGroupEntry) itemModel.getObject();
String styleName;
boolean defaultStyle = true;
if(entry.getStyle() != null) {
styleName = entry.getStyle().getName();
defaultStyle = false;
} else if(entry.getLayer().getDefaultStyle() != null) {
styleName = entry.getLayer().getDefaultStyle().getName();
} else {
styleName = null;
}
// build and returns the link, but disable it if the style is the default
SimpleAjaxLink link = new SimpleAjaxLink( id, new Model(styleName)) {
@Override
public void onClick(AjaxRequestTarget target) {
popupWindow.setInitialHeight( 375 );
popupWindow.setInitialWidth( 525 );
popupWindow.setTitle(new ParamResourceModel("chooseStyle", this));
popupWindow.setContent( new StyleListPanel( popupWindow.getContentId() ) {
@Override
protected void handleStyle(StyleInfo style, AjaxRequestTarget target) {
popupWindow.close( target );
LayerGroupEntry entry = (LayerGroupEntry) itemModel.getObject();
entry.setStyle( style );
//redraw
target.addComponent( layerTable );
}
});
popupWindow.show(target);
}
};
link.getLink().setEnabled(!defaultStyle);
return link;
}
Component removeLink(String id, IModel itemModel) {
final LayerGroupEntry entry = (LayerGroupEntry) itemModel.getObject();
ImageAjaxLink link = new ImageAjaxLink( id, new ResourceReference( getClass(), "../../img/icons/silk/delete.png") ) {
@Override
protected void onClick(AjaxRequestTarget target) {
items.remove( entry );
target.addComponent( layerTable );
}
};
link.getImage().add(new AttributeModifier("alt", true, new ParamResourceModel("AbstractLayerGroupPage.th.remove", link)));
return link;
}
Component positionPanel(String id, IModel itemModel) {
return new PositionPanel( id, (LayerGroupEntry) itemModel.getObject() );
}
static class LayerGroupEntryProvider extends GeoServerDataProvider<LayerGroupEntry> {
public static Property<LayerGroupEntry> LAYER =
new PropertyPlaceholder<LayerGroupEntry>( "layer" );
public static Property<LayerGroupEntry> DEFAULT_STYLE =
new PropertyPlaceholder<LayerGroupEntry>( "defaultStyle" );
public static Property<LayerGroupEntry> STYLE =
new PropertyPlaceholder<LayerGroupEntry>( "style" );
public static Property<LayerGroupEntry> REMOVE =
new PropertyPlaceholder<LayerGroupEntry>( "remove" );
public static Property<LayerGroupEntry> POSITION =
new PropertyPlaceholder<LayerGroupEntry>( "position" );
static List PROPERTIES = Arrays.asList( POSITION, LAYER, DEFAULT_STYLE, STYLE, REMOVE );
List<LayerGroupEntry> items;
public LayerGroupEntryProvider( List<LayerGroupEntry> items ) {
this.items = items;
}
@Override
protected List<LayerGroupEntry> getItems() {
return items;
}
@Override
protected List<Property<LayerGroupEntry>> getProperties() {
return PROPERTIES;
}
}
class PositionPanel extends Panel {
LayerGroupEntry entry;
public PositionPanel( String id, LayerGroupEntry entry ) {
super( id );
this.entry = entry;
if ( items.indexOf( entry ) > 0 ) {
ImageAjaxLink upLink = new ImageAjaxLink( "up", new ResourceReference( getClass(), "../../img/icons/silk/arrow_up.png") ) {
@Override
protected void onClick(AjaxRequestTarget target) {
int index = items.indexOf( PositionPanel.this.entry );
items.remove( index );
items.add( index-1, PositionPanel.this.entry );
target.addComponent( layerTable );
}
};
upLink.getImage().add(new AttributeModifier("alt", true, new ParamResourceModel("up", upLink)));
add( upLink);
}
else {
ImageAjaxLink blankLink = new ImageAjaxLink( "up", new ResourceReference( getClass(), "../../img/icons/blank.png") ) {
@Override
protected void onClick(AjaxRequestTarget target) {
}
};
blankLink.getImage().add(new AttributeModifier("alt", true, new Model("")));
add(blankLink);
}
if ( items.indexOf( entry ) < items.size() - 1 ) {
ImageAjaxLink downLink = new ImageAjaxLink( "down", new ResourceReference( getClass(), "../../img/icons/silk/arrow_down.png") ) {
@Override
protected void onClick(AjaxRequestTarget target) {
int index = items.indexOf( PositionPanel.this.entry );
items.remove( index );
items.add( index+1, PositionPanel.this.entry );
target.addComponent( layerTable );
}
};
downLink.getImage().add(new AttributeModifier("alt", true, new ParamResourceModel("down", downLink)));
add( downLink);
}
else {
ImageAjaxLink blankLink = new ImageAjaxLink( "down", new ResourceReference( getClass(), "../../img/icons/blank.png") ) {
@Override
protected void onClick(AjaxRequestTarget target) {
}
};
blankLink.getImage().add(new AttributeModifier("alt", true, new Model("")));
add( blankLink);
}
}
}
}