/* ***** 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 * Colin Phillips * Chris Charabaruk * ArentJan Banck * * 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 ***** */ /** * Enable/Disable Repeat items */ function updateRepeatItemEnabled() { var exceptionsDateButton = document.getElementById( "exception-dates-button" ); var exceptionsDateText = document.getElementById( "exception-dates-text" ); var repeatCheckBox = document.getElementById( "repeat-checkbox" ); var repeatDisableList = document.getElementsByAttribute( "disable-controller", "repeat" ); if( repeatCheckBox.checked ) { exceptionsDateButton.setAttribute( "popup", "oe-date-picker-popup" ); exceptionsDateText.setAttribute( "popup", "oe-date-picker-popup" ); // call remove attribute beacuse some widget code checks for the presense of a // disabled attribute, not the value. for( var i = 0; i < repeatDisableList.length; ++i ) { if( repeatDisableList[i].getAttribute( "today" ) != "true" ) repeatDisableList[i].removeAttribute( "disabled" ); } } else { exceptionsDateButton.removeAttribute( "popup" ); exceptionsDateText.removeAttribute( "popup" ); for( var j = 0; j < repeatDisableList.length; ++j ) { repeatDisableList[j].setAttribute( "disabled", "true" ); } } // udpate plural/singular updateRepeatPlural(); updateAlarmPlural(); // update until items whenever repeat changes updateUntilItemEnabled(); // extra interface depending on units updateRepeatUnitExtensions(); } /** * Update plural singular menu items */ function updateRepeatPlural() { updateMenuPlural( "repeat-length-field", "repeat-length-units" ); } /** * Update plural singular menu items */ function updateAlarmPlural() { updateMenuPlural( "alarm-length-field", "alarm-length-units" ); } /** * Update plural singular menu items */ function updateMenuPlural( lengthFieldId, menuId ) { var field = document.getElementById( lengthFieldId ); var menu = document.getElementById( menuId ); // figure out whether we should use singular or plural var length = field.value; var newLabelNumber; if( Number( length ) > 1 ) { newLabelNumber = "labelplural" } else { newLabelNumber = "labelsingular" } // see what we currently show and change it if required var oldLabelNumber = menu.getAttribute( "labelnumber" ); if( newLabelNumber != oldLabelNumber ) { // remember what we are showing now menu.setAttribute( "labelnumber", newLabelNumber ); // update the menu items var items = menu.getElementsByTagName( "menuitem" ); for( var i = 0; i < items.length; ++i ) { var menuItem = items[i]; var newLabel = menuItem.getAttribute( newLabelNumber ); menuItem.label = newLabel; menuItem.setAttribute( "label", newLabel ); } // force the menu selection to redraw var saveSelectedIndex = menu.selectedIndex; menu.selectedIndex = -1; menu.selectedIndex = saveSelectedIndex; } } /** * Enable/Disable Until items */ function updateUntilItemEnabled() { var repeatUntilRadio = document.getElementById( "repeat-until-radio" ); var repeatCheckBox = document.getElementById( "repeat-checkbox" ); var repeatEndText = document.getElementById( "repeat-end-date-text" ); var repeatEndPicker = document.getElementById( "repeat-end-date-button" ); if( repeatCheckBox.checked && repeatUntilRadio.selected ) { repeatEndText.removeAttribute( "disabled" ); repeatEndText.setAttribute( "popup", "oe-date-picker-popup" ); repeatEndPicker.removeAttribute( "disabled" ); repeatEndPicker.setAttribute( "popup", "oe-date-picker-popup" ); } else { repeatEndText.setAttribute( "disabled", "true" ); repeatEndText.removeAttribute( "popup" ); repeatEndPicker.setAttribute( "disabled", "true" ); repeatEndPicker.removeAttribute( "popup" ); } } function updateRepeatUnitExtensions( ) { var repeatMenu = document.getElementById( "repeat-length-units" ); var weekExtensions = document.getElementById( "repeat-extenstions-week" ); var monthExtensions = document.getElementById( "repeat-extenstions-month" ); //FIX ME! WHEN THE WINDOW LOADS, THIS DOESN'T EXIST if( repeatMenu.selectedItem ) { switch( repeatMenu.selectedItem.value ) { case "days": weekExtensions.setAttribute( "collapsed", "true" ); monthExtensions.setAttribute( "collapsed", "true" ); break; case "weeks": weekExtensions.removeAttribute( "collapsed" ); monthExtensions.setAttribute( "collapsed", "true" ); updateAdvancedWeekRepeat(); break; case "months": weekExtensions.setAttribute( "collapsed", "true" ); monthExtensions.removeAttribute( "collapsed" ); updateAdvancedRepeatDayOfMonth(); break; case "years": weekExtensions.setAttribute( "collapsed", "true" ); monthExtensions.setAttribute( "collapsed", "true" ); break; } sizeToContent(); } } /** * Enable/Disable Start/End items */ function updateStartEndItemEnabled() { var allDayCheckBox = document.getElementById( "all-day-event-checkbox" ); var startTimeLabel = document.getElementById( "start-time-label" ); var startTimePicker = document.getElementById( "start-time-button" ); var startTimeText = document.getElementById( "start-time-text" ); var endTimeLabel = document.getElementById( "end-time-label" ); var endTimePicker = document.getElementById( "end-time-button" ); var endTimeText = document.getElementById( "end-time-text" ); if( allDayCheckBox.checked ) { // disable popups by removing the popup attribute startTimeLabel.setAttribute( "disabled", "true" ); startTimeText.setAttribute( "disabled", "true" ); startTimeText.removeAttribute( "popup" ); startTimePicker.setAttribute( "disabled", "true" ); startTimePicker.removeAttribute( "popup" ); endTimeLabel.setAttribute( "disabled", "true" ); endTimeText.setAttribute( "disabled", "true" ); endTimeText.removeAttribute( "popup" ); endTimePicker.setAttribute( "disabled", "true" ); endTimePicker.removeAttribute( "popup" ); } else { // enable popups by setting the popup attribute startTimeLabel.removeAttribute( "disabled" ); startTimeText.removeAttribute( "disabled" ); startTimeText.setAttribute( "popup", "oe-time-picker-popup" ); startTimePicker.removeAttribute( "disabled" ); startTimePicker.setAttribute( "popup", "oe-time-picker-popup" ); endTimeLabel.removeAttribute( "disabled" ); endTimeText.removeAttribute( "disabled" ); endTimeText.setAttribute( "popup", "oe-time-picker-popup" ); endTimePicker.removeAttribute( "disabled" ); endTimePicker.setAttribute( "popup", "oe-time-picker-popup" ); } } /** * Handle key down in repeat field */ function repeatLengthKeyDown( repeatField ) { updateRepeatPlural(); } /** * Handle key down in alarm field */ function alarmLengthKeyDown( repeatField ) { updateAlarmPlural(); } function repeatUnitCommand( repeatMenu ) { updateRepeatUnitExtensions(); } /* ** Functions for advanced repeating elements */ function setAdvancedWeekRepeat() { var checked = false; if( gEvent.recurWeekdays > 0 ) { for( var i = 0; i < 7; i++ ) { checked = ( ( gEvent.recurWeekdays | eval( "kRepeatDay_"+i ) ) == eval( gEvent.recurWeekdays ) ); setFieldValue( "advanced-repeat-week-"+i, checked, "checked" ); setFieldValue( "advanced-repeat-week-"+i, false, "today" ); } } //get the day number for today. var startTime = getDateTimeFieldValue( "start-date-text" ); var dayNumber = startTime.getDay(); setFieldValue( "advanced-repeat-week-"+dayNumber, "true", "checked" ); setFieldValue( "advanced-repeat-week-"+dayNumber, "true", "disabled" ); setFieldValue( "advanced-repeat-week-"+dayNumber, "true", "today" ); } /* ** Functions for advanced repeating elements */ function getAdvancedWeekRepeat() { var Total = 0; for( var i = 0; i < 7; i++ ) { if( getFieldValue( "advanced-repeat-week-"+i, "checked" ) == true ) { Total += eval( "kRepeatDay_"+i ); } } return( Total ); } /* ** function to set the menu items text */ function updateAdvancedWeekRepeat() { //get the day number for today. var startTime = getDateTimeFieldValue( "start-date-text" ); var dayNumber = startTime.getDay(); //uncheck them all if the repeat checkbox is checked var repeatCheckBox = document.getElementById( "repeat-checkbox" ); if( repeatCheckBox.checked ) { //uncheck them all for( var i = 0; i < 7; i++ ) { setFieldValue( "advanced-repeat-week-"+i, false, "disabled" ); setFieldValue( "advanced-repeat-week-"+i, false, "today" ); } } setFieldValue( "advanced-repeat-week-"+dayNumber, "true", "checked" ); setFieldValue( "advanced-repeat-week-"+dayNumber, "true", "disabled" ); setFieldValue( "advanced-repeat-week-"+dayNumber, "true", "today" ); } /* ** function to set the menu items text */ function updateAdvancedRepeatDayOfMonth() { //get the day number for today. var startTime = getDateTimeFieldValue( "start-date-text" ); var dayNumber = startTime.getDate(); var dayExtension = getDayExtension( dayNumber ); var weekNumber = getWeekNumberOfMonth(); document.getElementById( "advanced-repeat-dayofmonth" ).setAttribute( "label", "On the "+dayNumber+dayExtension+" of the month" ); if( weekNumber == 4 && isLastDayOfWeekOfMonth() ) { //enable document.getElementById( "advanced-repeat-dayofweek" ).setAttribute( "label", getWeekNumberText( weekNumber )+" "+getDayOfWeek( dayNumber )+" of the month" ); document.getElementById( "advanced-repeat-dayofweek-last" ).removeAttribute( "collapsed" ); document.getElementById( "advanced-repeat-dayofweek-last" ).setAttribute( "label", "Last "+getDayOfWeek( dayNumber )+" of the month" ); } else if( weekNumber == 4 && !isLastDayOfWeekOfMonth() ) { document.getElementById( "advanced-repeat-dayofweek" ).setAttribute( "label", getWeekNumberText( weekNumber )+" "+getDayOfWeek( dayNumber )+" of the month" ); document.getElementById( "advanced-repeat-dayofweek-last" ).setAttribute( "collapsed", "true" ); } else { //disable document.getElementById( "advanced-repeat-dayofweek" ).setAttribute( "collapsed", "true" ); document.getElementById( "advanced-repeat-dayofweek-last" ).setAttribute( "label", "Last "+getDayOfWeek( dayNumber )+" of the month" ); } } /* ** function to enable or disable the add exception button */ function updateAddExceptionButton() { //get the date from the picker var datePickerValue = getDateTimeFieldValue( "exception-dates-text" ); if( isAlreadyException( datePickerValue ) || document.getElementById( "repeat-checkbox" ).getAttribute( "checked" ) != "true" ) { document.getElementById( "exception-add-button" ).setAttribute( "disabled", "true" ); } else { document.getElementById( "exception-add-button" ).removeAttribute( "disabled" ); } } function removeSelectedExceptionDate() { var Listbox = document.getElementById( "exception-dates-listbox" ); var SelectedItem = Listbox.selectedItem; if( SelectedItem ) Listbox.removeChild( SelectedItem ); } function addException( dateToAdd ) { if( !dateToAdd ) { //get the date from the date and time box. //returns a date object var dateToAdd = getDateTimeFieldValue( "exception-dates-text" ); } if( isAlreadyException( dateToAdd ) ) return; var DateLabel = formatDate( dateToAdd ); //add a row to the listbox document.getElementById( "exception-dates-listbox" ).appendItem( DateLabel, dateToAdd.getTime() ); sizeToContent(); } function isAlreadyException( dateObj ) { //check to make sure that the date is not already added. var listbox = document.getElementById( "exception-dates-listbox" ); for( var i = 0; i < listbox.childNodes.length; i++ ) { var dateToMatch = new Date( ); dateToMatch.setTime( listbox.childNodes[i].value ); if( dateToMatch.getMonth() == dateObj.getMonth() && dateToMatch.getFullYear() == dateObj.getFullYear() && dateToMatch.getDate() == dateObj.getDate() ) return true; } return false; } function getDayExtension( dayNumber ) { switch( dayNumber ) { case 1: case 21: case 31: return( "st" ); case 2: case 22: return( "nd" ); case 3: case 23: return( "rd" ); default: return( "th" ); } } function getDayOfWeek( ) { //get the day number for today. var startTime = getDateTimeFieldValue( "start-date-text" ); var dayNumber = startTime.getDay(); var dateStringBundle = srGetStrBundle("chrome://calendar/locale/dateFormat.properties"); //add one to the dayNumber because in the above prop. file, it starts at day1, but JS starts at 0 var oneBasedDayNumber = parseInt( dayNumber ) + 1; return( dateStringBundle.GetStringFromName( "day."+oneBasedDayNumber+".name" ) ); } function getWeekNumberOfMonth() { //get the day number for today. var startTime = getDateTimeFieldValue( "start-date-text" ); var oldStartTime = startTime; var thisMonth = startTime.getMonth(); var monthToCompare = thisMonth; var weekNumber = 0; while( monthToCompare == thisMonth ) { startTime = new Date( startTime.getTime() - ( 1000 * 60 * 60 * 24 * 7 ) ); monthToCompare = startTime.getMonth(); weekNumber++; } return( weekNumber ); } function isLastDayOfWeekOfMonth() { //get the day number for today. var startTime = getDateTimeFieldValue( "start-date-text" ); var oldStartTime = startTime; var thisMonth = startTime.getMonth(); var monthToCompare = thisMonth; var weekNumber = 0; while( monthToCompare == thisMonth ) { startTime = new Date( startTime.getTime() - ( 1000 * 60 * 60 * 24 * 7 ) ); monthToCompare = startTime.getMonth(); weekNumber++; } if( weekNumber > 3 ) { var nextWeek = new Date( oldStartTime.getTime() + ( 1000 * 60 * 60 * 24 * 7 ) ); if( nextWeek.getMonth() != thisMonth ) { //its the last week of the month return( true ); } } return( false ); } /* FILE ATTACHMENTS */ function removeSelectedAttachment() { var Listbox = document.getElementById( "attachmentBucket" ); var SelectedItem = Listbox.selectedItem; if( SelectedItem ) Listbox.removeChild( SelectedItem ); } function addAttachment( attachmentToAdd ) { if( !attachmentToAdd ) { return; } //add a row to the listbox document.getElementById( "attachmentBucket" ).appendItem( attachmentToAdd.url, attachmentToAdd.url ); sizeToContent(); } function getWeekNumberText( weekNumber ) { switch( weekNumber ) { case 1: return( "First" ); case 2: return( "Second" ); case 3: return( "Third" ); case 4: return( "Fourth" ); case 5: return( "Last" ); default: return( false ); } } /* URL */ function launchBrowser() { //get the URL from the text box var UrlToGoTo = document.getElementById( "uri-field" ).value; //launch the browser to that URL opener.open( UrlToGoTo, "calendar-opened-window" ); } /** * Helper function for filling the form, set the value of a property of a XUL element * * PARAMETERS * elementId - ID of XUL element to set * newValue - value to set property to ( if undefined no change is made ) * propertyName - OPTIONAL name of property to set, default is "value", use "checked" for * radios & checkboxes, "data" for drop-downs */ function setFieldValue( elementId, newValue, propertyName ) { var undefined; if( newValue !== undefined ) { var field = document.getElementById( elementId ); if( newValue === false ) { field.removeAttribute( propertyName ); } else { if( propertyName ) { field.setAttribute( propertyName, newValue ); } else { field.value = newValue; } } } } /** * Helper function for getting data from the form, * Get the value of a property of a XUL element * * PARAMETERS * elementId - ID of XUL element to get from * propertyName - OPTIONAL name of property to set, default is "value", use "checked" for * radios & checkboxes, "data" for drop-downs * RETURN * newValue - value of property */ function getFieldValue( elementId, propertyName ) { var field = document.getElementById( elementId ); if( propertyName ) { return field[ propertyName ]; } else { return field.value; } } /** * Helper function for getting a date/time from the form. * The element must have been set up with setDateFieldValue or setTimeFieldValue. * * PARAMETERS * elementId - ID of XUL element to get from * RETURN * newValue - Date value of element */ function getDateTimeFieldValue( elementId ) { var field = document.getElementById( elementId ); return field.editDate; } /** * Helper function for filling the form, set the value of a date field * * PARAMETERS * elementId - ID of time textbox to set * newDate - Date Object to use */ function setDateFieldValue( elementId, newDate ) { // set the value to a formatted date string var field = document.getElementById( elementId ); field.value = formatDate( newDate ); // add an editDate property to the item to hold the Date object // used in onDatePick to update the date from the date picker. // used in getDateTimeFieldValue to get the Date back out. // we clone the date object so changes made in place do not propagte field.editDate = new Date( newDate ); } /** * Helper function for filling the form, set the value of a time field * * PARAMETERS * elementId - ID of time textbox to set * newDate - Date Object to use */ function setTimeFieldValue( elementId, newDate ) { // set the value to a formatted time string var field = document.getElementById( elementId ); field.value = formatTime( newDate ); // add an editDate property to the item to hold the Date object // used in onTimePick to update the date from the time picker. // used in getDateTimeFieldValue to get the Date back out. // we clone the date object so changes made in place do not propagte field.editDate = new Date( newDate ); } /** * Take a Date object and return a displayable date string i.e.: May 5, 1959 * :TODO: This should be moved into DateFormater and made to use some kind of * locale or user date format preference. */ function formatDate( date ) { return( opener.gCalendarWindow.dateFormater.getFormatedDate( date ) ); } /** * Take a Date object and return a displayable time string i.e.: 12:30 PM */ function formatTime( time ) { var timeString = opener.gCalendarWindow.dateFormater.getFormatedTime( time ); return timeString; } function debug( Text ) { dump( "\n"+ Text + "\n"); }