///////////////////////////////////////////////////////////////////////////// // // Project ProjectForge Community Edition // www.projectforge.org // // Copyright (C) 2001-2014 Kai Reinhard (k.reinhard@micromata.de) // // ProjectForge is dual-licensed. // // This community edition 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; version 3 of the License. // // This community edition 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/. // ///////////////////////////////////////////////////////////////////////////// package org.projectforge.plugins.teamcal.integration; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import org.projectforge.user.PFUserContext; import org.projectforge.web.calendar.AbstractCalendarFilter; /** * @author Johannes Unterstein (j.unterstein@micromata.de) * @author M. Lauterbach (m.lauterbach@micromata.de) * */ public class TeamCalCalendarFilter extends AbstractCalendarFilter { private static final long serialVersionUID = 7361308619781209753L; private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(TeamCalCalendarFilter.class); static final String DEFAULT_COLOR = "#FAAF26"; private static final Set<Integer> EMPTY_INT_SET = new HashSet<Integer>(); private final List<TemplateEntry> templateEntries; private int activeTemplateEntryIndex = 0; private transient TemplateEntry activeTemplateEntry = null; public TeamCalCalendarFilter() { super(); templateEntries = new ArrayList<TemplateEntry>(); } /** * Try to find a previous used color for the given calendar in any entry of this filter. If found multiple ones, the newest one is used. * @param calId Id of the calendar to search for. * @return Previous used color for the given calendar or DEFAULT_COLOR if not found. */ public String getUsedColor(final Integer calId) { String lastCalendarColor = null; String lastColor = DEFAULT_COLOR; long lastCalendarEntry = 0; long lastEntry = 0; if (calId == null) { return lastCalendarColor; } // intelligent color choose for (final TemplateEntry entry : templateEntries) { for (final TemplateCalendarProperties props : entry.getCalendarProperties()) { if (calId.equals(props.getCalId()) == true) { if (props.getMillisOfLastChange() > lastCalendarEntry) { lastCalendarEntry = props.getMillisOfLastChange(); lastCalendarColor = props.getColorCode(); } } if (props.getMillisOfLastChange() > lastEntry) { lastEntry = props.getMillisOfLastChange(); lastColor = props.getColorCode(); } } } return lastCalendarColor != null ? lastCalendarColor : lastColor; } /** * @return the templateEntries */ public List<TemplateEntry> getTemplateEntries() { if (templateEntries.size() == 0) { createDefaultEntry(); } return templateEntries; } /** * Adds new entry and sets the new entry as active entry. * @param entry */ public void add(final TemplateEntry entry) { synchronized (templateEntries) { templateEntries.add(entry); sort(); setActiveTemplateEntry(entry); } } public void remove(final TemplateEntry entry) { synchronized (templateEntries) { final int index = templateEntries.indexOf(entry); templateEntries.remove(entry); if (index == activeTemplateEntryIndex) { activeTemplateEntryIndex = 0; } if (templateEntries.size() == 0) { createDefaultEntry(); } } activeTemplateEntry = null; } public void sort() { Collections.sort(templateEntries); } /** * @return the activeTemplateEntryIndex */ public int getActiveTemplateEntryIndex() { return activeTemplateEntryIndex; } /** * @param activeTemplateEntryIndex the activeTemplateEntryIndex to set * @return this for chaining. */ public TeamCalCalendarFilter setActiveTemplateEntryIndex(final int activeTemplateEntryIndex) { this.activeTemplateEntryIndex = activeTemplateEntryIndex; // Force to get active template entry by new index: this.activeTemplateEntry = null; return this; } /** * @return the activeTemplateEntry */ public TemplateEntry getActiveTemplateEntry() { if (this.activeTemplateEntry == null) { if (this.activeTemplateEntryIndex >= 0 && this.activeTemplateEntryIndex < this.templateEntries.size()) { this.activeTemplateEntry = this.templateEntries.get(this.activeTemplateEntryIndex); this.activeTemplateEntry.setDirty(); } else { // No filter entry given, create the standard filter: createDefaultEntry(); } } return this.activeTemplateEntry; } /** * @param activeTemplateEntry the activeTemplateEntry to set * @return this for chaining. */ public TeamCalCalendarFilter setActiveTemplateEntry(final TemplateEntry activeTemplateEntry) { int i = 0; for (final TemplateEntry entry : this.templateEntries) { if (entry.equals(activeTemplateEntry) == true) { this.activeTemplateEntryIndex = i; this.activeTemplateEntry = entry; this.activeTemplateEntry.setDirty(); break; } i++; } return this; } public Set<Integer> getActiveVisibleCalendarIds() { if (getActiveTemplateEntry() != null) { return this.activeTemplateEntry.getVisibleCalendarIds(); } else { if (EMPTY_INT_SET.isEmpty() == false) { log.error("************** Oups, dear developers, don't add entries to the empty HashSet returned by this method!!!!"); EMPTY_INT_SET.clear(); } return EMPTY_INT_SET; } } /** * Copies all template entries (active template and list) of the given source to this. This method is used to make a backup copy for * undoing changes in TeamCalDialog. * @param src */ public TeamCalCalendarFilter copyValuesFrom(final TeamCalCalendarFilter src) { if (src == null) { return this; } this.templateEntries.clear(); for (final TemplateEntry srcEntry : src.templateEntries) { final TemplateEntry entry = srcEntry.clone(); this.templateEntries.add(entry); } this.activeTemplateEntryIndex = src.activeTemplateEntryIndex; this.activeTemplateEntry = null; return this; } /** * For avoiding reload of Calendar if no changes are detected. (Was für'n Aufwand für so'n kleines Feature...) * @param other * @return */ public boolean isModified(final TeamCalCalendarFilter other) { if (other == null) { return false; } if (this.activeTemplateEntryIndex != other.activeTemplateEntryIndex) { return true; } if (templateEntries.size() != other.templateEntries.size()) { return true; } final Iterator<TemplateEntry> it1 = this.templateEntries.iterator(); final Iterator<TemplateEntry> it2 = other.templateEntries.iterator(); while (it1.hasNext() == true) { final TemplateEntry entry1 = it1.next(); final TemplateEntry entry2 = it2.next(); if (entry1.isModified(entry2) == true) { return true; } } return false; } public String getNewTemplateName(final String prefix) { if (templateEntries == null) { return prefix; } String current = prefix; for (int i = 1; i <= 10; i++) { for (final TemplateEntry entry : templateEntries) { if (current.equals(entry.getName()) == true) { if (i == 10) { // Don't try to get prefix + " 11", giving up: return null; } current = prefix + " " + i; break; } } } return current; } private void createDefaultEntry() { final TemplateEntry newTemplate = new TemplateEntry(); newTemplate.setName(PFUserContext.getLocalizedString("default")); newTemplate.setTimesheetUserId(PFUserContext.getUserId()).setShowBirthdays(true).setShowBreaks(true).setShowPlanning(true) .setShowStatistics(true); add(newTemplate); } /** * @see org.projectforge.web.calendar.ICalendarFilter#isShowBirthdays() */ @Override public boolean isShowBirthdays() { if (getActiveTemplateEntry() == null) { return false; } return activeTemplateEntry.isShowBirthdays(); } /** * @see org.projectforge.web.calendar.ICalendarFilter#setShowBirthdays(boolean) */ @Override public TeamCalCalendarFilter setShowBirthdays(final boolean showBirthdays) { if (getActiveTemplateEntry() != null) { activeTemplateEntry.setShowBirthdays(showBirthdays); } return this; } /** * @see org.projectforge.web.calendar.ICalendarFilter#isShowStatistics() */ @Override public boolean isShowStatistics() { if (getActiveTemplateEntry() == null) { return false; } return activeTemplateEntry.isShowStatistics(); } /** * @see org.projectforge.web.calendar.ICalendarFilter#setShowStatistics(boolean) */ @Override public TeamCalCalendarFilter setShowStatistics(final boolean showStatistics) { if (getActiveTemplateEntry() != null) { activeTemplateEntry.setShowStatistics(showStatistics); } return this; } /** * @see org.projectforge.web.calendar.ICalendarFilter#isShowPlanning() */ @Override public boolean isShowPlanning() { if (getActiveTemplateEntry() == null) { return false; } return activeTemplateEntry.isShowPlanning(); } /** * @see org.projectforge.web.calendar.ICalendarFilter#setShowPlanning(boolean) */ @Override public TeamCalCalendarFilter setShowPlanning(final boolean showPlanning) { if (getActiveTemplateEntry() != null) { activeTemplateEntry.setShowPlanning(showPlanning); } return this; } /** * @see org.projectforge.web.calendar.ICalendarFilter#getTimesheetUserId() */ @Override public Integer getTimesheetUserId() { if (getActiveTemplateEntry() == null) { return null; } return activeTemplateEntry.getTimesheetUserId(); } /** * @see org.projectforge.web.calendar.ICalendarFilter#setTimesheetUserId(java.lang.Integer) */ @Override public TeamCalCalendarFilter setTimesheetUserId(final Integer timesheetUserId) { if (getActiveTemplateEntry() != null) { activeTemplateEntry.setTimesheetUserId(timesheetUserId); } return this; } /** * @see org.projectforge.web.calendar.ICalendarFilter#isShowTimesheets() */ @Override public boolean isShowTimesheets() { if (getActiveTemplateEntry() == null) { return false; } return activeTemplateEntry.isShowTimesheets(); } /** * @see org.projectforge.web.calendar.ICalendarFilter#setShowTimesheets(boolean) */ @Override public TeamCalCalendarFilter setShowTimesheets(final boolean showTimesheets) { if (getActiveTemplateEntry() != null) { activeTemplateEntry.setShowTimesheets(showTimesheets); } return this; } /** * @see org.projectforge.web.calendar.ICalendarFilter#isShowBreaks() */ @Override public boolean isShowBreaks() { if (getActiveTemplateEntry() == null) { return false; } return activeTemplateEntry.isShowBreaks(); } /** * @see org.projectforge.web.calendar.ICalendarFilter#setShowBreaks(boolean) */ @Override public TeamCalCalendarFilter setShowBreaks(final boolean showBreaks) { if (getActiveTemplateEntry() != null) { activeTemplateEntry.setShowBreaks(showBreaks); } return this; } /** * @see org.projectforge.web.calendar.ICalendarFilter#getSelectedCalendar() */ @Override public String getSelectedCalendar() { if (getActiveTemplateEntry() == null) { return null; } return activeTemplateEntry.getSelectedCalendar(); } /** * @see org.projectforge.web.calendar.ICalendarFilter#setSelectedCalendar(java.lang.String) */ @Override public TeamCalCalendarFilter setSelectedCalendar(final String selectedCalendar) { if (getActiveTemplateEntry() != null) { activeTemplateEntry.setSelectedCalendar(selectedCalendar); } return this; } }