/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (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.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is OEone Calendar Code, released October 31st, 2001. * * The Initial Developer of the Original Code is * OEone Corporation. * Portions created by the Initial Developer are Copyright (C) 2001 * the Initial Developer. All Rights Reserved. * * Contributor(s): Garth Smedley * Mike Potter * Eric Belhaire * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ /*----------------------------------------------------------------- * C A L E N D A R C L A S S E S */ /*----------------------------------------------------------------- * CalendarWindow Class * * Maintains the three calendar views and the selection. * * PROPERTIES * eventSource - the event source, an instance of CalendarEventDataSource * dateFormater - a date formatter, an instance of DateFormater * * monthView - an instance of MonthView * weekView - an instance of WeekView * dayView - an instance of DayView * multiweekView - an instance of MultiweekView * * currentView - the currently active view, one of the above three instances * * selectedEvent - the selected event, instance of CalendarEvent * selectedDate - selected date, instance of Date * */ /** * CalendarWindow Constructor. * * PARAMETERS * calendarDataSource - The data source with all of the calendar events. * * NOTES * There is one instance of CalendarWindow */ function CalendarWindow( ) { //setup the preferences this.calendarPreferences = new calendarPreferences( this ); // miniMonth used by preferences this.miniMonth = document.getElementById( "lefthandcalendar" ); //setup the calendars this.calendarManager = new calendarManager( this ); //setup the calendar event selection this.EventSelection = new CalendarEventSelection( this ); //global date formater this.dateFormater = new DateFormater( this ); //the different views for the calendar this.monthView = new MonthView( this ); this.weekView = new WeekView( this ); this.dayView = new DayView( this ); this.multiweekView = new MultiweekView( this ); // we keep track of the selected date and the selected // event, start with selecting today. this.selectedEvent = null; this.selectedDate = new Date(); // set up the current view - we assume that this.currentView is NEVER null // after this this.currentView = null; //depending on the selected index, change views to that view. var SelectedIndex = document.getElementById( "calendar-deck" ).selectedIndex; switch( SelectedIndex ) { case "1": this.currentView = this.weekView; document.getElementById( "week-tree-hour-0" ).focus(); break; case "2": this.currentView = this.dayView; document.getElementById( "day-tree-item-0" ).focus(); break; case "3": this.currentView = this.multiweekView; break; default: this.currentView = this.monthView; break; } // now that everything is set up, we can start to observe the data source // make the observer, the calendarEventDataSource calls into the // observer when things change in the data source. var calendarWindow = this; this.calendarEventDataSourceObserver = { onLoad : function() { //this is basically useless, since the calendar window is not yet made yet. }, onStartBatch : function() { }, onEndBatch : function() { calendarWindow.currentView.refreshEvents( ); }, onAddItem : function( calendarEvent ) { if( !gICalLib.batchMode ) { if( calendarEvent ) { calendarWindow.setSelectedEvent( calendarEvent ); calendarWindow.currentView.refreshEvents( ); } } }, onModifyItem : function( calendarEvent, originalEvent ) { if( !gICalLib.batchMode ) { calendarWindow.currentView.refreshEvents( ); } }, onDeleteItem : function( calendarEvent, nextEvent ) { //if you put this outside of the batch mode, deleting all events //puts the calendar into an infinite loop. if( !gICalLib.batchMode ) { calendarWindow.currentView.refreshEvents( ); if ( nextEvent ) { calendarWindow.setSelectedEvent( nextEvent ); } else { //get the tree, see if there are items to highlight. var today = new Date( ); //calendarWindow.setSelectedDate( getNextOrPreviousRecurrence( calendarEvent ) ); calendarWindow.setSelectedDate( today ); if( "hiliteSelectedDate" in calendarWindow.currentView ) calendarWindow.currentView.hiliteSelectedDate( ); } } }, onAlarm : function( calendarEvent ) { }, onError : function() { } }; // add the observer to the event source gICalLib.addObserver( this.calendarEventDataSourceObserver ); } /** PUBLIC * * You must call this when you have finished with the CalendarWindow. * Removes the observer from the data source. */ CalendarWindow.prototype.close = function calWin_close( ) { gICalLib.removeObserver( this.calendarEventDataSourceObserver ); } /** PUBLIC * * Switch to the day view if it isn't already the current view */ CalendarWindow.prototype.switchToDayView = function calWin_switchToDayView( ) { document.getElementById( "day-tree-item-0" ).focus(); this.switchToView( this.dayView ) } /** PUBLIC * * Switch to the week view if it isn't already the current view */ CalendarWindow.prototype.switchToWeekView = function calWin_switchToWeekView( ) { document.getElementById( "week-tree-hour-0" ).focus(); this.switchToView( this.weekView ) } /** PUBLIC * * Switch to the month view if it isn't already the current view */ CalendarWindow.prototype.switchToMonthView = function calWin_switchToMonthView( ) { this.switchToView( this.monthView ) } /** PUBLIC * * Switch to the multiweek view if it isn't already the current view */ CalendarWindow.prototype.switchToMultiweekView = function calWin_switchToMultiweekView( ) { this.switchToView( this.multiweekView ) } /** PUBLIC * * Display today in the current view */ CalendarWindow.prototype.goToToday = function calWin_goToToday( ) { this.clearSelectedEvent( ); var Today = new Date(); this.currentView.goToDay( Today ); document.getElementById( "lefthandcalendar" ).value = Today; } /** PUBLIC * * Go to the next period in the current view */ CalendarWindow.prototype.goToNext = function calWin_goToNext( value ) { if(value){ this.currentView.goToNext( value ); }else{ this.currentView.goToNext(); } } /** PUBLIC * * Go to the previous period in the current view */ CalendarWindow.prototype.goToPrevious = function calWin_goToPrevious( value ) { if(value){ this.currentView.goToPrevious( value ); }else{ this.currentView.goToPrevious( ); } } /** PUBLIC * * Go to today in the current view */ CalendarWindow.prototype.goToDay = function calWin_goToDay( newDate ) { this.currentView.goToDay( newDate ); } /** PACKAGE * * Change the selected event * * PARAMETERS * selectedEvent - an instance of CalendarEvent, MUST be from the CalendarEventDataSource * */ CalendarWindow.prototype.setSelectedEvent = function calWin_setSelectedEvent( selectedEvent ) { this.EventSelection.replaceSelection( selectedEvent ); } /** PACKAGE * * Clear the selected event * * PARAMETERS * unSelectedEvent - if null: deselect the selected event. * - if a CalendarEvent: only deselect if it is the currently selected one. * */ CalendarWindow.prototype.clearSelectedEvent = function calWin_clearSelectedEvent( unSelectedEvent ) { var undefined; this.EventSelection.emptySelection( ); if( unSelectedEvent === undefined || unSelectedEvent == null ) { this.currentView.clearSelectedEvent( ); } } /** PUBLIC * * Set the selected date */ CalendarWindow.prototype.setSelectedDate = function calWin_setSelectedDate( date, noHighlight ) { // Copy the date because we might mess with it in place this.selectedDate = new Date( date ); /* on some machines, we need to check for .selectedItem first */ if( document.getElementById( "event-filter-menulist" ) && document.getElementById( "event-filter-menulist" ).selectedItem && document.getElementById( "event-filter-menulist" ).selectedItem.value == "current" ) { //redraw the top tree setTimeout( "refreshEventTree( getAndSetEventTable() );", 150 ); } if( "hiliteSelectedDate" in this.currentView && noHighlight != false ) this.currentView.hiliteSelectedDate( ); } /** PUBLIC * * Get the selected date */ CalendarWindow.prototype.getSelectedDate = function calWin_getSelectedDate( ) { // Copy the date because we might mess with it in place return new Date( this.selectedDate ); } /** PUBLIC * * Change the hour of the selected date */ CalendarWindow.prototype.setSelectedHour = function calWin_setSelectedHour( hour ) { var selectedDate = this.getSelectedDate(); selectedDate.setHours( hour ); selectedDate.setMinutes( 0 ); selectedDate.setSeconds( 0 ); this.setSelectedDate( selectedDate ); } /** PRIVATE * * Helper function to switch to a view * * PARAMETERS * newView - MUST be one of the three CalendarView instances created in the constructor */ CalendarWindow.prototype.switchToView = function calWin_switchToView( newView ) { // only switch if not already there if( this.currentView !== newView ) { // call switch from for the view we are leaving if( this.currentView ) { this.currentView.switchFrom(); } // change the current view this.currentView = newView; // switch to and refresh the view newView.switchTo(); newView.refresh(); } } /** PUBLIC * * This changes the text for the popuptooltip text * This is the same for any view. */ CalendarWindow.prototype.changeMouseOverInfo = function calWin_changeMouseOverInfo( calendarEvent, event ) { var Html = document.getElementById( "eventTooltip" ); while( Html.hasChildNodes() ) { Html.removeChild( Html.firstChild ); } if(event.currentTarget.calendarToDo) { var HolderBox = getPreviewTextForTask( event.currentTarget.calendarToDo ); } else { var HolderBox = getPreviewTextForRepeatingEvent( event.currentTarget.calendarEventDisplay ); } Html.appendChild( HolderBox ); } /** PRIVATE * * This returns the lowest element not in the array * eg. array(0, 0, 1, 3) would return 2 * Used to figure out where to put the day events. * */ CalendarWindow.prototype.getLowestElementNotInArray = function calWin_getLowestElementNotInArray( InputArray ) { var Temp = 1; var AllZero = true; //are all the elements in the array 0? //CAUTION: Watch the scope here. This function is called from inside a nested for loop. //You can't have the index variable named anything that is used in those for loops. for ( var Mike = 0; Mike < InputArray.length; Mike++ ) { if ( InputArray[Mike] > Temp ) { return (Temp); } if ( InputArray[Mike] > 0) { AllZero = false; Temp++; //don't increment if the array value is 0, otherwise add 1. } } if ( AllZero ) { return (1); } return (Temp); } /** PRIVATE * * Use this function to compare two numbers. Returns the difference. * This is used to sort an array, and sorts it in ascending order. * */ CalendarWindow.prototype.compareNumbers = function calWin_compareNumbers(a, b) { return a - b } CalendarWindow.prototype.onMouseUpCalendarSplitter = function calWinOnMouseUpCalendarSplitter() { //check if calendar-splitter is collapsed this.doResize(); } CalendarWindow.prototype.onMouseUpCalendarViewSplitter = function calWinOnMouseUpCalendarViewSplitter() { //check if calendar-view-splitter is collapsed if( document.getElementById( "bottom-events-box" ).getAttribute( "collapsed" ) != "true" ) { //do this because if they started with it collapsed, its not showing anything right now. //in a setTimeout to give the pull down menu time to draw. setTimeout( "refreshEventTree( getAndSetEventTable() );", 10 ); } this.doResize(); } /** PUBLIC * The resize handler, used to set the size of the views so they fit the screen. */ window.onresize = CalendarWindow.prototype.doResize = function calWin_doResize(){ gCalendarWindow.currentView.refresh(); } /*----------------------------------------------------------------- * CalendarView Class * * Abstract super class for the three view classes * * PROPERTIES * calendarWindow - instance of CalendarWindow that owns this view * */ function CalendarView( calendarWindow ) { this.calendarWindow = calendarWindow; } /** A way for subclasses to invoke the super constructor */ CalendarView.prototype.superConstructor = CalendarView; /** PUBLIC * * Select the date and show it in the view * Params: newDate: the new date to go to. * ShowEvent: Do we show an event being highlighted, or do we show a day being highlighted. */ CalendarView.prototype.goToDay = function calView_goToDay( newDate, ShowEvent ) { var oldDate = this.calendarWindow.getSelectedDate(); this.calendarWindow.setSelectedDate( newDate ); switch( this.calendarWindow.currentView ) { case this.calendarWindow.monthView: if( newDate.getFullYear() != oldDate.getFullYear() || newDate.getMonth() != oldDate.getMonth() ) { this.refresh( ShowEvent ) } break; case this.calendarWindow.multiweekView: case this.calendarWindow.weekView: case this.calendarWindow.dayView: if( newDate.getFullYear() != oldDate.getFullYear() || newDate.getMonth() != oldDate.getMonth() || newDate.getDate() != oldDate.getDate() ) { this.refresh( ShowEvent ) } break; } } /** PUBLIC * * Refresh display of events and the selection in the view */ CalendarView.prototype.refresh = function calView_refresh( ShowEvent ) { this.refreshDisplay( ShowEvent ) if(this.calendarWindow.currentView.doResize) this.calendarWindow.currentView.doResize(); this.refreshEvents() }