зеркало из https://github.com/mozilla/pjs.git
bug 349586 - Add migrator. Patch by jminta with contributions by lilmatt and ctalbert. r=ctalbert,lilmatt,jminta ui-r=mvl
This commit is contained in:
Родитель
fccd194c6e
Коммит
eb8377421f
|
@ -49,8 +49,6 @@ const MODE_TRUNCATE = 0x20;
|
|||
const MODE_SYNC = 0x40;
|
||||
const MODE_EXCL = 0x80;
|
||||
|
||||
var gItems = new Array();
|
||||
|
||||
/**
|
||||
* loadEventsFromFile
|
||||
* shows a file dialog, reads the selected file(s) and tries to parse events from it.
|
||||
|
@ -104,7 +102,7 @@ function loadEventsFromFile(aCalendar)
|
|||
{
|
||||
inputStream.init( fp.file, MODE_RDONLY, 0444, {} );
|
||||
|
||||
gItems = importer.importFromStream(inputStream, {});
|
||||
var items = importer.importFromStream(inputStream, {});
|
||||
inputStream.close();
|
||||
}
|
||||
catch(ex)
|
||||
|
@ -113,7 +111,7 @@ function loadEventsFromFile(aCalendar)
|
|||
}
|
||||
|
||||
if (aCalendar) {
|
||||
putItemsIntoCal(aCalendar);
|
||||
putItemsIntoCal(aCalendar, items);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -123,11 +121,11 @@ function loadEventsFromFile(aCalendar)
|
|||
if (count.value == 1) {
|
||||
// There's only one calendar, so it's silly to ask what calendar
|
||||
// the user wants to import into.
|
||||
putItemsIntoCal(calendars[0]);
|
||||
putItemsIntoCal(calendars[0], items);
|
||||
} else {
|
||||
// Ask what calendar to import into
|
||||
var args = new Object();
|
||||
args.onOk = putItemsIntoCal;
|
||||
args.onOk = function putItems(aCal) { putItemsIntoCal(aCal, items); };
|
||||
args.promptText = getCalStringBundle().GetStringFromName("importPrompt");
|
||||
openDialog("chrome://calendar/content/chooseCalendarDialog.xul",
|
||||
"_blank", "chrome,titlebar,modal,resizable", args);
|
||||
|
@ -135,7 +133,7 @@ function loadEventsFromFile(aCalendar)
|
|||
}
|
||||
}
|
||||
|
||||
function putItemsIntoCal(destCal) {
|
||||
function putItemsIntoCal(destCal, aItems) {
|
||||
// Set batch for the undo/redo transaction manager
|
||||
startBatchTransaction();
|
||||
|
||||
|
@ -162,7 +160,7 @@ function putItemsIntoCal(destCal) {
|
|||
lastError = aStatus;
|
||||
}
|
||||
// See if it is time to end the calendar's batch.
|
||||
if (count == gItems.length) {
|
||||
if (count == aItems.length) {
|
||||
destCal.endBatch();
|
||||
if (failedCount)
|
||||
showError(failedCount+" items failed to import. The last error was: "+lastError.toString());
|
||||
|
@ -170,7 +168,7 @@ function putItemsIntoCal(destCal) {
|
|||
}
|
||||
}
|
||||
|
||||
for each (item in gItems) {
|
||||
for each (item in aItems) {
|
||||
// XXX prompt when finding a duplicate.
|
||||
try {
|
||||
destCal.addItem(item, listener);
|
||||
|
|
|
@ -0,0 +1,779 @@
|
|||
/* ***** 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 Calendar migration code
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Joey Minta <jminta@gmail.com>
|
||||
* Portions created by the Initial Developer are Copyright (C) 2006
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Matthew Willis <mattwillis@gmail.com>
|
||||
* Clint Talbert <cmtalbert@myfastmail.com>
|
||||
*
|
||||
* 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 ***** */
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const SUNBIRD_UID = "{718e30fb-e89b-41dd-9da7-e25a45638b28}";
|
||||
const FIREFOX_UID = "{ec8030f7-c20a-464f-9b0e-13a3a9e97384}";
|
||||
|
||||
//
|
||||
// The front-end wizard bits.
|
||||
//
|
||||
var gMigrateWizard = {
|
||||
/**
|
||||
* Called from onload of the migrator window. Takes all of the migrators
|
||||
* that were passed in via window.arguments and adds them to checklist. The
|
||||
* user can then check these off to migrate the data from those sources.
|
||||
*/
|
||||
loadMigrators: function gmw_load() {
|
||||
var listbox = document.getElementById("datasource-list");
|
||||
|
||||
//XXX Once we have branding for lightning, this hack can go away
|
||||
var sbs = Cc["@mozilla.org/intl/stringbundle;1"]
|
||||
.getService(Ci.nsIStringBundleService);
|
||||
|
||||
var props = sbs.createBundle("chrome://calendar/locale/migration.properties");
|
||||
|
||||
if (gDataMigrator.isLightning()) {
|
||||
var wizard = document.getElementById("migration-wizard");
|
||||
var desc = document.getElementById("wizard-desc");
|
||||
// Since we don't translate "Lightning"...
|
||||
wizard.title = props.formatStringFromName("migrationTitle",
|
||||
["Lightning"],
|
||||
1);
|
||||
desc.textContent = props.formatStringFromName("migrationDescription",
|
||||
["Lightning"],
|
||||
1);
|
||||
}
|
||||
|
||||
LOG("migrators: " + window.arguments.length);
|
||||
for each (var migrator in window.arguments[0]) {
|
||||
var listItem = document.createElement("listitem");
|
||||
var checkCell = document.createElement("listcell");
|
||||
checkCell.setAttribute("type", "checkbox");
|
||||
|
||||
checkCell.setAttribute("checked", true);
|
||||
listItem.appendChild(checkCell);
|
||||
|
||||
var nameCell = document.createElement("listcell");
|
||||
nameCell.setAttribute("label", migrator.title);
|
||||
listItem.appendChild(nameCell);
|
||||
|
||||
listItem.migrator = migrator;
|
||||
listbox.appendChild(listItem);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Called from the second page of the wizard. Finds all of the migrators
|
||||
* that were checked and begins migrating their data. Also controls the
|
||||
* progress dialog so the user can see what is happening. (somewhat)
|
||||
*/
|
||||
migrateChecked: function gmw_migrate() {
|
||||
var migrators = [];
|
||||
|
||||
// Get all the checked migrators into an array
|
||||
var listbox = document.getElementById("datasource-list");
|
||||
for (var i = listbox.childNodes.length-1; i >= 0; i--) {
|
||||
LOG("Checking child node: " + listbox.childNodes[i].firstChild);
|
||||
if (listbox.childNodes[i].firstChild.getAttribute("checked")) {
|
||||
LOG("Adding migrator");
|
||||
migrators.push(listbox.childNodes[i].migrator);
|
||||
}
|
||||
}
|
||||
|
||||
// If no migrators were checked, then we're done
|
||||
if (migrators.length == 0) {
|
||||
window.close();
|
||||
}
|
||||
|
||||
// Don't let the user get away while we're migrating
|
||||
//XXX may want to wire this into the 'cancel' function once that's
|
||||
// written
|
||||
var wizard = document.getElementById("migration-wizard");
|
||||
wizard.canAdvance = false;
|
||||
wizard.canRewind = false;
|
||||
|
||||
// We're going to need this for the progress meter's description
|
||||
var sbs = Cc["@mozilla.org/intl/stringbundle;1"]
|
||||
.getService(Ci.nsIStringBundleService);
|
||||
var props = sbs.createBundle("chrome://calendar/locale/migration.properties");
|
||||
var label = document.getElementById("progress-label");
|
||||
var meter = document.getElementById("migrate-progressmeter");
|
||||
|
||||
var i = 0;
|
||||
var nextMig = 0;
|
||||
// Because some of our migrators involve async code, we need this
|
||||
// call-back function so we know when to start the next migrator.
|
||||
function getNextMigrator() {
|
||||
if (migrators[i]) {
|
||||
var mig = migrators[i];
|
||||
|
||||
// Increment i to point to the next migrator
|
||||
i++;
|
||||
LOG("starting migrator: " + mig.title);
|
||||
label.value = props.formatStringFromName("migratingApp",
|
||||
[mig.title],
|
||||
1);
|
||||
meter.value = (i-1)/migrators.length*100;
|
||||
mig.args.push(getNextMigrator);
|
||||
|
||||
try {
|
||||
mig.migrate.apply(mig, mig.args);
|
||||
} catch (e) {
|
||||
LOG("Failed to migrate: " + mig.title);
|
||||
LOG(e);
|
||||
getNextMigrator();
|
||||
}
|
||||
} else {
|
||||
LOG("migration done");
|
||||
wizard.canAdvance = true;
|
||||
label.value = props.GetStringFromName("finished");
|
||||
meter.value = 100;
|
||||
gMigrateWizard.setCanRewindFalse();
|
||||
}
|
||||
}
|
||||
|
||||
// And get the first migrator
|
||||
getNextMigrator();
|
||||
},
|
||||
|
||||
setCanRewindFalse: function gmw_finish() {
|
||||
document.getElementById('migration-wizard').canRewind = false;
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// The more back-end data detection bits
|
||||
//
|
||||
function dataMigrator(aTitle, aMigrateFunction, aArguments) {
|
||||
this.title = aTitle;
|
||||
this.migrate = aMigrateFunction;
|
||||
this.args = aArguments;
|
||||
}
|
||||
|
||||
var gDataMigrator = {
|
||||
mIsLightning: null,
|
||||
mIsInFirefox: false,
|
||||
mPlatform: null,
|
||||
mDirService: null,
|
||||
mIoService: null,
|
||||
|
||||
/**
|
||||
* Properly caches the service so that it doesn't load on startup
|
||||
*/
|
||||
get dirService() {
|
||||
if (!this.mDirService) {
|
||||
this.mDirService = Cc["@mozilla.org/file/directory_service;1"]
|
||||
.getService(Ci.nsIProperties);
|
||||
}
|
||||
return this.mDirService;
|
||||
},
|
||||
|
||||
get ioService() {
|
||||
if (!this.mIoService) {
|
||||
this.mIoService = Cc["@mozilla.org/network/io-service;1"]
|
||||
.getService(Ci.nsIIOService);
|
||||
}
|
||||
return this.mIoService;
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the value for mIsLightning, and sets it if this.mIsLightning is
|
||||
* not initialized. This is used by objects outside gDataMigrator to
|
||||
* access the mIsLightning member.
|
||||
*/
|
||||
isLightning: function is_ltn() {
|
||||
if (this.mIsLightning == null) {
|
||||
var appInfo = Cc["@mozilla.org/xre/app-info;1"]
|
||||
.getService(Ci.nsIXULAppInfo);
|
||||
this.mIsLightning = !(appInfo.ID == SUNBIRD_UID);
|
||||
return this.mIsLightning;
|
||||
}
|
||||
// else mIsLightning is initialized, return the value
|
||||
return this.mIsLightning;
|
||||
},
|
||||
|
||||
/**
|
||||
* Call to do a general data migration (for a clean profile) Will run
|
||||
* through all of the known migrator-checkers. These checkers will return
|
||||
* an array of valid dataMigrator objects, for each kind of data they find.
|
||||
* If there is at least one valid migrator, we'll pop open the migration
|
||||
* wizard, otherwise, we'll return silently.
|
||||
*/
|
||||
checkAndMigrate: function gdm_migrate() {
|
||||
var appInfo = Cc["@mozilla.org/xre/app-info;1"]
|
||||
.getService(Ci.nsIXULAppInfo);
|
||||
this.mIsLightning = !(appInfo.ID == SUNBIRD_UID)
|
||||
LOG("mIsLightning is: " + this.mIsLightning);
|
||||
if (appInfo.ID == FIREFOX_UID) {
|
||||
this.mIsInFirefox = true;
|
||||
// We can't handle Firefox Lightning yet
|
||||
LOG("Holy cow, you're Firefox-Lightning! sorry, can't help.");
|
||||
return;
|
||||
}
|
||||
|
||||
var xulRuntime = Cc["@mozilla.org/xre/app-info;1"]
|
||||
.getService(Ci.nsIXULRuntime);
|
||||
this.mPlatform = xulRuntime.OS.toLowerCase();
|
||||
|
||||
LOG("mPlatform is: " + this.mPlatform);
|
||||
|
||||
var DMs = [];
|
||||
var migrators = [this.checkOldCal, this.checkEvolution,
|
||||
this.checkIcal];
|
||||
// XXX also define a category and an interface here for pluggability
|
||||
for each (var migrator in migrators) {
|
||||
var migs = migrator.call(this);
|
||||
for each (var dm in migs) {
|
||||
DMs.push(dm);
|
||||
}
|
||||
}
|
||||
|
||||
if (DMs.length == 0) {
|
||||
// No migration available
|
||||
return;
|
||||
}
|
||||
LOG("DMs: " + DMs.length);
|
||||
|
||||
var url = "chrome://calendar/content/migration.xul";
|
||||
#ifdef XP_MACOSX
|
||||
var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
|
||||
.getService(Components.interfaces.nsIWindowMediator);
|
||||
var win = wm.getMostRecentWindow("Calendar:MigrationWizard");
|
||||
if (win) {
|
||||
win.focus();
|
||||
} else {
|
||||
openDialog(url, "migration", "centerscreen,chrome,resizable=no", DMs);
|
||||
}
|
||||
#else
|
||||
openDialog(url, "migration", "modal,centerscreen,chrome,resizable=no", DMs);
|
||||
#endif
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks to see if we can find any traces of an older moz-cal program.
|
||||
* This could be either the old calendar-extension, or Sunbird 0.2. If so,
|
||||
* it offers to move that data into our new storage format. Also, if we're
|
||||
* if we're Lightning, it will disable the old calendar extension, since it
|
||||
* conflicts with us.
|
||||
*/
|
||||
checkOldCal: function gdm_calold() {
|
||||
LOG("Checking for the old calendar extension/app");
|
||||
|
||||
// First things first. If we are Lightning and the calendar extension
|
||||
// is installed, we have to nuke it. The old extension defines some of
|
||||
// the same paths as we do, and the resulting file conflicts result in
|
||||
// first-class badness. getCompositeCalendar is a conflicting function
|
||||
// that exists in Lighnting's version of calendarUtils.js. If it isn't
|
||||
// defined, we have a conflict.
|
||||
if (this.isLightning() && !("getCompositeCalendar" in window)) {
|
||||
|
||||
// We can't use our normal helper-functions, because those might
|
||||
// conflict too.
|
||||
var sbs = Cc["@mozilla.org/intl/stringbundle;1"]
|
||||
.getService(Ci.nsIStringBundleService);
|
||||
var props = sbs.createBundle("chrome://calendar/locale/migration.properties");
|
||||
var brand = sbs.createBundle("chrome://branding/locale/brand.properties");
|
||||
var appName = brand.GetStringFromName("brandShortName");
|
||||
// Tell the user we're going to disable and restart
|
||||
var promptService = Cc["@mozilla.org/embedcomp/prompt-service;1"]
|
||||
.getService(Ci.nsIPromptService);
|
||||
promptService.alert(window,
|
||||
props.GetStringFromName("disableExtTitle"),
|
||||
props.formatStringFromName("disableExtText",
|
||||
[brand],1));
|
||||
|
||||
// Kiiillllll...
|
||||
var em = Cc["@mozilla.org/extensions/manager;1"]
|
||||
.getService(Ci.nsIExtensionManager);
|
||||
em.disableItem("{8e117890-a33f-424b-a2ea-deb272731365}");
|
||||
promptService.alert(window, getString("disableDoneTitle"),
|
||||
getString("disableExtDone"));
|
||||
var startup = Cc["@mozilla.org/toolkit/app-startup;1"]
|
||||
.getService(Ci.nsIAppStartup);
|
||||
startup.quit(Ci.nsIAppStartup.eRestart |
|
||||
Ci.nsIAppStartup.eAttemptQuit);
|
||||
}
|
||||
|
||||
// This is the function that the migration wizard will call to actually
|
||||
// migrate the data. It's defined here because we may use it multiple
|
||||
// times (with different aProfileDirs), for instance if there is both
|
||||
// a Thunderbird and Firefox cal-extension
|
||||
function extMigrator(aProfileDir, aCallback) {
|
||||
// Get the old datasource
|
||||
var dataSource = aProfileDir.clone();
|
||||
dataSource.append("CalendarManager.rdf");
|
||||
if (!dataSource.exists()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Let this be a lesson to anyone designing APIs. The RDF API is so
|
||||
// impossibly confusing that it's actually simpler/cleaner/shorter
|
||||
// to simply parse as XML and use the better DOM APIs.
|
||||
var req = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"]
|
||||
.createInstance(Ci.nsIXMLHttpRequest);
|
||||
req.open('GET', "file://" + dataSource.path, true);
|
||||
req.onreadystatechange = function calext_onreadychange() {
|
||||
if (req.readyState == 4) {
|
||||
LOG(req.responseText);
|
||||
parseAndMigrate(req.responseXML, aCallback)
|
||||
}
|
||||
};
|
||||
req.send(null);
|
||||
}
|
||||
|
||||
// Callback from the XHR above. Parses CalendarManager.rdf and imports
|
||||
// the data describe therein.
|
||||
function parseAndMigrate(aDoc, aCallback) {
|
||||
// For duplicate detection
|
||||
var calManager = getCalendarManager();
|
||||
var uris = [];
|
||||
for each (var oldCal in calManager.getCalendars({})) {
|
||||
uris.push(oldCal.uri);
|
||||
}
|
||||
|
||||
function getRDFAttr(aNode, aAttr) {
|
||||
return aNode.getAttributeNS("http://home.netscape.com/NC-rdf#",
|
||||
aAttr);
|
||||
}
|
||||
|
||||
const RDFNS = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
|
||||
var nodes = aDoc.getElementsByTagNameNS(RDFNS, "Description");
|
||||
LOG("nodes: " + nodes.length);
|
||||
for (var i = 0; i < nodes.length; i++) {
|
||||
LOG("Beginning cal node");
|
||||
var cal;
|
||||
var node = nodes[i];
|
||||
if (getRDFAttr(node, "remote") == "false") {
|
||||
LOG("not remote");
|
||||
var localFile = Cc["@mozilla.org/file/local;1"]
|
||||
.createInstance(Ci.nsILocalFile);
|
||||
localFile.initWithPath(getRDFAttr(node, "path"));
|
||||
cal = gDataMigrator.importICSToStorage(localFile);
|
||||
} else {
|
||||
// Remote subscription
|
||||
// XXX check for duplicates
|
||||
var url = makeURL(getRDFAttr(node, "remotePath"));
|
||||
cal = calManager.createCalendar("ics", url);
|
||||
}
|
||||
cal.name = getRDFAttr(node, "name");
|
||||
calManager.setCalendarPref(cal, "color",
|
||||
getRDFAttr(node, "color"));
|
||||
}
|
||||
aCallback();
|
||||
}
|
||||
|
||||
var migrators = [];
|
||||
|
||||
// Look in our current profile directory, in case we're upgrading in
|
||||
// place
|
||||
var profileDir = this.dirService.get("ProfD", Ci.nsILocalFile);
|
||||
profileDir.append("Calendar");
|
||||
if (profileDir.exists()) {
|
||||
LOG("Found old extension directory in current app");
|
||||
var title;
|
||||
if (this.mIsLightning) {
|
||||
title = "Mozilla Calendar Extension";
|
||||
} else {
|
||||
title = "Sunbird 0.2";
|
||||
}
|
||||
migrators.push(new dataMigrator(title, extMigrator, [profileDir]));
|
||||
}
|
||||
|
||||
// Check the profiles of the various other moz-apps for calendar data
|
||||
var profiles = [];
|
||||
|
||||
// Do they use Firefox?
|
||||
var ffPro, sbProf, tbProf;
|
||||
if ((ffProf = this.getFirefoxProfile())) {
|
||||
profiles.push(ffProf);
|
||||
}
|
||||
|
||||
if (this.mIsLightning) {
|
||||
// If we're lightning, check Sunbird
|
||||
if ((sbProf = this.getSunbirdProfile())) {
|
||||
profiles.push(sbProf);
|
||||
}
|
||||
} else {
|
||||
// Otherwise, check Thunderbird
|
||||
if ((tbProf = this.getThunderbirdProfile())) {
|
||||
profiles.push(tbProf);
|
||||
}
|
||||
}
|
||||
|
||||
// Now check all of the profiles in each of these folders for data
|
||||
for each (var prof in profiles) {
|
||||
var dirEnum = prof.directoryEntries;
|
||||
while (dirEnum.hasMoreElements()) {
|
||||
var profile = dirEnum.getNext().QueryInterface(Ci.nsIFile);
|
||||
if (profile.isFile()) {
|
||||
continue;
|
||||
} else {
|
||||
profile.append("Calendar");
|
||||
if (profile.exists()) {
|
||||
LOG("Found old extension directory at" + profile.path);
|
||||
var title = "Mozilla Calendar";
|
||||
migrators.push(new dataMigrator(title, extMigrator, [profile]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return migrators;
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks to see if Apple's iCal is installed and offers to migrate any data
|
||||
* the user has created in it.
|
||||
*/
|
||||
checkIcal: function gdm_ical() {
|
||||
LOG("Checking for ical data");
|
||||
|
||||
function icalMigrate(aDataDir, aCallback) {
|
||||
aDataDir.append("Sources");
|
||||
var dirs = aDataDir.directoryEntries;
|
||||
var calManager = getCalendarManager();
|
||||
|
||||
var i = 1;
|
||||
while(dirs.hasMoreElements()) {
|
||||
var dataDir = dirs.getNext().QueryInterface(Ci.nsIFile);
|
||||
var dataStore = dataDir.clone();
|
||||
dataStore.append("corestorage.ics");
|
||||
if (!dataStore.exists()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var chars = [];
|
||||
var fileStream = Cc["@mozilla.org/network/file-input-stream;1"]
|
||||
.createInstance(Ci.nsIFileInputStream);
|
||||
|
||||
fileStream.init(dataStore, 0x01, 0444, {});
|
||||
var convStream = Cc["@mozilla.org/intl/converter-input-stream;1"]
|
||||
.getService(Ci.nsIConverterInputStream);
|
||||
convStream.init(fileStream, 'UTF-8', 0, 0x0000);
|
||||
var tmpStr = {};
|
||||
var str = "";
|
||||
while (convStream.readString(-1, tmpStr)) {
|
||||
str += tmpStr.value;
|
||||
}
|
||||
|
||||
// Strip out the timezone definitions, since it makes the file
|
||||
// invalid otherwise
|
||||
var index = str.indexOf(";TZID=");
|
||||
while (index != -1) {
|
||||
var endIndex = str.indexOf(':', index);
|
||||
var otherEnd = str.indexOf(';', index+2);
|
||||
if (otherEnd < endIndex) {
|
||||
endIndex = otherEnd;
|
||||
}
|
||||
var sub = str.substring(index, endIndex);
|
||||
str = str.replace(sub, "", "g");
|
||||
index = str.indexOf(";TZID=");
|
||||
}
|
||||
var tempFile = gDataMigrator.dirService.get("TmpD", Ci.nsIFile);
|
||||
tempFile.append("icalTemp.ics");
|
||||
tempFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0600);
|
||||
var tempUri = gDataMigrator.ioService.newFileURI(tempFile);
|
||||
|
||||
var stream = Cc["@mozilla.org/network/file-output-stream;1"]
|
||||
.createInstance(Ci.nsIFileOutputStream);
|
||||
stream.init(tempFile, 0x2A, 0600, 0);
|
||||
var convStream = Cc["@mozilla.org/intl/converter-output-stream;1"]
|
||||
.getService(Ci.nsIConverterOutputStream);
|
||||
convStream.init(stream, 'UTF-8', 0, 0x0000);
|
||||
convStream.writeString(str);
|
||||
|
||||
var cal = gDataMigrator.importICSToStorage(tempFile);
|
||||
cal.name = "iCalendar"+i;
|
||||
i++;
|
||||
}
|
||||
LOG("icalMig making callback");
|
||||
aCallback();
|
||||
}
|
||||
var profileDir = this.dirService.get("ProfD", Ci.nsILocalFile);
|
||||
var icalSpec = profileDir.path;
|
||||
var icalFile;
|
||||
if (!this.isLightning()) {
|
||||
var diverge = icalSpec.indexOf("Sunbird");
|
||||
if (diverge == -1) {
|
||||
return [];
|
||||
}
|
||||
icalSpec = icalSpec.substr(0, diverge);
|
||||
icalFile = Cc["@mozilla.org/file/local;1"]
|
||||
.createInstance(Ci.nsILocalFile);
|
||||
icalFile.initWithPath(icalSpec);
|
||||
} else {
|
||||
var diverge = icalSpec.indexOf("Thunderbird");
|
||||
if (diverge == -1) {
|
||||
return [];
|
||||
}
|
||||
icalSpec = icalSpec.substr(0, diverge);
|
||||
icalFile = Cc["@mozilla.org/file/local;1"]
|
||||
.createInstance(Ci.nsILocalFile);
|
||||
icalFile.initWithPath(icalSpec);
|
||||
icalFile.append("Application Support");
|
||||
}
|
||||
|
||||
icalFile.append("iCal");
|
||||
if (icalFile.exists()) {
|
||||
return [new dataMigrator("Apple iCal", icalMigrate, [icalFile])];
|
||||
}
|
||||
|
||||
return [];
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks to see if Evolution is installed and offers to migrate any data
|
||||
* stored there.
|
||||
*/
|
||||
checkEvolution: function gdm_evolution() {
|
||||
LOG("Checking for evolution data");
|
||||
|
||||
function evoMigrate(aDataDir, aCallback) {
|
||||
aDataDir.append("Sources");
|
||||
var dirs = aDataDir.directoryEntries;
|
||||
var calManager = getCalendarManager();
|
||||
|
||||
var i = 1;
|
||||
while(dirs.hasMoreElements()) {
|
||||
var dataDir = dirs.getNext().QueryInterface(Ci.nsIFile);
|
||||
var dataStore = dataDir.clone();
|
||||
dataStore.append("calendar.ics");
|
||||
if (!dataStore.exists()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var cal = gDataMigrator.importICSToStorage(dataStore);
|
||||
//XXX
|
||||
cal.name = "Evolution"+i;
|
||||
i++;
|
||||
}
|
||||
aCallback();
|
||||
}
|
||||
|
||||
var profileDir = this.dirService.get("ProfD", Ci.nsILocalFile);
|
||||
var evoSpec = profileDir.path;
|
||||
var evoFile;
|
||||
if (!this.mIsLightning) {
|
||||
var diverge = evoSpec.indexOf(".mozilla");
|
||||
if (diverge == -1) {
|
||||
return [];
|
||||
}
|
||||
evoSpec = evoSpec.substr(0, diverge);
|
||||
evoFile = Cc["@mozilla.org/file/local;1"]
|
||||
.createInstance(Ci.nsILocalFile);
|
||||
evoFile.initWithPath(evoSpec);
|
||||
} else {
|
||||
var diverge = evoSpec.indexOf(".thunderbird");
|
||||
if (diverge == -1) {
|
||||
return [];
|
||||
}
|
||||
evoSpec = evoSpec.substr(0, diverge);
|
||||
evoFile = Cc["@mozilla.org/file/local;1"]
|
||||
.createInstance(Ci.nsILocalFile);
|
||||
evoFile.initWithPath(evoSpec);
|
||||
}
|
||||
evoFile.append(".evolution");
|
||||
evoFile.append("calendar");
|
||||
evoFile.append("local");
|
||||
evoFile.append("system");
|
||||
if (evoFile.exists()) {
|
||||
return [new dataMigrator("Evolution", evoMigrate, [evoFile])];
|
||||
}
|
||||
return [];
|
||||
},
|
||||
|
||||
importICSToStorage: function migrateIcsStorage(icsFile) {
|
||||
var calManager = getCalendarManager();
|
||||
var uris = [];
|
||||
for each (var oldCal in calManager.getCalendars({})) {
|
||||
uris.push(oldCal.uri.spec);
|
||||
}
|
||||
var uri = 'moz-profile-calendar://?id=';
|
||||
var i = 1;
|
||||
while (uris.indexOf(uri+i) != -1) {
|
||||
i++;
|
||||
}
|
||||
|
||||
var cal = calManager.createCalendar("storage", makeURL(uri+i));
|
||||
var icsImporter = Cc["@mozilla.org/calendar/import;1?type=ics"]
|
||||
.getService(Ci.calIImporter);
|
||||
|
||||
var inputStream = Cc["@mozilla.org/network/file-input-stream;1"]
|
||||
.createInstance(Ci.nsIFileInputStream);
|
||||
inputStream.init(icsFile, MODE_RDONLY, 0444, {} );
|
||||
var items = icsImporter.importFromStream(inputStream, {});
|
||||
// Defined in import-export.js
|
||||
putItemsIntoCal(cal, items);
|
||||
|
||||
calManager.registerCalendar(cal);
|
||||
return cal;
|
||||
},
|
||||
|
||||
/**
|
||||
* Helper functions for getting the profile directory of various MozApps
|
||||
* (Getting the profile dir is way harder than it should be.)
|
||||
*
|
||||
* Sunbird:
|
||||
* Unix: ~jdoe/.mozilla/sunbird/
|
||||
* Windows: %APPDATA%\Mozilla\Sunbird\Profiles
|
||||
* Mac OS X: ~jdoe/Library/Application Support/Sunbird/Profiles
|
||||
*
|
||||
* Firefox:
|
||||
* Unix: ~jdoe/.mozilla/firefox/
|
||||
* Windows: %APPDATA%\Mozilla\Firefox\Profiles
|
||||
* Mac OS X: ~jdoe/Library/Application Support/Firefox/Profiles
|
||||
*
|
||||
* Thunderbird:
|
||||
* Unix: ~jdoe/.thunderbird/
|
||||
* Windows: %APPDATA%\Thunderbird\Profiles
|
||||
* Mac OS X: ~jdoe/Library/Thunderbird/Profiles
|
||||
*
|
||||
* Notice that Firefox and Sunbird follow essentially the same pattern, so
|
||||
* we group them with getNormalProfile
|
||||
*/
|
||||
getFirefoxProfile: function gdm_getFF() {
|
||||
return this.getNormalProfile("Firefox");
|
||||
},
|
||||
|
||||
getThunderbirdProfile: function gdm_getTB() {
|
||||
var profileDir = this.dirService.get("ProfD", Ci.nsILocalFile);
|
||||
|
||||
var appSpec = this.ioService.newFileURI(profileDir).path;
|
||||
var localFile = Cc["@mozilla.org/file/local;1"]
|
||||
.createInstance(Ci.nsILocalFile);
|
||||
var truncate;
|
||||
if (this.mIsLightning) {
|
||||
truncate = appSpec.indexOf("Profiles");
|
||||
appSpec = appSpec.substr(0, truncate);
|
||||
localFile.initWithPath(appSpec);
|
||||
localFile.append("Profiles");
|
||||
} else {
|
||||
// Now it gets ugly
|
||||
switch (this.mPlatform) {
|
||||
case "darwin": // Mac OS X
|
||||
truncate = appSpec.indexOf("Application");
|
||||
appSpec = appSpec.substr(0, truncate);
|
||||
localFile.initWithPath(appSpec);
|
||||
localFile.append("Thunderbird");
|
||||
localFile.append("Profiles");
|
||||
break;
|
||||
case "winnt":
|
||||
truncate = appSpec.indexOf("Mozilla");
|
||||
appSpec = appSpec.substr(0, truncate);
|
||||
localFile.initWithPath(appSpec);
|
||||
localFile.append("Thunderbird");
|
||||
localFile.append("Profiles");
|
||||
break;
|
||||
default: // Unix
|
||||
truncate = appSpec.indexOf(".mozilla");
|
||||
appSpec = appSpec.substr(0, truncate);
|
||||
localFile.append(".thunderbird");
|
||||
}
|
||||
}
|
||||
return localFile;
|
||||
},
|
||||
|
||||
getSunbirdProfile: function gdm_getSB() {
|
||||
return this.getNormalProfile("Sunbird");
|
||||
},
|
||||
|
||||
getNormalProfile: function gdm_getNorm(aAppName) {
|
||||
var profileDir = this.dirService.get("ProfD", Ci.nsILocalFile);
|
||||
var appSpec = this.ioService.newFileURI(profileDir).path;
|
||||
var localFile = Cc["@mozilla.org/file/local;1"]
|
||||
.createInstance(Ci.nsILocalFile);
|
||||
|
||||
// This variable marks the path-index where the current profile diverges
|
||||
// from the aAppName profile. We'll cut off the path here and then
|
||||
// append the known path to the aAppName profile.
|
||||
var truncate;
|
||||
|
||||
if (this.isLightning()) { // We're in Thunderbird
|
||||
switch (this.mPlatform) {
|
||||
case "darwin": // Mac OS X
|
||||
truncate = appSpec.indexOf("Thunderbird");
|
||||
appSpec = appSpec.substr(0, truncate);
|
||||
localFile.initWithPath(appSpec);
|
||||
localFile.append("Application Support");
|
||||
localFile.append(aAppName);
|
||||
localFile.append("Profiles");
|
||||
break;
|
||||
case "winnt":
|
||||
truncate = appSpec.indexOf("Thunderbird");
|
||||
appSpec = appSpec.substr(0, truncate);
|
||||
localFile.initWithPath(appSpec);
|
||||
localFile.append("Mozilla");
|
||||
localFile.append(aAppName);
|
||||
localFile.append("Profiles");
|
||||
break;
|
||||
default: // Unix
|
||||
truncate = appSpec.indexOf(".thunderbird");
|
||||
appSpec = appSpec.substr(0, truncate);
|
||||
localFile.initWithPath(appSpec);
|
||||
localFile.append(".mozilla");
|
||||
localFile.append(aAppName.toLowerCase());
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (this.mPlatform) {
|
||||
// On Mac and Windows, we can just remove the "Sunbird" and
|
||||
// replace it with "Firefox" to get to Firefox
|
||||
case "darwin": // Mac OS X
|
||||
case "winnt":
|
||||
idx = appSpec.indexOf("Sunbird");
|
||||
appSpec = appSpec.substr(0, idx);
|
||||
localFile.initWithPath(appSpec);
|
||||
localFile.append(aAppName);
|
||||
localFile.append("Profiles");
|
||||
break;
|
||||
default: // Unix
|
||||
idx = appSpec.indexOf("sunbird");
|
||||
appSpec = appSpec.substr(0, idx);
|
||||
localFile.initWithPath(ffSpec);
|
||||
localFile.append(aAppName.toLowerCase());
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (localFile.exists()) {
|
||||
return localFile;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
function LOG(aString) {
|
||||
if (!getPrefSafe("calendar.migration.log", false)) {
|
||||
return;
|
||||
}
|
||||
var consoleService = Cc["@mozilla.org/consoleservice;1"]
|
||||
.getService(Ci.nsIConsoleService);
|
||||
consoleService.logStringMessage(aString);
|
||||
dump(aString+"\n");
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- ***** 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 Calendar migration code.
|
||||
-
|
||||
- The Initial Developer of the Original Code is
|
||||
- Joey Minta <jminta@gmail.com>
|
||||
- Portions created by the Initial Developer are Copyright (C) 2006
|
||||
- the Initial Developer. All Rights Reserved.
|
||||
-
|
||||
- Contributor(s):
|
||||
-
|
||||
- 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 LGPL or the GPL. 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 ***** -->
|
||||
|
||||
<!-- Style sheets -->
|
||||
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
|
||||
|
||||
<!DOCTYPE dialog
|
||||
[
|
||||
<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
|
||||
%brandDTD;
|
||||
<!ENTITY % migrationDtd SYSTEM "chrome://calendar/locale/migration.dtd">
|
||||
%migrationDtd;
|
||||
]>
|
||||
|
||||
<wizard id="migration-wizard"
|
||||
title="&migration.title;"
|
||||
windowtype="Calendar:MigrationWizard"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="gMigrateWizard.loadMigrators()"
|
||||
branded="true"
|
||||
persist="screenX screenY">
|
||||
|
||||
<script type="application/x-javascript" src="chrome://calendar/content/migration.js"/>
|
||||
<script type="application/x-javascript" src="chrome://calendar/content/import-export.js"/>
|
||||
<script type="application/x-javascript" src="chrome://calendar/content/calendarUtils.js"/>
|
||||
|
||||
<wizardpage id="wizardPage1"
|
||||
pageid="initialPage"
|
||||
next="progressPage"
|
||||
label="&migration.welcome;"
|
||||
description="&migration.list.description;">
|
||||
<description id="wizard-desc">&migration.list.description;</description>
|
||||
<listbox id="datasource-list" flex="1">
|
||||
<listcols>
|
||||
<listcol/>
|
||||
<listcol flex="1"/>
|
||||
</listcols>
|
||||
</listbox>
|
||||
</wizardpage>
|
||||
|
||||
<wizardpage id="wizardPage2"
|
||||
pageid="progressPage"
|
||||
label="&migration.importing;"
|
||||
onpageshow="gMigrateWizard.migrateChecked()"
|
||||
description="&migration.progress.description;">
|
||||
<description>&migration.progress.description;</description>
|
||||
<vbox flex="1">
|
||||
<progressmeter id="migrate-progressmeter" mode="determined"
|
||||
value="0" flex="1"/>
|
||||
<label value="" flex="1" id="progress-label"/>
|
||||
</vbox>
|
||||
</wizardpage>
|
||||
</wizard>
|
|
@ -29,6 +29,8 @@ calendar.jar:
|
|||
content/calendar/calErrorPrompt.xul (content/calErrorPrompt.xul)
|
||||
content/calendar/chooseCalendarDialog.xul (content/chooseCalendarDialog.xul)
|
||||
content/calendar/import-export.js (content/import-export.js)
|
||||
* content/calendar/migration.js (content/migration.js)
|
||||
content/calendar/migration.xul (content/migration.xul)
|
||||
content/calendar/preferences/editCategory.xul (content/preferences/editCategory.xul)
|
||||
% skin calendar classic/1.0 %skin/classic/calendar/
|
||||
#expand skin/classic/calendar/cal-icon32.png (themes/__THEME__/cal-icon32.png)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
content lightning jar:chrome/lightning.jar!/content/lightning/
|
||||
locale lightning en-US jar:chrome/lightning-en-US.jar!/locale/en-US/lightning/
|
||||
overlay chrome://messenger/content/messenger.xul chrome://lightning/content/lightning-migration.xul
|
||||
overlay chrome://messenger/content/messenger.xul chrome://lightning/content/messenger-overlay-sidebar.xul
|
||||
overlay chrome://messenger/content/preferences/preferences.xul chrome://lightning/content/messenger-overlay-preferences.xul
|
||||
overlay chrome://messenger/content/messenger.xul chrome://lightning/content/messenger-overlay-toolbar.xul
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- ***** 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 Calendar migration code
|
||||
-
|
||||
- The Initial Developer of the Original Code is
|
||||
- Joey Minta <jminta@gmail.com>
|
||||
- Portions created by the Initial Developer are Copyright (C) 2006
|
||||
- the Initial Developer. All Rights Reserved.
|
||||
-
|
||||
- Contributor(s):
|
||||
-
|
||||
- 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 LGPL or the GPL. 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 ***** -->
|
||||
|
||||
<!-- The old calendar extension, if it is installed in the same profile as
|
||||
- Lightning, will break Lightning because it ships several files that
|
||||
- have the same chrome address as files that Lightning ships. This file
|
||||
- exists so we can check for whether that extension is installed and nuke it
|
||||
- in that case. Note that this check *cannot* be done in any file that may
|
||||
- die as a result of the conflict (including messanger-overlay-sidebar.js).
|
||||
- Nor can it depend on files which may conflict, like calendarUtils.js.
|
||||
-->
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin/global.css" type="text/css"?>
|
||||
<?xul-overlay href="chrome://global/content/dialogOverlay.xul"?>
|
||||
|
||||
<!-- DTD File with all strings specific to the file -->
|
||||
<!DOCTYPE overlay
|
||||
[
|
||||
]>
|
||||
|
||||
<overlay id="ltnMigrationOverlay"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
<script type="application/x-javascript" src="chrome://calendar/content/migration.js"/>
|
||||
<script type="application/x-javascript"><![CDATA[
|
||||
function checkOld() {
|
||||
document.removeEventListener("load", checkOld, true);
|
||||
var calMgr = Components.classes["@mozilla.org/calendar/manager;1"]
|
||||
.getService(Components.interfaces.calICalendarManager);
|
||||
var cals = calMgr.getCalendars({});
|
||||
if (!cals.length) {
|
||||
// There are no calendars, so we are running for the first time
|
||||
gDataMigrator.checkAndMigrate();
|
||||
}
|
||||
}
|
||||
document.addEventListener("load", checkOld, true);
|
||||
]]></script>
|
||||
|
||||
<deck id="displayDeck"/>
|
||||
|
||||
</overlay>
|
|
@ -9,6 +9,7 @@ lightning.jar:
|
|||
content/lightning/agenda-tree.js (content/agenda-tree.js)
|
||||
content/lightning/lightning-standalone.xul (content/lightning-standalone.xul)
|
||||
content/lightning/messenger-overlay-preferences.xul (content/messenger-overlay-preferences.xul)
|
||||
content/lightning/lightning-migration.xul (content/lightning-migration.xul)
|
||||
content/lightning/lightning-preferences.xul (content/lightning-preferences.xul)
|
||||
content/lightning/lightning-preferences.js (content/lightning-preferences.js)
|
||||
content/lightning/messenger-overlay-toolbar.xul (content/messenger-overlay-toolbar.xul)
|
||||
|
@ -131,6 +132,8 @@ calendar-en-US.jar:
|
|||
locale/en-US/calendar/wcap.properties (/calendar/locales/en-US/chrome/calendar/wcap.properties)
|
||||
locale/en-US/calendar/dateFormat.properties (/calendar/locales/en-US/chrome/calendar/dateFormat.properties)
|
||||
locale/en-US/calendar/menuOverlay.dtd (/calendar/locales/en-US/chrome/calendar/menuOverlay.dtd)
|
||||
locale/en-US/calendar/migration.dtd (/calendar/locales/en-US/chrome/calendar/migration.dtd)
|
||||
locale/en-US/calendar/migration.properties (/calendar/locales/en-US/chrome/calendar/migration.properties)
|
||||
locale/en-US/calendar/preferences/alarms.dtd (/calendar/locales/en-US/chrome/calendar/preferences/alarms.dtd)
|
||||
locale/en-US/calendar/preferences/categories.dtd (/calendar/locales/en-US/chrome/calendar/preferences/categories.dtd)
|
||||
locale/en-US/calendar/preferences/general.dtd (/calendar/locales/en-US/chrome/calendar/preferences/general.dtd)
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
<!-- ***** 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 Calendar migration code.
|
||||
-
|
||||
- The Initial Developer of the Original Code is
|
||||
- Joey Minta <jminta@gmail.com>
|
||||
- Portions created by the Initial Developer are Copyright (C) 2006
|
||||
- the Initial Developer. All Rights Reserved.
|
||||
-
|
||||
- Contributor(s):
|
||||
-
|
||||
- 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 LGPL or the GPL. 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 ***** -->
|
||||
|
||||
<!ENTITY migration.title "&brandFullName;: Data Import">
|
||||
<!ENTITY migration.welcome "Welcome">
|
||||
<!ENTITY migration.importing "Importing">
|
||||
<!ENTITY migration.list.description "&brandShortName; can import calendar data from many popular applications. Data from the following applications were found on your computer. Please select which of these you would like to import data from.">
|
||||
<!ENTITY migration.progress.description "Importing selected data">
|
||||
<!ENTITY migration.finished.description "Data import complete">
|
|
@ -0,0 +1,46 @@
|
|||
# ***** 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 Calendar migration code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Joey Minta <jminta@gmail.com>
|
||||
# Portions created by the Initial Developer are Copyright (C) 2006
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Matthew Willis <lilmatt@mozilla.com>
|
||||
#
|
||||
# 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 *****
|
||||
|
||||
migratingApp = Migrating %1$S…
|
||||
|
||||
# The next two lines are duplicated from migration.dtd until there is branding
|
||||
# for lightning
|
||||
migrationTitle = %1$S: Data Import
|
||||
migrationDescription=%1$S can import calendar data from many popular applications. Data from the following applications were found on your computer. Please select which of these you would like to import data from.
|
||||
finished = Complete
|
||||
disableExtTitle = Incompatible Extension Found
|
||||
disableExtText = You have the old Mozilla Calendar Extension installed which is not compatible with Lightning. It will be disabled and %1$S will restart.
|
|
@ -25,6 +25,8 @@ calendar-@AB_CD@.jar:
|
|||
locale/@AB_CD@/calendar/email.properties (%chrome/calendar/email.properties)
|
||||
locale/@AB_CD@/calendar/global.dtd (%chrome/calendar/global.dtd)
|
||||
locale/@AB_CD@/calendar/menuOverlay.dtd (%chrome/calendar/menuOverlay.dtd)
|
||||
locale/@AB_CD@/calendar/migration.dtd (%chrome/calendar/migration.dtd)
|
||||
locale/@AB_CD@/calendar/migration.properties (%chrome/calendar/migration.properties)
|
||||
locale/@AB_CD@/calendar/overlay.dtd (%chrome/calendar/overlay.dtd)
|
||||
locale/@AB_CD@/calendar/preferences/advanced.dtd (%chrome/calendar/preferences/advanced.dtd)
|
||||
locale/@AB_CD@/calendar/preferences/alarms.dtd (%chrome/calendar/preferences/alarms.dtd)
|
||||
|
|
|
@ -275,6 +275,13 @@ function initCalendarManager()
|
|||
|
||||
homeCalendar.name = name;
|
||||
composite.addCalendar(homeCalendar);
|
||||
// Wrapping this in a try/catch block, as if any of the migration code
|
||||
// fails, the app may not load.
|
||||
try {
|
||||
gDataMigrator.checkAndMigrate();
|
||||
} catch (e) {
|
||||
Components.utils.reportError("Migrator error: " + e);
|
||||
}
|
||||
}
|
||||
calMgr.addObserver(calCalendarManagerObserver);
|
||||
composite.addObserver(calCompositeCalendarObserver);
|
||||
|
|
|
@ -76,6 +76,7 @@
|
|||
<script type="application/x-javascript" src="chrome://calendar/content/unifinder.js"/>
|
||||
<script type="application/x-javascript" src="chrome://calendar/content/unifinderToDo.js"/>
|
||||
<script type="application/x-javascript" src="chrome://calendar/content/calendar-views.js"/>
|
||||
<script type="application/x-javascript" src="chrome://calendar/content/migration.js"/>
|
||||
|
||||
<!-- NEEDED FOR APPLICATION SUPPORT -->
|
||||
<script type="application/x-javascript" src="chrome://calendar/content/applicationUtil.js"/>
|
||||
|
|
Загрузка…
Ссылка в новой задаче