You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by jl...@apache.org on 2006/05/29 03:59:09 UTC

svn commit: r410011 [2/5] - in /myfaces/tomahawk/trunk: core/src/main/java/org/apache/myfaces/custom/schedule/ core/src/main/java/org/apache/myfaces/custom/schedule/model/ core/src/main/java/org/apache/myfaces/custom/schedule/renderer/ core/src/main/ja...

Added: myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/schedule/model/ScheduleDay.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/schedule/model/ScheduleDay.java?rev=410011&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/schedule/model/ScheduleDay.java (added)
+++ myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/schedule/model/ScheduleDay.java Sun May 28 18:59:05 2006
@@ -0,0 +1,156 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * 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 org.apache.myfaces.custom.schedule.model;
+
+
+import java.io.Serializable;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.Iterator;
+import java.util.TreeSet;
+
+import org.apache.myfaces.custom.schedule.util.ScheduleEntryComparator;
+
+
+/**
+ * <p>
+ * This class represents one day in the schedule component
+ * </p>
+ *
+ * @author Jurgen Lust (latest modification by $Author: werpu $)
+ * @version $Revision: 371736 $
+ */
+public class ScheduleDay
+    extends Day
+    implements Serializable, Comparable
+{
+    //~ Instance fields --------------------------------------------------------
+
+    /**
+     * serial id for serialisation versioning
+     */
+    private static final long serialVersionUID = 1L;
+    private final TreeSet entries;
+
+    //~ Constructors -----------------------------------------------------------
+
+    /**
+     * Creates a new ScheduleDay object.
+     *
+     * @param date the date
+     */
+    public ScheduleDay(Date date)
+    {
+        super(date);
+        this.entries = new TreeSet(new ScheduleEntryComparator());
+    }
+
+    //~ Methods ----------------------------------------------------------------
+
+    /**
+     * @return true if there are no schedule entries
+     */
+    public boolean isEmpty()
+    {
+        return entries.isEmpty();
+    }
+
+    /**
+     * <p>
+     * Add an entry to this day
+     * </p>
+     *
+     * @param entry the entry to add
+     *
+     * @return true if successful
+     */
+    public boolean addEntry(ScheduleEntry entry)
+    {
+        if (
+            (entry == null) || (entry.getStartTime() == null) ||
+                (entry.getEndTime() == null)
+        ) {
+            return false;
+        }
+
+        Calendar cal = GregorianCalendar.getInstance();
+        cal.setTime(entry.getEndTime());
+        cal.add(Calendar.DATE, 1);
+        cal.set(Calendar.HOUR_OF_DAY, 0);
+        cal.set(Calendar.MINUTE, 0);
+        cal.set(Calendar.SECOND, 0);
+        cal.set(Calendar.MILLISECOND, 0);
+
+        Date endDate = cal.getTime();
+        cal.setTime(entry.getStartTime());
+
+        while (cal.getTime().before(endDate)) {
+            if (equalsDate(cal.getTime())) {
+                entries.add(entry);
+
+                return true;
+            }
+
+            cal.add(Calendar.DATE, 1);
+        }
+
+        return false;
+    }
+
+    /**
+     * <p>
+     * Remove all entries from this day
+     * </p>
+     */
+    public void clear()
+    {
+        entries.clear();
+    }
+
+    /**
+     * @return an iterator for the schedule entries of this day
+     */
+    public Iterator iterator()
+    {
+        return entries.iterator();
+    }
+
+    /**
+     * <p>
+     * Remove an entry from this day
+     * </p>
+     *
+     * @param entry the entry to remove
+     *
+     * @return true if successful
+     */
+    public boolean remove(ScheduleEntry entry)
+    {
+        return entries.remove(entry);
+    }
+
+    /**
+     * @return the number of entries that are shown on this day
+     */
+    public int size()
+    {
+        return entries.size();
+    }
+}
+//The End

Added: myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/schedule/model/ScheduleEntry.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/schedule/model/ScheduleEntry.java?rev=410011&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/schedule/model/ScheduleEntry.java (added)
+++ myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/schedule/model/ScheduleEntry.java Sun May 28 18:59:05 2006
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * 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 org.apache.myfaces.custom.schedule.model;
+
+import java.util.Date;
+
+
+/**
+ * <p>
+ * A schedule entry is an appointment or event.
+ * </p>
+ *
+ * @author Jurgen Lust (latest modification by $Author: skitching $)
+ * @version $Revision: 349804 $
+ */
+public interface ScheduleEntry
+{
+    //~ Methods ----------------------------------------------------------------
+
+    /**
+     * @return Returns the description.
+     */
+    public abstract String getDescription();
+
+    /**
+     * @return Returns the endTime.
+     */
+    public abstract Date getEndTime();
+
+    /**
+     * @return Returns the id.
+     */
+    public abstract String getId();
+
+    /**
+     * @return Returns the startTime.
+     */
+    public abstract Date getStartTime();
+
+    /**
+     * @return Returns the subtitle.
+     */
+    public abstract String getSubtitle();
+
+    /**
+     * @return Returns the title.
+     */
+    public abstract String getTitle();
+}
+//The End

Added: myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/schedule/model/ScheduleModel.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/schedule/model/ScheduleModel.java?rev=410011&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/schedule/model/ScheduleModel.java (added)
+++ myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/schedule/model/ScheduleModel.java Sun May 28 18:59:05 2006
@@ -0,0 +1,141 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * 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 org.apache.myfaces.custom.schedule.model;
+
+import java.util.Date;
+import java.util.Iterator;
+
+
+/**
+ * <p>
+ * The underlying model of the UISchedule component. You should implement this
+ * interface when creating real implementations, which would typically be backed
+ * by a database.
+ * </p>
+ *
+ * @author Jurgen Lust (latest modification by $Author: schof $)
+ * @version $Revision: 368941 $
+ */
+public interface ScheduleModel
+{
+    //~ Static fields/initializers ---------------------------------------------
+
+    public static final int DAY = 0;
+    public static final int WORKWEEK = 1;
+    public static final int WEEK = 2;
+    public static final int MONTH = 3;
+
+    //~ Methods ----------------------------------------------------------------
+
+    /**
+     * @return true if there are no entries
+     */
+    public abstract boolean isEmpty();
+
+    /**
+     * @param mode the mode: DAY, WORKWEEK, WEEK or MONTH
+     */
+    public abstract void setMode(int mode);
+
+    /**
+     * @return the mode: DAY, WORKWEEK, WEEK or MONTH
+     */
+    public abstract int getMode();
+
+    /**
+     * @param date the date to select
+     */
+    public abstract void setSelectedDate(Date date);
+
+    /**
+     * @return the selected date
+     */
+    public abstract Date getSelectedDate();
+
+    /**
+     * @param selectedEntry the entry to select
+     */
+    public abstract void setSelectedEntry(ScheduleEntry selectedEntry);
+
+    /**
+     * @return the selected entry
+     */
+    public abstract ScheduleEntry getSelectedEntry();
+    
+    /**
+     * @return whether an entry is currently selected
+     */
+    public abstract boolean isEntrySelected();
+
+    /**
+     * <p>
+     * Check if the schedule contains the specified date
+     * </p>
+     *
+     * @param date the date to check
+     *
+     * @return whether the schedule containts this date
+     */
+    public abstract boolean containsDate(Date date);
+
+    /**
+     * <p>
+     * Get the day at position <i>index</i>.
+     * </p>
+     *
+     * @param index the index
+     *
+     * @return the day
+     */
+    public abstract Object get(int index);
+
+    /**
+     * @return an iterator for the days
+     */
+    public abstract Iterator iterator();
+
+    /**
+     * @return the number of days in this model
+     */
+    public abstract int size();
+    
+    /**
+     * Add an entry to the this model. 
+     *  
+     * @param entry the entry to be added
+     */
+    public abstract void addEntry(ScheduleEntry entry);
+    
+    /**
+     * Remove an entry from this model
+     * 
+     * @param entry the entry to be removed
+     */
+    public abstract void removeEntry(ScheduleEntry entry);
+    
+    /**
+     * Remove the currently selected entry from this model. If no entry
+     * is currently selected, nothing should happen.
+     */
+    public abstract void removeSelectedEntry();
+    
+    /**
+     * Reload the entries for the currently selected period
+     */
+    public abstract void refresh();
+}
+//The End

Added: myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/schedule/model/SimpleScheduleModel.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/schedule/model/SimpleScheduleModel.java?rev=410011&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/schedule/model/SimpleScheduleModel.java (added)
+++ myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/schedule/model/SimpleScheduleModel.java Sun May 28 18:59:05 2006
@@ -0,0 +1,171 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * 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 org.apache.myfaces.custom.schedule.model;
+
+import java.io.Serializable;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.TreeSet;
+
+import org.apache.myfaces.custom.schedule.util.ScheduleEntryComparator;
+
+/**
+ * <p>
+ * A simple implementation of the ScheduleModel, not backed by any kind of
+ * datasource: entries have to be added manually.
+ * </p>
+ * 
+ * @author Jurgen Lust (latest modification by $Author: werpu $)
+ * @version $Revision: 371736 $
+ */
+public class SimpleScheduleModel extends AbstractScheduleModel implements
+        Serializable
+{
+    // ~ Instance fields
+    // --------------------------------------------------------
+
+    /**
+     * serial id for serialisation versioning
+     */
+    private static final long serialVersionUID = 1L;
+
+    private final TreeSet entries;
+
+    private final HashMap holidays;
+
+    private final DateFormat holidayFormat = new SimpleDateFormat("yyyyMMdd");
+
+    // ~ Constructors
+    // -----------------------------------------------------------
+
+    /**
+     * Creates a new SimpleScheduleModel object.
+     */
+    public SimpleScheduleModel()
+    {
+        this.entries = new TreeSet(new ScheduleEntryComparator());
+        this.holidays = new HashMap();
+    }
+
+    // ~ Methods
+    // ----------------------------------------------------------------
+
+    /**
+     * Set the name of a holiday.
+     * 
+     * @param date
+     *            the date
+     * @param holidayName
+     *            the name of the holiday
+     */
+    public void setHoliday(Date date, String holidayName)
+    {
+        if (date == null)
+        {
+            return;
+        }
+
+        String key = holidayFormat.format(date);
+        holidays.put(key, holidayName);
+    }
+
+    /**
+     * Add an entry to the model.
+     * 
+     * @param entry
+     *            the entry to add
+     */
+    public void addEntry(ScheduleEntry entry)
+    {
+        entries.add(entry);
+    }
+
+    /**
+     * Remove an entry from the model.
+     * 
+     * @param entry
+     *            the entry to remove
+     */
+    public void removeEntry(ScheduleEntry entry)
+    {
+        entries.remove(entry);
+    }
+
+    /**
+     * @see org.apache.myfaces.custom.schedule.model.ScheduleModel#removeSelectedEntry()
+     */
+    public void removeSelectedEntry()
+    {
+        if (!isEntrySelected())
+            return;
+        removeEntry(getSelectedEntry());
+        setSelectedEntry(null);
+        refresh();
+    }
+
+    /**
+     * @see org.apache.myfaces.custom.schedule.model.AbstractScheduleModel#loadEntries(java.util.Date,
+     *      java.util.Date)
+     */
+    protected Collection loadEntries(Date startDate, Date endDate)
+    {
+        ArrayList selection = new ArrayList();
+
+        for (Iterator entryIterator = entries.iterator(); entryIterator
+                .hasNext();)
+        {
+            ScheduleEntry entry = (ScheduleEntry) entryIterator.next();
+
+            if (entry.getEndTime().before(startDate)
+                    || entry.getStartTime().after(endDate))
+            {
+                continue;
+            }
+
+            selection.add(entry);
+        }
+
+        return selection;
+    }
+
+    /**
+     * @see org.apache.myfaces.custom.schedule.model.AbstractScheduleModel#loadDayAttributes(org.apache.myfaces.custom.schedule.model.Day)
+     */
+    protected void loadDayAttributes(Day day)
+    {
+        if (day == null)
+            return;
+        String key = holidayFormat.format(day.getDate());
+        String holiday = (String) holidays.get(key);
+        if (holiday != null)
+        {
+            day.setSpecialDayName(holiday);
+            day.setWorkingDay(false);
+        } else
+        {
+            day.setSpecialDayName(null);
+            day.setWorkingDay(true);
+        }
+    }
+}
+// The End

Added: myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/schedule/renderer/AbstractCompactScheduleRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/schedule/renderer/AbstractCompactScheduleRenderer.java?rev=410011&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/schedule/renderer/AbstractCompactScheduleRenderer.java (added)
+++ myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/schedule/renderer/AbstractCompactScheduleRenderer.java Sun May 28 18:59:05 2006
@@ -0,0 +1,398 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * 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 org.apache.myfaces.custom.schedule.renderer;
+
+import java.io.IOException;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.TreeSet;
+
+import javax.faces.component.UIComponent;
+import javax.faces.component.UIForm;
+import javax.faces.context.FacesContext;
+import javax.faces.context.ResponseWriter;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.myfaces.custom.schedule.HtmlSchedule;
+import org.apache.myfaces.custom.schedule.model.ScheduleDay;
+import org.apache.myfaces.custom.schedule.model.ScheduleEntry;
+import org.apache.myfaces.custom.schedule.util.ScheduleUtil;
+import org.apache.myfaces.shared_tomahawk.renderkit.html.HTML;
+
+/**
+ * <p>
+ * Abstract superclass for the week and month view renderers.
+ * </p>
+ * 
+ * @author Jurgen Lust (latest modification by $Author: jlust $)
+ * @author Bruno Aranda (adaptation of Jurgen's code to myfaces)
+ * @version $Revision: 398348 $
+ */
+public abstract class AbstractCompactScheduleRenderer extends
+                                                      AbstractScheduleRenderer
+{
+    private static final Log log = LogFactory.getLog(AbstractCompactScheduleRenderer.class);
+
+    // ~ Methods
+    // ----------------------------------------------------------------
+
+    /**
+     * @see javax.faces.render.Renderer#encodeChildren(javax.faces.context.FacesContext,
+     *      javax.faces.component.UIComponent)
+     */
+    public void encodeChildren(FacesContext context, UIComponent component)
+            throws IOException
+    {
+        // the children are rendered in the encodeBegin phase
+    }
+
+    /**
+     * @see javax.faces.render.Renderer#encodeEnd(javax.faces.context.FacesContext,
+     *      javax.faces.component.UIComponent)
+     */
+    public void encodeEnd(FacesContext context, UIComponent component)
+            throws IOException
+    {
+        // all rendering is done in the begin phase
+    }
+
+    /**
+     * @return The default height, in pixels, of one row in the schedule grid
+     */
+    protected abstract int getDefaultRowHeight();
+
+    /**
+     * @return The name of the property that determines the row height
+     */
+    protected abstract String getRowHeightProperty();
+
+    /**
+     * @param attributes
+     *            The attributes
+     * 
+     * @return The row height, in pixels
+     */
+    protected int getRowHeight(Map attributes)
+    {
+        int rowHeight = 0;
+
+        try
+        {
+            rowHeight = Integer.valueOf(
+                    (String) attributes.get(getRowHeightProperty())).intValue();
+        } catch (Exception e)
+        {
+            rowHeight = 0;
+        }
+
+        if (rowHeight == 0)
+        {
+            rowHeight = getDefaultRowHeight();
+        }
+
+        return rowHeight;
+    }
+
+    /**
+     * <p>
+     * Draw one day in the schedule
+     * </p>
+     * 
+     * @param context
+     *            the FacesContext
+     * @param writer
+     *            the ResponseWriter
+     * @param schedule
+     *            the schedule
+     * @param day
+     *            the day that should be drawn
+     * @param cellWidth
+     *            the width of the cell
+     * @param dayOfWeek
+     *            the day of the week
+     * @param dayOfMonth
+     *            the day of the month
+     * @param isWeekend
+     *            is it a weekend day?
+     * @param isCurrentMonth
+     *            is the day in the currently selected month?
+     * @param rowspan
+     *            the rowspan for the table cell
+     * 
+     * @throws IOException
+     *             when the cell could not be drawn
+     */
+    protected void writeDayCell(FacesContext context, ResponseWriter writer,
+                                HtmlSchedule schedule, ScheduleDay day, float cellWidth,
+                                int dayOfWeek, int dayOfMonth, boolean isWeekend,
+                                boolean isCurrentMonth, int rowspan) throws IOException
+    {
+        final String clientId = schedule.getClientId(context);
+        final UIForm parentForm = getParentForm(schedule);
+        final Map attributes = schedule.getAttributes();
+        final String formId = parentForm == null ? null : parentForm.getClientId(context);
+        final String dayHeaderId = clientId + "_header_" + ScheduleUtil.getDateId(day.getDate());
+        final String dayBodyId = clientId + "_body_" + ScheduleUtil.getDateId(day.getDate());
+        writer.startElement(HTML.TD_ELEM, schedule);
+
+        writer.writeAttribute("rowspan", String.valueOf(rowspan), null);
+
+        writer.writeAttribute(HTML.CLASS_ATTR, getStyleClass(schedule,
+                                                             isCurrentMonth ? "day" : "inactive-day"), null);
+
+        // determine the height of the day in pixels
+        StringBuffer styleBuffer = new StringBuffer();
+
+        int rowHeight = getRowHeight(attributes);
+        String myRowHeight = "height: ";
+        String myContentHeight = "height: ";
+
+        if (rowHeight > 0)
+        {
+            if (isWeekend)
+            {
+                myRowHeight += (rowHeight / 2) + "px;";
+                myContentHeight += ((rowHeight / 2) - 19) + "px;";
+            }
+            else
+            {
+                myRowHeight += (rowHeight + 1) + "px;"; //need to add 1 to get the weekends right
+                myContentHeight += ((rowHeight + 1) - 18) + "px;"; //18 instead of 19, to get the weekends right
+            }
+         }
+        else
+        {
+            myRowHeight += "100%;";
+            myContentHeight += "100%;";
+        }
+
+        styleBuffer.append(myRowHeight);
+
+        writer.writeAttribute(HTML.STYLE_ATTR, styleBuffer.toString()
+                                               + " width: " + cellWidth + "%;", null);
+
+        writer.startElement(HTML.TABLE_ELEM, schedule);
+
+        writer.writeAttribute(HTML.CLASS_ATTR, getStyleClass(schedule, "day"),
+                              null);
+        writer.writeAttribute(HTML.STYLE_ATTR, styleBuffer.toString()
+                                               + " width: 100%;", null);
+
+        writer.writeAttribute(HTML.CELLPADDING_ATTR, "0", null);
+        writer.writeAttribute(HTML.CELLSPACING_ATTR, "0", null);
+
+        // day header
+        writer.startElement(HTML.TR_ELEM, schedule);
+        writer.startElement(HTML.TD_ELEM, schedule);
+        writer.writeAttribute(HTML.CLASS_ATTR,
+                              getStyleClass(schedule, "header"), null);
+        writer.writeAttribute(HTML.STYLE_ATTR,
+                              "height: 18px; width: 100%; overflow: hidden", null);
+        writer.writeAttribute(HTML.ID_ATTR, dayHeaderId, null);
+        //register an onclick event listener to a day header which will capture
+        //the date
+        if (!schedule.isReadonly() && schedule.isSubmitOnClick()) {
+            writer.writeAttribute(
+                    HTML.ONMOUSEUP_ATTR,
+                    "fireScheduleDateClicked(this, event, '"
+                    + formId + "', '"
+                    + clientId
+                    + "');",
+                    null);
+        }
+
+        
+        
+        writer.writeText(getDateString(context, schedule, day.getDate()), null);
+        writer.endElement(HTML.TD_ELEM);
+        writer.endElement(HTML.TR_ELEM);
+
+        // day content
+        writer.startElement(HTML.TR_ELEM, schedule);
+        writer.startElement(HTML.TD_ELEM, schedule);
+
+        writer.writeAttribute(HTML.CLASS_ATTR, getStyleClass(schedule,
+                                                             "content"), null);
+
+        // determine the height of the day content in pixels
+        StringBuffer contentStyleBuffer = new StringBuffer();
+        contentStyleBuffer.append(myContentHeight);
+        contentStyleBuffer.append(" width: 100%;");
+        writer.writeAttribute(HTML.STYLE_ATTR, contentStyleBuffer.toString(),
+                              null);
+
+        writer.startElement(HTML.DIV_ELEM, schedule);
+        writer
+                .writeAttribute(
+                        HTML.STYLE_ATTR,
+                        "width: 100%; height: 100%; overflow: auto; vertical-align: top;",
+                        null);
+        writer.writeAttribute(HTML.ID_ATTR, dayBodyId, null);
+        //register an onclick event listener to a day cell which will capture
+        //the date
+        if (!schedule.isReadonly() && schedule.isSubmitOnClick()) {
+            writer.writeAttribute(
+                    HTML.ONMOUSEUP_ATTR,
+                    "fireScheduleTimeClicked(this, event, '"
+                    + formId + "', '"
+                    + clientId
+                    + "');",
+                    null);
+        }
+
+        writer.startElement(HTML.TABLE_ELEM, schedule);
+        writer.writeAttribute(HTML.STYLE_ATTR, "width: 100%;", null);
+
+        writeEntries(context, schedule, day, writer);
+
+        writer.endElement(HTML.TABLE_ELEM);
+        writer.endElement(HTML.DIV_ELEM);
+        writer.endElement(HTML.TD_ELEM);
+        writer.endElement(HTML.TR_ELEM);
+        writer.endElement(HTML.TABLE_ELEM);
+        writer.endElement(HTML.TD_ELEM);
+    }
+
+    /**
+     * <p>
+     * Draw the schedule entries in the specified day cell
+     * </p>
+     * 
+     * @param context
+     *            the FacesContext
+     * @param schedule
+     *            the schedule
+     * @param day
+     *            the day
+     * @param writer
+     *            the ResponseWriter
+     * 
+     * @throws IOException
+     *             when the entries could not be drawn
+     */
+    protected void writeEntries(FacesContext context, HtmlSchedule schedule,
+                                ScheduleDay day, ResponseWriter writer) throws IOException
+    {
+        final UIForm parentForm = getParentForm(schedule);
+        final String clientId = schedule.getClientId(context);
+        final String formId = parentForm == null ? null : parentForm.getClientId(context);
+        final TreeSet entrySet = new TreeSet(comparator);
+
+        for (Iterator entryIterator = day.iterator(); entryIterator.hasNext();)
+        {
+            ScheduleEntry entry = (ScheduleEntry) entryIterator.next();
+            entrySet.add(entry);
+        }
+
+        for (Iterator entryIterator = entrySet.iterator(); entryIterator
+                .hasNext();)
+        {
+            ScheduleEntry entry = (ScheduleEntry) entryIterator.next();
+            writer.startElement(HTML.TR_ELEM, schedule);
+            writer.startElement(HTML.TD_ELEM, schedule);
+
+            if (isSelected(schedule, entry))
+            {
+                writer.writeAttribute(HTML.CLASS_ATTR, getStyleClass(schedule,
+                                                                     "selected"), null);
+            }
+
+            //compose the CSS style for the entry box
+            StringBuffer entryStyle = new StringBuffer();
+            entryStyle.append("width: 100%;");
+            String entryColor = getEntryRenderer(schedule).getColor(context, schedule, entry, isSelected(schedule, entry));
+            if (isSelected(schedule, entry) && entryColor != null) {
+                entryStyle.append(" background-color: ");
+                entryStyle.append(entryColor);
+                entryStyle.append(";");
+                entryStyle.append(" border-color: ");
+                entryStyle.append(entryColor);
+                entryStyle.append(";");
+            }
+
+            writer.writeAttribute(HTML.STYLE_ATTR, entryStyle.toString(), null);
+
+            // draw the tooltip
+            if (showTooltip(schedule))
+            {
+                getEntryRenderer(schedule).renderToolTip(context, writer,
+                                                         schedule, entry, isSelected(schedule, entry));
+            }
+
+            if (!isSelected(schedule, entry) && !schedule.isReadonly())
+            {
+                writer.startElement("a", schedule);
+                writer.writeAttribute("href", "#", null);
+
+                writer.writeAttribute(
+                        HTML.ONMOUSEUP_ATTR,
+                        "fireEntrySelected('"
+                        + formId + "', '"
+                        + clientId + "', '"
+                        + entry.getId()
+                        + "');",
+                        null);
+            }
+
+            // draw the content
+            getEntryRenderer(schedule).renderContent(context, writer, schedule,
+                                                     day, entry, true, isSelected(schedule, entry));
+
+            if (!isSelected(schedule, entry) && !schedule.isReadonly())
+            {
+                writer.endElement("a");
+            }
+
+            writer.endElement(HTML.TD_ELEM);
+            writer.endElement(HTML.TR_ELEM);
+        }
+    }
+
+    private boolean isSelected(HtmlSchedule schedule, ScheduleEntry entry)
+    {
+        ScheduleEntry selectedEntry = schedule.getModel().getSelectedEntry();
+
+        if (selectedEntry == null)
+        {
+            return false;
+        }
+
+        return selectedEntry.getId().equals(entry.getId());
+    }
+    
+    /**
+     * In the compact renderer, we don't take the y coordinate of the mouse
+     * into account when determining the last clicked date.
+     */
+    protected Date determineLastClickedDate(HtmlSchedule schedule, String dateId, String yPos) {
+        Calendar cal = GregorianCalendar.getInstance();
+        //the dateId is the schedule client id + "_" + yyyyMMdd 
+        String day = dateId.substring(dateId.lastIndexOf("_") + 1);
+        Date date = ScheduleUtil.getDateFromId(day);
+        
+        if (date != null) cal.setTime(date);
+        cal.set(Calendar.HOUR_OF_DAY, schedule.getVisibleStartHour());
+        log.debug("last clicked datetime: " + cal.getTime());
+        return cal.getTime();
+    }
+    
+}
+// The End

Added: myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/schedule/renderer/AbstractScheduleRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/schedule/renderer/AbstractScheduleRenderer.java?rev=410011&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/schedule/renderer/AbstractScheduleRenderer.java (added)
+++ myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/schedule/renderer/AbstractScheduleRenderer.java Sun May 28 18:59:05 2006
@@ -0,0 +1,453 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * 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 org.apache.myfaces.custom.schedule.renderer;
+
+import java.io.IOException;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Map;
+
+import javax.faces.component.UIComponent;
+import javax.faces.component.UIForm;
+import javax.faces.context.FacesContext;
+import javax.faces.context.ResponseWriter;
+import javax.faces.el.ValueBinding;
+import javax.faces.event.ActionEvent;
+import javax.faces.render.Renderer;
+
+import org.apache.myfaces.custom.schedule.HtmlSchedule;
+import org.apache.myfaces.custom.schedule.ScheduleMouseEvent;
+import org.apache.myfaces.custom.schedule.model.ScheduleEntry;
+import org.apache.myfaces.custom.schedule.util.ScheduleEntryComparator;
+import org.apache.myfaces.custom.schedule.util.ScheduleUtil;
+import org.apache.myfaces.renderkit.html.util.AddResource;
+import org.apache.myfaces.renderkit.html.util.AddResourceFactory;
+import org.apache.myfaces.shared_tomahawk.renderkit.html.HTML;
+
+/**
+ * <p>
+ * Abstract superclass for all renderer of the UISchedule component
+ * </p>
+ *
+ * @author Jurgen Lust (latest modification by $Author: mkienenb $)
+ * @author Bruno Aranda (adaptation of Jurgen's code to myfaces)
+ * @version $Revision: 389938 $
+ */
+public abstract class AbstractScheduleRenderer extends Renderer
+{
+    //~ Static fields/initializers ---------------------------------------------
+    protected static final ScheduleEntryComparator comparator = new ScheduleEntryComparator();
+    protected static final String LAST_CLICKED_DATE = "_last_clicked_date";
+    protected static final String LAST_CLICKED_Y = "_last_clicked_y";
+
+    //~ Methods ----------------------------------------------------------------
+
+    /**
+     * @see javax.faces.render.Renderer#decode(javax.faces.context.FacesContext,
+     *      javax.faces.component.UIComponent)
+     */
+    public void decode(FacesContext context, UIComponent component)
+    {
+        HtmlSchedule schedule = (HtmlSchedule) component;
+        boolean queueAction = false;
+        if (ScheduleUtil.canModifyValue(component))
+        {
+            Map parameters = context.getExternalContext()
+                    .getRequestParameterMap();
+            String selectedEntryId = (String) parameters.get((String) schedule
+                    .getClientId(context));
+            String lastClickedDateId = (String) parameters.get((String) schedule.getClientId(context) + LAST_CLICKED_DATE);
+            String lastClickedY = (String) parameters.get((String) schedule.getClientId(context) + LAST_CLICKED_Y);
+            
+            ScheduleMouseEvent mouseEvent = null;
+
+            if ((selectedEntryId != null) && (selectedEntryId.length() > 0))
+            {
+                ScheduleEntry entry = schedule.findEntry(selectedEntryId);
+                schedule.setSubmittedEntry(entry);
+                mouseEvent = new ScheduleMouseEvent(schedule, ScheduleMouseEvent.SCHEDULE_ENTRY_CLICKED);
+                queueAction = true;
+            }
+
+            if (schedule.isSubmitOnClick())
+            {
+                schedule.resetMouseEvents();
+                if ((lastClickedY != null) && (lastClickedY.length() > 0))
+                {
+                    //the body of the schedule was clicked
+                    schedule.setLastClickedDateAndTime(determineLastClickedDate(schedule, lastClickedDateId, lastClickedY));
+                    mouseEvent = new ScheduleMouseEvent(schedule, ScheduleMouseEvent.SCHEDULE_BODY_CLICKED);
+                    queueAction = true;
+                } else if ((lastClickedDateId != null) && (lastClickedDateId.length() > 0)){
+                    //the header of the schedule was clicked
+                    schedule.setLastClickedDateAndTime(determineLastClickedDate(schedule, lastClickedDateId, "0"));
+                    mouseEvent = new ScheduleMouseEvent(schedule, ScheduleMouseEvent.SCHEDULE_HEADER_CLICKED);
+                    queueAction = true;
+                } else if (mouseEvent == null){
+                    //the form was posted without mouse events on the schedule
+                    mouseEvent = new ScheduleMouseEvent(schedule, ScheduleMouseEvent.SCHEDULE_NOTHING_CLICKED);
+                }
+            }
+
+            if (mouseEvent != null) schedule.queueEvent(mouseEvent);
+        }
+        if (queueAction)
+        {
+            schedule.queueEvent(new ActionEvent(schedule));
+        }
+    }
+
+    /**
+     * @see javax.faces.render.Renderer#encodeBegin(javax.faces.context.FacesContext,
+     *      javax.faces.component.UIComponent)
+     */
+    public void encodeBegin(FacesContext context, UIComponent component)
+            throws IOException
+    {
+        if (!component.isRendered())
+        {
+            return;
+        }
+
+        HtmlSchedule schedule = (HtmlSchedule) component;
+        ResponseWriter writer = context.getResponseWriter();
+
+        String css = "css/schedule.css";
+
+        //add needed CSS and Javascript files to the header 
+
+        AddResource addResource = AddResourceFactory.getInstance(context);
+        addResource.addStyleSheet(context, AddResource.HEADER_BEGIN,
+                HtmlSchedule.class, css);
+        addResource.addJavaScriptAtPosition(context, AddResource.HEADER_BEGIN,
+                HtmlSchedule.class, "javascript/schedule.js");
+        addResource.addJavaScriptAtPosition(context, AddResource.HEADER_BEGIN,
+                HtmlSchedule.class, "javascript/alphaAPI.js");
+        addResource.addJavaScriptAtPosition(context, AddResource.HEADER_BEGIN,
+                HtmlSchedule.class, "javascript/domLib.js");
+        addResource.addJavaScriptAtPosition(context, AddResource.HEADER_BEGIN,
+                HtmlSchedule.class, "javascript/domTT.js");
+        addResource.addJavaScriptAtPosition(context, AddResource.HEADER_BEGIN,
+                HtmlSchedule.class, "javascript/fadomatic.js");
+
+        //hidden input field containing the id of the selected entry
+        writer.startElement(HTML.INPUT_ELEM, schedule);
+        writer.writeAttribute(HTML.TYPE_ATTR, "hidden", null);
+        writer.writeAttribute(HTML.NAME_ATTR, schedule.getClientId(context),
+                "clientId");
+        writer.endElement(HTML.INPUT_ELEM);
+        //hidden input field containing the id of the last clicked date
+        writer.startElement(HTML.INPUT_ELEM, schedule);
+        writer.writeAttribute(HTML.TYPE_ATTR, "hidden", null);
+        writer.writeAttribute(HTML.NAME_ATTR, schedule.getClientId(context) + "_last_clicked_date",
+                "clicked_date");
+        writer.endElement(HTML.INPUT_ELEM);
+        //hidden input field containing the y coordinate of the mouse when
+        //the schedule was clicked. This will be used to determine the hour
+        //of day.
+        writer.startElement(HTML.INPUT_ELEM, schedule);
+        writer.writeAttribute(HTML.TYPE_ATTR, "hidden", null);
+        writer.writeAttribute(HTML.NAME_ATTR, schedule.getClientId(context) + "_last_clicked_y",
+                "clicked_y");
+        writer.endElement(HTML.INPUT_ELEM);
+    }
+
+    /**
+     * <p>
+     * Get the String representation of a date, taking into account the
+     * specified date format or the current Locale.
+     * </p>
+     *
+     * @param context the FacesContext
+     * @param component the component
+     * @param date the date
+     *
+     * @return the date string
+     */
+    protected String getDateString(FacesContext context, UIComponent component,
+            Date date)
+    {
+        DateFormat format;
+        String pattern = getHeaderDateFormat(component);
+
+        if ((pattern != null) && (pattern.length() > 0))
+        {
+            format = new SimpleDateFormat(pattern);
+        }
+        else
+        {
+            if (context.getApplication().getDefaultLocale() != null)
+            {
+                format = DateFormat.getDateInstance(DateFormat.MEDIUM, context
+                        .getApplication().getDefaultLocale());
+            }
+            else
+            {
+                format = DateFormat.getDateInstance(DateFormat.MEDIUM);
+            }
+        }
+
+        return format.format(date);
+    }
+
+    /**
+     * <p>
+     * The theme used when rendering the schedule
+     * </p>
+     * 
+     * @param component the component
+     * 
+     * @return the theme
+     */
+    protected String getTheme(UIComponent component)
+    {
+        //first check if the theme property is a value binding expression
+        ValueBinding binding = component.getValueBinding("theme");
+        if (binding != null)
+        {
+            String value = (String) binding.getValue(FacesContext
+                    .getCurrentInstance());
+
+            if (value != null)
+            {
+                return value;
+            }
+        }
+        //it's not a value binding expression, so check for the string value
+        //in the attributes
+        Map attributes = component.getAttributes();
+        String theme = (String) attributes.get("theme");
+        if (theme == null || theme.length() < 1)
+            theme = "default";
+        return theme;
+    }
+
+    /**
+     * <p>
+     * Allow the developer to specify custom CSS classnames for the schedule
+     * component.
+     * </p>
+     * @param component the component
+     * @param className the default CSS classname
+     * @return the custom classname
+     */
+    protected String getStyleClass(UIComponent component, String className)
+    {
+        //first check if the styleClass property is a value binding expression
+        ValueBinding binding = component.getValueBinding(className);
+        if (binding != null)
+        {
+            String value = (String) binding.getValue(FacesContext
+                    .getCurrentInstance());
+
+            if (value != null)
+            {
+                return value;
+            }
+        }
+        //it's not a value binding expression, so check for the string value
+        //in the attributes
+        Map attributes = component.getAttributes();
+        String returnValue = (String) attributes.get(className);
+        return returnValue == null ? className : returnValue;
+    }
+
+    /**
+     * <p>
+     * The date format that is used in the schedule header
+     * </p>
+     *
+     * @param component the component
+     *
+     * @return Returns the headerDateFormat.
+     */
+    protected String getHeaderDateFormat(UIComponent component)
+    {
+        //first check if the headerDateFormat property is a value binding expression
+        ValueBinding binding = component.getValueBinding("headerDateFormat");
+        if (binding != null)
+        {
+            String value = (String) binding.getValue(FacesContext
+                    .getCurrentInstance());
+
+            if (value != null)
+            {
+                return value;
+            }
+        }
+        //it's not a value binding expression, so check for the string value
+        //in the attributes
+        Map attributes = component.getAttributes();
+        return (String) attributes.get("headerDateFormat");
+    }
+
+    /**
+     * <p>
+     * Get the parent form of the schedule component
+     * </p>
+     *
+     * @param component the component
+     *
+     * @return the parent form
+     */
+    protected UIForm getParentForm(UIComponent component)
+    {
+        UIComponent parent = component.getParent();
+
+        while (parent != null)
+        {
+            if (parent instanceof UIForm)
+            {
+                break;
+            }
+
+            parent = parent.getParent();
+        }
+
+        return (UIForm) parent;
+    }
+
+    /**
+     * <p>
+     * Should the tooltip be made visible?
+     * </p>
+     *
+     * @param component the component
+     *
+     * @return whether or not tooltips should be rendered
+     */
+    protected boolean showTooltip(UIComponent component)
+    {
+        //first check if the tooltip property is a value binding expression
+        ValueBinding binding = component.getValueBinding("tooltip");
+        if (binding != null)
+        {
+            Boolean value = (Boolean) binding.getValue(FacesContext
+                    .getCurrentInstance());
+
+            if (value != null)
+            {
+                return value.booleanValue();
+            }
+        }
+        //it's not a value binding expression, so check for the string value
+        //in the attributes
+        Map attributes = component.getAttributes();
+        return Boolean.valueOf((String) attributes.get("tooltip"))
+                .booleanValue();
+    }
+
+    /**
+     * The user of the Schedule component can customize the look and feel
+     * by specifying a custom implementation of the ScheduleEntryRenderer.
+     * This method gets an instance of the specified class, or if none
+     * was specified, takes the default.
+     * 
+     * @param component the Schedule component
+     * @return a ScheduleEntryRenderer instance
+     */
+    protected ScheduleEntryRenderer getEntryRenderer(UIComponent component)
+    {
+        ScheduleEntryRenderer entryRenderer = null;
+        Map attributes = component.getAttributes();
+        //First check if there an entryRenderer has already been instantiated
+        Object rendererObject = attributes.get("entryRendererInstance");
+        if (rendererObject instanceof ScheduleEntryRenderer)
+        {
+            entryRenderer = (ScheduleEntryRenderer) rendererObject;
+        }
+        else
+        {
+            //No entryRenderer was instantiated, do that here
+            String className = null;
+            //Was the classname specified as attribute of the component?
+            ValueBinding binding = component.getValueBinding("entryRenderer");
+            if (binding != null)
+            {
+                className = (String) binding.getValue(FacesContext
+                        .getCurrentInstance());
+            }
+            if (className == null)
+            {
+                className = (String) attributes.get("entryRenderer");
+            }
+            try
+            { //try to instantiate a renderer of the specified class
+                entryRenderer = (ScheduleEntryRenderer) Class
+                        .forName(className).newInstance();
+            }
+            catch (Exception e)
+            {
+                //something went wrong, let's take the default
+                entryRenderer = new DefaultScheduleEntryRenderer();
+            }
+            //Store the instance in the component attributes for later use
+            attributes.put("entryRendererInstance", entryRenderer);
+        }
+        return entryRenderer;
+    }
+
+    /**
+     * @return The default height, in pixels, of one row in the schedule grid
+     */
+    protected abstract int getDefaultRowHeight();
+
+    /**
+     * @return The name of the property that determines the row height
+     */
+    protected abstract String getRowHeightProperty();
+
+    /**
+     * @param attributes
+     *            The attributes
+     * 
+     * @return The row height, in pixels
+     */
+    protected int getRowHeight(Map attributes)
+    {
+        int rowHeight = 0;
+
+        try
+        {
+            Integer rowHeightObject = (Integer) attributes
+                    .get(getRowHeightProperty());
+            rowHeight = rowHeightObject.intValue();
+        }
+        catch (Exception e)
+        {
+            rowHeight = 0;
+        }
+
+        if (rowHeight <= 0)
+        {
+            rowHeight = getDefaultRowHeight();
+        }
+
+        return rowHeight;
+    }
+    
+    /**
+     * Determine the last clicked date
+     * @param schedule the schedule component
+     * @param dateId the string identifying the date
+     * @param yPos the y coordinate of the mouse
+     * @return the clicked date
+     */
+    protected abstract Date determineLastClickedDate(HtmlSchedule schedule, String dateId, String yPos);
+}
+//The End

Added: myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/schedule/renderer/DefaultScheduleEntryRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/schedule/renderer/DefaultScheduleEntryRenderer.java?rev=410011&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/schedule/renderer/DefaultScheduleEntryRenderer.java (added)
+++ myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/schedule/renderer/DefaultScheduleEntryRenderer.java Sun May 28 18:59:05 2006
@@ -0,0 +1,230 @@
+/*
+ * Copyright 2005 The Apache Software Foundation.
+ *
+ * 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 org.apache.myfaces.custom.schedule.renderer;
+
+import java.io.IOException;
+import java.text.DateFormat;
+import java.util.Date;
+import java.util.Map;
+
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.context.ResponseWriter;
+import javax.faces.el.ValueBinding;
+
+import org.apache.myfaces.custom.schedule.HtmlSchedule;
+import org.apache.myfaces.custom.schedule.model.ScheduleDay;
+import org.apache.myfaces.custom.schedule.model.ScheduleEntry;
+import org.apache.myfaces.shared_tomahawk.renderkit.html.HTML;
+
+/**
+ * The default implementation of the ScheduleEntryRenderer
+ * 
+ * @author Jurgen Lust (latest modification by $Author$)
+ * @version $Revision$
+ */
+public class DefaultScheduleEntryRenderer implements ScheduleEntryRenderer
+{
+    private static final long serialVersionUID = 4987926168243581739L;
+
+    /**
+     * @see org.apache.myfaces.custom.schedule.renderer.ScheduleEntryRenderer#renderContent(javax.faces.context.FacesContext, javax.faces.context.ResponseWriter, org.apache.myfaces.custom.schedule.HtmlSchedule, org.apache.myfaces.custom.schedule.model.ScheduleDay, org.apache.myfaces.custom.schedule.model.ScheduleEntry, boolean, boolean)
+     */
+    public void renderContent(FacesContext context, ResponseWriter writer,
+                              HtmlSchedule schedule, ScheduleDay day, ScheduleEntry entry,
+                              boolean compact, boolean selected) throws IOException
+    {
+        if (compact)
+        {
+            StringBuffer text = new StringBuffer();
+            Date startTime = entry.getStartTime();
+
+            if (day.getDayStart().after(entry.getStartTime()))
+            {
+                startTime = day.getDayStart();
+            }
+
+            Date endTime = entry.getEndTime();
+
+            if (day.getDayEnd().before(entry.getEndTime()))
+            {
+                endTime = day.getDayEnd();
+            }
+
+            DateFormat format = DateFormat.getTimeInstance(DateFormat.SHORT);
+            text.append(format.format(startTime));
+            text.append("-");
+            text.append(format.format(endTime));
+            text.append(": ");
+            text.append(entry.getTitle());
+
+            writer.writeText(text.toString(), null);
+        } else
+        {
+            if (selected)
+            {
+                StringBuffer entryStyle = new StringBuffer();
+                entryStyle.append("height: 100%; width: 100%;");
+                //the left border of a selected entry should have the same
+                //color as the entry border
+                String entryColor = getColor(context, schedule, entry, selected);
+                if (entryColor != null) {
+                    entryStyle.append("border-color: ");
+                    entryStyle.append(entryColor);
+                    entryStyle.append(";");
+                }
+                // draw the contents of the selected entry
+                writer.startElement(HTML.DIV_ELEM, null);
+                writer.writeAttribute(HTML.CLASS_ATTR, getStyleClass(schedule,
+                                                                     "text"), null);
+                writer.writeAttribute(HTML.STYLE_ATTR,entryStyle.toString(), null);
+                // write the title of the entry
+                if (entry.getTitle() != null)
+                {
+                    writer.startElement(HTML.SPAN_ELEM, schedule);
+                    writer.writeAttribute(HTML.CLASS_ATTR, getStyleClass(
+                            schedule, "title"), null);
+                    writer.writeText(entry.getTitle(), null);
+                    writer.endElement(HTML.SPAN_ELEM);
+                }
+                if (entry.getSubtitle() != null)
+                {
+                    writer.startElement("br", schedule);
+                    writer.endElement("br");
+                    writer.startElement(HTML.SPAN_ELEM, schedule);
+                    writer.writeAttribute(HTML.CLASS_ATTR, getStyleClass(
+                            schedule, "subtitle"), null);
+                    writer.writeText(entry.getSubtitle(), null);
+                    writer.endElement(HTML.SPAN_ELEM);
+                }
+
+                writer.endElement(HTML.DIV_ELEM);
+            } else
+            {
+                // write the title
+                if (entry.getTitle() != null)
+                {
+                    writer.startElement(HTML.SPAN_ELEM, schedule);
+                    writer.writeAttribute(HTML.CLASS_ATTR, getStyleClass(
+                            schedule, "title"), null);
+                    writer.writeText(entry.getTitle(), null);
+                    writer.endElement(HTML.SPAN_ELEM);
+                }
+                // write the subtitle
+                if (entry.getSubtitle() != null)
+                {
+                    writer.startElement("br", schedule);
+                    writer.endElement("br");
+                    writer.startElement(HTML.SPAN_ELEM, schedule);
+                    writer.writeAttribute(HTML.CLASS_ATTR, getStyleClass(
+                            schedule, "subtitle"), null);
+                    writer.writeText(entry.getSubtitle(), null);
+                    writer.endElement(HTML.SPAN_ELEM);
+                }
+            }
+        }
+
+    }
+
+    /**
+     * @see org.apache.myfaces.custom.schedule.renderer.ScheduleEntryRenderer#getColor(javax.faces.context.FacesContext, org.apache.myfaces.custom.schedule.HtmlSchedule, org.apache.myfaces.custom.schedule.model.ScheduleEntry, boolean)
+     */
+    public String getColor(FacesContext context, HtmlSchedule schedule,
+                           ScheduleEntry entry, boolean selected)
+    {
+        return null;
+    }
+
+    /**
+     * @see org.apache.myfaces.custom.schedule.renderer.ScheduleEntryRenderer#renderToolTip(javax.faces.context.FacesContext, javax.faces.context.ResponseWriter, org.apache.myfaces.custom.schedule.HtmlSchedule, org.apache.myfaces.custom.schedule.model.ScheduleEntry, boolean)
+     */
+    public void renderToolTip(FacesContext context, ResponseWriter writer,
+                              HtmlSchedule schedule, ScheduleEntry entry, boolean selected)
+            throws IOException
+    {
+        StringBuffer buffer = new StringBuffer();
+        buffer
+                .append("return makeTrue(domTT_activate(this, event, 'caption', '");
+
+        if (entry.getTitle() != null)
+        {
+            buffer.append(escape(entry.getTitle()));
+        }
+
+        buffer.append("', 'content', '<i>");
+
+        if (entry.getSubtitle() != null)
+        {
+            buffer.append(escape(entry.getSubtitle()));
+        }
+
+        buffer.append("</i>");
+
+        if (entry.getDescription() != null)
+        {
+            buffer.append("<br/>");
+            buffer.append(escape(entry.getDescription()));
+        }
+
+        buffer.append("', 'trail', true));");
+        writer.writeAttribute("onmouseover", buffer.toString(), null);
+    }
+
+    private String escape(String text)
+    {
+        if (text == null)
+        {
+            return null;
+        }
+
+        return text.replaceAll("'", "&quot;");
+    }
+
+    /**
+     * <p>
+     * Allow the developer to specify custom CSS classnames for the schedule
+     * component.
+     * </p>
+     * 
+     * @param component
+     *            the component
+     * @param className
+     *            the default CSS classname
+     * @return the custom classname
+     */
+    protected String getStyleClass(UIComponent component, String className)
+    {
+        // first check if the styleClass property is a value binding expression
+        ValueBinding binding = component.getValueBinding(className);
+        if (binding != null)
+        {
+            String value = (String) binding.getValue(FacesContext
+                    .getCurrentInstance());
+
+            if (value != null)
+            {
+                return value;
+            }
+        }
+        // it's not a value binding expression, so check for the string value
+        // in the attributes
+        Map attributes = component.getAttributes();
+        String returnValue = (String) attributes.get(className);
+        return returnValue == null ? className : returnValue;
+    }
+
+}

Added: myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/schedule/renderer/ScheduleCompactMonthRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/schedule/renderer/ScheduleCompactMonthRenderer.java?rev=410011&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/schedule/renderer/ScheduleCompactMonthRenderer.java (added)
+++ myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/schedule/renderer/ScheduleCompactMonthRenderer.java Sun May 28 18:59:05 2006
@@ -0,0 +1,164 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * 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 org.apache.myfaces.custom.schedule.renderer;
+
+
+import java.io.IOException;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.Iterator;
+
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.context.ResponseWriter;
+
+import org.apache.myfaces.custom.schedule.HtmlSchedule;
+import org.apache.myfaces.custom.schedule.model.ScheduleDay;
+import org.apache.myfaces.shared_tomahawk.renderkit.html.HTML;
+
+
+/**
+ * <p>
+ * Renderer for the month view of the Schedule component
+ * </p>
+ *
+ * @author Jurgen Lust (latest modification by $Author: schof $)
+ * @author Bruno Aranda (adaptation of Jurgen's code to myfaces)
+ * @version $Revision: 382051 $
+ */
+public class ScheduleCompactMonthRenderer
+    extends AbstractCompactScheduleRenderer
+{
+    //~ Methods ----------------------------------------------------------------
+
+    /**
+     * @see javax.faces.render.Renderer#encodeBegin(javax.faces.context.FacesContext,
+     *      javax.faces.component.UIComponent)
+     */
+    public void encodeBegin(
+        FacesContext context,
+        UIComponent component
+    )
+        throws IOException
+    {
+        if (!component.isRendered()) {
+            return;
+        }
+
+        super.encodeBegin(context, component);
+
+        HtmlSchedule schedule = (HtmlSchedule) component;
+        ResponseWriter writer = context.getResponseWriter();
+
+        //container div for the schedule grid
+        writer.startElement(HTML.DIV_ELEM, schedule);
+        writer.writeAttribute(HTML.CLASS_ATTR, "schedule-compact-" + getTheme(schedule), null);
+        writer.writeAttribute(
+            HTML.STYLE_ATTR, "border-style: none; overflow: hidden;", null
+        );
+
+        writer.startElement(HTML.TABLE_ELEM, schedule);
+        writer.writeAttribute(HTML.CLASS_ATTR, getStyleClass(schedule, "month"), null);
+        writer.writeAttribute(
+            HTML.STYLE_ATTR, "position: relative; left: 0px; top: 0px; width: 100%;",
+            null
+        );
+        writer.writeAttribute(HTML.CELLPADDING_ATTR, "0", null);
+        writer.writeAttribute(HTML.CELLSPACING_ATTR, "1", null);
+        writer.writeAttribute("border", "0", null);
+        writer.writeAttribute(HTML.WIDTH_ATTR, "100%", null);
+        writer.startElement(HTML.TBODY_ELEM, schedule);
+
+        Calendar cal = GregorianCalendar.getInstance();
+        cal.setTime(schedule.getModel().getSelectedDate());
+        int selectedMonth = cal.get(Calendar.MONTH);
+
+        for (
+            Iterator dayIterator = schedule.getModel().iterator();
+            dayIterator.hasNext();
+        ) {
+            ScheduleDay day = (ScheduleDay) dayIterator.next();
+            cal.setTime(day.getDate());
+
+            int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
+            int dayOfMonth = cal.get(Calendar.DAY_OF_MONTH);
+            int currentMonth = cal.get(Calendar.MONTH);
+            boolean isWeekend =
+                (dayOfWeek == Calendar.SATURDAY) ||
+                (dayOfWeek == Calendar.SUNDAY);
+
+            cal.setTime(day.getDate());
+
+            writeDayCell(
+                context, writer, schedule, day, dayOfWeek, dayOfMonth, isWeekend,
+                currentMonth == selectedMonth, isWeekend ? 1 : 2
+            );
+
+        }
+
+        writer.endElement(HTML.TBODY_ELEM);
+        writer.endElement(HTML.TABLE_ELEM);
+
+        writer.endElement(HTML.DIV_ELEM);
+    }
+
+    /**
+     * @see AbstractCompactScheduleRenderer#getDefaultRowHeight()
+     */
+    protected int getDefaultRowHeight()
+    {
+        return 120;
+    }
+
+    /**
+     * @see AbstractCompactScheduleRenderer#getRowHeightProperty()
+     */
+    protected String getRowHeightProperty()
+    {
+        return "compactMonthRowHeight";
+    }
+
+    /**
+     */
+    protected void writeDayCell(
+        FacesContext context,
+        ResponseWriter writer,
+        HtmlSchedule schedule,
+        ScheduleDay day,
+        int dayOfWeek,
+        int dayOfMonth,
+        boolean isWeekend,
+        boolean isCurrentMonth,
+        int rowspan
+    )
+        throws IOException
+    {
+        if ((dayOfWeek == Calendar.MONDAY) || (dayOfWeek == Calendar.SUNDAY)) {
+            writer.startElement(HTML.TR_ELEM, schedule);
+        }
+
+        super.writeDayCell(
+            context, writer, schedule, day, 100f / 6, dayOfWeek, dayOfMonth,
+            isWeekend, isCurrentMonth, rowspan
+        );
+
+        if ((dayOfWeek == Calendar.SATURDAY) || (dayOfWeek == Calendar.SUNDAY)) {
+            writer.endElement(HTML.TR_ELEM);
+        }
+    }
+}
+//The End

Added: myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/schedule/renderer/ScheduleCompactWeekRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/schedule/renderer/ScheduleCompactWeekRenderer.java?rev=410011&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/schedule/renderer/ScheduleCompactWeekRenderer.java (added)
+++ myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/schedule/renderer/ScheduleCompactWeekRenderer.java Sun May 28 18:59:05 2006
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * 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 org.apache.myfaces.custom.schedule.renderer;
+
+
+import org.apache.myfaces.custom.schedule.HtmlSchedule;
+import org.apache.myfaces.custom.schedule.model.ScheduleDay;
+import org.apache.myfaces.shared_tomahawk.renderkit.html.HTML;
+
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.context.ResponseWriter;
+import java.io.IOException;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.Iterator;
+
+
+/**
+ * <p>
+ * Renderer for the week view of the UISchedule component
+ * </p>
+ *
+ * @author Jurgen Lust (latest modification by $Author: schof $)
+ * @author Bruno Aranda (adaptation of Jurgen's code to myfaces)
+ * @version $Revision: 382051 $
+ */
+public class ScheduleCompactWeekRenderer
+    extends AbstractCompactScheduleRenderer
+{
+    //~ Methods ----------------------------------------------------------------
+
+    /**
+     * @see javax.faces.render.Renderer#encodeBegin(javax.faces.context.FacesContext,
+     *      javax.faces.component.UIComponent)
+     */
+    public void encodeBegin(
+        FacesContext context,
+        UIComponent component
+    )
+        throws IOException
+    {
+        if (!component.isRendered()) {
+            return;
+        }
+
+        super.encodeBegin(context, component);
+
+        HtmlSchedule schedule = (HtmlSchedule) component;
+        ResponseWriter writer = context.getResponseWriter();
+
+        //container div for the schedule grid
+        writer.startElement(HTML.DIV_ELEM, schedule);
+        writer.writeAttribute(HTML.CLASS_ATTR, "schedule-compact-" + getTheme(schedule), null);
+        writer.writeAttribute(
+            HTML.STYLE_ATTR, "border-style: none; overflow: hidden;", null
+        );
+
+        writer.startElement(HTML.TABLE_ELEM, schedule);
+        writer.writeAttribute(HTML.CLASS_ATTR, getStyleClass(schedule, "week"), null);
+        writer.writeAttribute(
+            HTML.STYLE_ATTR, "position: relative; left: 0px; top: 0px; width: 100%;",
+            null
+        );
+        writer.writeAttribute(HTML.CELLPADDING_ATTR, "0", null);
+        writer.writeAttribute(HTML.CELLSPACING_ATTR, "1", null);
+        writer.writeAttribute("border", "0", null);
+        writer.writeAttribute(HTML.WIDTH_ATTR, "100%", null);
+        writer.startElement(HTML.TBODY_ELEM, schedule);
+
+        Calendar cal = GregorianCalendar.getInstance();
+
+        for (
+            Iterator dayIterator = schedule.getModel().iterator();
+                dayIterator.hasNext();
+        ) {
+            ScheduleDay day = (ScheduleDay) dayIterator.next();
+            cal.setTime(day.getDate());
+
+            int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
+            int dayOfMonth = cal.get(Calendar.DAY_OF_MONTH);
+            boolean isWeekend =
+                (dayOfWeek == Calendar.SATURDAY) ||
+                (dayOfWeek == Calendar.SUNDAY);
+
+            if (
+                (dayOfWeek == Calendar.MONDAY) ||
+                    (dayOfWeek == Calendar.WEDNESDAY) ||
+                    (dayOfWeek == Calendar.FRIDAY) ||
+                    (dayOfWeek == Calendar.SUNDAY)
+            ) {
+                writer.startElement(HTML.TR_ELEM, schedule);
+            }
+
+            writeDayCell(
+                context, writer, schedule, day, 50f, dayOfWeek, dayOfMonth,
+                isWeekend, true, (dayOfWeek == Calendar.FRIDAY) ? 2 : 1
+            );
+
+            if (
+                (dayOfWeek == Calendar.TUESDAY) ||
+                    (dayOfWeek == Calendar.THURSDAY) ||
+                    (dayOfWeek == Calendar.SATURDAY) ||
+                    (dayOfWeek == Calendar.SUNDAY)
+            ) {
+                writer.endElement(HTML.TR_ELEM);
+            }
+        }
+
+        writer.endElement(HTML.TBODY_ELEM);
+        writer.endElement(HTML.TABLE_ELEM);
+
+        writer.endElement(HTML.DIV_ELEM);
+    }
+
+    /**
+     * @see org.apache.myfaces.custom.schedule.renderer.AbstractCompactScheduleRenderer#getDefaultRowHeight()
+     */
+    protected int getDefaultRowHeight()
+    {
+        return 200;
+    }
+
+    /**
+     * @see org.apache.myfaces.custom.schedule.renderer.AbstractCompactScheduleRenderer#getRowHeightProperty()
+     */
+    protected String getRowHeightProperty()
+    {
+        return "compactWeekRowHeight";
+    }
+}
+//The End

Added: myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/schedule/renderer/ScheduleDelegatingRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/schedule/renderer/ScheduleDelegatingRenderer.java?rev=410011&view=auto
==============================================================================
--- myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/schedule/renderer/ScheduleDelegatingRenderer.java (added)
+++ myfaces/tomahawk/trunk/core/src/main/java/org/apache/myfaces/custom/schedule/renderer/ScheduleDelegatingRenderer.java Sun May 28 18:59:05 2006
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2004 The Apache Software Foundation.
+ *
+ * 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 org.apache.myfaces.custom.schedule.renderer;
+
+import java.io.IOException;
+
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.render.Renderer;
+
+import org.apache.myfaces.custom.schedule.HtmlSchedule;
+import org.apache.myfaces.custom.schedule.model.ScheduleModel;
+
+/**
+ * <p>
+ * Renderer for the Schedule component that delegates the actual rendering
+ * to a compact or detailed renderer, depending on the mode of the ScheduleModel
+ * </p>
+ *
+ * @author Jurgen Lust (latest modification by $Author: skitching $)
+ * @author Bruno Aranda (adaptation of Jurgen's code to myfaces)
+ * @version $Revision: 367444 $
+ */
+public class ScheduleDelegatingRenderer extends Renderer
+{
+    //~ Instance fields --------------------------------------------------------
+
+    private final ScheduleCompactMonthRenderer monthDelegate = new ScheduleCompactMonthRenderer();
+    private final ScheduleCompactWeekRenderer weekDelegate = new ScheduleCompactWeekRenderer();
+    private final ScheduleDetailedDayRenderer dayDelegate = new ScheduleDetailedDayRenderer();
+
+    //~ Methods ----------------------------------------------------------------
+
+    /**
+     * @see javax.faces.render.Renderer#decode(javax.faces.context.FacesContext,
+     *      javax.faces.component.UIComponent)
+     */
+    public void decode(FacesContext context, UIComponent component)
+    {
+        getDelegateRenderer(component).decode(context, component);
+    }
+
+    /**
+     * @see javax.faces.render.Renderer#encodeBegin(javax.faces.context.FacesContext,
+     *      javax.faces.component.UIComponent)
+     */
+    public void encodeBegin(FacesContext context, UIComponent component)
+            throws IOException
+    {
+        getDelegateRenderer(component).encodeBegin(context, component);
+    }
+
+    /**
+     * @see javax.faces.render.Renderer#encodeChildren(javax.faces.context.FacesContext,
+     *      javax.faces.component.UIComponent)
+     */
+    public void encodeChildren(FacesContext context, UIComponent component)
+            throws IOException
+    {
+        getDelegateRenderer(component).encodeChildren(context, component);
+    }
+
+    /**
+     * @see javax.faces.render.Renderer#encodeEnd(javax.faces.context.FacesContext,
+     *      javax.faces.component.UIComponent)
+     */
+    public void encodeEnd(FacesContext context, UIComponent component)
+            throws IOException
+    {
+        getDelegateRenderer(component).encodeEnd(context, component);
+    }
+
+    private Renderer getDelegateRenderer(UIComponent component)
+    {
+        HtmlSchedule schedule = (HtmlSchedule) component;
+
+        if ((schedule == null) || (schedule.getModel() == null))
+        {
+            return dayDelegate;
+        }
+
+        switch (schedule.getModel().getMode())
+        {
+        case ScheduleModel.WEEK:
+            return weekDelegate;
+
+        case ScheduleModel.MONTH:
+            return monthDelegate;
+
+        default:
+            return dayDelegate;
+        }
+    }
+}
+//The End