org.activityinfo.ui.client.page.report.editor.ElementWidget.java Source code

Java tutorial

Introduction

Here is the source code for org.activityinfo.ui.client.page.report.editor.ElementWidget.java

Source

package org.activityinfo.ui.client.page.report.editor;

/*
 * #%L
 * ActivityInfo Server
 * %%
 * Copyright (C) 2009 - 2013 UNICEF
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as
 * published by the Free Software Foundation, either version 3 of the 
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public 
 * License along with this program.  If not, see
 * <http://www.gnu.org/licenses/gpl-3.0.html>.
 * #L%
 */

import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.MessageBoxEvent;
import com.extjs.gxt.ui.client.widget.Dialog;
import com.extjs.gxt.ui.client.widget.MessageBox;
import com.extjs.gxt.ui.client.widget.MessageBox.MessageBoxType;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.DivElement;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.SpanElement;
import com.google.gwt.dom.client.Style.Display;
import com.google.gwt.dom.client.Style.Visibility;
import com.google.gwt.resources.client.CssResource;
import com.google.gwt.safehtml.shared.SafeHtmlUtils;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.inject.Inject;
import com.google.inject.Provider;
import org.activityinfo.i18n.shared.I18N;
import org.activityinfo.legacy.client.Dispatcher;
import org.activityinfo.legacy.shared.command.GenerateElement;
import org.activityinfo.legacy.shared.command.RenderReportHtml;
import org.activityinfo.legacy.shared.command.result.HtmlResult;
import org.activityinfo.legacy.shared.reports.content.Content;
import org.activityinfo.legacy.shared.reports.model.PivotChartReportElement;
import org.activityinfo.legacy.shared.reports.model.ReportElement;
import org.activityinfo.legacy.shared.reports.model.TextReportElement;
import org.activityinfo.ui.client.component.report.view.ChartOFCView;
import org.activityinfo.ui.client.page.report.editor.ElementDialog.Callback;

public class ElementWidget extends Composite {

    private static ElementWidgetUiBinder uiBinder = GWT.create(ElementWidgetUiBinder.class);

    interface ElementWidgetUiBinder extends UiBinder<Widget, ElementWidget> {
    }

    interface EventHandler {
        void onElementRemoveClicked(ElementWidget widget);

        void onElementChanged(ElementWidget widget);
    }

    interface MyStyle extends CssResource {
        String title();

        String container();

        String editButton();

        String removeButton();

        String blockHover();
    }

    @UiField
    HTMLPanel htmlPanel;

    @UiField
    MyStyle style;

    @UiField
    SpanElement titleElement;
    @UiField
    SpanElement titleChangeElement;
    @UiField
    DivElement buttonElement;
    @UiField
    DivElement contentElement;
    @UiField
    DivElement contentContainerElement;
    @UiField
    DivElement loadingElement;

    private ReportElement model;

    private Dispatcher dispatcher;
    private Provider<ElementDialog> dialogProvider;

    private EventHandler parent;

    @Inject
    public ElementWidget(Dispatcher dispatcher, Provider<ElementDialog> dialogProvider) {
        this.dispatcher = dispatcher;
        this.dialogProvider = dialogProvider;

        initWidget(uiBinder.createAndBindUi(this));

        sinkEvents(Event.MOUSEEVENTS | Event.ONCLICK);
    }

    public void bindHandler(EventHandler handler) {
        this.parent = handler;
    }

    public void bind(ReportElement model) {
        this.model = model;
        titleElement.setInnerText(ElementTitles.format(model));
        // for now, preview html is rendered server side,
        // except for charts which we can't due to appthengine
        // limitations with text rendering. Thats' fine because we
        // want to do everything client side eventually anyway
        if (model instanceof PivotChartReportElement) {
            loadView();
        } else {
            loadHtml();
        }
    }

    private void loadView() {
        dispatcher.execute(new GenerateElement<Content>(model), new AsyncCallback<Content>() {

            @Override
            public void onFailure(Throwable caught) {
                // TODO
            }

            @Override
            public void onSuccess(Content result) {
                model.setContent(result);
                ChartOFCView view = new ChartOFCView();
                view.setHeight(256);
                view.setBorders(false);
                view.show((PivotChartReportElement) model);
                loadingElement.getStyle().setDisplay(Display.NONE);
                htmlPanel.add(view, contentElement);
            }
        });
    }

    public ReportElement getModel() {
        return model;
    }

    private void loadHtml() {

        contentElement.setInnerHTML("");
        loadingElement.getStyle().setDisplay(Display.BLOCK);
        if (model instanceof TextReportElement) {
            renderStaticHtml();
        } else {
            dispatcher.execute(new RenderReportHtml(model), new AsyncCallback<HtmlResult>() {

                @Override
                public void onFailure(Throwable caught) {
                    // TODO Auto-generated method stub

                }

                @Override
                public void onSuccess(HtmlResult result) {
                    updateHtml(result.getHtml());
                }
            });
        }
    }

    private void renderStaticHtml() {
        String text = ((TextReportElement) model).getText();
        updateHtml(text != null ? SafeHtmlUtils.htmlEscape(text) : "");
    }

    private void updateHtml(String html) {
        loadingElement.getStyle().setDisplay(Display.NONE);
        contentElement.setInnerHTML(html);
    }

    @Override
    public void onBrowserEvent(Event event) {
        Element clicked = event.getEventTarget().cast();
        if (event.getTypeInt() == Event.ONCLICK) {
            if (titleChangeElement.isOrHasChild(clicked)) {
                editTitle();
            } else if (clicked.getClassName().contains(style.editButton())) {
                edit();
            } else if (clicked.getClassName().contains(style.removeButton())) {
                parent.onElementRemoveClicked(this);
            } else if (contentElement.isOrHasChild(clicked)) {
                edit();
            }

        } else if (event.getTypeInt() == Event.ONMOUSEOVER) {
            buttonElement.getStyle().setVisibility(Visibility.VISIBLE);
            titleChangeElement.getStyle().setVisibility(Visibility.VISIBLE);
            contentContainerElement.addClassName(style.blockHover());
        } else if (event.getTypeInt() == Event.ONMOUSEOUT) {
            buttonElement.getStyle().setVisibility(Visibility.HIDDEN);
            titleChangeElement.getStyle().setVisibility(Visibility.HIDDEN);
            contentContainerElement.removeClassName(style.blockHover());
        }
    }

    private void editTitle() {
        final MessageBox box = new MessageBox();
        box.setTitleHtml(SafeHtmlUtils.htmlEscape(I18N.CONSTANTS.changeTitleDialogTitle()));
        box.setType(MessageBoxType.PROMPT);
        box.setButtons(Dialog.OKCANCEL);
        box.show();
        box.getTextBox().setValue(model.getTitle());
        box.addCallback(new Listener<MessageBoxEvent>() {

            @Override
            public void handleEvent(MessageBoxEvent be) {
                if (be.getButtonClicked().getItemId().equals(Dialog.OK)) {
                    model.setTitle(box.getTextBox().getValue());
                    titleElement.setInnerText(ElementTitles.format(model));
                }
            }
        });
    }

    private void edit() {
        ElementDialog dialog = dialogProvider.get();
        dialog.hideCancel();
        dialog.show(model, new Callback() {

            @Override
            public void onOK(boolean dirty) {
                onElementUpdated();
            }

            @Override
            public void onClose(boolean dirty) {
                onElementUpdated();
            }
        });
    }

    private void onElementUpdated() {
        loadHtml();
        parent.onElementChanged(ElementWidget.this);
    }
}