/* * * Copyright (C) 2007-2015 Licensed to the Comunes Association (CA) under * one or more contributor license agreements (see COPYRIGHT for details). * The CA licenses this file to you under the GNU Affero General Public * License version 3, (the "License"); you may not use this file except in * compliance with the License. This file is part of kune. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * */ package cc.kune.events.client.viewer; import java.util.Date; import java.util.HashMap; import java.util.Map; import javax.annotation.Nonnull; import cc.kune.common.client.actions.ui.descrip.Position; import cc.kune.common.client.log.Log; import cc.kune.common.client.notify.NotifyUser; import cc.kune.common.client.utils.DateUtils; import cc.kune.common.shared.i18n.I18nTranslationService; import cc.kune.common.shared.res.ICalConstants; import cc.kune.common.shared.utils.TextUtils; import cc.kune.core.client.rpcservices.ContentServiceAsync; import cc.kune.core.client.state.Session; import cc.kune.core.shared.domain.utils.StateToken; import cc.kune.core.shared.dto.HasContent; import cc.kune.core.shared.dto.StateEventContainerDTO; import cc.kune.events.client.actions.CalendarOnOverMenu; import cc.kune.events.shared.EventsClientConversionUtil; import cc.kune.events.shared.EventsToolConstants; import cc.kune.gspace.client.viewers.AbstractFolderViewerView; import cc.kune.gspace.client.viewers.FolderViewerUtils; import com.bradrydzewski.gwt.calendar.client.Appointment; import com.bradrydzewski.gwt.calendar.client.AppointmentStyle; import com.bradrydzewski.gwt.calendar.client.CalendarViews; import com.bradrydzewski.gwt.calendar.client.HasAppointments; import com.bradrydzewski.gwt.calendar.client.HasLayout; import com.bradrydzewski.gwt.calendar.client.event.CreateHandler; import com.bradrydzewski.gwt.calendar.client.event.DeleteEvent; import com.bradrydzewski.gwt.calendar.client.event.DeleteHandler; import com.bradrydzewski.gwt.calendar.client.event.HasDateRequestHandlers; import com.bradrydzewski.gwt.calendar.client.event.HasDeleteHandlers; import com.bradrydzewski.gwt.calendar.client.event.HasMouseOverHandlers; import com.bradrydzewski.gwt.calendar.client.event.HasTimeBlockClickHandlers; import com.bradrydzewski.gwt.calendar.client.event.HasUpdateHandlers; import com.bradrydzewski.gwt.calendar.client.event.MouseOverEvent; import com.bradrydzewski.gwt.calendar.client.event.MouseOverHandler; import com.bradrydzewski.gwt.calendar.client.event.TimeBlockClickEvent; import com.bradrydzewski.gwt.calendar.client.event.TimeBlockClickHandler; import com.bradrydzewski.gwt.calendar.client.event.UpdateEvent; import com.bradrydzewski.gwt.calendar.client.event.UpdateHandler; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.logical.shared.HasOpenHandlers; import com.google.gwt.event.logical.shared.HasSelectionHandlers; import com.google.gwt.event.logical.shared.OpenEvent; import com.google.gwt.event.logical.shared.OpenHandler; import com.google.gwt.event.logical.shared.SelectionEvent; import com.google.gwt.event.logical.shared.SelectionHandler; import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.datepicker.client.CalendarUtil; import com.google.inject.Inject; import com.google.inject.Provider; import com.google.web.bindery.event.shared.EventBus; import com.gwtplatform.mvp.client.Presenter; import com.gwtplatform.mvp.client.annotations.ProxyCodeSplit; import com.gwtplatform.mvp.client.proxy.Proxy; import com.gwtplatform.mvp.client.proxy.RevealRootContentEvent; // TODO: Auto-generated Javadoc /** * The Class CalendarViewerPresenter. * * @author vjrj@ourproject.org (Vicente J. Ruiz Jurado) */ public class CalendarViewerPresenter extends Presenter<CalendarViewerPresenter.CalendarViewerView, CalendarViewerPresenter.CalendarViewerProxy> implements CalendarViewer { /** * The Interface CalendarViewerProxy. * * @author vjrj@ourproject.org (Vicente J. Ruiz Jurado) */ @ProxyCodeSplit public interface CalendarViewerProxy extends Proxy<CalendarViewerPresenter> { } /** * The Interface CalendarViewerView. * * @author vjrj@ourproject.org (Vicente J. Ruiz Jurado) */ public interface CalendarViewerView extends HasSelectionHandlers<Appointment>, HasDeleteHandlers<Appointment>, HasOpenHandlers<Appointment>, HasTimeBlockClickHandlers<Date>, HasUpdateHandlers<Appointment>, HasDateRequestHandlers<Date>, HasMouseOverHandlers<Appointment>, HasLayout, HasAppointments, AbstractFolderViewerView { /* * (non-Javadoc) * * @see * com.bradrydzewski.gwt.calendar.client.HasAppointments#addAppointment( * com.bradrydzewski.gwt.calendar.client.Appointment) */ @Override void addAppointment(Appointment app); /** * Adds the click handler. * * @param clickHandler * the click handler * @return the handler registration */ HandlerRegistration addClickHandler(ClickHandler clickHandler); /** * Adds the create handler. * * @param handler * the handler * @return the handler registration */ HandlerRegistration addCreateHandler(CreateHandler<Appointment> handler); /** * Gets the client x. * * @return the client x */ int getClientX(); /** * Gets the client y. * * @return the client y */ int getClientY(); /** * Gets the current date. * * @return the current date */ Date getCurrentDate(); /** * Gets the date. * * @return the date */ Date getDate(); /** * Go today. */ void goToday(); /* * (non-Javadoc) * * @see * com.bradrydzewski.gwt.calendar.client.HasAppointments#removeAppointment * (com.bradrydzewski.gwt.calendar.client.Appointment) */ @Override void removeAppointment(Appointment app); /** * Sets the date. * * @param date * the new date */ void setDate(Date date); /** * Sets the on mouse over tooltip text. * * @param text * the new on mouse over tooltip text */ void setOnMouseOverTooltipText(String text); /** * Sets the view. * * @param view * the new view */ void setView(CalendarViews view); /** * Sets the view. * * @param view * the view * @param days * the days */ void setView(CalendarViews view, int days); /** * Update title. * * @param currentCalView * the current cal view */ void updateTitle(CalendarViews currentCalView); } /** The Constant DEF_VIEW. */ private static final CalendarViews DEF_VIEW = CalendarViews.DAY; /** The app to edit. */ public Appointment appToEdit = NO_APPOINT; /** The content service. */ private final Provider<ContentServiceAsync> contentService; /** The current cal view. */ private CalendarViews currentCalView; /** The current days view. */ private int currentDaysView = 7; /** The folder viewer utils. */ private final FolderViewerUtils folderViewerUtils; /** The i18n. */ private final I18nTranslationService i18n; /** The on over date. */ private Date onOverDate; /** The on over menu. */ private final CalendarOnOverMenu onOverMenu; /** The session. */ private final Session session; /** * Instantiates a new calendar viewer presenter. * * @param eventBus * the event bus * @param view * the view * @param proxy * the proxy * @param folderViewerUtils * the folder viewer utils * @param onOverMenu * the on over menu * @param session * the session * @param i18n * the i18n * @param contentService * the content service */ @Inject public CalendarViewerPresenter(final EventBus eventBus, final CalendarViewerView view, final CalendarViewerProxy proxy, final FolderViewerUtils folderViewerUtils, final CalendarOnOverMenu onOverMenu, final Session session, final I18nTranslationService i18n, final Provider<ContentServiceAsync> contentService) { super(eventBus, view, proxy); this.folderViewerUtils = folderViewerUtils; this.onOverMenu = onOverMenu; this.session = session; this.i18n = i18n; this.contentService = contentService; addListeners(); this.currentCalView = DEF_VIEW; // This is necessary? // setViewImpl(DEF_VIEW, currentDaysView); } /* * (non-Javadoc) * * @see * cc.kune.events.client.viewer.CalendarViewer#addAppointment(com.bradrydzewski * .gwt.calendar.client.Appointment) */ @Override public void addAppointment(final Appointment app) { getView().addAppointment(app); } /** * Adds the listeners. */ private void addListeners() { getView().setOnMouseOverTooltipText( i18n.t("Double click to open. Also you can resize or drag&drop this event")); getView().addDeleteHandler(new DeleteHandler<Appointment>() { @Override public void onDelete(final DeleteEvent<Appointment> event) { NotifyUser.info(i18n.t(TextUtils.IN_DEVELOPMENT)); event.setCancelled(true); } }); getView().addTimeBlockClickHandler(new TimeBlockClickHandler<Date>() { @Override public void onTimeBlockClick(final TimeBlockClickEvent<Date> event) { // NotifyUser.info("on time block"); appToEdit = NO_APPOINT; onOverDate = event.getTarget(); updateMenuItems(); showMenu(); } }); getView().addMouseOverHandler(new MouseOverHandler<Appointment>() { @Override public void onMouseOver(final MouseOverEvent<Appointment> event) { // NotifyUser.info("on mouse over " + } }); getView().addUpdateHandler(new UpdateHandler<Appointment>() { @Override public void onUpdate(final UpdateEvent<Appointment> event) { final boolean editable = session.getCurrentState().getGroupRights().isEditable(); if (!editable) { NotifyUser.error(i18n.t("Only members can update events")); } event.setCancelled(!editable); final Appointment app = event.getTarget(); final Map<String, String> map = new HashMap<String, String>(); map.put(ICalConstants.DATE_TIME_START, DateUtils.toString(app.getStart())); map.put(ICalConstants.DATE_TIME_END, DateUtils.toString(app.getEnd())); contentService.get().setGadgetProperties(session.getUserHash(), new StateToken(app.getId()), EventsToolConstants.TYPE_MEETING_DEF_GADGETNAME, map, new AsyncCallback<Void>() { @Override public void onFailure(final Throwable caught) { event.setCancelled(true); } @Override public void onSuccess(final Void result) { } }); hideMenu(); } }); getView().addOpenHandler(new OpenHandler<Appointment>() { @Override public void onOpen(final OpenEvent<Appointment> event) { // NotifyUser.info("open handler"); updateMenuItems(); showMenu(); } }); getView().addSelectionHandler(new SelectionHandler<Appointment>() { @Override public void onSelection(final SelectionEvent<Appointment> event) { appToEdit = event.getSelectedItem(); onOverDate = event.getSelectedItem().getStart(); // This is not very usable: // updateMenuItems(); // showMenu(); } }); } /* * (non-Javadoc) * * @see cc.kune.gspace.client.tool.ContentViewer#attach() */ @Override public void attach() { getView().attach(); updateTitle(); } /* * (non-Javadoc) * * @see cc.kune.events.client.viewer.CalendarViewer#decrement() */ @Override public void decrement() { incrementDate(false); } /* * (non-Javadoc) * * @see cc.kune.gspace.client.tool.ContentViewer#detach() */ @Override public void detach() { getView().detach(); } /* * (non-Javadoc) * * @see cc.kune.events.client.viewer.CalendarViewer#getAppToEdit() */ @Override public Appointment getAppToEdit() { return appToEdit; } /* * (non-Javadoc) * * @see cc.kune.events.client.viewer.CalendarViewer#getDate() */ @Override public Date getDate() { return getView().getDate(); } /* * (non-Javadoc) * * @see cc.kune.events.client.viewer.CalendarViewer#getOnOverDate() */ @Override public Date getOnOverDate() { return onOverDate; } /* * (non-Javadoc) * * @see cc.kune.events.client.viewer.CalendarViewer#goToday() */ @Override public void goToday() { getView().goToday(); updateTitle(); } /** * Hide menu. */ private void hideMenu() { onOverMenu.get().hide(); } /* * (non-Javadoc) * * @see cc.kune.events.client.viewer.CalendarViewer#increment() */ @Override public void increment() { incrementDate(true); } /** * Increment date. * * @param positive * the positive */ private void incrementDate(final boolean positive) { final Date date = getDate(); switch (currentCalView) { case DAY: case AGENDA: CalendarUtil.addDaysToDate(date, currentDaysView * (positive ? 1 : -1)); break; case MONTH: CalendarUtil.addMonthsToDate(date, (positive ? 1 : -1)); break; } setDate(date); updateTitle(); } /** * Checks if is valid. * * @param app * the app * @return true, if is valid */ private boolean isValid(final Appointment app) { return app.getStart() != null && app.getEnd() != null; } /* * (non-Javadoc) * * @see * cc.kune.events.client.viewer.CalendarViewer#removeAppointment(com.bradrydzewski * .gwt.calendar.client.Appointment) */ @Override public void removeAppointment(final Appointment app) { getView().removeAppointment(app); } /* * (non-Javadoc) * * @see com.gwtplatform.mvp.client.Presenter#revealInParent() */ @Override protected void revealInParent() { RevealRootContentEvent.fire(this, this); } /* * (non-Javadoc) * * @see * cc.kune.gspace.client.tool.ContentViewer#setContent(cc.kune.core.shared * .dto.HasContent) */ @Override public void setContent(@Nonnull final HasContent state) { setViewImpl(currentCalView, currentDaysView); folderViewerUtils.setContent(getView(), state); getView().showFolder(); final StateEventContainerDTO eventState = (StateEventContainerDTO) state; updateMenuItems(); getView().clearAppointments(); getView().suspendLayout(); for (final Map<String, String> map : eventState.getAppointments()) { Appointment app; try { app = EventsClientConversionUtil.toApp(map); app.setId(map.get(ICalConstants._INTERNAL_ID)); app.setStyle(AppointmentStyle.GREEN); if (isValid(app)) { getView().addAppointment(app); } else { Log.error("Appointment is not valid: " + app); } } catch (final Exception e) { Log.error("Appointment is not valid"); } } getView().resumeLayout(); } /* * (non-Javadoc) * * @see cc.kune.events.client.viewer.CalendarViewer#setDate(java.util.Date) */ @Override public void setDate(final Date date) { getView().setDate(date); } /** * Sets the menu position. * * @param x * the x * @param y * the y */ private void setMenuPosition(final int x, final int y) { onOverMenu.get().setMenuPosition(new Position(x, y)); } /* * (non-Javadoc) * * @see * cc.kune.events.client.viewer.CalendarViewer#setView(com.bradrydzewski.gwt * .calendar.client.CalendarViews) */ @Override public void setView(final CalendarViews calView) { setViewImpl(calView); } /* * (non-Javadoc) * * @see * cc.kune.events.client.viewer.CalendarViewer#setView(com.bradrydzewski.gwt * .calendar.client.CalendarViews, int) */ @Override public void setView(final CalendarViews calView, final int days) { setViewImpl(calView, days); } /** * Sets the view impl. * * @param calView * the new view impl */ private void setViewImpl(final CalendarViews calView) { this.currentCalView = calView; this.currentDaysView = 1; getView().setView(calView); updateTitle(); } /** * Sets the view impl. * * @param calView * the cal view * @param days * the days */ private void setViewImpl(final CalendarViews calView, final int days) { this.currentCalView = calView; this.currentDaysView = days; getView().setView(calView, days); updateTitle(); } /** * Show menu. */ private void showMenu() { setMenuPosition(getView().getClientX(), getView().getClientY()); onOverMenu.get().show(); } /** * Update menu items. */ private void updateMenuItems() { CalendarStateChangeEvent.fire(getEventBus()); } /** * Update title. */ private void updateTitle() { getView().updateTitle(currentCalView); } }