releases-comm-central/calendar/base/content/calendar-management.js

304 строки
11 KiB
JavaScript

/* ***** 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 code.
*
* The Initial Developer of the Original Code is
* Philipp Kewisch <mozilla@kewis.ch>
* Portions created by the Initial Developer are Copyright (C) 2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Michiel van Leeuwen <mvl@exedo.nl>
* Joey Minta <jminta@gmail.com>
* Berend Cornelius <berend.cornelius@sun.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 ***** */
/**
* Get this window's currently selected calendar.
*
* @return The currently selected calendar.
*/
function getSelectedCalendar() {
return getCompositeCalendar().defaultCalendar;
}
/**
* Deletes the passed calendar, prompting the user if he really wants to do
* this. If there is only one calendar left, no calendar is removed and the user
* is not prompted.
*
* @param aCalendar The calendar to delete.
*/
function promptDeleteCalendar(aCalendar) {
var calendars = getCalendarManager().getCalendars({});
if (calendars.length <= 1) {
// If this is the last calendar, don't delete it.
return;
}
var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
.getService(Components.interfaces.nsIPromptService);
var ok = promptService.confirm(
window,
calGetString("calendar", "unsubscribeCalendarTitle"),
calGetString("calendar",
"unsubscribeCalendarMessage",
[aCalendar.name]),
{});
if (ok) {
var calMgr = getCalendarManager();
calMgr.unregisterCalendar(aCalendar);
calMgr.deleteCalendar(aCalendar);
}
}
/**
* Called to initialize the calendar manager for a window.
*/
function loadCalendarManager() {
// Set up the composite calendar in the calendar list widget.
let tree = document.getElementById("calendar-list-tree-widget");
tree.compositeCalendar = getCompositeCalendar();
// Create the home calendar if no calendar exists.
let calendars = getCalendarManager().getCalendars({});
if (!calendars.length) {
initHomeCalendar();
}
}
/**
* Creates the initial "Home" calendar if no calendar exists.
*/
function initHomeCalendar() {
let calMgr = cal.getCalendarManager();
let composite = getCompositeCalendar();
let url = makeURL("moz-profile-calendar://");
let homeCalendar = calMgr.createCalendar("storage", url);
calMgr.registerCalendar(homeCalendar);
let name = calGetString("calendar", "homeCalendarName");
homeCalendar.name = name;
cal.setPref("calendar.list.sortOrder", homeCalendar.id);
composite.addCalendar(homeCalendar);
// Wrapping this in a try/catch block, as if any of the migration code
// fails, the app may not load.
if (getPrefSafe("calendar.migrator.enabled", true)) {
try {
gDataMigrator.checkAndMigrate();
} catch (e) {
Components.utils.reportError("Migrator error: " + e);
}
}
return homeCalendar;
}
/**
* Called to clean up the calendar manager for a window.
*/
function unloadCalendarManager() {
var composite = getCompositeCalendar();
composite.setStatusObserver(null, null);
}
/**
* Updates the sort order preference based on the given event. The event is a
* "SortOrderChanged" event, emitted from the calendar-list-tree binding. You
* can also pass in an object like { sortOrder: "Space separated calendar ids" }
*
* @param event The SortOrderChanged event described above.
*/
function updateSortOrderPref(event) {
let sortOrderString = event.sortOrder.join(" ");
cal.setPref("calendar.list.sortOrder", sortOrderString);
}
/**
* Handler function to call when the tooltip is showing on the calendar list.
*
* @param event The DOM event provoked by the tooltip showing.
*/
function calendarListTooltipShowing(event) {
let tree = document.getElementById("calendar-list-tree-widget");
let calendar = tree.getCalendarFromEvent(event);
let tooltipText = false;
if (calendar) {
let currentStatus = calendar.getProperty("currentStatus");
if (!Components.isSuccessCode(currentStatus)){
tooltipText = calGetString("calendar", "tooltipCalendarDisabled", [calendar.name]);
} else if (calendar.readOnly) {
tooltipText = calGetString("calendar", "tooltipCalendarReadOnly", [calendar.name]);
}
}
setElementValue("calendar-list-tooltip", tooltipText, "label");
return (tooltipText != false);
}
/**
* A handler called to set up the context menu on the calendar list.
*
* @param event The DOM event that caused the context menu to open.
* @return Returns true if the context menu should be shown.
*/
function calendarListSetupContextMenu(event) {
let col = {};
let row = {};
let calendar;
let calendars = getCalendarManager().getCalendars({});
let treeNode = document.getElementById("calendar-list-tree-widget");
if (document.popupNode.localName == "tree") {
// Using VK_APPS to open the context menu will target the tree
// itself. In that case we won't have a client point even for
// opening the context menu. The "target" element should then be the
// selected calendar.
row.value = treeNode.tree.currentIndex;
col.value = treeNode.getColumn("calendarname-treecol");
calendar = treeNode.getCalendar(row.value);
} else {
// Using the mouse, the context menu will open on the treechildren
// element. Here we can use client points.
calendar = treeNode.getCalendarFromEvent(event, col, row);
}
if (col.value &&
col.value.element.getAttribute("anonid") == "checkbox-treecol") {
// Don't show the context menu if the checkbox was clicked.
return false;
}
document.getElementById("list-calendars-context-menu").contextCalendar = calendar;
// Only enable calendar search if there's actually the chance of finding something:
let hasProviders = getCalendarSearchService().getProviders({}).length < 1 && "true";
setElementValue("list-calendars-context-find", hasProviders, "collapsed");
if (calendar) {
enableElement("list-calendars-context-edit");
enableElement("list-calendars-context-publish");
// Only enable the delete calendars item if there is more than one
// calendar. We don't want to have the last calendar deleted.
if (calendars.length > 1) {
enableElement("list-calendars-context-delete");
}
} else {
disableElement("list-calendars-context-edit");
disableElement("list-calendars-context-publish");
disableElement("list-calendars-context-delete");
}
return true;
}
var compositeObserver = {
QueryInterface: function cO_QueryInterface(aIID) {
return cal.doQueryInterface(this,
calendarManagementCompositeObserver.prototype,
aIID,
[Components.interfaces.calICompositeObserver]);
},
onCalendarAdded: function cO_onCalendarAdded(aCalendar) {
// Update the calendar commands for number of remote calendars and for
// more than one calendar
document.commandDispatcher.updateCommands("calendar_commands");
},
onCalendarRemoved: function cO_onCalendarRemoved(aCalendar) {
// Update commands to disallow deleting the last calendar and only
// allowing reload remote calendars when there are remote calendars.
document.commandDispatcher.updateCommands("calendar_commands");
}
};
/**
* Opens the subscriptions dialog modally.
*/
function openCalendarSubscriptionsDialog() {
// the dialog will reset this to auto when it is done loading
window.setCursor("wait");
// open the dialog modally
window.openDialog("chrome://calendar/content/calendar-subscriptions-dialog.xul",
"_blank",
"chrome,titlebar,modal,resizable");
}
/**
* Calendar Offline Manager
*/
var calendarOfflineManager = {
QueryInterface: function cOM_QueryInterface(aIID) {
return doQueryInterface(this, calendarOfflineManager.prototype, aIID,
[Components.interfaces.nsIObserver, Components.interfaces.nsISupports]);
},
init: function cOM_init() {
if (this.initialized) {
throw Components.results.NS_ERROR_ALREADY_INITIALIZED;
}
var os = Components.classes["@mozilla.org/observer-service;1"]
.getService(Components.interfaces.nsIObserverService);
os.addObserver(this, "network:offline-status-changed", false);
this.updateOfflineUI(!this.isOnline());
this.initialized = true;
},
uninit: function cOM_uninit() {
if (!this.initialized) {
throw Components.results.NS_ERROR_NOT_INITIALIZED;
}
var os = Components.classes["@mozilla.org/observer-service;1"]
.getService(Components.interfaces.nsIObserverService);
os.removeObserver(this, "network:offline-status-changed", false);
this.initialized = false;
},
isOnline: function cOM_isOnline() {
return (!getIOService().offline);
},
updateOfflineUI: function cOM_updateOfflineUI(aIsOffline) {
// Refresh the current view
currentView().goToDay(currentView().selectedDay);
// Set up disabled locks for offline
document.commandDispatcher.updateCommands("calendar_commands");
},
observe: function cOM_observe(aSubject, aTopic, aState) {
if (aTopic == "network:offline-status-changed") {
this.updateOfflineUI(aState == "offline");
}
}
};