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