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 *     Alexandre Russel
016 *
017 * $Id$
018 */
019
020package org.nuxeo.ecm.platform.annotations.gwt.client.view;
021
022import java.util.ArrayList;
023import java.util.List;
024import java.util.Map;
025
026import org.nuxeo.ecm.platform.annotations.gwt.client.AnnotationConstant;
027import org.nuxeo.ecm.platform.annotations.gwt.client.configuration.AnnotationDefinition;
028import org.nuxeo.ecm.platform.annotations.gwt.client.configuration.WebConfiguration;
029import org.nuxeo.ecm.platform.annotations.gwt.client.configuration.filter.TypeFilter;
030import org.nuxeo.ecm.platform.annotations.gwt.client.controler.AnnotationController;
031import org.nuxeo.ecm.platform.annotations.gwt.client.model.Annotation;
032import org.nuxeo.ecm.platform.annotations.gwt.client.util.XPointerFactory;
033import org.nuxeo.ecm.platform.annotations.gwt.client.view.i18n.TranslationConstants;
034
035import com.allen_sauer.gwt.log.client.Log;
036import com.google.gwt.core.client.GWT;
037import com.google.gwt.dom.client.Document;
038import com.google.gwt.dom.client.Element;
039import com.google.gwt.user.client.Window;
040import com.google.gwt.user.client.ui.Button;
041import com.google.gwt.user.client.ui.ClickListener;
042import com.google.gwt.user.client.ui.DockPanel;
043import com.google.gwt.user.client.ui.HorizontalPanel;
044import com.google.gwt.user.client.ui.KeyboardListenerAdapter;
045import com.google.gwt.user.client.ui.Label;
046import com.google.gwt.user.client.ui.ListBox;
047import com.google.gwt.user.client.ui.PopupPanel;
048import com.google.gwt.user.client.ui.TextArea;
049import com.google.gwt.user.client.ui.VerticalPanel;
050import com.google.gwt.user.client.ui.Widget;
051
052/**
053 * @author <a href="mailto:arussel@nuxeo.com">Alexandre Russel</a>
054 */
055public class NewAnnotationPopup extends PopupPanel {
056
057    private class AnnotationTextArea extends TextArea {
058
059        public AnnotationTextArea() {
060            addKeyboardListener(new KeyboardListenerAdapter() {
061                public void onKeyUp(Widget sender, char keyCode, int modifiers) {
062                    String content = getText();
063                    if (content.trim().equals("")) {
064                        submit.setEnabled(false);
065                    } else {
066                        submit.setEnabled(true);
067                    }
068                }
069
070                @SuppressWarnings("deprecation")
071                @Override
072                public void onKeyPress(Widget sender, char keyCode, int modifiers) {
073                    TextArea ta = (TextArea) sender;
074                    String content = ta.getText();
075                    if (Character.isLetterOrDigit(keyCode) || Character.isSpace(keyCode)) {
076                        if (content.length() >= AnnotationConstant.MAX_ANNOTATION_TEXT_LENGTH) {
077                            ta.cancelKey();
078                        }
079                    }
080                }
081            });
082            setCharacterWidth(30);
083            setVisibleLines(6);
084        }
085    }
086
087    private final AnnotationController controller;
088
089    public String selectedAnnotationType = null;
090
091    private final ListBox listBox = new ListBox();
092
093    private final List<ListBox> fieldListBoxes = new ArrayList<ListBox>();
094
095    private final VerticalPanel verticalPanel = new VerticalPanel();
096
097    private final DockPanel dockPanel = new DockPanel();
098
099    private final AnnotationTextArea annotationTextArea = new AnnotationTextArea();
100
101    private final HorizontalPanel flowPanel = new HorizontalPanel();
102
103    private final Button submit;
104
105    private final Button cancel;
106
107    private final Element element;
108
109    private final boolean removeOnCancel;
110
111    public NewAnnotationPopup(final Element element, final AnnotationController controller,
112            final boolean removeOnCancel, final String annotationType) {
113        this(element, controller, removeOnCancel, annotationType, null);
114    }
115
116    public NewAnnotationPopup(final Element element, final AnnotationController controller,
117            final boolean removeOnCancel, final String annotationType, final String annotationName) {
118        this.controller = controller;
119        this.element = element;
120        this.removeOnCancel = removeOnCancel;
121
122        GWT.log("creating new annotation pop up", null);
123        int scroll = Document.get().getBody().getScrollTop();
124        controller.setFrameScrollFromTop(scroll);
125        dockPanel.setStyleName("annotationsNewAnnotationPopup");
126
127        dockPanel.add(verticalPanel, DockPanel.NORTH);
128        dockPanel.add(annotationTextArea, DockPanel.CENTER);
129        dockPanel.add(flowPanel, DockPanel.SOUTH);
130
131        if (annotationName != null) {
132            selectedAnnotationType = annotationName;
133            // Add into the view
134            verticalPanel.add(new Label(selectedAnnotationType));
135
136            Map<String, String[]> fields = controller.getWebConfiguration().getAnnotationDefinition(annotationName).getFields();
137            for (String fieldName : fields.keySet()) {
138                ListBox fieldListBox = new ListBox();
139                fieldListBox.setName(fieldName);
140                for (String choice : fields.get(fieldName)) {
141                    fieldListBox.addItem(choice);
142                }
143                fieldListBoxes.add(fieldListBox);
144
145                // Add into the view
146                verticalPanel.add(fieldListBox);
147            }
148        } else {
149            WebConfiguration webConf = controller.getWebConfiguration();
150            List<AnnotationDefinition> annotationDefs = webConf.getAnnotationDefinitions(new TypeFilter(annotationType));
151            if (annotationDefs.size() == 1) {
152                selectedAnnotationType = annotationDefs.get(0).getName();
153                String label = selectedAnnotationType;
154                // If this is the default annotation (Comment), internationalize the
155                // title
156                if (label.equals(AnnotationConstant.COMMENT_ANNOTATION_NAME)) {
157                    TranslationConstants translationContants = GWT.create(TranslationConstants.class);
158                    label = translationContants.comment();
159                }
160
161                // Add into the view
162                verticalPanel.add(new Label(label));
163            } else {
164                for (AnnotationDefinition annotationDef : annotationDefs) {
165                    listBox.addItem(annotationDef.getName());
166                }
167
168                // Add into the view
169                verticalPanel.add(listBox);
170            }
171
172        }
173
174        TranslationConstants translationContants = GWT.create(TranslationConstants.class);
175        submit = new Button(translationContants.submit());
176        submit.setEnabled(false);
177        flowPanel.add(submit);
178        cancel = new Button(translationContants.cancel());
179        flowPanel.add(cancel);
180        submit.addClickListener(new CommitListener(element, annotationName));
181
182        cancel.addClickListener(new ClickListener() {
183            public void onClick(Widget sender) {
184                cancel();
185            }
186        });
187
188        this.add(dockPanel);
189    }
190
191    public void cancel() {
192        if (removeOnCancel) {
193            element.getParentElement().removeChild(element);
194        }
195        controller.setCancelNewAnnotation();
196        controller.removeSelectedTextDecoration();
197        hide();
198    }
199
200    @Override
201    public void show() {
202        Log.debug("popup.show: " + Window.getScrollTop() + 50);
203        setPopupPosition(50 + Window.getScrollLeft(), Window.getScrollTop() + 50);
204        controller.openCreationPopup();
205        super.show();
206    }
207
208    @Override
209    public void hide() {
210        controller.closeCreationPopup();
211        super.hide();
212    }
213
214    @Override
215    public void onLoad() {
216        super.onLoad();
217        annotationTextArea.setFocus(true);
218    }
219
220    private String getType() {
221        if (selectedAnnotationType != null) {
222            return selectedAnnotationType;
223        } else {
224            return listBox.getItemText(listBox.getSelectedIndex());
225        }
226
227    }
228
229    private class CommitListener implements ClickListener {
230
231        public final Element element;
232
233        public CommitListener(Element element, String annotationName) {
234            this.element = element;
235        }
236
237        public void onClick(Widget sender) {
238            String text = annotationTextArea.getText();
239            if (text.length() > AnnotationConstant.MAX_ANNOTATION_TEXT_LENGTH) {
240                Window.alert("Your annotation must not exceed " + AnnotationConstant.MAX_ANNOTATION_TEXT_LENGTH
241                        + " characters long.");
242                return;
243            }
244            Annotation annotation = controller.getNewAnnotation();
245
246            annotation.setBody(text);
247            annotation.setType(getType());
248
249            for (ListBox fieldListBox : fieldListBoxes) {
250                annotation.getFields().put(fieldListBox.getName(),
251                        fieldListBox.getItemText(fieldListBox.getSelectedIndex()));
252            }
253
254            if (XPointerFactory.isImageRange(annotation.getXpointer().getXpointerString())) {
255                if (element != null) {
256                    element.getParentNode().removeChild(element);
257                }
258            }
259
260            controller.removeSelectedTextDecoration();
261            controller.submitNewAnnotation();
262            hide();
263        }
264    }
265
266}