mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-01 17:23:59 +00:00
Fixing import export bugs.
This commit is contained in:
parent
959f7765c8
commit
231abc4a95
@ -78,7 +78,7 @@ h1 {
|
||||
|
||||
<td id="mozver">
|
||||
<h1>
|
||||
<a id="mozlink" href="http://www.mozilla.org/projects/calendar/" target="_new">Mozilla Calendar 2002073111-cal</a>
|
||||
<a id="mozlink" href="http://www.mozilla.org/projects/calendar/" target="_new">Mozilla Calendar 2002081513-cal</a>
|
||||
</h1>
|
||||
<script type="application/x-javascript">
|
||||
// using try..catch to handle empty useragents and other cases where the regex fails to apply
|
||||
|
@ -664,9 +664,9 @@ function changeToolTipTextForToDo( event )
|
||||
DateHtml.appendChild( DateText );
|
||||
HolderBox.appendChild( DateHtml );
|
||||
|
||||
var DateHtml = document.createElement( "description" );
|
||||
DateHtml = document.createElement( "description" );
|
||||
var dueDate = new Date( toDoItem.due.getTime() );
|
||||
var DateText = document.createTextNode( "Due Date: "+gCalendarWindow.dateFormater.getFormatedDate( dueDate ) );
|
||||
DateText = document.createTextNode( "Due Date: "+gCalendarWindow.dateFormater.getFormatedDate( dueDate ) );
|
||||
DateHtml.appendChild( DateText );
|
||||
HolderBox.appendChild( DateHtml );
|
||||
|
||||
@ -720,9 +720,9 @@ function getPreviewText( calendarEvent )
|
||||
DateHtml.appendChild( DateText );
|
||||
HolderBox.appendChild( DateHtml );
|
||||
|
||||
var DateHtml = document.createElement( "description" );
|
||||
DateHtml = document.createElement( "description" );
|
||||
var endDate = new Date( calendarEvent.end.getTime() );
|
||||
var DateText = document.createTextNode( "End: "+gCalendarWindow.dateFormater.getFormatedDate( endDate )+" "+gCalendarWindow.dateFormater.getFormatedTime( endDate ) );
|
||||
DateText = document.createTextNode( "End: "+gCalendarWindow.dateFormater.getFormatedDate( endDate )+" "+gCalendarWindow.dateFormater.getFormatedTime( endDate ) );
|
||||
DateHtml.appendChild( DateText );
|
||||
HolderBox.appendChild( DateHtml );
|
||||
|
||||
@ -774,3 +774,80 @@ function reloadApplication()
|
||||
{
|
||||
gCalendarWindow.currentView.refreshEvents();
|
||||
}
|
||||
|
||||
|
||||
/** PUBLIC
|
||||
*
|
||||
* Print events using a stylesheet.
|
||||
* Mostly Hack to get going, Should probably be rewritten later when stylesheets are available
|
||||
* XXX Is it possible to directly load the document into a window without tempfile?
|
||||
*/
|
||||
|
||||
var printWindow;
|
||||
var tempfile;
|
||||
|
||||
// the print is called with a timeout, otherwise the document isn't loaded before printing.
|
||||
// onload event didn't seem to fire.
|
||||
function delayedPrint()
|
||||
{
|
||||
printWindow.print();
|
||||
printWindow.close();
|
||||
if( tempfile.exists() )
|
||||
tempfile.remove( false );
|
||||
}
|
||||
|
||||
// returns a nsIFile object of a unique file in the temp directory
|
||||
function makeTempFile( extension )
|
||||
{
|
||||
const osTempDir = "TmpD";
|
||||
const flContractID = "@mozilla.org/file/directory_service;1";
|
||||
const flIID = Components.interfaces.nsIProperties;
|
||||
var fileLocator = Components.classes[flContractID].getService(flIID);
|
||||
var tempFile = fileLocator.get(osTempDir, Components.interfaces.nsIFile);
|
||||
tempFile.append("~tmp" + Math.floor(Math.random() * 1000) + extension );
|
||||
|
||||
return tempFile;
|
||||
}
|
||||
|
||||
function printEventArray( calendarEventArray, stylesheet )
|
||||
{
|
||||
var xcsDocument = getXcsDocument( calendarEventArray );
|
||||
|
||||
var newProcessInstruction = xcsDocument.createProcessingInstruction(
|
||||
"xml-stylesheet",
|
||||
"href=\"" + stylesheet + "\" type=\"text/xsl\"");
|
||||
xcsDocument.insertBefore(newProcessInstruction, xcsDocument.firstChild);
|
||||
|
||||
newProcessInstruction = xcsDocument.createProcessingInstruction(
|
||||
"xml", "version=\"1.0\" encoding=\"UTF-8\"");
|
||||
xcsDocument.insertBefore(newProcessInstruction, xcsDocument.firstChild);
|
||||
|
||||
var serializer = new XMLSerializer;
|
||||
var serialDocument = serializer.serializeToString ( xcsDocument );
|
||||
|
||||
// XXX TODO Can we directly load the xml-document into a window???
|
||||
tempfile = makeTempFile( ".xml" );
|
||||
saveDataToFile(tempfile.path, serialDocument);
|
||||
|
||||
var tempfileUrl = Components.classes["@mozilla.org/network/standard-url;1"].createInstance(Components.interfaces.nsIFileURL);
|
||||
tempfileUrl.file = tempfile;
|
||||
|
||||
printWindow = window.open( tempfileUrl.spec );
|
||||
if( printWindow )
|
||||
{
|
||||
printWindow.locationbar.visible = false;
|
||||
printWindow.personalbar.visible = false;
|
||||
printWindow.statusbar.visible = false;
|
||||
printWindow.toolbar.visible = false;
|
||||
|
||||
// XXX HACK open is async, find a way to detect if content is loaded
|
||||
// using onload doesn't fire?
|
||||
setTimeout("delayedPrint()", 1000);
|
||||
}
|
||||
}
|
||||
|
||||
function print()
|
||||
{
|
||||
printEventArray(
|
||||
gCalendarWindow.EventSelection.selectedEvents, "chrome://calendar/content/converters/sortEvents.xsl" );
|
||||
}
|
||||
|
@ -87,6 +87,7 @@
|
||||
<command id="delete_command_no_confirm" oncommand="unifinderDeleteCommand( true )" disabled="true"/>
|
||||
<command id="modify_command" oncommand="unifinderEditCommand()" disabled="true"/>
|
||||
<command id="send_event_command" oncommand="sendEvent()" disabled="true"/>
|
||||
<command id="print_command" oncommand="print()" disabled="true"/>
|
||||
<command id="cut_command" oncommand="cutToClipboard()" disabled="true"/>
|
||||
<command id="copy_command" oncommand="copyToClipboard()" disabled="true"/>
|
||||
<command id="paste_command" oncommand="pasteFromClipboard()"/>
|
||||
@ -114,6 +115,7 @@
|
||||
<key id="new_event_key" key="N" modifiers="control" observes="new_command"/>
|
||||
<key id="new_todo_key" key="M" modifiers="control" observes="new_todo_command"/>
|
||||
<key id="modify_event_key" key="E" modifiers="control" observes="modify_command"/>
|
||||
<key id="print_key" key="P" modifiers="control" observes="print_command"/>
|
||||
<key id="import_key" key="I" modifiers="control" observes="import_command"/>
|
||||
<key id="export_key" key="O" modifiers="control" observes="export_command"/>
|
||||
|
||||
|
@ -155,10 +155,6 @@ DayView.prototype.refreshEvents = function( )
|
||||
//}
|
||||
//TextNode.setAttribute( "value", "All-Day Events: " );
|
||||
|
||||
//set the seperator to nothing. After the first one, we'll change it to ", " so that we add commas between text.
|
||||
|
||||
var Seperator = " ";
|
||||
|
||||
// get the events for the day and loop through them
|
||||
|
||||
var dayEventList = this.calendarWindow.eventSource.getEventsForDay( this.calendarWindow.getSelectedDate() );
|
||||
@ -247,10 +243,6 @@ DayView.prototype.refreshEvents = function( )
|
||||
//note the use of the AllDayText Attribute.
|
||||
//This is used to remove the text when the day is changed.
|
||||
|
||||
SeperatorNode = document.createElement( "label" );
|
||||
SeperatorNode.setAttribute( "value", Seperator );
|
||||
//SeperatorNode.setAttribute( "AllDayText", "true" );
|
||||
|
||||
newTextNode = document.createElement( "label" );
|
||||
newTextNode.setAttribute( "value", eventText );
|
||||
newTextNode.calendarEventDisplay = calendarEventDisplay;
|
||||
@ -258,8 +250,7 @@ DayView.prototype.refreshEvents = function( )
|
||||
newTextNode.setAttribute( "onclick", "dayEventItemClick( this, event )" );
|
||||
newTextNode.setAttribute( "ondblclick", "dayEventItemDoubleClick( this, event )" );
|
||||
newTextNode.setAttribute( "tooltip", "savetip" );
|
||||
|
||||
//newTextNode.setAttribute( "AllDayText", "true" );
|
||||
newTextNode.setAttribute( "AllDayText", "true" );
|
||||
|
||||
newImage = document.createElement("image");
|
||||
newImage.setAttribute( "class", "all-day-event-class" );
|
||||
@ -270,12 +261,8 @@ DayView.prototype.refreshEvents = function( )
|
||||
newImage.setAttribute( "tooltip", "savetip" );
|
||||
//newImage.setAttribute( "AllDayText", "true" );
|
||||
|
||||
AllDayBox.appendChild( SeperatorNode );
|
||||
AllDayBox.appendChild( newImage );
|
||||
AllDayBox.appendChild( newTextNode );
|
||||
|
||||
//change the seperator to add commas after the text.
|
||||
Seperator = ", ";
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -39,6 +39,8 @@
|
||||
*
|
||||
****/
|
||||
|
||||
// XSL stylesheet directory
|
||||
var convertersDirectory = "chrome://calendar/content/converters/";
|
||||
|
||||
// File constants copied from file-utils.js
|
||||
const MODE_RDONLY = 0x01;
|
||||
@ -50,6 +52,21 @@ const MODE_TRUNCATE = 0x20;
|
||||
const MODE_SYNC = 0x40;
|
||||
const MODE_EXCL = 0x80;
|
||||
|
||||
const filterCalendar = "Calendar Files";
|
||||
const extensionCalendar = ".ics";
|
||||
const filterXcs = "iCalendar XML Document";
|
||||
const extensionXcs = ".xcs";
|
||||
const filterXml = "XML Document";
|
||||
const extensionXml = ".xml";
|
||||
const filterRtf = "Rich Text Format (RTF)";
|
||||
const extensionRtf = ".rtf";
|
||||
const filterHtml = "HTML Files";
|
||||
const extensionHtml = ".html";
|
||||
const filterCsv = "Comma Separated";
|
||||
const extensionCsv = ".csv";
|
||||
const filterRdf = "iCalendar RDF";
|
||||
const extensionRdf = ".rdf";
|
||||
|
||||
|
||||
/**** loadEventsFromFile
|
||||
* shows a file dialog, read the selected file and tries to parse events from it.
|
||||
@ -63,18 +80,27 @@ function loadEventsFromFile()
|
||||
|
||||
fp.init(window, "Open", nsIFilePicker.modeOpen);
|
||||
|
||||
// fp.defaultString = "*.ics";
|
||||
fp.defaultExtension = "ics"
|
||||
|
||||
fp.appendFilter( "Calendar Files", "*.ics" );
|
||||
fp.appendFilter( filterCalendar, "*" + extensionCalendar );
|
||||
fp.appendFilter( filterXcs, "*" + extensionXcs );
|
||||
|
||||
fp.show();
|
||||
|
||||
if (fp.file && fp.file.path.length > 0)
|
||||
{
|
||||
var aDataStream = readDataFromFile( fp.file.path );
|
||||
var calendarEventArray = parseIcalData( aDataStream );
|
||||
var calendarEventArray;
|
||||
|
||||
switch (fp.filterIndex) {
|
||||
case 0 : // ics
|
||||
calendarEventArray = parseIcalData( aDataStream );
|
||||
break;
|
||||
case 1 : // xcs
|
||||
calendarEventArray = parseXCSData( aDataStream );
|
||||
break;
|
||||
}
|
||||
|
||||
// Show a dialog with option to import events with or without dialogs
|
||||
var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService();
|
||||
promptService = promptService.QueryInterface(Components.interfaces.nsIPromptService);
|
||||
@ -89,17 +115,20 @@ function loadEventsFromFile()
|
||||
null,null,null,null, result);
|
||||
if(buttonPressed == 0) // YES
|
||||
{
|
||||
addEventsToCalendar( calendarEventArray );
|
||||
}
|
||||
addEventsToCalendar( calendarEventArray );
|
||||
return true;
|
||||
}
|
||||
else if(buttonPressed == 1) // NO
|
||||
{
|
||||
addEventsToCalendar( calendarEventArray, true );
|
||||
addEventsToCalendar( calendarEventArray, true );
|
||||
return true;
|
||||
}
|
||||
else if(buttonPressed == 2) // CANCEL
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -247,13 +276,13 @@ function parseIcalData( icalStr )
|
||||
|
||||
calendarEvent = createEvent();
|
||||
|
||||
// if parsing import iCalendar failed, add date as description
|
||||
if ( !calendarEvent.parseIcalString(eventData) )
|
||||
// parsing import iCalendar failed.
|
||||
{
|
||||
// initialize start and end dates.
|
||||
initCalendarEvent( calendarEvent );
|
||||
|
||||
// Save clipboard text into description.
|
||||
// Save the parsed text as description.
|
||||
calendarEvent.description = icalStr;
|
||||
}
|
||||
|
||||
@ -265,6 +294,20 @@ function parseIcalData( icalStr )
|
||||
return calendarEventArray;
|
||||
}
|
||||
|
||||
/**** parseXCSData
|
||||
*
|
||||
*/
|
||||
|
||||
function parseXCSData( xcsString )
|
||||
{
|
||||
var gParser = new DOMParser;
|
||||
var xmlDocument = gParser.parseFromString(xcsString, 'text/xml');
|
||||
|
||||
var result = serializeDocument(xmlDocument, "xcs2ics.xsl");
|
||||
|
||||
return parseIcalData( result );
|
||||
}
|
||||
|
||||
|
||||
/**** readDataFromFile
|
||||
*
|
||||
@ -318,7 +361,7 @@ function readDataFromFile( aFilePath )
|
||||
function saveEventsToFile( calendarEventArray )
|
||||
{
|
||||
if( !calendarEventArray)
|
||||
var calendarEventArray = gCalendarWindow.EventSelection.selectedEvents;
|
||||
calendarEventArray = gCalendarWindow.EventSelection.selectedEvents;
|
||||
|
||||
if (calendarEventArray.length == 0)
|
||||
{
|
||||
@ -328,38 +371,65 @@ function saveEventsToFile( calendarEventArray )
|
||||
|
||||
// No show the 'Save As' dialog and ask for a filename to save to
|
||||
const nsIFilePicker = Components.interfaces.nsIFilePicker;
|
||||
|
||||
|
||||
var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
|
||||
|
||||
|
||||
// caller can force disable of sand box, even if ON globally
|
||||
|
||||
|
||||
fp.init(window, "Save As", nsIFilePicker.modeSave);
|
||||
|
||||
fp.defaultString = "Mozilla Calendar events";
|
||||
|
||||
if(calendarEventArray.length == 1 && calendarEventArray[0].title)
|
||||
fp.defaultString = calendarEventArray[0].title;
|
||||
else
|
||||
fp.defaultString = "Mozilla Calendar events";
|
||||
|
||||
fp.defaultExtension = "ics";
|
||||
|
||||
fp.appendFilter( "Calendar Files", "*.ics" );
|
||||
fp.appendFilter( "Rich Text Format (RTF)", "*.rtf" );
|
||||
fp.appendFilter( filterCalendar, "*" + extensionCalendar );
|
||||
fp.appendFilter( filterRtf, "*" + extensionRtf );
|
||||
fp.appendFilters(nsIFilePicker.filterHTML);
|
||||
|
||||
fp.appendFilter( filterCsv, "*" + extensionCsv );
|
||||
fp.appendFilter( filterXcs, "*" + extensionXcs );
|
||||
fp.appendFilter( filterRdf, "*" + extensionRdf );
|
||||
|
||||
fp.show();
|
||||
|
||||
// Now find out as what to save, convert the events and save to file.
|
||||
if (fp.file && fp.file.path.length > 0)
|
||||
{
|
||||
var aDataStream;
|
||||
var extension;
|
||||
switch (fp.filterIndex) {
|
||||
case 0 : // ics
|
||||
aDataStream = eventArrayToICalString( calendarEventArray, true );
|
||||
extension = extensionCalendar;
|
||||
break;
|
||||
case 1 : // rtf
|
||||
aDataStream = eventArrayToRTF( calendarEventArray );
|
||||
extension = extensionRtf;
|
||||
break;
|
||||
case 2 : // html
|
||||
aDataStream = eventArrayToHTML( calendarEventArray );
|
||||
extension = ".htm";
|
||||
break;
|
||||
case 3 : // csv
|
||||
aDataStream = eventArrayToCsv( calendarEventArray );
|
||||
extension = extensionCsv;
|
||||
break;
|
||||
case 4 : // xCal
|
||||
aDataStream = eventArrayToXCS( calendarEventArray );
|
||||
extension = extensionXcs;
|
||||
break;
|
||||
case 5 : // rdf
|
||||
aDataStream = eventArrayToRdf( calendarEventArray );
|
||||
extension = extensionRdf;
|
||||
break;
|
||||
}
|
||||
saveDataToFile(fp.file.path, aDataStream);
|
||||
var filePath = fp.file.path;
|
||||
if(filePath.indexOf(".") == -1 )
|
||||
filePath += extension;
|
||||
|
||||
saveDataToFile(filePath, aDataStream);
|
||||
}
|
||||
}
|
||||
|
||||
@ -485,6 +555,74 @@ function eventArrayToRTF( calendarEventArray )
|
||||
}
|
||||
|
||||
|
||||
/**** eventArrayToXML
|
||||
* Converts a array of events to a XML string
|
||||
*/
|
||||
/*
|
||||
function eventArrayToXML( calendarEventArray )
|
||||
{
|
||||
var xmlDocument = getXmlDocument( calendarEventArray );
|
||||
var serializer = new XMLSerializer;
|
||||
|
||||
return serializer.serializeToString (xmlDocument )
|
||||
}
|
||||
*/
|
||||
|
||||
/**** eventArrayToCsv
|
||||
* Converts a array of events to comma delimited text.
|
||||
*/
|
||||
|
||||
function eventArrayToCsv( calendarEventArray )
|
||||
{
|
||||
var xcsDocument = getXcsDocument( calendarEventArray );
|
||||
|
||||
return serializeDocument( xcsDocument, "xcs2csv.xsl" );
|
||||
}
|
||||
|
||||
|
||||
/**** eventArrayToRdf
|
||||
* Converts a array of events to RDF
|
||||
*/
|
||||
|
||||
function eventArrayToRdf( calendarEventArray )
|
||||
{
|
||||
var xcsDocument = getXcsDocument( calendarEventArray );
|
||||
|
||||
return serializeDocument( xcsDocument, "xcs2rdf.xsl" );
|
||||
}
|
||||
|
||||
|
||||
/**** eventArrayToXCS
|
||||
* Converts a array of events to a xCal string
|
||||
*/
|
||||
|
||||
function eventArrayToXCS( calendarEventArray )
|
||||
{
|
||||
var xmlDoc = getXmlDocument( calendarEventArray );
|
||||
var xcsDoc = transformXML( xmlDoc, "xml2xcs.xsl" );
|
||||
// add the doctype
|
||||
/* Doctype uri blocks excel import
|
||||
var newdoctype = xcsDoc.implementation.createDocumentType(
|
||||
"iCalendar",
|
||||
"-//IETF//DTD XCAL//iCalendar XML//EN",
|
||||
"http://www.ietf.org/internet-drafts/draft-ietf-calsch-many-xcal-02.txt");
|
||||
if (newdoctype)
|
||||
xcsDoc.insertBefore(newdoctype, xcsDoc.firstChild);
|
||||
*/
|
||||
var serializer = new XMLSerializer;
|
||||
|
||||
// XXX MAJOR UGLY HACK!! Serializer doesn't insert XML Declaration
|
||||
// http://bugzilla.mozilla.org/show_bug.cgi?id=63558
|
||||
var serialDocument = serializer.serializeToString ( xcsDoc );
|
||||
|
||||
if( serialDocument.indexOf( "<?xml" ) == -1 )
|
||||
serialDocument = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + serialDocument;
|
||||
|
||||
return serialDocument;
|
||||
// return serializer.serializeToString ( xcsDoc )
|
||||
}
|
||||
|
||||
|
||||
/**** saveDataToFile
|
||||
*
|
||||
* Save data to a file. Creates a new file or overwrites an existing file.
|
||||
@ -500,7 +638,7 @@ function saveDataToFile(aFilePath, aDataStream)
|
||||
var localFileInstance;
|
||||
var outputStream;
|
||||
|
||||
LocalFileInstance = Components.classes[LOCALFILE_CTRID].createInstance(nsILocalFile);
|
||||
var LocalFileInstance = Components.classes[LOCALFILE_CTRID].createInstance(nsILocalFile);
|
||||
LocalFileInstance.initWithPath(aFilePath);
|
||||
|
||||
outputStream = Components.classes[FILEOUT_CTRID].createInstance(nsIFileOutputStream);
|
||||
@ -516,3 +654,332 @@ function saveDataToFile(aFilePath, aDataStream)
|
||||
alert("Unable to write to file: " + aFilePath );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////
|
||||
// XML/XSL functions //
|
||||
////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Get the local path to the chrome directory
|
||||
*/
|
||||
/*
|
||||
function getChromeDir()
|
||||
{
|
||||
const JS_DIR_UTILS_FILE_DIR_CID = "@mozilla.org/file/directory_service;1";
|
||||
const JS_DIR_UTILS_I_PROPS = "nsIProperties";
|
||||
const JS_DIR_UTILS_DIR = new Components.Constructor(JS_DIR_UTILS_FILE_DIR_CID, JS_DIR_UTILS_I_PROPS);
|
||||
const JS_DIR_UTILS_CHROME_DIR = "AChrom";
|
||||
|
||||
var rv;
|
||||
|
||||
try
|
||||
{
|
||||
rv=(new JS_DIR_UTILS_DIR()).get(JS_DIR_UTILS_CHROME_DIR, Components.interfaces.nsIFile);
|
||||
}
|
||||
|
||||
catch (e)
|
||||
{
|
||||
//jslibError(e, "(unexpected error)", "NS_ERROR_FAILURE", JS_DIR_UTILS_FILE+":getChromeDir");
|
||||
rv=null;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
function getTemplatesPath( templateName )
|
||||
{
|
||||
var templatesDir = getChromeDir();
|
||||
templatesDir.append( "calendar" );
|
||||
templatesDir.append( "content" );
|
||||
templatesDir.append( "templates" );
|
||||
templatesDir.append( templateName );
|
||||
return templatesDir.path;
|
||||
}
|
||||
|
||||
function xslt(xmlUri, xslUri)
|
||||
{
|
||||
// TODO: Check uri's for CHROME:// and convert path to local path
|
||||
var xslProc = new XSLTProcessor();
|
||||
|
||||
var result = document.implementation.createDocument("", "", null);
|
||||
var xmlDoc = document.implementation.createDocument("", "", null);
|
||||
var xslDoc = document.implementation.createDocument("", "", null);
|
||||
|
||||
xmlDoc.load(xmlUri, "text/xml");
|
||||
xslDoc.load(xslUri, "text/xml");
|
||||
xslProc.transformDocument(xmlDoc, xslDoc, result, null);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
/** PRIVATE
|
||||
*
|
||||
* Opens a file and returns the content
|
||||
* It supports Uri's like chrome://
|
||||
*/
|
||||
|
||||
function loadFile(aUriSpec)
|
||||
{
|
||||
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
|
||||
var serv = Components.classes["@mozilla.org/network/io-service;1"].
|
||||
getService(Components.interfaces.nsIIOService);
|
||||
if (!serv) {
|
||||
throw Components.results.ERR_FAILURE;
|
||||
}
|
||||
var chan = serv.newChannel(aUriSpec, null, null);
|
||||
var instream =
|
||||
Components.classes["@mozilla.org/scriptableinputstream;1"].createInstance(Components.interfaces.nsIScriptableInputStream);
|
||||
instream.init(chan.open());
|
||||
|
||||
return instream.read(instream.available());
|
||||
}
|
||||
|
||||
/** PUBLIC GetXcsDocument
|
||||
*
|
||||
*/
|
||||
|
||||
function getXcsDocument( calendarEventArray )
|
||||
{
|
||||
var xmlDocument = getXmlDocument( calendarEventArray );
|
||||
|
||||
var xcsDocument = transformXML( xmlDocument, "xml2xcs.xsl" );
|
||||
|
||||
var processingInstruction = xcsDocument.createProcessingInstruction(
|
||||
"xml", "version=\"1.0\" encoding=\"UTF-8\"");
|
||||
// xcsDocument.insertBefore(processingInstruction, xcsDocument.firstChild);
|
||||
|
||||
return xcsDocument;
|
||||
}
|
||||
|
||||
|
||||
/** PUBLIC
|
||||
*
|
||||
* Opens a xsl transformation file and applies it to xmlDocuments.
|
||||
* xslFile can be in the convertersDirectory, or a full Uri
|
||||
* Returns the resulting document
|
||||
*/
|
||||
|
||||
function transformXML( xmlDocument, xslFilename )
|
||||
{
|
||||
var xslProc = new XSLTProcessor();
|
||||
var gParser = new DOMParser;
|
||||
// .load isn't synchrone
|
||||
// var xslDoc = document.implementation.createDocument("", "", null);
|
||||
// xslDoc.load(path, "text/xml");
|
||||
|
||||
// if only passsed a filename, assume it is a file in the default directory
|
||||
if( xslFilename.indexOf( ":" ) == -1 )
|
||||
xslFilename = convertersDirectory + xslFilename;
|
||||
|
||||
var xslContent = loadFile( xslFilename );
|
||||
var xslDocument = gParser.parseFromString(xslContent, 'text/xml');
|
||||
var result = document.implementation.createDocument("", "", null);
|
||||
|
||||
xslProc.transformDocument(xmlDocument, xslDocument, result, null);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/** PUBLIC
|
||||
*
|
||||
* Serializes a DOM document.if stylesheet is null, returns the document serialized
|
||||
* Applies the stylesheet when available, and return the serialized transformed document,
|
||||
* or the transformiix data
|
||||
*/
|
||||
|
||||
function serializeDocument( xmlDocument, stylesheet )
|
||||
{
|
||||
var serializer = new XMLSerializer;
|
||||
if( stylesheet )
|
||||
{
|
||||
var resultDocument = transformXML( xmlDocument, stylesheet );
|
||||
var transformiixResult = resultDocument.getElementById( "transformiixResult" );
|
||||
if( transformiixResult && transformiixResult.hasChildNodes() )
|
||||
{ // It's a document starting with:
|
||||
// <a0:html xmlns:a0="http://www.w3.org/1999/xhtml">
|
||||
// <a0:head/><a0:body><a0:pre id="transformiixResult">
|
||||
var textNode = transformiixResult.firstChild;
|
||||
if( textNode.nodeType == textNode.TEXT_NODE )
|
||||
return textNode.nodeValue;
|
||||
else
|
||||
return serializer.serializeString( transformiixResult );
|
||||
}
|
||||
else
|
||||
// No transformiixResult, return the serialized transformed document
|
||||
return serializer.serializeToString ( resultDocument );
|
||||
}
|
||||
else
|
||||
// No transformation, return the serialized xmlDocument
|
||||
return serializer.serializeToString ( xmlDocument );
|
||||
}
|
||||
|
||||
/** PUBLIC
|
||||
*
|
||||
* not used?
|
||||
*/
|
||||
|
||||
function deserializeDocument(text, stylesheet )
|
||||
{
|
||||
var gParser = new DOMParser;
|
||||
var xmlDocument = gParser.parseFromString(text, 'text/xml');
|
||||
}
|
||||
|
||||
/** PRIVATE
|
||||
*
|
||||
* transform a calendar event into a dom node.
|
||||
* hack, this is going to be part of libical
|
||||
*/
|
||||
|
||||
function makeXmlNode( xmlDocument, calendarEvent )
|
||||
{
|
||||
|
||||
// Adds a property node to a event node
|
||||
// do not add empty properties, valueType is optional
|
||||
var addPropertyNode = function( xmlDocument, eventNode, name, value, valueType )
|
||||
{
|
||||
if(!value)
|
||||
return;
|
||||
|
||||
var propertyNode = xmlDocument.createElement( "property" );
|
||||
propertyNode.setAttribute( "name", name );
|
||||
|
||||
var valueNode = xmlDocument.createElement( "value" );
|
||||
var textNode = xmlDocument.createTextNode( value );
|
||||
|
||||
if( valueType )
|
||||
valueNode.setAttribute( "value", valueType );
|
||||
|
||||
valueNode.appendChild( textNode );
|
||||
propertyNode.appendChild( valueNode );
|
||||
eventNode.appendChild( propertyNode );
|
||||
}
|
||||
|
||||
var checkString = function( str )
|
||||
{
|
||||
if( typeof( str ) == "string" )
|
||||
return str;
|
||||
else
|
||||
return ""
|
||||
}
|
||||
|
||||
var checkNumber = function( num )
|
||||
{
|
||||
if( typeof( num ) == "undefined" || num == null )
|
||||
return "";
|
||||
else
|
||||
return num
|
||||
}
|
||||
|
||||
var checkBoolean = function( bool )
|
||||
{
|
||||
if( bool == "false")
|
||||
return "false"
|
||||
else if( bool ) // this is false for: false, 0, undefined, null, ""
|
||||
return "true";
|
||||
else
|
||||
return "false"
|
||||
}
|
||||
|
||||
// create a string in the iCalendar format, UTC time '20020412T121314Z'
|
||||
var checkDate = function ( dt, isDate )
|
||||
{ var dateObj = new Date( dt.getTime() );
|
||||
var result = "";
|
||||
result += dateObj.getUTCFullYear();
|
||||
|
||||
if( dateObj.getMonth() + 1 < 10 )
|
||||
result += "0";
|
||||
result += dateObj.getUTCMonth() + 1;
|
||||
|
||||
if( dateObj.getUTCDate() < 10 )
|
||||
result += "0";
|
||||
result += dateObj.getUTCDate();
|
||||
|
||||
if( !isDate )
|
||||
{
|
||||
result += "T"
|
||||
|
||||
if( dateObj.getUTCHours() < 10 )
|
||||
result += "0";
|
||||
result += dateObj.getUTCHours();
|
||||
|
||||
if( dateObj.getUTCMinutes() < 10 )
|
||||
result += "0";
|
||||
result += dateObj.getUTCMinutes();
|
||||
|
||||
if( dateObj.getUTCSeconds() < 10 )
|
||||
result += "0";
|
||||
result += dateObj.getUTCSeconds();
|
||||
result += "Z";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// make the event tag
|
||||
var calendarNode = xmlDocument.createElement( "component" );
|
||||
calendarNode.setAttribute( "name", "VCALENDAR" );
|
||||
|
||||
addPropertyNode( xmlDocument, calendarNode, "PRODID", "-//Mozilla.org/NONSGML Mozilla Calendar V 1.0 //EN" );
|
||||
addPropertyNode( xmlDocument, calendarNode, "VERSION", "2.0" );
|
||||
if(calendarEvent.method == calendarEvent.ICAL_METHOD_PUBLISH)
|
||||
addPropertyNode( xmlDocument, calendarNode, "METHOD", "PUBLISH" );
|
||||
else if(calendarEvent.method == calendarEvent.ICAL_METHOD_REQUEST )
|
||||
addPropertyNode( xmlDocument, calendarNode, "METHOD", "REQUEST" );
|
||||
|
||||
var eventNode = xmlDocument.createElement( "component" );
|
||||
eventNode.setAttribute( "name", "VEVENT" );
|
||||
|
||||
addPropertyNode( xmlDocument, eventNode, "UID", calendarEvent.id );
|
||||
addPropertyNode( xmlDocument, eventNode, "SUMMARY", checkString( calendarEvent.title ) );
|
||||
addPropertyNode( xmlDocument, eventNode, "DTSTAMP", checkDate( calendarEvent.stamp ) );
|
||||
if( calendarEvent.allDay )
|
||||
addPropertyNode( xmlDocument, eventNode, "DTSTART", checkDate( calendarEvent.start, true ), "DATE" );
|
||||
else
|
||||
{
|
||||
addPropertyNode( xmlDocument, eventNode, "DTSTART", checkDate( calendarEvent.start ) );
|
||||
addPropertyNode( xmlDocument, eventNode, "DTEND", checkDate( calendarEvent.end ) );
|
||||
}
|
||||
|
||||
addPropertyNode( xmlDocument, eventNode, "DESCRIPTION", checkString( calendarEvent.description ) );
|
||||
addPropertyNode( xmlDocument, eventNode, "CATEGORIES", checkString( calendarEvent.categories ) );
|
||||
addPropertyNode( xmlDocument, eventNode, "LOCATION", checkString( calendarEvent.location ) );
|
||||
addPropertyNode( xmlDocument, eventNode, "PRIVATEEVENT", checkString( calendarEvent.privateEvent ) );
|
||||
addPropertyNode( xmlDocument, eventNode, "URL", checkString( calendarEvent.url ) );
|
||||
addPropertyNode( xmlDocument, eventNode, "PRIORITY", checkNumber( calendarEvent.priority ) );
|
||||
|
||||
calendarNode.appendChild( eventNode );
|
||||
return calendarNode;
|
||||
}
|
||||
|
||||
/** PUBLIC
|
||||
*
|
||||
* Transforms an array of calendar events into a dom-document
|
||||
* hack, this is going to be part of libical
|
||||
*/
|
||||
|
||||
function getXmlDocument ( eventList )
|
||||
{
|
||||
// use the domparser to create the XML
|
||||
var domParser = new DOMParser;
|
||||
// start with one tag
|
||||
var xmlDocument = domParser.parseFromString( "<libical/>", "text/xml" );
|
||||
|
||||
// get the top tag, there will only be one.
|
||||
var topNodeList = xmlDocument.getElementsByTagName( "libical" );
|
||||
var topNode = topNodeList[0];
|
||||
|
||||
|
||||
// add each event as an element
|
||||
|
||||
for( var index = 0; index < eventList.length; ++index )
|
||||
{
|
||||
var calendarEvent = eventList[ index ];
|
||||
|
||||
var eventNode = this.makeXmlNode( xmlDocument, calendarEvent );
|
||||
|
||||
topNode.appendChild( eventNode );
|
||||
}
|
||||
return xmlDocument;
|
||||
}
|
||||
|
@ -105,6 +105,8 @@
|
||||
<menuseparator/>
|
||||
<menuitem id="calendar-mail-event" observes="send_event_command" label="&event.mail.event;"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="calendar-print-menu" observes="print_command" label="&calendar.print.label;"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="calendar-close" observes="close_calendar_command" label="&calendar.menu.options.close;"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
|
@ -156,6 +156,8 @@ CalendarEventSelection.prototype.onSelectionChanged = function ( )
|
||||
{
|
||||
document.getElementById("send_event_command").removeAttribute("disabled");
|
||||
}
|
||||
|
||||
document.getElementById( "print_command" ).removeAttribute( "disabled" );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -169,6 +171,8 @@ CalendarEventSelection.prototype.onSelectionChanged = function ( )
|
||||
document.getElementById( "modify_command" ).setAttribute( "disabled", "true" );
|
||||
|
||||
document.getElementById("send_event_command").setAttribute("disabled", "true");
|
||||
|
||||
document.getElementById("print_command").setAttribute("disabled", "true");
|
||||
}
|
||||
|
||||
for( var index in this.observerList )
|
||||
|
@ -155,10 +155,6 @@ DayView.prototype.refreshEvents = function( )
|
||||
//}
|
||||
//TextNode.setAttribute( "value", "All-Day Events: " );
|
||||
|
||||
//set the seperator to nothing. After the first one, we'll change it to ", " so that we add commas between text.
|
||||
|
||||
var Seperator = " ";
|
||||
|
||||
// get the events for the day and loop through them
|
||||
|
||||
var dayEventList = this.calendarWindow.eventSource.getEventsForDay( this.calendarWindow.getSelectedDate() );
|
||||
@ -247,10 +243,6 @@ DayView.prototype.refreshEvents = function( )
|
||||
//note the use of the AllDayText Attribute.
|
||||
//This is used to remove the text when the day is changed.
|
||||
|
||||
SeperatorNode = document.createElement( "label" );
|
||||
SeperatorNode.setAttribute( "value", Seperator );
|
||||
//SeperatorNode.setAttribute( "AllDayText", "true" );
|
||||
|
||||
newTextNode = document.createElement( "label" );
|
||||
newTextNode.setAttribute( "value", eventText );
|
||||
newTextNode.calendarEventDisplay = calendarEventDisplay;
|
||||
@ -258,8 +250,7 @@ DayView.prototype.refreshEvents = function( )
|
||||
newTextNode.setAttribute( "onclick", "dayEventItemClick( this, event )" );
|
||||
newTextNode.setAttribute( "ondblclick", "dayEventItemDoubleClick( this, event )" );
|
||||
newTextNode.setAttribute( "tooltip", "savetip" );
|
||||
|
||||
//newTextNode.setAttribute( "AllDayText", "true" );
|
||||
newTextNode.setAttribute( "AllDayText", "true" );
|
||||
|
||||
newImage = document.createElement("image");
|
||||
newImage.setAttribute( "class", "all-day-event-class" );
|
||||
@ -270,12 +261,8 @@ DayView.prototype.refreshEvents = function( )
|
||||
newImage.setAttribute( "tooltip", "savetip" );
|
||||
//newImage.setAttribute( "AllDayText", "true" );
|
||||
|
||||
AllDayBox.appendChild( SeperatorNode );
|
||||
AllDayBox.appendChild( newImage );
|
||||
AllDayBox.appendChild( newTextNode );
|
||||
|
||||
//change the seperator to add commas after the text.
|
||||
Seperator = ", ";
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -39,6 +39,8 @@
|
||||
*
|
||||
****/
|
||||
|
||||
// XSL stylesheet directory
|
||||
var convertersDirectory = "chrome://calendar/content/converters/";
|
||||
|
||||
// File constants copied from file-utils.js
|
||||
const MODE_RDONLY = 0x01;
|
||||
@ -50,6 +52,21 @@ const MODE_TRUNCATE = 0x20;
|
||||
const MODE_SYNC = 0x40;
|
||||
const MODE_EXCL = 0x80;
|
||||
|
||||
const filterCalendar = "Calendar Files";
|
||||
const extensionCalendar = ".ics";
|
||||
const filterXcs = "iCalendar XML Document";
|
||||
const extensionXcs = ".xcs";
|
||||
const filterXml = "XML Document";
|
||||
const extensionXml = ".xml";
|
||||
const filterRtf = "Rich Text Format (RTF)";
|
||||
const extensionRtf = ".rtf";
|
||||
const filterHtml = "HTML Files";
|
||||
const extensionHtml = ".html";
|
||||
const filterCsv = "Comma Separated";
|
||||
const extensionCsv = ".csv";
|
||||
const filterRdf = "iCalendar RDF";
|
||||
const extensionRdf = ".rdf";
|
||||
|
||||
|
||||
/**** loadEventsFromFile
|
||||
* shows a file dialog, read the selected file and tries to parse events from it.
|
||||
@ -63,18 +80,27 @@ function loadEventsFromFile()
|
||||
|
||||
fp.init(window, "Open", nsIFilePicker.modeOpen);
|
||||
|
||||
// fp.defaultString = "*.ics";
|
||||
fp.defaultExtension = "ics"
|
||||
|
||||
fp.appendFilter( "Calendar Files", "*.ics" );
|
||||
fp.appendFilter( filterCalendar, "*" + extensionCalendar );
|
||||
fp.appendFilter( filterXcs, "*" + extensionXcs );
|
||||
|
||||
fp.show();
|
||||
|
||||
if (fp.file && fp.file.path.length > 0)
|
||||
{
|
||||
var aDataStream = readDataFromFile( fp.file.path );
|
||||
var calendarEventArray = parseIcalData( aDataStream );
|
||||
var calendarEventArray;
|
||||
|
||||
switch (fp.filterIndex) {
|
||||
case 0 : // ics
|
||||
calendarEventArray = parseIcalData( aDataStream );
|
||||
break;
|
||||
case 1 : // xcs
|
||||
calendarEventArray = parseXCSData( aDataStream );
|
||||
break;
|
||||
}
|
||||
|
||||
// Show a dialog with option to import events with or without dialogs
|
||||
var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService();
|
||||
promptService = promptService.QueryInterface(Components.interfaces.nsIPromptService);
|
||||
@ -89,17 +115,20 @@ function loadEventsFromFile()
|
||||
null,null,null,null, result);
|
||||
if(buttonPressed == 0) // YES
|
||||
{
|
||||
addEventsToCalendar( calendarEventArray );
|
||||
}
|
||||
addEventsToCalendar( calendarEventArray );
|
||||
return true;
|
||||
}
|
||||
else if(buttonPressed == 1) // NO
|
||||
{
|
||||
addEventsToCalendar( calendarEventArray, true );
|
||||
addEventsToCalendar( calendarEventArray, true );
|
||||
return true;
|
||||
}
|
||||
else if(buttonPressed == 2) // CANCEL
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -247,13 +276,13 @@ function parseIcalData( icalStr )
|
||||
|
||||
calendarEvent = createEvent();
|
||||
|
||||
// if parsing import iCalendar failed, add date as description
|
||||
if ( !calendarEvent.parseIcalString(eventData) )
|
||||
// parsing import iCalendar failed.
|
||||
{
|
||||
// initialize start and end dates.
|
||||
initCalendarEvent( calendarEvent );
|
||||
|
||||
// Save clipboard text into description.
|
||||
// Save the parsed text as description.
|
||||
calendarEvent.description = icalStr;
|
||||
}
|
||||
|
||||
@ -265,6 +294,20 @@ function parseIcalData( icalStr )
|
||||
return calendarEventArray;
|
||||
}
|
||||
|
||||
/**** parseXCSData
|
||||
*
|
||||
*/
|
||||
|
||||
function parseXCSData( xcsString )
|
||||
{
|
||||
var gParser = new DOMParser;
|
||||
var xmlDocument = gParser.parseFromString(xcsString, 'text/xml');
|
||||
|
||||
var result = serializeDocument(xmlDocument, "xcs2ics.xsl");
|
||||
|
||||
return parseIcalData( result );
|
||||
}
|
||||
|
||||
|
||||
/**** readDataFromFile
|
||||
*
|
||||
@ -318,7 +361,7 @@ function readDataFromFile( aFilePath )
|
||||
function saveEventsToFile( calendarEventArray )
|
||||
{
|
||||
if( !calendarEventArray)
|
||||
var calendarEventArray = gCalendarWindow.EventSelection.selectedEvents;
|
||||
calendarEventArray = gCalendarWindow.EventSelection.selectedEvents;
|
||||
|
||||
if (calendarEventArray.length == 0)
|
||||
{
|
||||
@ -328,38 +371,65 @@ function saveEventsToFile( calendarEventArray )
|
||||
|
||||
// No show the 'Save As' dialog and ask for a filename to save to
|
||||
const nsIFilePicker = Components.interfaces.nsIFilePicker;
|
||||
|
||||
|
||||
var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
|
||||
|
||||
|
||||
// caller can force disable of sand box, even if ON globally
|
||||
|
||||
|
||||
fp.init(window, "Save As", nsIFilePicker.modeSave);
|
||||
|
||||
fp.defaultString = "Mozilla Calendar events";
|
||||
|
||||
if(calendarEventArray.length == 1 && calendarEventArray[0].title)
|
||||
fp.defaultString = calendarEventArray[0].title;
|
||||
else
|
||||
fp.defaultString = "Mozilla Calendar events";
|
||||
|
||||
fp.defaultExtension = "ics";
|
||||
|
||||
fp.appendFilter( "Calendar Files", "*.ics" );
|
||||
fp.appendFilter( "Rich Text Format (RTF)", "*.rtf" );
|
||||
fp.appendFilter( filterCalendar, "*" + extensionCalendar );
|
||||
fp.appendFilter( filterRtf, "*" + extensionRtf );
|
||||
fp.appendFilters(nsIFilePicker.filterHTML);
|
||||
|
||||
fp.appendFilter( filterCsv, "*" + extensionCsv );
|
||||
fp.appendFilter( filterXcs, "*" + extensionXcs );
|
||||
fp.appendFilter( filterRdf, "*" + extensionRdf );
|
||||
|
||||
fp.show();
|
||||
|
||||
// Now find out as what to save, convert the events and save to file.
|
||||
if (fp.file && fp.file.path.length > 0)
|
||||
{
|
||||
var aDataStream;
|
||||
var extension;
|
||||
switch (fp.filterIndex) {
|
||||
case 0 : // ics
|
||||
aDataStream = eventArrayToICalString( calendarEventArray, true );
|
||||
extension = extensionCalendar;
|
||||
break;
|
||||
case 1 : // rtf
|
||||
aDataStream = eventArrayToRTF( calendarEventArray );
|
||||
extension = extensionRtf;
|
||||
break;
|
||||
case 2 : // html
|
||||
aDataStream = eventArrayToHTML( calendarEventArray );
|
||||
extension = ".htm";
|
||||
break;
|
||||
case 3 : // csv
|
||||
aDataStream = eventArrayToCsv( calendarEventArray );
|
||||
extension = extensionCsv;
|
||||
break;
|
||||
case 4 : // xCal
|
||||
aDataStream = eventArrayToXCS( calendarEventArray );
|
||||
extension = extensionXcs;
|
||||
break;
|
||||
case 5 : // rdf
|
||||
aDataStream = eventArrayToRdf( calendarEventArray );
|
||||
extension = extensionRdf;
|
||||
break;
|
||||
}
|
||||
saveDataToFile(fp.file.path, aDataStream);
|
||||
var filePath = fp.file.path;
|
||||
if(filePath.indexOf(".") == -1 )
|
||||
filePath += extension;
|
||||
|
||||
saveDataToFile(filePath, aDataStream);
|
||||
}
|
||||
}
|
||||
|
||||
@ -485,6 +555,74 @@ function eventArrayToRTF( calendarEventArray )
|
||||
}
|
||||
|
||||
|
||||
/**** eventArrayToXML
|
||||
* Converts a array of events to a XML string
|
||||
*/
|
||||
/*
|
||||
function eventArrayToXML( calendarEventArray )
|
||||
{
|
||||
var xmlDocument = getXmlDocument( calendarEventArray );
|
||||
var serializer = new XMLSerializer;
|
||||
|
||||
return serializer.serializeToString (xmlDocument )
|
||||
}
|
||||
*/
|
||||
|
||||
/**** eventArrayToCsv
|
||||
* Converts a array of events to comma delimited text.
|
||||
*/
|
||||
|
||||
function eventArrayToCsv( calendarEventArray )
|
||||
{
|
||||
var xcsDocument = getXcsDocument( calendarEventArray );
|
||||
|
||||
return serializeDocument( xcsDocument, "xcs2csv.xsl" );
|
||||
}
|
||||
|
||||
|
||||
/**** eventArrayToRdf
|
||||
* Converts a array of events to RDF
|
||||
*/
|
||||
|
||||
function eventArrayToRdf( calendarEventArray )
|
||||
{
|
||||
var xcsDocument = getXcsDocument( calendarEventArray );
|
||||
|
||||
return serializeDocument( xcsDocument, "xcs2rdf.xsl" );
|
||||
}
|
||||
|
||||
|
||||
/**** eventArrayToXCS
|
||||
* Converts a array of events to a xCal string
|
||||
*/
|
||||
|
||||
function eventArrayToXCS( calendarEventArray )
|
||||
{
|
||||
var xmlDoc = getXmlDocument( calendarEventArray );
|
||||
var xcsDoc = transformXML( xmlDoc, "xml2xcs.xsl" );
|
||||
// add the doctype
|
||||
/* Doctype uri blocks excel import
|
||||
var newdoctype = xcsDoc.implementation.createDocumentType(
|
||||
"iCalendar",
|
||||
"-//IETF//DTD XCAL//iCalendar XML//EN",
|
||||
"http://www.ietf.org/internet-drafts/draft-ietf-calsch-many-xcal-02.txt");
|
||||
if (newdoctype)
|
||||
xcsDoc.insertBefore(newdoctype, xcsDoc.firstChild);
|
||||
*/
|
||||
var serializer = new XMLSerializer;
|
||||
|
||||
// XXX MAJOR UGLY HACK!! Serializer doesn't insert XML Declaration
|
||||
// http://bugzilla.mozilla.org/show_bug.cgi?id=63558
|
||||
var serialDocument = serializer.serializeToString ( xcsDoc );
|
||||
|
||||
if( serialDocument.indexOf( "<?xml" ) == -1 )
|
||||
serialDocument = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + serialDocument;
|
||||
|
||||
return serialDocument;
|
||||
// return serializer.serializeToString ( xcsDoc )
|
||||
}
|
||||
|
||||
|
||||
/**** saveDataToFile
|
||||
*
|
||||
* Save data to a file. Creates a new file or overwrites an existing file.
|
||||
@ -500,7 +638,7 @@ function saveDataToFile(aFilePath, aDataStream)
|
||||
var localFileInstance;
|
||||
var outputStream;
|
||||
|
||||
LocalFileInstance = Components.classes[LOCALFILE_CTRID].createInstance(nsILocalFile);
|
||||
var LocalFileInstance = Components.classes[LOCALFILE_CTRID].createInstance(nsILocalFile);
|
||||
LocalFileInstance.initWithPath(aFilePath);
|
||||
|
||||
outputStream = Components.classes[FILEOUT_CTRID].createInstance(nsIFileOutputStream);
|
||||
@ -516,3 +654,332 @@ function saveDataToFile(aFilePath, aDataStream)
|
||||
alert("Unable to write to file: " + aFilePath );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////
|
||||
// XML/XSL functions //
|
||||
////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Get the local path to the chrome directory
|
||||
*/
|
||||
/*
|
||||
function getChromeDir()
|
||||
{
|
||||
const JS_DIR_UTILS_FILE_DIR_CID = "@mozilla.org/file/directory_service;1";
|
||||
const JS_DIR_UTILS_I_PROPS = "nsIProperties";
|
||||
const JS_DIR_UTILS_DIR = new Components.Constructor(JS_DIR_UTILS_FILE_DIR_CID, JS_DIR_UTILS_I_PROPS);
|
||||
const JS_DIR_UTILS_CHROME_DIR = "AChrom";
|
||||
|
||||
var rv;
|
||||
|
||||
try
|
||||
{
|
||||
rv=(new JS_DIR_UTILS_DIR()).get(JS_DIR_UTILS_CHROME_DIR, Components.interfaces.nsIFile);
|
||||
}
|
||||
|
||||
catch (e)
|
||||
{
|
||||
//jslibError(e, "(unexpected error)", "NS_ERROR_FAILURE", JS_DIR_UTILS_FILE+":getChromeDir");
|
||||
rv=null;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
function getTemplatesPath( templateName )
|
||||
{
|
||||
var templatesDir = getChromeDir();
|
||||
templatesDir.append( "calendar" );
|
||||
templatesDir.append( "content" );
|
||||
templatesDir.append( "templates" );
|
||||
templatesDir.append( templateName );
|
||||
return templatesDir.path;
|
||||
}
|
||||
|
||||
function xslt(xmlUri, xslUri)
|
||||
{
|
||||
// TODO: Check uri's for CHROME:// and convert path to local path
|
||||
var xslProc = new XSLTProcessor();
|
||||
|
||||
var result = document.implementation.createDocument("", "", null);
|
||||
var xmlDoc = document.implementation.createDocument("", "", null);
|
||||
var xslDoc = document.implementation.createDocument("", "", null);
|
||||
|
||||
xmlDoc.load(xmlUri, "text/xml");
|
||||
xslDoc.load(xslUri, "text/xml");
|
||||
xslProc.transformDocument(xmlDoc, xslDoc, result, null);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
/** PRIVATE
|
||||
*
|
||||
* Opens a file and returns the content
|
||||
* It supports Uri's like chrome://
|
||||
*/
|
||||
|
||||
function loadFile(aUriSpec)
|
||||
{
|
||||
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
|
||||
var serv = Components.classes["@mozilla.org/network/io-service;1"].
|
||||
getService(Components.interfaces.nsIIOService);
|
||||
if (!serv) {
|
||||
throw Components.results.ERR_FAILURE;
|
||||
}
|
||||
var chan = serv.newChannel(aUriSpec, null, null);
|
||||
var instream =
|
||||
Components.classes["@mozilla.org/scriptableinputstream;1"].createInstance(Components.interfaces.nsIScriptableInputStream);
|
||||
instream.init(chan.open());
|
||||
|
||||
return instream.read(instream.available());
|
||||
}
|
||||
|
||||
/** PUBLIC GetXcsDocument
|
||||
*
|
||||
*/
|
||||
|
||||
function getXcsDocument( calendarEventArray )
|
||||
{
|
||||
var xmlDocument = getXmlDocument( calendarEventArray );
|
||||
|
||||
var xcsDocument = transformXML( xmlDocument, "xml2xcs.xsl" );
|
||||
|
||||
var processingInstruction = xcsDocument.createProcessingInstruction(
|
||||
"xml", "version=\"1.0\" encoding=\"UTF-8\"");
|
||||
// xcsDocument.insertBefore(processingInstruction, xcsDocument.firstChild);
|
||||
|
||||
return xcsDocument;
|
||||
}
|
||||
|
||||
|
||||
/** PUBLIC
|
||||
*
|
||||
* Opens a xsl transformation file and applies it to xmlDocuments.
|
||||
* xslFile can be in the convertersDirectory, or a full Uri
|
||||
* Returns the resulting document
|
||||
*/
|
||||
|
||||
function transformXML( xmlDocument, xslFilename )
|
||||
{
|
||||
var xslProc = new XSLTProcessor();
|
||||
var gParser = new DOMParser;
|
||||
// .load isn't synchrone
|
||||
// var xslDoc = document.implementation.createDocument("", "", null);
|
||||
// xslDoc.load(path, "text/xml");
|
||||
|
||||
// if only passsed a filename, assume it is a file in the default directory
|
||||
if( xslFilename.indexOf( ":" ) == -1 )
|
||||
xslFilename = convertersDirectory + xslFilename;
|
||||
|
||||
var xslContent = loadFile( xslFilename );
|
||||
var xslDocument = gParser.parseFromString(xslContent, 'text/xml');
|
||||
var result = document.implementation.createDocument("", "", null);
|
||||
|
||||
xslProc.transformDocument(xmlDocument, xslDocument, result, null);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/** PUBLIC
|
||||
*
|
||||
* Serializes a DOM document.if stylesheet is null, returns the document serialized
|
||||
* Applies the stylesheet when available, and return the serialized transformed document,
|
||||
* or the transformiix data
|
||||
*/
|
||||
|
||||
function serializeDocument( xmlDocument, stylesheet )
|
||||
{
|
||||
var serializer = new XMLSerializer;
|
||||
if( stylesheet )
|
||||
{
|
||||
var resultDocument = transformXML( xmlDocument, stylesheet );
|
||||
var transformiixResult = resultDocument.getElementById( "transformiixResult" );
|
||||
if( transformiixResult && transformiixResult.hasChildNodes() )
|
||||
{ // It's a document starting with:
|
||||
// <a0:html xmlns:a0="http://www.w3.org/1999/xhtml">
|
||||
// <a0:head/><a0:body><a0:pre id="transformiixResult">
|
||||
var textNode = transformiixResult.firstChild;
|
||||
if( textNode.nodeType == textNode.TEXT_NODE )
|
||||
return textNode.nodeValue;
|
||||
else
|
||||
return serializer.serializeString( transformiixResult );
|
||||
}
|
||||
else
|
||||
// No transformiixResult, return the serialized transformed document
|
||||
return serializer.serializeToString ( resultDocument );
|
||||
}
|
||||
else
|
||||
// No transformation, return the serialized xmlDocument
|
||||
return serializer.serializeToString ( xmlDocument );
|
||||
}
|
||||
|
||||
/** PUBLIC
|
||||
*
|
||||
* not used?
|
||||
*/
|
||||
|
||||
function deserializeDocument(text, stylesheet )
|
||||
{
|
||||
var gParser = new DOMParser;
|
||||
var xmlDocument = gParser.parseFromString(text, 'text/xml');
|
||||
}
|
||||
|
||||
/** PRIVATE
|
||||
*
|
||||
* transform a calendar event into a dom node.
|
||||
* hack, this is going to be part of libical
|
||||
*/
|
||||
|
||||
function makeXmlNode( xmlDocument, calendarEvent )
|
||||
{
|
||||
|
||||
// Adds a property node to a event node
|
||||
// do not add empty properties, valueType is optional
|
||||
var addPropertyNode = function( xmlDocument, eventNode, name, value, valueType )
|
||||
{
|
||||
if(!value)
|
||||
return;
|
||||
|
||||
var propertyNode = xmlDocument.createElement( "property" );
|
||||
propertyNode.setAttribute( "name", name );
|
||||
|
||||
var valueNode = xmlDocument.createElement( "value" );
|
||||
var textNode = xmlDocument.createTextNode( value );
|
||||
|
||||
if( valueType )
|
||||
valueNode.setAttribute( "value", valueType );
|
||||
|
||||
valueNode.appendChild( textNode );
|
||||
propertyNode.appendChild( valueNode );
|
||||
eventNode.appendChild( propertyNode );
|
||||
}
|
||||
|
||||
var checkString = function( str )
|
||||
{
|
||||
if( typeof( str ) == "string" )
|
||||
return str;
|
||||
else
|
||||
return ""
|
||||
}
|
||||
|
||||
var checkNumber = function( num )
|
||||
{
|
||||
if( typeof( num ) == "undefined" || num == null )
|
||||
return "";
|
||||
else
|
||||
return num
|
||||
}
|
||||
|
||||
var checkBoolean = function( bool )
|
||||
{
|
||||
if( bool == "false")
|
||||
return "false"
|
||||
else if( bool ) // this is false for: false, 0, undefined, null, ""
|
||||
return "true";
|
||||
else
|
||||
return "false"
|
||||
}
|
||||
|
||||
// create a string in the iCalendar format, UTC time '20020412T121314Z'
|
||||
var checkDate = function ( dt, isDate )
|
||||
{ var dateObj = new Date( dt.getTime() );
|
||||
var result = "";
|
||||
result += dateObj.getUTCFullYear();
|
||||
|
||||
if( dateObj.getMonth() + 1 < 10 )
|
||||
result += "0";
|
||||
result += dateObj.getUTCMonth() + 1;
|
||||
|
||||
if( dateObj.getUTCDate() < 10 )
|
||||
result += "0";
|
||||
result += dateObj.getUTCDate();
|
||||
|
||||
if( !isDate )
|
||||
{
|
||||
result += "T"
|
||||
|
||||
if( dateObj.getUTCHours() < 10 )
|
||||
result += "0";
|
||||
result += dateObj.getUTCHours();
|
||||
|
||||
if( dateObj.getUTCMinutes() < 10 )
|
||||
result += "0";
|
||||
result += dateObj.getUTCMinutes();
|
||||
|
||||
if( dateObj.getUTCSeconds() < 10 )
|
||||
result += "0";
|
||||
result += dateObj.getUTCSeconds();
|
||||
result += "Z";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// make the event tag
|
||||
var calendarNode = xmlDocument.createElement( "component" );
|
||||
calendarNode.setAttribute( "name", "VCALENDAR" );
|
||||
|
||||
addPropertyNode( xmlDocument, calendarNode, "PRODID", "-//Mozilla.org/NONSGML Mozilla Calendar V 1.0 //EN" );
|
||||
addPropertyNode( xmlDocument, calendarNode, "VERSION", "2.0" );
|
||||
if(calendarEvent.method == calendarEvent.ICAL_METHOD_PUBLISH)
|
||||
addPropertyNode( xmlDocument, calendarNode, "METHOD", "PUBLISH" );
|
||||
else if(calendarEvent.method == calendarEvent.ICAL_METHOD_REQUEST )
|
||||
addPropertyNode( xmlDocument, calendarNode, "METHOD", "REQUEST" );
|
||||
|
||||
var eventNode = xmlDocument.createElement( "component" );
|
||||
eventNode.setAttribute( "name", "VEVENT" );
|
||||
|
||||
addPropertyNode( xmlDocument, eventNode, "UID", calendarEvent.id );
|
||||
addPropertyNode( xmlDocument, eventNode, "SUMMARY", checkString( calendarEvent.title ) );
|
||||
addPropertyNode( xmlDocument, eventNode, "DTSTAMP", checkDate( calendarEvent.stamp ) );
|
||||
if( calendarEvent.allDay )
|
||||
addPropertyNode( xmlDocument, eventNode, "DTSTART", checkDate( calendarEvent.start, true ), "DATE" );
|
||||
else
|
||||
{
|
||||
addPropertyNode( xmlDocument, eventNode, "DTSTART", checkDate( calendarEvent.start ) );
|
||||
addPropertyNode( xmlDocument, eventNode, "DTEND", checkDate( calendarEvent.end ) );
|
||||
}
|
||||
|
||||
addPropertyNode( xmlDocument, eventNode, "DESCRIPTION", checkString( calendarEvent.description ) );
|
||||
addPropertyNode( xmlDocument, eventNode, "CATEGORIES", checkString( calendarEvent.categories ) );
|
||||
addPropertyNode( xmlDocument, eventNode, "LOCATION", checkString( calendarEvent.location ) );
|
||||
addPropertyNode( xmlDocument, eventNode, "PRIVATEEVENT", checkString( calendarEvent.privateEvent ) );
|
||||
addPropertyNode( xmlDocument, eventNode, "URL", checkString( calendarEvent.url ) );
|
||||
addPropertyNode( xmlDocument, eventNode, "PRIORITY", checkNumber( calendarEvent.priority ) );
|
||||
|
||||
calendarNode.appendChild( eventNode );
|
||||
return calendarNode;
|
||||
}
|
||||
|
||||
/** PUBLIC
|
||||
*
|
||||
* Transforms an array of calendar events into a dom-document
|
||||
* hack, this is going to be part of libical
|
||||
*/
|
||||
|
||||
function getXmlDocument ( eventList )
|
||||
{
|
||||
// use the domparser to create the XML
|
||||
var domParser = new DOMParser;
|
||||
// start with one tag
|
||||
var xmlDocument = domParser.parseFromString( "<libical/>", "text/xml" );
|
||||
|
||||
// get the top tag, there will only be one.
|
||||
var topNodeList = xmlDocument.getElementsByTagName( "libical" );
|
||||
var topNode = topNodeList[0];
|
||||
|
||||
|
||||
// add each event as an element
|
||||
|
||||
for( var index = 0; index < eventList.length; ++index )
|
||||
{
|
||||
var calendarEvent = eventList[ index ];
|
||||
|
||||
var eventNode = this.makeXmlNode( xmlDocument, calendarEvent );
|
||||
|
||||
topNode.appendChild( eventNode );
|
||||
}
|
||||
return xmlDocument;
|
||||
}
|
||||
|
@ -105,6 +105,8 @@
|
||||
<menuseparator/>
|
||||
<menuitem id="calendar-mail-event" observes="send_event_command" label="&event.mail.event;"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="calendar-print-menu" observes="print_command" label="&calendar.print.label;"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="calendar-close" observes="close_calendar_command" label="&calendar.menu.options.close;"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
|
@ -225,6 +225,7 @@ function unifinderMouseDownToDo( event )
|
||||
// TODO HACK notifiers should be rewritten to integrate events and todos
|
||||
document.getElementById( "delete_command" ).removeAttribute( "disabled" );
|
||||
document.getElementById( "delete_command_no_confirm" ).removeAttribute( "disabled" );
|
||||
document.getElementById( "print_command" ).setAttribute( "disabled", "true" );
|
||||
} else
|
||||
{
|
||||
if(event.button == 2)
|
||||
@ -234,6 +235,8 @@ function unifinderMouseDownToDo( event )
|
||||
// TODO HACK notifiers should be rewritten to integrate events and todos
|
||||
document.getElementById( "delete_command" ).setAttribute( "disabled", "true" );
|
||||
document.getElementById( "delete_command_no_confirm" ).setAttribute( "disabled", "true" );
|
||||
// printing tasks not supported
|
||||
document.getElementById( "print_command" ).setAttribute( "disabled", "true" );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -31,14 +31,21 @@ calendar.jar:
|
||||
content/calendar/sound.wav (content/sound.wav)
|
||||
content/calendar/unifinder.js (content/unifinder.js)
|
||||
content/calendar/unifinderToDo.js (content/unifinderToDo.js)
|
||||
content/calendar/converters/date-time.xsl (content/converters/date-time.xsl)
|
||||
content/calendar/converters/ecsJune.xsl (content/converters/ecsJune.xsl)
|
||||
content/calendar/converters/sortEvents.xsl (content/converters/sortEvents.xsl)
|
||||
content/calendar/converters/xcs2csv.xsl (content/converters/xcs2csv.xsl)
|
||||
content/calendar/converters/xcs2ics.xsl (content/converters/xcs2ics.xsl)
|
||||
content/calendar/converters/xcs2rdf.xsl (content/converters/xcs2rdf.xsl)
|
||||
content/calendar/converters/xml2xcs.xsl (content/converters/xml2xcs.xsl)
|
||||
content/calendar/datepicker/datepicker-overlay.xul (content/datepicker/datepicker-overlay.xul)
|
||||
content/calendar/datepicker/datepicker.js (content/datepicker/datepicker.js)
|
||||
content/calendar/timepicker/timepicker-overlay.xul (content/timepicker/timepicker-overlay.xul)
|
||||
content/calendar/timepicker/timepicker.js (content/timepicker/timepicker.js)
|
||||
content/calendar/pref/calendarPrefOverlay.xul (content/pref/calendarPrefOverlay.xul)
|
||||
content/calendar/pref/rootCalendarPref.js (content/pref/rootCalendarPref.js)
|
||||
content/calendar/pref/calendarPref.js (content/pref/calendarPref.js)
|
||||
content/calendar/pref/calendarPref.xul (content/pref/calendarPref.xul)
|
||||
content/calendar/pref/calendarPrefOverlay.xul (content/pref/calendarPrefOverlay.xul)
|
||||
content/calendar/pref/rootCalendarPref.js (content/pref/rootCalendarPref.js)
|
||||
content/calendar/timepicker/timepicker-overlay.xul (content/timepicker/timepicker-overlay.xul)
|
||||
content/calendar/timepicker/timepicker.js (content/timepicker/timepicker.js)
|
||||
locale/en-US/calendar/calendar.dtd (locale/en-US/calendar.dtd)
|
||||
locale/en-US/calendar/calendarMenuOverlay.dtd (locale/en-US/calendarMenuOverlay.dtd)
|
||||
locale/en-US/calendar/calendarOverlay.dtd (locale/en-US/calendarOverlay.dtd)
|
||||
@ -48,6 +55,49 @@ calendar.jar:
|
||||
locale/en-US/calendar/contents.rdf (locale/en-US/contents.rdf)
|
||||
locale/en-US/calendar/dateFormat.properties (locale/en-US/dateFormat.properties)
|
||||
locale/en-US/calendar/global.dtd (locale/en-US/global.dtd)
|
||||
skin/classic/calendar/all_day_event.gif (skin/classic/all_day_event.gif)
|
||||
skin/classic/calendar/all_day_event_down.gif (skin/classic/all_day_event_down.gif)
|
||||
skin/classic/calendar/all_day_event_hover.gif (skin/classic/all_day_event_hover.gif)
|
||||
skin/classic/calendar/btn1.png (skin/classic/btn1.png)
|
||||
skin/classic/calendar/calendar-16.gif (skin/classic/calendar-16.gif)
|
||||
skin/classic/calendar/calendar.css (skin/classic/calendar.css)
|
||||
skin/classic/calendar/calendarOverlay.css (skin/classic/calendarOverlay.css)
|
||||
skin/classic/calendar/calendarEventAlertDialog.css (skin/classic/calendarEventAlertDialog.css)
|
||||
skin/classic/calendar/calendarEventDialog.css (skin/classic/calendarEventDialog.css)
|
||||
skin/classic/calendar/calendar_topbar.gif (skin/classic/calendar_topbar.gif)
|
||||
skin/classic/calendar/contactsSelectAddressesDialog.css (skin/classic/contactsSelectAddressesDialog.css)
|
||||
skin/classic/calendar/contents.rdf (skin/classic/contents.rdf)
|
||||
skin/classic/calendar/day_left_gradient.png (skin/classic/day_left_gradient.png)
|
||||
skin/classic/calendar/dialogOverlay.css (skin/classic/dialogOverlay.css)
|
||||
skin/classic/calendar/dot.png (skin/classic/dot.png)
|
||||
skin/classic/calendar/dot_selected.png (skin/classic/dot_selected.png)
|
||||
skin/classic/calendar/event.png (skin/classic/event.png)
|
||||
skin/classic/calendar/event_alarm.png (skin/classic/event_alarm.png)
|
||||
skin/classic/calendar/event_attachment.png (skin/classic/event_attachment.png)
|
||||
skin/classic/calendar/event_repeating.png (skin/classic/event_repeating.png)
|
||||
skin/classic/calendar/prevnextarrow.png (skin/classic/prevnextarrow.png)
|
||||
skin/classic/calendar/taskbar-cal.gif (skin/classic/taskbar-cal.gif)
|
||||
skin/classic/calendar/taskbar-cal-act.gif (skin/classic/taskbar-cal-act.gif)
|
||||
skin/classic/calendar/ca-event-dialog/calendar_disabled.gif (skin/classic/ca-event-dialog/calendar_disabled.gif)
|
||||
skin/classic/calendar/ca-event-dialog/calendar_down.gif (skin/classic/ca-event-dialog/calendar_down.gif)
|
||||
skin/classic/calendar/ca-event-dialog/calendar_hover.gif (skin/classic/ca-event-dialog/calendar_hover.gif)
|
||||
skin/classic/calendar/ca-event-dialog/calendar_up.gif (skin/classic/ca-event-dialog/calendar_up.gif)
|
||||
skin/classic/calendar/ca-event-dialog/clock_disabled.gif (skin/classic/ca-event-dialog/clock_disabled.gif)
|
||||
skin/classic/calendar/ca-event-dialog/clock_down.gif (skin/classic/ca-event-dialog/clock_down.gif)
|
||||
skin/classic/calendar/ca-event-dialog/clock_hover.gif (skin/classic/ca-event-dialog/clock_hover.gif)
|
||||
skin/classic/calendar/ca-event-dialog/clock_up.gif (skin/classic/ca-event-dialog/clock_up.gif)
|
||||
skin/classic/calendar/ca-event-dialog/new_event_icon.png (skin/classic/ca-event-dialog/new_event_icon.png)
|
||||
skin/classic/calendar/datepicker/datepicker.css (skin/classic/datepicker/datepicker.css)
|
||||
skin/classic/calendar/datepicker/day_grid.png (skin/classic/datepicker/day_grid.png)
|
||||
skin/classic/calendar/datepicker/left_arrow.png (skin/classic/datepicker/left_arrow.png)
|
||||
skin/classic/calendar/datepicker/right_arrow.png (skin/classic/datepicker/right_arrow.png)
|
||||
skin/classic/calendar/timepicker/time_picker_minutes_bottom.png (skin/classic/timepicker/time_picker_minutes_bottom.png)
|
||||
skin/classic/calendar/timepicker/timepicker.css (skin/classic/timepicker/timepicker.css)
|
||||
skin/classic/calendar/unifinder/checkbox_checked.png (skin/classic/unifinder/checkbox_checked.png)
|
||||
skin/classic/calendar/unifinder/checkbox_unchecked.png (skin/classic/unifinder/checkbox_unchecked.png)
|
||||
skin/classic/calendar/unifinder/priority_header.png (skin/classic/unifinder/priority_header.png)
|
||||
skin/classic/calendar/unifinder/priority_high.png (skin/classic/unifinder/priority_high.png)
|
||||
skin/classic/calendar/unifinder/priority_low.png (skin/classic/unifinder/priority_low.png)
|
||||
skin/modern/calendar/all_day_event.gif (skin/modern/all_day_event.gif)
|
||||
skin/modern/calendar/all_day_event_down.gif (skin/modern/all_day_event_down.gif)
|
||||
skin/modern/calendar/all_day_event_hover.gif (skin/modern/all_day_event_hover.gif)
|
||||
@ -92,45 +142,3 @@ calendar.jar:
|
||||
skin/modern/calendar/unifinder/priority_header.png (skin/modern/unifinder/priority_header.png)
|
||||
skin/modern/calendar/unifinder/priority_high.png (skin/modern/unifinder/priority_high.png)
|
||||
skin/modern/calendar/unifinder/priority_low.png (skin/modern/unifinder/priority_low.png)
|
||||
skin/classic/calendar/all_day_event.gif (skin/classic/all_day_event.gif)
|
||||
skin/classic/calendar/all_day_event_down.gif (skin/classic/all_day_event_down.gif)
|
||||
skin/classic/calendar/all_day_event_hover.gif (skin/classic/all_day_event_hover.gif)
|
||||
skin/classic/calendar/btn1.png (skin/classic/btn1.png)
|
||||
skin/classic/calendar/calendar-16.gif (skin/classic/calendar-16.gif)
|
||||
skin/classic/calendar/calendar.css (skin/classic/calendar.css)
|
||||
skin/classic/calendar/calendarOverlay.css (skin/classic/calendarOverlay.css)
|
||||
skin/classic/calendar/calendarEventAlertDialog.css (skin/classic/calendarEventAlertDialog.css)
|
||||
skin/classic/calendar/calendarEventDialog.css (skin/classic/calendarEventDialog.css)
|
||||
skin/classic/calendar/calendar_topbar.gif (skin/classic/calendar_topbar.gif)
|
||||
skin/classic/calendar/contactsSelectAddressesDialog.css (skin/classic/contactsSelectAddressesDialog.css)
|
||||
skin/classic/calendar/contents.rdf (skin/classic/contents.rdf)
|
||||
skin/classic/calendar/day_left_gradient.png (skin/classic/day_left_gradient.png)
|
||||
skin/classic/calendar/dialogOverlay.css (skin/classic/dialogOverlay.css)
|
||||
skin/classic/calendar/dot.png (skin/classic/dot.png)
|
||||
skin/classic/calendar/dot_selected.png (skin/classic/dot_selected.png)
|
||||
skin/classic/calendar/event.png (skin/classic/event.png)
|
||||
skin/classic/calendar/event_alarm.png (skin/classic/event_alarm.png)
|
||||
skin/classic/calendar/event_attachment.png (skin/classic/event_attachment.png)
|
||||
skin/classic/calendar/prevnextarrow.png (skin/classic/prevnextarrow.png)
|
||||
skin/classic/calendar/taskbar-cal.gif (skin/classic/taskbar-cal.gif)
|
||||
skin/classic/calendar/taskbar-cal-act.gif (skin/classic/taskbar-cal-act.gif)
|
||||
skin/classic/calendar/ca-event-dialog/calendar_disabled.gif (skin/classic/ca-event-dialog/calendar_disabled.gif)
|
||||
skin/classic/calendar/ca-event-dialog/calendar_down.gif (skin/classic/ca-event-dialog/calendar_down.gif)
|
||||
skin/classic/calendar/ca-event-dialog/calendar_hover.gif (skin/classic/ca-event-dialog/calendar_hover.gif)
|
||||
skin/classic/calendar/ca-event-dialog/calendar_up.gif (skin/classic/ca-event-dialog/calendar_up.gif)
|
||||
skin/classic/calendar/ca-event-dialog/clock_disabled.gif (skin/classic/ca-event-dialog/clock_disabled.gif)
|
||||
skin/classic/calendar/ca-event-dialog/clock_down.gif (skin/classic/ca-event-dialog/clock_down.gif)
|
||||
skin/classic/calendar/ca-event-dialog/clock_hover.gif (skin/classic/ca-event-dialog/clock_hover.gif)
|
||||
skin/classic/calendar/ca-event-dialog/clock_up.gif (skin/classic/ca-event-dialog/clock_up.gif)
|
||||
skin/classic/calendar/ca-event-dialog/new_event_icon.png (skin/classic/ca-event-dialog/new_event_icon.png)
|
||||
skin/classic/calendar/datepicker/datepicker.css (skin/classic/datepicker/datepicker.css)
|
||||
skin/classic/calendar/datepicker/day_grid.png (skin/classic/datepicker/day_grid.png)
|
||||
skin/classic/calendar/datepicker/left_arrow.png (skin/classic/datepicker/left_arrow.png)
|
||||
skin/classic/calendar/datepicker/right_arrow.png (skin/classic/datepicker/right_arrow.png)
|
||||
skin/classic/calendar/timepicker/time_picker_minutes_bottom.png (skin/classic/timepicker/time_picker_minutes_bottom.png)
|
||||
skin/classic/calendar/timepicker/timepicker.css (skin/classic/timepicker/timepicker.css)
|
||||
skin/classic/calendar/unifinder/checkbox_checked.png (skin/classic/unifinder/checkbox_checked.png)
|
||||
skin/classic/calendar/unifinder/checkbox_unchecked.png (skin/classic/unifinder/checkbox_unchecked.png)
|
||||
skin/classic/calendar/unifinder/priority_header.png (skin/classic/unifinder/priority_header.png)
|
||||
skin/classic/calendar/unifinder/priority_high.png (skin/classic/unifinder/priority_high.png)
|
||||
skin/classic/calendar/unifinder/priority_low.png (skin/classic/unifinder/priority_low.png)
|
||||
|
@ -55,6 +55,15 @@
|
||||
<!ENTITY event.mail.event "Mail Calendar Event">
|
||||
<!ENTITY event.mail.event.accesskey "m">
|
||||
|
||||
<!ENTITY calendar.print.label "Print...">
|
||||
<!ENTITY calendar.print.accesskey "r">
|
||||
|
||||
<!ENTITY calendar.print.label "Print Preview">
|
||||
<!ENTITY calendar.print.accesskey "v">
|
||||
|
||||
<!ENTITY calendar.print.label "Page Setup...">
|
||||
<!ENTITY calendar.print.accesskey "u">
|
||||
|
||||
<!ENTITY calendar.import.label "Import...">
|
||||
<!ENTITY calendar.import.accesskey "i">
|
||||
|
||||
|
@ -59,6 +59,8 @@
|
||||
<!ENTITY time.22 "10:00 PM" >
|
||||
<!ENTITY time.23 "11:00 PM" >
|
||||
|
||||
<!ENTITY allDayEvents.label "All Day Events">
|
||||
|
||||
<!-- Month Names -->
|
||||
<!ENTITY day.1.Ddd "Sun" >
|
||||
<!ENTITY day.2.Ddd "Mon" >
|
||||
|
@ -55,6 +55,15 @@
|
||||
<!ENTITY event.mail.event "Mail Calendar Event">
|
||||
<!ENTITY event.mail.event.accesskey "m">
|
||||
|
||||
<!ENTITY calendar.print.label "Print...">
|
||||
<!ENTITY calendar.print.accesskey "r">
|
||||
|
||||
<!ENTITY calendar.print.label "Print Preview">
|
||||
<!ENTITY calendar.print.accesskey "v">
|
||||
|
||||
<!ENTITY calendar.print.label "Page Setup...">
|
||||
<!ENTITY calendar.print.accesskey "u">
|
||||
|
||||
<!ENTITY calendar.import.label "Import...">
|
||||
<!ENTITY calendar.import.accesskey "i">
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user