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}