All Downloads are FREE. Search and download functionalities are using the official Maven repository.

eu.future.earth.gwt.client.date.month.MonthPanel Maven / Gradle / Ivy

There is a newer version: 3.3
Show newest version
/*
 * Copyright 2007 Future Earth, [email protected]
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package eu.future.earth.gwt.client.date.month;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.user.client.ui.DockLayoutPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.RequiresResize;
import com.google.gwt.user.client.ui.ResizeComposite;
import com.google.gwt.user.client.ui.RootPanel;

import eu.future.earth.gwt.client.FtrGwtDateCss;
import eu.future.earth.gwt.client.date.DateEvent;
import eu.future.earth.gwt.client.date.DateEvent.DateEventActions;
import eu.future.earth.gwt.client.date.DateEventListener;
import eu.future.earth.gwt.client.date.DatePanel;
import eu.future.earth.gwt.client.date.DateRenderer;
import eu.future.earth.gwt.client.date.DateUtils;
import eu.future.earth.gwt.client.date.EventPanel;
import eu.future.earth.gwt.client.date.HasDateEventHandlers;
import eu.future.earth.gwt.client.date.PanelFactory;
import eu.future.earth.gwt.client.date.PanelType;

public class MonthPanel extends ResizeComposite implements RequiresResize, DateEventListener, DatePanel, HasDateEventHandlers {

	private ArrayList> dropControllers = new ArrayList>();

	private Calendar current = new GregorianCalendar();

	private Calendar helperCal = new GregorianCalendar(); // NOPMD;

	private DockLayoutPanel main = new DockLayoutPanel(Unit.PX);

	private DockLayoutPanel days = new DockLayoutPanel(Unit.PCT);

	private DockLayoutPanel center = new DockLayoutPanel(Unit.PCT);

	// private Grid monthPanels = new Grid(7, 7);

	private List> panels = new ArrayList>();

	private List registrations = new ArrayList();

	public int getFirstDayOfWeek() {
		return firstDayOfWeek;
	}

	public void setFirstDayOfWeek(int newFirstDayOfWeek) {
		if (firstDayOfWeek == newFirstDayOfWeek) {
			return;
		}
		this.firstDayOfWeek = newFirstDayOfWeek;
		current.setFirstDayOfWeek(firstDayOfWeek);
		buildPanel();
	}

	private int firstDayOfWeek = Calendar.MONDAY;

	private MonthPanelDragController dragController = null;

	private DateRenderer renderer = null;

	public MonthPanel(DateRenderer newRenderer) {
		super();
		initWidget(main);
		main.addNorth(days, 20);
		main.add(center);
		setRenderer(newRenderer);
		final DateTimeFormat dayFormatter = DateTimeFormat.getFormat("E");
		int wide = 100 / 7;
		for (int i = firstDayOfWeek; i < 7 + firstDayOfWeek; i++) {
			helperCal.set(Calendar.DAY_OF_WEEK, i);
			if (i == ((7 + firstDayOfWeek) - 1)) {
				days.add(new HTML(dayFormatter.format(helperCal.getTime())));
			} else {
				days.addWest(new HTML(dayFormatter.format(helperCal.getTime())), wide);
			}
		}
		setStyleName(FtrGwtDateCss.MONTH_PANEL);
		main.setStyleName(FtrGwtDateCss.MONTH_PANEL);
	}

	public final void setRenderer(DateRenderer newRenderer) {
		renderer = newRenderer;
		if (renderer.enableDragAndDrop()) {
			if (dragController != null) {
				for (int i = 0; i < dropControllers.size(); i++) {
					final MonthPanelDropController real = dropControllers.get(i);
					dragController.unregisterDropController(real);
				}
			}
			dragController = new MonthPanelDragController(RootPanel.get());
		}
		buildPanel();
	}

	public void setDate(Date newDate) {
		if (DateUtils.isSameDay(current.getTime(), newDate)) {
			return;
		}
		current.setTime(newDate);
		buildPanel();
	}

	private Date firstShow = null;

	private Date lastShow = null;

	private Date firstLogical = null;

	private Date lastLogical = null;

	public void buildPanel() {
		if (renderer.enableDragAndDrop()) {
			for (int i = 0; i < dropControllers.size(); i++) {
				final MonthPanelDropController real = dropControllers.get(i);
				dragController.unregisterDropController(real);
			}
			dropControllers.clear();
		}

		for (HandlerRegistration registration : registrations) {
			registration.removeHandler();
		}

		registrations.clear();
		center.clear();
		helperCal.setFirstDayOfWeek(firstDayOfWeek);
		final Calendar today = new GregorianCalendar();
		
		// set logical first day of the month
		helperCal.setTime(current.getTime());
		helperCal.set(Calendar.DAY_OF_MONTH, 1);
		helperCal.set(Calendar.HOUR_OF_DAY, 0);
		helperCal.set(Calendar.MINUTE, 0);
		helperCal.set(Calendar.SECOND, 0);
		helperCal.set(Calendar.MILLISECOND, 0);
		firstLogical = helperCal.getTime();
		// set logical last day of the month
		helperCal.add(Calendar.MONTH, 1);
		helperCal.add(Calendar.MILLISECOND, -1);
		lastLogical = helperCal.getTime();
		// now loop over full weeks for showing days
		helperCal.setTime(current.getTime());
		helperCal.add(Calendar.DAY_OF_MONTH, -(helperCal.get(Calendar.DAY_OF_MONTH)));
		while (helperCal.get(Calendar.DAY_OF_WEEK) != helperCal.getFirstDayOfWeek()) {
			helperCal.add(Calendar.DAY_OF_MONTH, -1);
		}
		panels.clear();
		firstShow = helperCal.getTime();
		double prc6 = 100/6;
		double prc7 = 100/7;
		for (int y = 1; y < 7; y++) {

			DockLayoutPanel row = new DockLayoutPanel(Unit.PCT);
			if (y == 6) {
				center.add(row);
			} else {
				center.addNorth(row, prc6);
			}
			for (int x = 0; x < 7; x++) {
				final MonthPanelDayPanel result = makeDayPanel(helperCal);
				panels.add(result);
				registrations.add(result.addDateEventHandler(this));
				if (DateUtils.isSameDay(today, helperCal)) {
					result.addStyleName(FtrGwtDateCss.DATE_DAY_TODAY);
				}
				if (x == 6) {
					row.add(result);
				} else {
					row.addWest(result, prc7);
				}
				if (renderer.enableDragAndDrop() && dragController != null) {
					final MonthPanelDropController dropController = new MonthPanelDropController(result);
					dropControllers.add(dropController);
					dragController.registerDropController(dropController);
				}
				helperCal.add(Calendar.DAY_OF_MONTH, 1);
			}
		}
		lastShow = helperCal.getTime();
	}

	private MonthPanelDayPanel makeDayPanel(Calendar calender) {
		return new MonthPanelDayPanel(calender.get(Calendar.DAY_OF_MONTH), calender.getTime(), this, renderer);
	}

	@SuppressWarnings("unchecked")
	public void addEventData(T newEvent) {
		for (MonthPanelDayPanel result : panels) {
			if (result.isDay(newEvent)) {
				final EventPanel entry = (EventPanel) renderer.createPanel(newEvent, getType());
				if (dragController != null && entry.isDraggable()) {
					dragController.makeDraggable(entry, entry.getDraggableItem());
				}
				entry.addParentDateEventHandler(this);
				result.addEvent(entry);
			}
		}
	}

	public void notifyReady(DateEventActions action, T data, boolean reload) {
		if (reload) {
			loadData();
		}
		switch (action) {
		case ADD_DONE: {
			addEventData(data);
			break;
		}
		case REMOVE_DONE: {
			removeEventData(data);
			break;
		}
		case UPDATE_DONE: {
			updateEventData(data);
			break;
		}
		default:
			break;
		}
		DateEvent.fire(this, action, data);
	}

	public void loadData() {
		clearData();
		renderer.getEventsForRange(getFirstDateShow(), getLastDateShow(), this, true);
	}

	public void handleDateEvent(DateEvent newEvent) {
		switch (newEvent.getCommand()) {
		case DRAG_DROP: {
			renderer.updateEvent(renderer.createUpdateHandler(this, newEvent.getData()));
			break;
		}
		case UPDATE: {
			renderer.updateEvent(renderer.createUpdateHandler(this, newEvent.getData()));
			break;
		}
		case REMOVE: {
			renderer.removeEvent(renderer.createRemoveHandler(this, newEvent.getData()));
			break;
		}
		case ADD: {
			renderer.addEvent(renderer.createAddHandler(this, newEvent.getData()));
			break;
		}
		case ADD_DONE: {
			addEventData(newEvent.getData());
			DateEvent.fire(this, newEvent.getDate(), newEvent.getCommand(), newEvent.getData());
			break;
		}
		case REMOVE_DONE: {
			removeEventData(newEvent.getData());
			DateEvent.fire(this, newEvent.getDate(), newEvent.getCommand(), newEvent.getData());
			break;
		}
		case UPDATE_DONE: {
			updateEventData(newEvent.getData());
			DateEvent.fire(this, newEvent.getDate(), newEvent.getCommand(), newEvent.getData());
			break;
		}
		case EDIT: {
			renderer.editAfterClick(newEvent.getData(), this);
			break;
		}
		case RELOAD: {
			loadData();
			DateEvent.fire(this, newEvent.getDate(), newEvent.getCommand(), newEvent.getData());
			break;
		}
		default:
			DateEvent.fire(this, newEvent.getDate(), newEvent.getCommand(), newEvent.getData());
			break;
		}
	}

	public HandlerRegistration addDateEventHandler(DateEventListener handler) {
		return addHandler(handler, DateEvent.getType());
	}

	public DateRenderer getRenderer() {
		return renderer;
	}

	public Date next() {
		current.add(Calendar.MONTH, 1);
		buildPanel();
		return current.getTime();
	}

	public Date prev() {
		current.add(Calendar.MONTH, -1);
		buildPanel();
		return current.getTime();
	}

	public Date nextMore() {
		current.add(Calendar.YEAR, 1);
		buildPanel();
		return current.getTime();
	}

	public Date prevMore() {
		current.add(Calendar.YEAR, -1);
		buildPanel();
		return current.getTime();
	}

	public void updateEventData(T newEvent) {
		removeEventData(newEvent);
		addEventData(newEvent);
	}

	public void removeEventData(T newEvent) {
		for (MonthPanelDayPanel result : panels) {
			EventPanel removed = result.removeEvent(newEvent);
			if (removed != null) {
				removed.clearParent();
				return;
			}
		}
	}

	public Date getFirstDateShow() {
		return firstShow;
	}

	public Date getLastDateShow() {
		return lastShow;
	}

	public Date getFirstDateLogical() {
		return firstLogical;
	}

	public Date getLastDateLogical() {
		return lastLogical;
	}

	public void clearData() {
		for (MonthPanelDayPanel result : panels) {
			result.clearEvents();
		}
	}

	public PanelType getType() {
		return PanelType.MONTH;
	}

	public void setEvents(List events) {
		clearData();
		addEventsByList(events);
	}

	public void addEventsByList(List events) {
		if (events != null) {
			for (int i = 0; i < events.size(); i++) {
				addEventData(events.get(i));
			}
		}
	}

	public static class Factory implements PanelFactory {

		public DatePanel createDatePanel(DateRenderer renderer) {
			return new MonthPanel(renderer);
		}

		//Writing equals and hashCode methods such that various instances would appear as the same instance.
		//Singleton could not be used due to use of generics.
		public boolean equals(Object obj) {
			return obj != null && getClass().equals( obj.getClass() );
		}

		public int hashCode() {
			return getClass().hashCode();
		}
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy