001/* 002 * (C) Copyright 2006-2008 Nuxeo SAS (http://nuxeo.com/) and contributors. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the GNU Lesser General Public License 006 * (LGPL) version 2.1 which accompanies this distribution, and is available at 007 * http://www.gnu.org/licenses/lgpl.html 008 * 009 * This library is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 012 * Lesser General Public License for more details. 013 * 014 * Contributors: 015 * troger 016 * 017 * $Id$ 018 */ 019 020package org.nuxeo.ecm.platform.annotations.gwt.client.view.listener; 021 022import java.util.HashMap; 023import java.util.Map; 024import java.util.Set; 025 026import org.nuxeo.ecm.platform.annotations.gwt.client.AnnotationConstant; 027import org.nuxeo.ecm.platform.annotations.gwt.client.AnnotationFrameApplication; 028import org.nuxeo.ecm.platform.annotations.gwt.client.configuration.AnnotationDefinition; 029import org.nuxeo.ecm.platform.annotations.gwt.client.controler.AnnotationController; 030import org.nuxeo.ecm.platform.annotations.gwt.client.model.Annotation; 031import org.nuxeo.ecm.platform.annotations.gwt.client.util.AnnotationUtils; 032import org.nuxeo.ecm.platform.annotations.gwt.client.util.Utils; 033 034import com.allen_sauer.gwt.log.client.Log; 035import com.google.gwt.user.client.DOM; 036import com.google.gwt.user.client.Event; 037import com.google.gwt.user.client.EventListener; 038import com.google.gwt.user.client.Timer; 039import com.google.gwt.user.client.Window; 040import com.google.gwt.user.client.ui.DockPanel; 041import com.google.gwt.user.client.ui.Frame; 042import com.google.gwt.user.client.ui.HTML; 043import com.google.gwt.user.client.ui.HorizontalPanel; 044import com.google.gwt.user.client.ui.Image; 045import com.google.gwt.user.client.ui.Label; 046import com.google.gwt.user.client.ui.PopupPanel; 047import com.google.gwt.user.client.ui.VerticalPanel; 048 049/** 050 * @author <a href="mailto:troger@nuxeo.com">Thomas Roger</a> 051 */ 052public class AnnotationPopupEventListener implements EventListener { 053 054 private class AnnotationPopup extends PopupPanel { 055 056 private boolean showing = false; 057 058 public AnnotationPopup() { 059 createPopup(); 060 } 061 062 private void createPopup() { 063 VerticalPanel shownAnnotation = new VerticalPanel(); 064 shownAnnotation.addStyleName("annotation-mousover"); 065 HorizontalPanel horizontalPanel = new HorizontalPanel(); 066 if (controller == null) { 067 return; // we are in a test case; 068 } 069 AnnotationDefinition def = controller.getWebConfiguration().getAnnotationDefinition( 070 annotation.getShortType()); 071 Image image = new Image(Utils.getBaseHref() + def.getIcon()); 072 horizontalPanel.add(image); 073 horizontalPanel.add(new Label(annotation.getFormattedDate())); 074 075 // add the displayed fields 076 Set<String> displayedFields = controller.getWebConfiguration().getDisplayedFields(); 077 for (String displayedField : displayedFields) { 078 String value = annotation.getFields().get(displayedField); 079 horizontalPanel.add(new Label("•")); 080 horizontalPanel.add(new Label(value != null ? value : " ")); 081 082 } 083 084 shownAnnotation.add(horizontalPanel); 085 if (annotation.isBodyUrl()) { 086 Frame frame = new Frame(); 087 frame.setUrl(annotation.getBody()); 088 shownAnnotation.add(frame); 089 } else { 090 String text = annotation.getBody(); 091 text = AnnotationUtils.replaceCarriageReturns(text); 092 HTML label = new HTML(text); 093 label.setStyleName("annotation-body"); 094 shownAnnotation.add(label); 095 } 096 DockPanel dockPanel = new DockPanel(); 097 dockPanel.add(shownAnnotation, DockPanel.CENTER); 098 add(dockPanel); 099 100 DOM.sinkEvents(getElement(), Event.ONMOUSEOVER | Event.ONMOUSEOUT); 101 } 102 103 @Override 104 public void onBrowserEvent(Event event) { 105 Log.debug("Event in AnnotationPopup"); 106 onEvent(event); 107 } 108 109 @Override 110 public void show() { 111 showing = true; 112 super.show(); 113 } 114 115 @Override 116 public void hide() { 117 showing = false; 118 super.hide(); 119 } 120 121 @Override 122 public void hide(boolean autoClosed) { 123 showing = false; 124 super.hide(autoClosed); 125 } 126 127 public boolean isShown() { 128 return showing; 129 } 130 131 } 132 133 private static final Map<Annotation, AnnotationPopupEventListener> LISTENERS = new HashMap<Annotation, AnnotationPopupEventListener>(); 134 135 private final Annotation annotation; 136 137 private final AnnotationController controller; 138 139 private final AnnotationPopup annotationPopup; 140 141 private boolean enabled = true; 142 143 private final Timer timer = new Timer() { 144 @Override 145 public void run() { 146 annotationPopup.hide(); 147 } 148 }; 149 150 public static AnnotationPopupEventListener getAnnotationPopupEventListener(Annotation annotation, 151 AnnotationController controller) { 152 AnnotationPopupEventListener listener = LISTENERS.get(annotation); 153 if (listener == null) { 154 listener = new AnnotationPopupEventListener(annotation, controller); 155 LISTENERS.put(annotation, listener); 156 controller.registerAnnotationPopupListener(listener); 157 } 158 return listener; 159 } 160 161 private AnnotationPopupEventListener(Annotation annotation, AnnotationController controller) { 162 this.annotation = annotation; 163 this.controller = controller; 164 annotationPopup = new AnnotationPopup(); 165 annotationPopup.setStyleName("annotationsPopupEvent"); 166 } 167 168 private void onEvent(Event event) { 169 if (annotation == null || controller == null || !enabled) { 170 AnnotationFrameApplication.getMainEventListener().onBrowserEvent(event); 171 return; 172 } 173 if (event.getTypeInt() == Event.ONMOUSEOVER) { 174 if (!annotationPopup.isShown()) { 175 annotationPopup.setPopupPosition(event.getClientX() + Window.getScrollLeft(), event.getClientY() 176 + Window.getScrollTop()); 177 annotationPopup.show(); 178 } 179 // reset the timer 180 timer.cancel(); 181 } else if (event.getTypeInt() == Event.ONMOUSEOUT) { 182 timer.schedule(AnnotationConstant.POPUP_PANEL_BLINK_TIMEOUT_MILI); 183 } 184 } 185 186 public void onBrowserEvent(Event event) { 187 onEvent(event); 188 } 189 190 public void enable() { 191 enabled = true; 192 } 193 194 public void disable() { 195 enabled = false; 196 } 197 198}