/** * Copyright (c) 2011 Alexander De Leon Battista * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package es.upm.fi.dia.oeg.map4rdf.client.widget; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import com.google.gwt.core.client.GWT; import com.google.gwt.dom.client.Style.Cursor; import com.google.gwt.dom.client.Style.Position; import com.google.gwt.dom.client.Style.Unit; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.http.client.URL; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.ui.Anchor; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.Image; import com.google.gwt.user.client.ui.InlineHTML; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.Panel; import com.google.gwt.user.client.ui.ScrollPanel; import com.google.gwt.user.client.ui.VerticalPanel; import com.google.gwt.user.client.ui.Widget; import net.customware.gwt.dispatch.client.DispatchAsync; import net.customware.gwt.presenter.client.EventBus; import es.upm.fi.dia.oeg.map4rdf.client.action.GetMultipleConfigurationParameters; import es.upm.fi.dia.oeg.map4rdf.client.action.GetMultipleConfigurationParametersResult; import es.upm.fi.dia.oeg.map4rdf.client.conf.ConfIDInterface; import es.upm.fi.dia.oeg.map4rdf.client.event.BufferSetPointEvent; import es.upm.fi.dia.oeg.map4rdf.client.event.CloseMapMainPopupEvent; import es.upm.fi.dia.oeg.map4rdf.client.event.DashboardDoSelectedResultWidgetEvent; import es.upm.fi.dia.oeg.map4rdf.client.event.EditResourceEvent; import es.upm.fi.dia.oeg.map4rdf.client.event.OnSelectedConfiguration; import es.upm.fi.dia.oeg.map4rdf.client.event.OnSelectedConfigurationHandler; import es.upm.fi.dia.oeg.map4rdf.client.event.ResultWidgetAddEvent; import es.upm.fi.dia.oeg.map4rdf.client.event.ResultWidgetDoSelectedEvent; import es.upm.fi.dia.oeg.map4rdf.client.event.ResultWidgetRemoveEvent; import es.upm.fi.dia.oeg.map4rdf.client.event.RoutesAddPointEvent; import es.upm.fi.dia.oeg.map4rdf.client.event.StatisticsSummaryEvent; import es.upm.fi.dia.oeg.map4rdf.client.resource.BrowserMessages; import es.upm.fi.dia.oeg.map4rdf.client.resource.BrowserResources; import es.upm.fi.dia.oeg.map4rdf.client.util.AdditionalInfoExecuter; import es.upm.fi.dia.oeg.map4rdf.client.util.AdditionalInfoExecuter.InfoCallback; import es.upm.fi.dia.oeg.map4rdf.client.util.AdditionalInfoSummary; import es.upm.fi.dia.oeg.map4rdf.client.util.GeoUtils; import es.upm.fi.dia.oeg.map4rdf.client.util.ParametersSummaryMove; import es.upm.fi.dia.oeg.map4rdf.client.util.RoutesAddGeoResourceType; import es.upm.fi.dia.oeg.map4rdf.client.util.WidgetsNames; import es.upm.fi.dia.oeg.map4rdf.share.GeoResource; import es.upm.fi.dia.oeg.map4rdf.share.Geometry; import es.upm.fi.dia.oeg.map4rdf.share.MapShape; import es.upm.fi.dia.oeg.map4rdf.share.conf.ParameterNames; import es.upm.fi.dia.oeg.map4rdf.share.conf.SharedGeometryModels; /** * @author Alexander De Leon * Adapted by: @author Francisco Siles */ public class GeoResourceSummary extends Composite { private final ConfIDInterface configID; private BrowserMessages messages; private BrowserResources resources; private WidgetFactory widgetFactory; private GeoResource lastGeoResource; private Geometry lastGeometry; private EventBus eventBus; private GeoResourceSummaryInfo summary; private final int intSizeImages=35; private final String sizeImages=intSizeImages+"px"; private final int intSizeAllTable=intSizeImages*3; private final String sizeAllTable=intSizeAllTable+"px";//sizeImages*3 private final int widgetDistance=3;//distance between widgets private Panel mainPanel; private ArrayList<Widget> allWidgetInOrder; private Map<String,Widget> allWidgetsWithName; private ParametersSummaryMove parametersSummary; private SummaryMove summaryMove; private Widget routesWidget; private Widget bufferWidget; private Widget infoWidget; private Widget editWidget; private Widget statisticsWidget; private Anchor twitterAnchor; private Anchor rdfAnchor; private Widget wikipediaResultWidget; private Widget wikipediaWidget; private String twitterURL; private String wikipediaParseURL=GWT.getModuleBaseURL()+"parseWikipedia?URL="; private Map<String,String> additionalsInfo; private DispatchAsync dispatchAsync; private Panel centerPanel; /*If you modify this constant remember to modify GeoResourceSummary.getPointVisualization() * the widgets need to be in the same order that this constant and the same length*/ public final String SUMMARY_WIDGETS_NAMES = WidgetsNames.ALL_IN_ORDER; private int moveType; public GeoResourceSummary(ConfIDInterface configID,DispatchAsync dispatchAsync,EventBus eventBus,BrowserMessages messages, BrowserResources appResources, WidgetFactory widgetFactory) { this.configID = configID; this.messages = messages; this.resources=appResources; this.eventBus = eventBus; this.widgetFactory = widgetFactory; allWidgetsWithName=new HashMap<String, Widget>(); allWidgetInOrder=new ArrayList<Widget>(); this.dispatchAsync=dispatchAsync; if(configID.existsConfigID()){ initAsync(); }else{ eventBus.addHandler(OnSelectedConfiguration.getType(), new OnSelectedConfigurationHandler() { @Override public void onSelectecConfiguration(String configID) { initAsync(); } }); } initWidget(createUi()); } private void initAsync(){ List<String> parameters= new ArrayList<String>(); parameters.add(ParameterNames.SUMMARY_WIDGETS); parameters.add(ParameterNames.TWITTER_STATUS_URL); parameters.add(ParameterNames.GEOMETRY_MODEL); dispatchAsync.execute(new GetMultipleConfigurationParameters(configID.getConfigID(),parameters), new AsyncCallback<GetMultipleConfigurationParametersResult>() { @Override public void onFailure(Throwable caught) { GeoResourceSummary.this.widgetFactory.getDialogBox().showError( GeoResourceSummary.this.messages.moduleCantContactWithServer("GeoResourceSummary")); initAsync(null); } @Override public void onSuccess(GetMultipleConfigurationParametersResult result) { String summaryWidgets=result.getResults().get(ParameterNames.SUMMARY_WIDGETS); if(summaryWidgets==null || summaryWidgets.isEmpty()){ GeoResourceSummary.this.widgetFactory.getDialogBox().showError( GeoResourceSummary.this.messages.configParameterNullOrEmpty(ParameterNames.SUMMARY_WIDGETS)); initAsync(null); }else{ initAsync(summaryWidgets.toLowerCase()); } String twitter=result.getResults().get(ParameterNames.TWITTER_STATUS_URL); if(twitter!=null && !twitter.isEmpty()){ twitterURL=twitter; }else{ GeoResourceSummary.this.widgetFactory.getDialogBox().showError( GeoResourceSummary.this.messages.configParameterNullOrEmpty(ParameterNames.TWITTER_STATUS_URL)); } String geometryModel=result.getResults().get(ParameterNames.GEOMETRY_MODEL); if(geometryModel!=null && !geometryModel.isEmpty()){ summary=getSummary(geometryModel); }else{ GeoResourceSummary.this.widgetFactory.getDialogBox().showError( GeoResourceSummary.this.messages.configParameterNullOrEmpty(ParameterNames.GEOMETRY_MODEL)); } } }); } public void setGeoResource(final GeoResource resource, Geometry geometry) { //TODO Analyze if it is easy to implement closeProperSummary depend on configuration param. openOrCloseSummary(false); lastGeoResource=resource; lastGeometry=geometry; centerPanel.clear(); centerPanel.add(getCenterImage()); AdditionalInfoExecuter.cancelAllCallbacks(); AdditionalInfoExecuter.getAdditionalInfo(configID.getConfigID(), dispatchAsync, resource, new InfoCallback() { @Override public void success(AdditionalInfoSummary additionalInfo) { summary.clearAdditionalInfo(); additionalsInfo=additionalInfo.getAdditionalInfo(); if(additionalInfo.haveImage()){ centerPanel.clear(); Image image= new Image(GWT.getModuleBaseURL() + additionalInfo.getImage()); image.getElement().getStyle().setCursor(Cursor.POINTER); image.getElement().getStyle().setPosition(Position.ABSOLUTE); image.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { close(); } }); centerPanel.add(image); } summary.addAdditionalInfo(additionalsInfo); } }); if(wikipediaResultWidget!=null){ eventBus.fireEvent(new ResultWidgetRemoveEvent(wikipediaResultWidget)); wikipediaResultWidget=null; } if(GeoUtils.getCentroid(geometry)!=null){ routesWidget.setVisible(true); bufferWidget.setVisible(true); }else{ routesWidget.setVisible(false); bufferWidget.setVisible(false); } if (resource.getUri()!=null) { infoWidget.setVisible(true); twitterAnchor.setVisible(true); twitterAnchor.setHref(twitterURL+URL.encode(resource.getUri())); rdfAnchor.setVisible(true); rdfAnchor.setHref(resource.getUri()); editWidget.setVisible(true); statisticsWidget.setVisible(true); wikipediaWidget.setVisible(true); } else { editWidget.setVisible(false); twitterAnchor.setVisible(false); rdfAnchor.setVisible(false); wikipediaWidget.setVisible(false); if(geometry.getType() != MapShape.Type.POINT){ infoWidget.setVisible(false); statisticsWidget.setVisible(false); } } ArrayList<Widget> visibleWidget= new ArrayList<Widget>(); for(int i=0;i<allWidgetInOrder.size();i++){ if(allWidgetInOrder.get(i).isVisible()){ visibleWidget.add(allWidgetInOrder.get(i)); } } summaryMove.cancelMove(); parametersSummary=initializeParametersSummary(visibleWidget.size(),moveType); summary.setGeoResource(resource, geometry); summaryMove=new SummaryMove(visibleWidget, parametersSummary, this); moveInitialPosition(); summaryMove.startMoveWidgets(); } public void moveLeftTopOfCenter(Widget widget,int left,int top){ int centerLeft=intSizeImages; int centerTop=intSizeImages; left=centerLeft+left; top=centerTop-top; widget.getElement().getStyle().setLeft(left, Unit.PX); widget.getElement().getStyle().setTop(top, Unit.PX); } private Widget createUi() { mainPanel= new FlowPanel(); mainPanel.setSize(sizeAllTable, sizeAllTable); Image image=new Image(resources.summaryBackGround()); image.setSize(sizeAllTable, sizeAllTable); mainPanel.getElement().getStyle().setProperty("background", image.getElement().getStyle().getBackgroundImage()+" no-repeat scroll 0px 0px transparent"); mainPanel.add(centerPanel=getCenter()); centerPanel.getElement().getStyle().setPosition(Position.ABSOLUTE); centerPanel.getElement().getStyle().setLeft(intSizeImages, Unit.PX); centerPanel.getElement().getStyle().setTop(intSizeImages, Unit.PX); return mainPanel; } private void initAsync(String summaryWidgets){ initPointVisualization(); if(summaryWidgets!=null && !summaryWidgets.isEmpty()){ String split[]=summaryWidgets.split(";"); for(String i:summaryWidgets.split(";")){ if(allWidgetsWithName.containsKey(i)){ Widget widget=allWidgetsWithName.get(i); mainPanel.add(widget); allWidgetInOrder.add(widget); } if(split[split.length-1].toLowerCase().contains("type")){ try { String type[]=split[split.length-1].split(":"); moveType=Integer.parseInt(type[type.length-1]); } catch (Exception e) { } } } }else{ for(Widget i:allWidgetsWithName.values()){ mainPanel.add(i); allWidgetInOrder.add(i); } } parametersSummary=initializeParametersSummary(allWidgetInOrder.size(),moveType); summaryMove=new SummaryMove(allWidgetInOrder, parametersSummary, this); } private Panel initPointVisualization(){ Widget widget; /*This */ /*To add new widget in the summary please * modify Constants.SUMMARY_WIDGETS_NAMES add the new name of the widget * and add the widget in the same order this appear in Constants.SUMMARY_WIDGETS_NAMES;*/ String summaryArrayWidgets[]=SUMMARY_WIDGETS_NAMES.split(";"); int i=0; widget=getInfo(); infoWidget=widget; allWidgetsWithName.put(summaryArrayWidgets[i++], widget); widget.getElement().getStyle().setPosition(Position.ABSOLUTE); widget=getWikipedia(); wikipediaWidget=widget; allWidgetsWithName.put(summaryArrayWidgets[i++], widget); widget.getElement().getStyle().setPosition(Position.ABSOLUTE); widget=getSetToBuffer(); bufferWidget=widget; allWidgetsWithName.put(summaryArrayWidgets[i++], widget); widget.getElement().getStyle().setPosition(Position.ABSOLUTE); widget=getTwitter(); allWidgetsWithName.put(summaryArrayWidgets[i++], widget); widget.getElement().getStyle().setPosition(Position.ABSOLUTE); widget=getClose(); allWidgetsWithName.put(summaryArrayWidgets[i++], widget); widget.getElement().getStyle().setPosition(Position.ABSOLUTE); widget=getEdit(); allWidgetsWithName.put(summaryArrayWidgets[i++], widget); widget.getElement().getStyle().setPosition(Position.ABSOLUTE); widget=getAddToRoutes(); routesWidget=widget; allWidgetsWithName.put(summaryArrayWidgets[i++], widget); widget.getElement().getStyle().setPosition(Position.ABSOLUTE); widget=getRDF(); allWidgetsWithName.put(summaryArrayWidgets[i++], widget); widget.getElement().getStyle().setPosition(Position.ABSOLUTE); widget=getStatistics(); statisticsWidget=widget; allWidgetsWithName.put(summaryArrayWidgets[i++], widget); widget.getElement().getStyle().setPosition(Position.ABSOLUTE); return mainPanel; } private Widget getStatistics(){ Image image= new Image(resources.statsSummaryIcon()); image.setSize(sizeImages, sizeImages); image.setTitle(messages.statistics()); image.getElement().getStyle().setCursor(Cursor.POINTER); image.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { openPopupStatisticsView(); } }); return image; } private Widget getInfo(){ Image image= new Image(resources.infoIcon()); image.setSize(sizeImages, sizeImages); image.setTitle(messages.infoResource()); image.getElement().getStyle().setCursor(Cursor.POINTER); image.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { openOrCloseSummary(!summary.isVisible()); } }); return image; } private Widget getWikipedia(){ Image image= new Image(resources.wikipediaIcon()); image.setSize(sizeImages, sizeImages); image.setTitle(messages.wikipediaTitle()); image.getElement().getStyle().setCursor(Cursor.POINTER); image.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { revealWikipedia(); } }); return image; } private Widget getEdit(){ Image image= new Image(resources.editIcon()); image.setSize(sizeImages, sizeImages); image.setTitle(messages.edit()); image.getElement().getStyle().setCursor(Cursor.POINTER); image.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { EditResourceEvent editEvent = new EditResourceEvent(lastGeoResource.getUri()); eventBus.fireEvent(editEvent); } }); editWidget=image; return editWidget; } private Widget getRDF(){ rdfAnchor=new Anchor(); rdfAnchor.setSize(sizeImages, sizeImages); Image image=new Image(resources.rdfIcon()); image.setSize(sizeImages, sizeImages); rdfAnchor.setTitle(messages.rdfTitle()); rdfAnchor.getElement().appendChild(image.getElement()); rdfAnchor.setTarget("_blank"); return rdfAnchor; } private GeoResourceSummaryInfo getSummary(String geometryModel){ if(SharedGeometryModels.AEMET.equalsIgnoreCase(geometryModel)){ return new GeoResourceSummaryInfoAemet(configID,dispatchAsync, resources, messages, widgetFactory); } if(SharedGeometryModels.VIAJERO.equalsIgnoreCase(geometryModel)){ return new GeoResourceSummaryInfoViajero(configID,dispatchAsync,eventBus, resources, messages); } return new GeoResourceSummaryInfoDefault(messages, resources); } private Widget getAddToRoutes(){ Image image=new Image(resources.routesIcon()); image.setSize(sizeImages, sizeImages); image.setTitle(messages.addToRoutes()); image.getElement().getStyle().setCursor(Cursor.POINTER); image.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { addToRoute(); } }); return image; } private Widget getSetToBuffer(){ Image image=new Image(resources.bufferIcon()); image.setSize(sizeImages, sizeImages); image.setTitle(messages.setToBuffer()); image.getElement().getStyle().setCursor(Cursor.POINTER); image.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { setToBuffer(); } }); return image; } private Panel getCenter(){ FlowPanel panel= new FlowPanel(); panel.setSize(sizeImages,sizeImages); panel.add(getCenterImage()); return panel; } private Widget getCenterImage(){ Image image=new Image(resources.transparentImage()); image.setSize(sizeImages, sizeImages); image.getElement().getStyle().setCursor(Cursor.POINTER); image.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { close(); } }); return image; } private Widget getTwitter(){ twitterAnchor=new Anchor(); twitterAnchor.setSize(sizeImages, sizeImages); Image image=new Image(resources.twitterIcon()); image.setSize(sizeImages, sizeImages); twitterAnchor.setTitle(messages.twitterTitle()); twitterAnchor.getElement().appendChild(image.getElement()); twitterAnchor.setTarget("_blank"); return twitterAnchor; } private Widget getClose(){ Image image=new Image(resources.closeIcon()); image.setSize(sizeImages, sizeImages); image.setTitle(messages.close()); image.getElement().getStyle().setCursor(Cursor.POINTER); image.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { close(); } }); return image; } private void revealWikipedia() { if(wikipediaResultWidget!=null){ eventBus.fireEvent(new ResultWidgetRemoveEvent(wikipediaResultWidget)); wikipediaResultWidget=null; } if(!lastGeoResource.getWikipediaURL().isEmpty()){ String wikipediaURL=lastGeoResource.getWikipediaURL().iterator().next(); VerticalPanel panel=new VerticalPanel(); Anchor anchor=new Anchor(messages.wikipediaTitle(), wikipediaURL); anchor.setTarget("_blank"); panel.add(anchor); ScrollPanel scroll= new ScrollPanel(new InlineHTML("<iframe src=\""+wikipediaParseURL+wikipediaURL+"\" style=\"width: 97%; height:"+String.valueOf(Window.getClientHeight()-400)+"px\">")); panel.add(scroll); wikipediaResultWidget=panel; }else{ VerticalPanel panel=new VerticalPanel(); panel.add(new Label(messages.wikipediaNotFound())); wikipediaResultWidget=panel; } eventBus.fireEvent(new ResultWidgetAddEvent(wikipediaResultWidget, messages.wikipedia())); eventBus.fireEvent(new ResultWidgetDoSelectedEvent(wikipediaResultWidget)); eventBus.fireEvent(new DashboardDoSelectedResultWidgetEvent()); } private void addToRoute(){ eventBus.fireEvent(new RoutesAddPointEvent(lastGeoResource, lastGeometry, RoutesAddGeoResourceType.OtherPopup)); } private void setToBuffer(){ eventBus.fireEvent(new BufferSetPointEvent(lastGeoResource, lastGeometry)); } private void close(){ //TODO Analyze if it is easy to implement closeProperSummary depend on configuration param. closeProperSummary(); if(wikipediaResultWidget!=null){ eventBus.fireEvent(new ResultWidgetRemoveEvent(wikipediaResultWidget)); wikipediaResultWidget=null; } eventBus.fireEvent(new CloseMapMainPopupEvent()); } private void openPopupStatisticsView(){ eventBus.fireEvent(new StatisticsSummaryEvent(true, lastGeoResource)); } public void closeSummary(){ openOrCloseSummary(false); } private void openOrCloseSummary(boolean openOrClose){ if(openOrClose){ openProperSummary(); }else{ closeProperSummary(); } } private void openProperSummary(){ if(!summary.isVisible()){ summary.show(); } } private void closeProperSummary(){ if(summary.isVisible()){ summary.close(); } } private void moveInitialPosition(){ summaryMove.moveToInitialPosition(); } private ParametersSummaryMove initializeParametersSummary(int widgetsSize,int moveType){ if(widgetsSize==0){widgetsSize=1;} final int parameter=(int)((int)(104/widgetsSize))*widgetsSize; final int firtsTotalTime=parameter*3; final int secondTotalTime=parameter; final int steps=parameter; final int diffSteps=10; final int diffSpecialSteps=steps/widgetsSize;//procure that the division have a int result. int radiousPX=(int)(((intSizeImages+widgetDistance)*widgetsSize)/(2*Math.PI)); if(radiousPX<intSizeImages){ radiousPX=intSizeImages; } return new ParametersSummaryMove(firtsTotalTime,secondTotalTime, steps, diffSteps, diffSpecialSteps, radiousPX,intSizeImages,widgetDistance,moveType); } }