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