gecko-dev/calendar/resources/content/calendarRepeatOverlay.js

821 lines
22 KiB
JavaScript
Raw Normal View History

/* ***** 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 <garths@oeone.com>
* Mike Potter <mikep@oeone.com>
* Colin Phillips <colinp@oeone.com>
* Chris Charabaruk <ccharabaruk@meldstar.com>
* ArentJan Banck <ajbanck@planet.nl>
*
* 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");
}