зеркало из https://github.com/mozilla/pjs.git
Adding in the ability to remember publishing preferences.
This commit is contained in:
Родитель
c1c8ebff4b
Коммит
d2552acf96
|
@ -78,7 +78,7 @@ h1 {
|
||||||
|
|
||||||
<td id="mozver">
|
<td id="mozver">
|
||||||
<h1>
|
<h1>
|
||||||
<a id="mozlink" href="http://www.mozilla.org/projects/calendar/" target="_new">Mozilla Calendar 2002111311-cal</a>
|
<a id="mozlink" href="http://www.mozilla.org/projects/calendar/" target="_new">Mozilla Calendar 2002111516-cal</a>
|
||||||
</h1>
|
</h1>
|
||||||
<script type="application/x-javascript">
|
<script type="application/x-javascript">
|
||||||
// using try..catch to handle empty useragents and other cases where the regex fails to apply
|
// using try..catch to handle empty useragents and other cases where the regex fails to apply
|
||||||
|
|
|
@ -94,64 +94,109 @@ function convertToUnicode(aCharset, aSrc )
|
||||||
|
|
||||||
function loadEventsFromFile()
|
function loadEventsFromFile()
|
||||||
{
|
{
|
||||||
const nsIFilePicker = Components.interfaces.nsIFilePicker;
|
|
||||||
|
|
||||||
var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
|
|
||||||
|
|
||||||
fp.init(window, "Open", nsIFilePicker.modeOpen);
|
|
||||||
|
|
||||||
fp.defaultExtension = "ics"
|
|
||||||
|
|
||||||
fp.appendFilter( filterCalendar, "*" + extensionCalendar );
|
|
||||||
fp.appendFilter( filterXcs, "*" + extensionXcs );
|
|
||||||
fp.appendFilter( filterOutlookCsv, "*" + extensionCsv );
|
|
||||||
fp.show();
|
|
||||||
|
|
||||||
if (fp.file && fp.file.path.length > 0)
|
var dupResult = { cancelled: false, discard: true, prompt: false };
|
||||||
{
|
|
||||||
|
openDialog("chrome://calendar/content/importDuplicatesDialog.xul", "caDuplicates", "chrome,modal,centerscreen", dupResult );
|
||||||
|
if (dupResult.cancelled == true)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// dump("*******************\n");
|
||||||
|
// dump("cancelled: " + dupResult.cancelled + "\n");
|
||||||
|
// dump("discard: " + dupResult.discard + "\n");
|
||||||
|
// dump("prompt: " + dupResult.prompt + "\n");
|
||||||
|
// dump("*******************\n");
|
||||||
|
|
||||||
|
const nsIFilePicker = Components.interfaces.nsIFilePicker;
|
||||||
|
|
||||||
|
var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
|
||||||
|
|
||||||
|
fp.init(window, "Open", nsIFilePicker.modeOpen);
|
||||||
|
fp.defaultExtension = "ics";
|
||||||
|
|
||||||
|
fp.appendFilter( filterCalendar, "*" + extensionCalendar );
|
||||||
|
fp.appendFilter( filterXcs, "*" + extensionXcs );
|
||||||
|
fp.appendFilter( filterOutlookCsv, "*" + extensionCsv );
|
||||||
|
fp.show();
|
||||||
|
|
||||||
|
if (fp.file && fp.file.path.length > 0)
|
||||||
|
{
|
||||||
var aDataStream = readDataFromFile( fp.file.path, "UTF-8" );
|
var aDataStream = readDataFromFile( fp.file.path, "UTF-8" );
|
||||||
var calendarEventArray;
|
var calendarEventArray = new Array();
|
||||||
|
var duplicateEventArray = new Array();
|
||||||
|
|
||||||
switch (fp.filterIndex) {
|
switch (fp.filterIndex) {
|
||||||
case 0 : // ics
|
case 0 : // ics
|
||||||
calendarEventArray = parseIcalData( aDataStream );
|
calendarEventArray = parseIcalData( aDataStream );
|
||||||
break;
|
break;
|
||||||
case 1 : // xcs
|
case 1 : // xcs
|
||||||
calendarEventArray = parseXCSData( aDataStream );
|
calendarEventArray = parseXCSData( aDataStream );
|
||||||
break;
|
break;
|
||||||
case 2: // csv
|
case 2: // csv
|
||||||
calendarEventArray = parseOutlookCSVData( aDataStream );
|
var ret = parseOutlookCSVData( aDataStream, dupResult.discard, dupResult.prompt );
|
||||||
break;
|
calendarEventArray = ret.calendarEventArray;
|
||||||
|
duplicateEventArray = ret.calendarDuplicateArray;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// If there are no events to import, let the user know
|
||||||
|
//
|
||||||
|
if (calendarEventArray.length == 0 && (duplicateEventArray.length == 0 || dupResult.discard == true) ) {
|
||||||
|
alert("No events to import...");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Show a dialog with option to import events with or without dialogs
|
// Show a dialog with option to import events with or without dialogs
|
||||||
var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService();
|
var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService();
|
||||||
promptService = promptService.QueryInterface(Components.interfaces.nsIPromptService);
|
promptService = promptService.QueryInterface(Components.interfaces.nsIPromptService);
|
||||||
var result = {value:0};
|
var result = {value:0};
|
||||||
|
|
||||||
var buttonPressed =
|
if (calendarEventArray.length > 0) {
|
||||||
promptService.confirmEx(window,
|
|
||||||
"Import", "About to import " + calendarEventArray.length + " event(s).\nDo you want to open all events to import before importing?",
|
var buttonPressed =
|
||||||
(promptService.BUTTON_TITLE_YES * promptService.BUTTON_POS_0) +
|
promptService.confirmEx(window,
|
||||||
(promptService.BUTTON_TITLE_NO * promptService.BUTTON_POS_1) +
|
"Import", "About to import " + calendarEventArray.length + " event(s).\nDo you want to open all new events to import before importing?",
|
||||||
(promptService.BUTTON_TITLE_CANCEL * promptService.BUTTON_POS_2),
|
(promptService.BUTTON_TITLE_YES * promptService.BUTTON_POS_0) +
|
||||||
null,null,null,null, result);
|
(promptService.BUTTON_TITLE_NO * promptService.BUTTON_POS_1) +
|
||||||
if(buttonPressed == 0) // YES
|
(promptService.BUTTON_TITLE_CANCEL * promptService.BUTTON_POS_2),
|
||||||
{
|
null,null,null,null, result);
|
||||||
addEventsToCalendar( calendarEventArray );
|
|
||||||
return true;
|
if(buttonPressed == 0) // YES
|
||||||
|
{
|
||||||
|
addEventsToCalendar( calendarEventArray );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if(buttonPressed == 1) // NO
|
||||||
|
{
|
||||||
|
addEventsToCalendar( calendarEventArray, true );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if(buttonPressed == 2) // CANCEL
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if(buttonPressed == 1) // NO
|
|
||||||
{
|
|
||||||
addEventsToCalendar( calendarEventArray, true );
|
// Depending on how the user chose to deal with duplicates,
|
||||||
return true;
|
// either add them blindly, or prompt then for each.
|
||||||
}
|
//
|
||||||
else if(buttonPressed == 2) // CANCEL
|
if (duplicateEventArray.length > 0) {
|
||||||
{
|
|
||||||
return false;
|
if (dupResult.discard == false) {
|
||||||
}
|
|
||||||
}
|
if (dupResult.prompt)
|
||||||
return false;
|
alert("Some duplicate entries were imported. Each one will display in the New Event dialog,\n where you can skip it using Cancel, or edit and accept it using OK.");
|
||||||
|
|
||||||
|
addEventsToCalendar( duplicateEventArray, !dupResult.prompt );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -323,62 +368,63 @@ function entryExists( date, subject) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function promptToKeepEntry(title, startTime, endTime)
|
||||||
|
{
|
||||||
|
return confirm(
|
||||||
|
"Add duplicate entry:\n\n" +
|
||||||
|
"Title: " + title + "\n" +
|
||||||
|
"Start Time: " + startTime.toString() + "\n" +
|
||||||
|
"End Time: " + endTime.toString() + "\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**** parseOutlookCSVData
|
/**** parseOutlookCSVData
|
||||||
*
|
*
|
||||||
* Takes a text block of iCalendar events and tries to split that into individual events.
|
* Takes a text block of iCalendar events and tries to split that into individual events.
|
||||||
* Parses those events and returns an array of calendarEvents.
|
* Parses those events and returns an array of calendarEvents.
|
||||||
*/
|
*/
|
||||||
|
function parseOutlookCSVData( icalStr, discardDuplicates, promptEach )
|
||||||
function parseOutlookCSVData( icalStr )
|
|
||||||
{
|
{
|
||||||
var lines = icalStr.split("\n");
|
var lines = icalStr.split("\n");
|
||||||
var calendarEvent;
|
var calendarEvent;
|
||||||
var calendarEventArray = new Array();
|
var eventArray = new Array();
|
||||||
|
var dupArray = new Array();
|
||||||
var lineIndex = 1;
|
var lineIndex = 1;
|
||||||
var totalLines = lines.length-1;
|
var totalLines = lines.length-1;
|
||||||
|
var exists = false;
|
||||||
var skipped = 0, added = 0;
|
|
||||||
|
|
||||||
while (lineIndex < totalLines) {
|
while (lineIndex < totalLines) {
|
||||||
|
|
||||||
var fields = lines[lineIndex].split('","');
|
var fields = lines[lineIndex].split('","');
|
||||||
|
fields[0] = fields[0].substring(1); // strip off the leading quote...
|
||||||
fields[0] = fields[0].substring(1);
|
|
||||||
|
|
||||||
dump(fields[0] + "\n");
|
|
||||||
dump(fields[1] + "\n");
|
|
||||||
dump(fields[2] + "\n");
|
|
||||||
dump(fields[3] + "\n");
|
|
||||||
dump(fields[4] + "\n");
|
|
||||||
dump("\n");
|
|
||||||
|
|
||||||
var title = fields[0];
|
var title = fields[0];
|
||||||
var stime = new Date(fields[1] + " " + fields[2]);
|
var stime = new Date(fields[1] + " " + fields[2]);
|
||||||
var etime = new Date(fields[3] + " " + fields[4]);
|
var etime = new Date(fields[3] + " " + fields[4]);
|
||||||
|
|
||||||
|
exists = entryExists(stime, title);
|
||||||
if (!entryExists(stime, title)) {
|
|
||||||
|
|
||||||
calendarEvent = createEvent();
|
calendarEvent = createEvent();
|
||||||
calendarEvent.id = createUniqueID( );
|
calendarEvent.id = createUniqueID( );
|
||||||
calendarEvent.title = title;
|
calendarEvent.title = title;
|
||||||
calendarEvent.start.setTime(stime);
|
calendarEvent.start.setTime(stime);
|
||||||
calendarEvent.end.setTime(etime);
|
calendarEvent.end.setTime(etime);
|
||||||
|
|
||||||
calendarEventArray[ calendarEventArray.length ] = calendarEvent;
|
|
||||||
dump("added: " + title);
|
|
||||||
|
|
||||||
++added;
|
if ( !exists )
|
||||||
}
|
eventArray[ eventArray.length ] = calendarEvent;
|
||||||
else
|
else
|
||||||
++skipped;
|
dupArray[ dupArray.length ] = calendarEvent;
|
||||||
|
|
||||||
|
|
||||||
++lineIndex;
|
++lineIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
alert("Skipped: " + skipped + ", added: " + added);
|
// dump("*** calendar entries : " + eventArray.length + "\n");
|
||||||
|
// dump("*** duplicate entries: " + dupArray.length + "\n");
|
||||||
|
|
||||||
return calendarEventArray;
|
return { calendarEventArray: eventArray, calendarDuplicateArray: dupArray };
|
||||||
}
|
}
|
||||||
|
|
||||||
/**** parseIcalData
|
/**** parseIcalData
|
||||||
|
|
|
@ -1,125 +0,0 @@
|
||||||
/* ***** 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 ***** */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***** calendar/calendarEventDialog.js
|
|
||||||
* AUTHOR
|
|
||||||
* Garth Smedley
|
|
||||||
* REQUIRED INCLUDES
|
|
||||||
* <script type="application/x-javascript" src="chrome://calendar/content/dateUtils.js"/>
|
|
||||||
* <script type="application/x-javascript" src="chrome://calendar/content/calendarEvent.js"/>
|
|
||||||
*
|
|
||||||
* NOTES
|
|
||||||
* Code for the calendar's new/edit event dialog.
|
|
||||||
*
|
|
||||||
* Invoke this dialog to create a new event as follows:
|
|
||||||
|
|
||||||
var args = new Object();
|
|
||||||
args.mode = "new"; // "new" or "edit"
|
|
||||||
args.onOk = <function>; // funtion to call when OK is clicked
|
|
||||||
args.calendarEvent = calendarEvent; // newly creatd calendar event to be editted
|
|
||||||
|
|
||||||
calendar.openDialog("caNewEvent", "chrome://calendar/content/calendarEventDialog.xul", true, args );
|
|
||||||
*
|
|
||||||
* Invoke this dialog to edit an existing event as follows:
|
|
||||||
*
|
|
||||||
var args = new Object();
|
|
||||||
args.mode = "edit"; // "new" or "edit"
|
|
||||||
args.onOk = <function>; // funtion to call when OK is clicked
|
|
||||||
args.calendarEvent = calendarEvent; // javascript object containin the event to be editted
|
|
||||||
|
|
||||||
* When the user clicks OK the onOk function will be called with a calendar event object.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* IMPLEMENTATION NOTES
|
|
||||||
**********
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------
|
|
||||||
* W I N D O W V A R I A B L E S
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
var gOnOkFunction; // function to be called when user clicks OK
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------
|
|
||||||
* W I N D O W F U N C T I O N S
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when the dialog is loaded.
|
|
||||||
*/
|
|
||||||
|
|
||||||
function loadCalendarPublishDialog()
|
|
||||||
{
|
|
||||||
// Get arguments, see description at top of file
|
|
||||||
|
|
||||||
var args = window.arguments[0];
|
|
||||||
|
|
||||||
gOnOkFunction = args.onOk;
|
|
||||||
|
|
||||||
var firstFocus = document.getElementById( "publish-url-textbox" );
|
|
||||||
firstFocus.focus();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when the OK button is clicked.
|
|
||||||
*/
|
|
||||||
|
|
||||||
function onOKCommand()
|
|
||||||
{
|
|
||||||
var CalendarPublishObject = new Object();
|
|
||||||
|
|
||||||
CalendarPublishObject.url = document.getElementById( "publish-url-textbox" ).value;
|
|
||||||
CalendarPublishObject.remotePath = document.getElementById( "publish-remotefilename-textbox" ).value;
|
|
||||||
CalendarPublishObject.username = document.getElementById( "publish-username-textbox" ).value;
|
|
||||||
CalendarPublishObject.password = document.getElementById( "publish-password-textbox" ).value;
|
|
||||||
|
|
||||||
// call caller's on OK function
|
|
||||||
gOnOkFunction( CalendarPublishObject );
|
|
||||||
|
|
||||||
// tell standard dialog stuff to close the dialog
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
|
@ -177,14 +177,21 @@ function CalendarWindow( calendarDataSource )
|
||||||
|
|
||||||
if ( nextEvent )
|
if ( nextEvent )
|
||||||
{
|
{
|
||||||
calendarWindow.setSelectedEvent( nextEvent );
|
calendarWindow.setSelectedEvent( nextEvent );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if( calendarWindow.currentView == calendarWindow.monthView )
|
//get the tree, see if there are items to highlight.
|
||||||
{
|
|
||||||
calendarWindow.currentView.hiliteSelectedDate( );
|
var today = new Date( );
|
||||||
}
|
|
||||||
|
//calendarWindow.setSelectedDate( getNextOrPreviousRecurrence( calendarEvent ) );
|
||||||
|
calendarWindow.setSelectedDate( today );
|
||||||
|
|
||||||
|
//if( calendarWindow.currentView == calendarWindow.monthView )
|
||||||
|
//{
|
||||||
|
// calendarWindow.currentView.hiliteSelectedDate( );
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||||
|
|
||||||
|
<dialog
|
||||||
|
|
||||||
|
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||||
|
id="duplicate-prompt"
|
||||||
|
title="Duplicate Management"
|
||||||
|
buttons="accept,cancel"
|
||||||
|
pack="right"
|
||||||
|
ondialogaccept="setCancelled(false); return true;"
|
||||||
|
ondialogcancel="setCancelled(true); return true;"
|
||||||
|
onload="loadDefaults();"
|
||||||
|
|
||||||
|
>
|
||||||
|
|
||||||
|
<script type="application/x-javascript" src="chrome://calendar/content/importDuplicatesDialog.js"/>
|
||||||
|
|
||||||
|
<groupbox id="dupControls">
|
||||||
|
|
||||||
|
<caption id="groupBoxTitle" label="What to do with duplicates:"/>
|
||||||
|
|
||||||
|
<box align="center">
|
||||||
|
|
||||||
|
<radiogroup id="dup-group" >
|
||||||
|
<radio id="auto-discard" selected="true" label="Automatically discard duplicates" oncommand="togglePrompting(false); setDiscardDuplicates(true);"/>
|
||||||
|
<radio id="add-duplicates" label="Add duplicates" oncommand="togglePrompting(true); setDiscardDuplicates(false);"/>
|
||||||
|
</radiogroup>
|
||||||
|
|
||||||
|
</box>
|
||||||
|
|
||||||
|
<hbox style="margin-left: .25in">
|
||||||
|
|
||||||
|
<checkbox id="prompt-on-add" disabled="true" selected="true" label="Prompt for each"
|
||||||
|
oncommand="this.checked = !this.checked; setPromptOnAdd(this.checked);"/>
|
||||||
|
|
||||||
|
</hbox>
|
||||||
|
|
||||||
|
</groupbox>
|
||||||
|
|
||||||
|
</dialog>
|
|
@ -94,64 +94,109 @@ function convertToUnicode(aCharset, aSrc )
|
||||||
|
|
||||||
function loadEventsFromFile()
|
function loadEventsFromFile()
|
||||||
{
|
{
|
||||||
const nsIFilePicker = Components.interfaces.nsIFilePicker;
|
|
||||||
|
|
||||||
var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
|
|
||||||
|
|
||||||
fp.init(window, "Open", nsIFilePicker.modeOpen);
|
|
||||||
|
|
||||||
fp.defaultExtension = "ics"
|
|
||||||
|
|
||||||
fp.appendFilter( filterCalendar, "*" + extensionCalendar );
|
|
||||||
fp.appendFilter( filterXcs, "*" + extensionXcs );
|
|
||||||
fp.appendFilter( filterOutlookCsv, "*" + extensionCsv );
|
|
||||||
fp.show();
|
|
||||||
|
|
||||||
if (fp.file && fp.file.path.length > 0)
|
var dupResult = { cancelled: false, discard: true, prompt: false };
|
||||||
{
|
|
||||||
|
openDialog("chrome://calendar/content/importDuplicatesDialog.xul", "caDuplicates", "chrome,modal,centerscreen", dupResult );
|
||||||
|
if (dupResult.cancelled == true)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// dump("*******************\n");
|
||||||
|
// dump("cancelled: " + dupResult.cancelled + "\n");
|
||||||
|
// dump("discard: " + dupResult.discard + "\n");
|
||||||
|
// dump("prompt: " + dupResult.prompt + "\n");
|
||||||
|
// dump("*******************\n");
|
||||||
|
|
||||||
|
const nsIFilePicker = Components.interfaces.nsIFilePicker;
|
||||||
|
|
||||||
|
var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
|
||||||
|
|
||||||
|
fp.init(window, "Open", nsIFilePicker.modeOpen);
|
||||||
|
fp.defaultExtension = "ics";
|
||||||
|
|
||||||
|
fp.appendFilter( filterCalendar, "*" + extensionCalendar );
|
||||||
|
fp.appendFilter( filterXcs, "*" + extensionXcs );
|
||||||
|
fp.appendFilter( filterOutlookCsv, "*" + extensionCsv );
|
||||||
|
fp.show();
|
||||||
|
|
||||||
|
if (fp.file && fp.file.path.length > 0)
|
||||||
|
{
|
||||||
var aDataStream = readDataFromFile( fp.file.path, "UTF-8" );
|
var aDataStream = readDataFromFile( fp.file.path, "UTF-8" );
|
||||||
var calendarEventArray;
|
var calendarEventArray = new Array();
|
||||||
|
var duplicateEventArray = new Array();
|
||||||
|
|
||||||
switch (fp.filterIndex) {
|
switch (fp.filterIndex) {
|
||||||
case 0 : // ics
|
case 0 : // ics
|
||||||
calendarEventArray = parseIcalData( aDataStream );
|
calendarEventArray = parseIcalData( aDataStream );
|
||||||
break;
|
break;
|
||||||
case 1 : // xcs
|
case 1 : // xcs
|
||||||
calendarEventArray = parseXCSData( aDataStream );
|
calendarEventArray = parseXCSData( aDataStream );
|
||||||
break;
|
break;
|
||||||
case 2: // csv
|
case 2: // csv
|
||||||
calendarEventArray = parseOutlookCSVData( aDataStream );
|
var ret = parseOutlookCSVData( aDataStream, dupResult.discard, dupResult.prompt );
|
||||||
break;
|
calendarEventArray = ret.calendarEventArray;
|
||||||
|
duplicateEventArray = ret.calendarDuplicateArray;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// If there are no events to import, let the user know
|
||||||
|
//
|
||||||
|
if (calendarEventArray.length == 0 && (duplicateEventArray.length == 0 || dupResult.discard == true) ) {
|
||||||
|
alert("No events to import...");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Show a dialog with option to import events with or without dialogs
|
// Show a dialog with option to import events with or without dialogs
|
||||||
var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService();
|
var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService();
|
||||||
promptService = promptService.QueryInterface(Components.interfaces.nsIPromptService);
|
promptService = promptService.QueryInterface(Components.interfaces.nsIPromptService);
|
||||||
var result = {value:0};
|
var result = {value:0};
|
||||||
|
|
||||||
var buttonPressed =
|
if (calendarEventArray.length > 0) {
|
||||||
promptService.confirmEx(window,
|
|
||||||
"Import", "About to import " + calendarEventArray.length + " event(s).\nDo you want to open all events to import before importing?",
|
var buttonPressed =
|
||||||
(promptService.BUTTON_TITLE_YES * promptService.BUTTON_POS_0) +
|
promptService.confirmEx(window,
|
||||||
(promptService.BUTTON_TITLE_NO * promptService.BUTTON_POS_1) +
|
"Import", "About to import " + calendarEventArray.length + " event(s).\nDo you want to open all new events to import before importing?",
|
||||||
(promptService.BUTTON_TITLE_CANCEL * promptService.BUTTON_POS_2),
|
(promptService.BUTTON_TITLE_YES * promptService.BUTTON_POS_0) +
|
||||||
null,null,null,null, result);
|
(promptService.BUTTON_TITLE_NO * promptService.BUTTON_POS_1) +
|
||||||
if(buttonPressed == 0) // YES
|
(promptService.BUTTON_TITLE_CANCEL * promptService.BUTTON_POS_2),
|
||||||
{
|
null,null,null,null, result);
|
||||||
addEventsToCalendar( calendarEventArray );
|
|
||||||
return true;
|
if(buttonPressed == 0) // YES
|
||||||
|
{
|
||||||
|
addEventsToCalendar( calendarEventArray );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if(buttonPressed == 1) // NO
|
||||||
|
{
|
||||||
|
addEventsToCalendar( calendarEventArray, true );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if(buttonPressed == 2) // CANCEL
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if(buttonPressed == 1) // NO
|
|
||||||
{
|
|
||||||
addEventsToCalendar( calendarEventArray, true );
|
// Depending on how the user chose to deal with duplicates,
|
||||||
return true;
|
// either add them blindly, or prompt then for each.
|
||||||
}
|
//
|
||||||
else if(buttonPressed == 2) // CANCEL
|
if (duplicateEventArray.length > 0) {
|
||||||
{
|
|
||||||
return false;
|
if (dupResult.discard == false) {
|
||||||
}
|
|
||||||
}
|
if (dupResult.prompt)
|
||||||
return false;
|
alert("Some duplicate entries were imported. Each one will display in the New Event dialog,\n where you can skip it using Cancel, or edit and accept it using OK.");
|
||||||
|
|
||||||
|
addEventsToCalendar( duplicateEventArray, !dupResult.prompt );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -323,62 +368,63 @@ function entryExists( date, subject) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function promptToKeepEntry(title, startTime, endTime)
|
||||||
|
{
|
||||||
|
return confirm(
|
||||||
|
"Add duplicate entry:\n\n" +
|
||||||
|
"Title: " + title + "\n" +
|
||||||
|
"Start Time: " + startTime.toString() + "\n" +
|
||||||
|
"End Time: " + endTime.toString() + "\n"
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**** parseOutlookCSVData
|
/**** parseOutlookCSVData
|
||||||
*
|
*
|
||||||
* Takes a text block of iCalendar events and tries to split that into individual events.
|
* Takes a text block of iCalendar events and tries to split that into individual events.
|
||||||
* Parses those events and returns an array of calendarEvents.
|
* Parses those events and returns an array of calendarEvents.
|
||||||
*/
|
*/
|
||||||
|
function parseOutlookCSVData( icalStr, discardDuplicates, promptEach )
|
||||||
function parseOutlookCSVData( icalStr )
|
|
||||||
{
|
{
|
||||||
var lines = icalStr.split("\n");
|
var lines = icalStr.split("\n");
|
||||||
var calendarEvent;
|
var calendarEvent;
|
||||||
var calendarEventArray = new Array();
|
var eventArray = new Array();
|
||||||
|
var dupArray = new Array();
|
||||||
var lineIndex = 1;
|
var lineIndex = 1;
|
||||||
var totalLines = lines.length-1;
|
var totalLines = lines.length-1;
|
||||||
|
var exists = false;
|
||||||
var skipped = 0, added = 0;
|
|
||||||
|
|
||||||
while (lineIndex < totalLines) {
|
while (lineIndex < totalLines) {
|
||||||
|
|
||||||
var fields = lines[lineIndex].split('","');
|
var fields = lines[lineIndex].split('","');
|
||||||
|
fields[0] = fields[0].substring(1); // strip off the leading quote...
|
||||||
fields[0] = fields[0].substring(1);
|
|
||||||
|
|
||||||
dump(fields[0] + "\n");
|
|
||||||
dump(fields[1] + "\n");
|
|
||||||
dump(fields[2] + "\n");
|
|
||||||
dump(fields[3] + "\n");
|
|
||||||
dump(fields[4] + "\n");
|
|
||||||
dump("\n");
|
|
||||||
|
|
||||||
var title = fields[0];
|
var title = fields[0];
|
||||||
var stime = new Date(fields[1] + " " + fields[2]);
|
var stime = new Date(fields[1] + " " + fields[2]);
|
||||||
var etime = new Date(fields[3] + " " + fields[4]);
|
var etime = new Date(fields[3] + " " + fields[4]);
|
||||||
|
|
||||||
|
exists = entryExists(stime, title);
|
||||||
if (!entryExists(stime, title)) {
|
|
||||||
|
|
||||||
calendarEvent = createEvent();
|
calendarEvent = createEvent();
|
||||||
calendarEvent.id = createUniqueID( );
|
calendarEvent.id = createUniqueID( );
|
||||||
calendarEvent.title = title;
|
calendarEvent.title = title;
|
||||||
calendarEvent.start.setTime(stime);
|
calendarEvent.start.setTime(stime);
|
||||||
calendarEvent.end.setTime(etime);
|
calendarEvent.end.setTime(etime);
|
||||||
|
|
||||||
calendarEventArray[ calendarEventArray.length ] = calendarEvent;
|
|
||||||
dump("added: " + title);
|
|
||||||
|
|
||||||
++added;
|
if ( !exists )
|
||||||
}
|
eventArray[ eventArray.length ] = calendarEvent;
|
||||||
else
|
else
|
||||||
++skipped;
|
dupArray[ dupArray.length ] = calendarEvent;
|
||||||
|
|
||||||
|
|
||||||
++lineIndex;
|
++lineIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
alert("Skipped: " + skipped + ", added: " + added);
|
// dump("*** calendar entries : " + eventArray.length + "\n");
|
||||||
|
// dump("*** duplicate entries: " + dupArray.length + "\n");
|
||||||
|
|
||||||
return calendarEventArray;
|
return { calendarEventArray: eventArray, calendarDuplicateArray: dupArray };
|
||||||
}
|
}
|
||||||
|
|
||||||
/**** parseIcalData
|
/**** parseIcalData
|
||||||
|
|
|
@ -89,17 +89,7 @@
|
||||||
|
|
||||||
<groupbox align="start" orient="vertical">
|
<groupbox align="start" orient="vertical">
|
||||||
<caption label="&pref.mainbox.label;"/>
|
<caption label="&pref.mainbox.label;"/>
|
||||||
<description>&pref.alarmgoesoff.label;</description>
|
<hbox>
|
||||||
<checkbox id="alarmplaysound" prefstring="calendar.alarms.playsound"
|
|
||||||
label="&pref.playasound;" />
|
|
||||||
|
|
||||||
<checkbox id="alarmshow" prefstring="calendar.alarms.show"
|
|
||||||
label="&pref.showalarmbox;" />
|
|
||||||
|
|
||||||
<description>Default address to send alarms to:</description>
|
|
||||||
<textbox id="alarmemailaddress" prefstring="calendar.alarms.emailaddress" flex="1"/>
|
|
||||||
|
|
||||||
<vbox>
|
|
||||||
<description>&pref.dateformat.label;</description>
|
<description>&pref.dateformat.label;</description>
|
||||||
<menulist id="dateformat" crop="none" prefstring="calendar.date.format">
|
<menulist id="dateformat" crop="none" prefstring="calendar.date.format">
|
||||||
<menupopup id="dateformat">
|
<menupopup id="dateformat">
|
||||||
|
@ -107,9 +97,9 @@
|
||||||
<menuitem id="dateformat-short-menuitem" label="&pref.dateformat.short;" value="1"/>
|
<menuitem id="dateformat-short-menuitem" label="&pref.dateformat.short;" value="1"/>
|
||||||
</menupopup>
|
</menupopup>
|
||||||
</menulist>
|
</menulist>
|
||||||
</vbox>
|
</hbox>
|
||||||
|
|
||||||
<vbox>
|
<hbox>
|
||||||
<description>&pref.weekstarts.label;</description>
|
<description>&pref.weekstarts.label;</description>
|
||||||
<menulist id="weekstarts" prefstring="calendar.week.start">
|
<menulist id="weekstarts" prefstring="calendar.week.start">
|
||||||
<menupopup id="weekstarts">
|
<menupopup id="weekstarts">
|
||||||
|
@ -122,7 +112,7 @@
|
||||||
<menuitem label="&pref.weekstarts.saturday;" value="6"/>
|
<menuitem label="&pref.weekstarts.saturday;" value="6"/>
|
||||||
</menupopup>
|
</menupopup>
|
||||||
</menulist>
|
</menulist>
|
||||||
</vbox>
|
</hbox>
|
||||||
|
|
||||||
<hbox align="center">
|
<hbox align="center">
|
||||||
<description>&pref.defaultlength.label;</description>
|
<description>&pref.defaultlength.label;</description>
|
||||||
|
@ -137,13 +127,25 @@
|
||||||
</hbox>
|
</hbox>
|
||||||
|
|
||||||
<checkbox id="reloadonlaunch" preftype="bool" prefstring="calendar.servers.reloadonlaunch" label="&pref.reloadonlaunch;" />
|
<checkbox id="reloadonlaunch" preftype="bool" prefstring="calendar.servers.reloadonlaunch" label="&pref.reloadonlaunch;" />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</groupbox>
|
</groupbox>
|
||||||
<groupbox>
|
<groupbox>
|
||||||
<vbox>
|
<caption label="Alarms"/>
|
||||||
<caption label="&pref.categories.label;"/>
|
<description>&pref.alarmgoesoff.label;</description>
|
||||||
|
<checkbox id="alarmplaysound" prefstring="calendar.alarms.playsound"
|
||||||
|
label="&pref.playasound;" />
|
||||||
|
|
||||||
|
<checkbox id="alarmshow" prefstring="calendar.alarms.show" label="&pref.showalarmbox;" />
|
||||||
|
|
||||||
|
<hbox>
|
||||||
|
<description>Default address to send alarms to:</description>
|
||||||
|
<textbox id="alarmemailaddress" prefstring="calendar.alarms.emailaddress" flex="1"/>
|
||||||
|
</hbox>
|
||||||
|
|
||||||
|
</groupbox>
|
||||||
|
|
||||||
|
<groupbox>
|
||||||
|
<caption label="&pref.categories.label;"/>
|
||||||
|
<vbox>
|
||||||
<textbox id="categories" prefstring="calendar.categories.names"/>
|
<textbox id="categories" prefstring="calendar.categories.names"/>
|
||||||
<description flex="1">&pref.categories.help.description;</description>
|
<description flex="1">&pref.categories.help.description;</description>
|
||||||
</vbox>
|
</vbox>
|
||||||
|
|
|
@ -62,10 +62,18 @@
|
||||||
</groupbox>
|
</groupbox>
|
||||||
|
|
||||||
<treechildren id="panelChildren">
|
<treechildren id="panelChildren">
|
||||||
<treeitem id="calendarPanel" container="false">
|
<treeitem id="calendarPanel" container="true">
|
||||||
<treerow>
|
<treerow>
|
||||||
<treecell class="treecell-indent" url="chrome://calendar/content/pref/calendarPref.xul" label="&calendar.label;" id="calendar"/>
|
<treecell class="treecell-indent" url="chrome://calendar/content/pref/calendarPref.xul" label="&calendar.label;" id="calendar"/>
|
||||||
</treerow>
|
</treerow>
|
||||||
|
<treechildren id="panelChildren">
|
||||||
|
<treeitem id="calendarPublishPanel" container="false">
|
||||||
|
<treerow>
|
||||||
|
<treecell class="treecell-indent" url="chrome://calendar/content/pref/publishPrefs.xul" label="Publish Prefs" id="calendarPublish"/>
|
||||||
|
</treerow>
|
||||||
|
</treeitem>
|
||||||
|
</treechildren>
|
||||||
|
|
||||||
</treeitem>
|
</treeitem>
|
||||||
</treechildren>
|
</treechildren>
|
||||||
|
|
||||||
|
|
|
@ -62,10 +62,18 @@
|
||||||
</groupbox>
|
</groupbox>
|
||||||
|
|
||||||
<treechildren id="panelChildren">
|
<treechildren id="panelChildren">
|
||||||
<treeitem id="calendarPanel" container="false">
|
<treeitem id="calendarPanel" container="true">
|
||||||
<treerow>
|
<treerow>
|
||||||
<treecell class="treecell-indent" url="chrome://calendar/content/pref/calendarPref.xul" label="&calendar.label;" id="calendar"/>
|
<treecell class="treecell-indent" url="chrome://calendar/content/pref/calendarPref.xul" label="&calendar.label;" id="calendar"/>
|
||||||
</treerow>
|
</treerow>
|
||||||
|
<treechildren id="panelChildren">
|
||||||
|
<treeitem id="calendarPublishPanel" container="false">
|
||||||
|
<treerow>
|
||||||
|
<treecell class="treecell-indent" url="chrome://calendar/content/pref/publishPrefs.xul" label="Publish Prefs" id="calendarPublish"/>
|
||||||
|
</treerow>
|
||||||
|
</treeitem>
|
||||||
|
</treechildren>
|
||||||
|
|
||||||
</treeitem>
|
</treeitem>
|
||||||
</treechildren>
|
</treechildren>
|
||||||
|
|
||||||
|
|
|
@ -97,6 +97,12 @@ function loadCalendarPublishDialog()
|
||||||
|
|
||||||
gOnOkFunction = args.onOk;
|
gOnOkFunction = args.onOk;
|
||||||
|
|
||||||
|
//get default values from the prefs
|
||||||
|
document.getElementById( "publish-url-textbox" ).value = opener.getCharPref( opener.gCalendarWindow.calendarPreferences.calendarPref, "publish.path", "" );
|
||||||
|
document.getElementById( "publish-remotefilename-textbox" ).value = opener.getCharPref( opener.gCalendarWindow.calendarPreferences.calendarPref, "publish.filename", "" );
|
||||||
|
document.getElementById( "publish-username-textbox" ).value = opener.getCharPref( opener.gCalendarWindow.calendarPreferences.calendarPref, "publish.username", "" );
|
||||||
|
document.getElementById( "publish-password-textbox" ).value = opener.getCharPref( opener.gCalendarWindow.calendarPreferences.calendarPref, "publish.password", "" );
|
||||||
|
|
||||||
var firstFocus = document.getElementById( "publish-url-textbox" );
|
var firstFocus = document.getElementById( "publish-url-textbox" );
|
||||||
firstFocus.focus();
|
firstFocus.focus();
|
||||||
}
|
}
|
||||||
|
@ -123,3 +129,4 @@ function onOKCommand()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,8 @@ calendar.jar:
|
||||||
content/calendar/contactsSelectAddressesDialog.js (content/contactsSelectAddressesDialog.js)
|
content/calendar/contactsSelectAddressesDialog.js (content/contactsSelectAddressesDialog.js)
|
||||||
content/calendar/contents.rdf (content/contents.rdf)
|
content/calendar/contents.rdf (content/contents.rdf)
|
||||||
content/calendar/dateUtils.js (content/dateUtils.js)
|
content/calendar/dateUtils.js (content/dateUtils.js)
|
||||||
|
content/calendar/importDuplicatesDialog.js (content/importDuplicatesDialog.js)
|
||||||
|
content/calendar/importDuplicatesDialog.xul (content/importDuplicatesDialog.xul)
|
||||||
content/calendar/sound.wav (content/sound.wav)
|
content/calendar/sound.wav (content/sound.wav)
|
||||||
content/calendar/unifinder.js (content/unifinder.js)
|
content/calendar/unifinder.js (content/unifinder.js)
|
||||||
content/calendar/unifinderToDo.js (content/unifinderToDo.js)
|
content/calendar/unifinderToDo.js (content/unifinderToDo.js)
|
||||||
|
@ -65,6 +67,7 @@ calendar.jar:
|
||||||
content/calendar/jslib/rdf/rdfResource.js (content/jslib/rdf/rdfResource.js)
|
content/calendar/jslib/rdf/rdfResource.js (content/jslib/rdf/rdfResource.js)
|
||||||
content/calendar/pref/calendarPref.xul (content/pref/calendarPref.xul)
|
content/calendar/pref/calendarPref.xul (content/pref/calendarPref.xul)
|
||||||
content/calendar/pref/calendarPrefOverlay.xul (content/pref/calendarPrefOverlay.xul)
|
content/calendar/pref/calendarPrefOverlay.xul (content/pref/calendarPrefOverlay.xul)
|
||||||
|
content/calendar/pref/publishPrefs.xul (content/pref/publishPrefs.xul)
|
||||||
content/calendar/pref/rootCalendarPref.js (content/pref/rootCalendarPref.js)
|
content/calendar/pref/rootCalendarPref.js (content/pref/rootCalendarPref.js)
|
||||||
content/calendar/timepicker/timepicker-overlay.xul (content/timepicker/timepicker-overlay.xul)
|
content/calendar/timepicker/timepicker-overlay.xul (content/timepicker/timepicker-overlay.xul)
|
||||||
content/calendar/timepicker/timepicker.js (content/timepicker/timepicker.js)
|
content/calendar/timepicker/timepicker.js (content/timepicker/timepicker.js)
|
||||||
|
|
|
@ -1067,6 +1067,7 @@ treechildren:-moz-tree-cell-text(completed)
|
||||||
|
|
||||||
/* TO DO LIST IMAGES */
|
/* TO DO LIST IMAGES */
|
||||||
|
|
||||||
|
/* this is the header image */
|
||||||
#unifinder-todo-tree-col-completed {
|
#unifinder-todo-tree-col-completed {
|
||||||
list-style-image : url("chrome://global/skin/checkbox/cbox-check.gif");
|
list-style-image : url("chrome://global/skin/checkbox/cbox-check.gif");
|
||||||
}
|
}
|
||||||
|
@ -1103,6 +1104,7 @@ treechildren:-moz-tree-image(unifinder-todo-tree-col-completed, completed, curre
|
||||||
list-style-image : url("chrome://global/skin/checkbox/cbox-act-check.gif");
|
list-style-image : url("chrome://global/skin/checkbox/cbox-act-check.gif");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This is the header image */
|
||||||
#unifinder-todo-tree-col-priority {
|
#unifinder-todo-tree-col-priority {
|
||||||
list-style-image : url( "chrome://calendar/skin/unifinder/priority_header.png" )
|
list-style-image : url( "chrome://calendar/skin/unifinder/priority_header.png" )
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче