/* ***** 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 Mozilla Calendar code. * * The Initial Developer of the Original Code is * ArentJan Banck . * Portions created by the Initial Developer are Copyright (C) 2002 * the Initial Developer. All Rights Reserved. * * Contributor(s): ArentJan Banck * * 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 ***** */ /***** calendarClipboard * * NOTES * TODO items * - Add a clipboard listener, to enable/disable menu-items depending if * valid clipboard data is available. * ******/ function getClipboard() { const kClipboardContractID = "@mozilla.org/widget/clipboard;1"; const kClipboardIID = Components.interfaces.nsIClipboard; return Components.classes[kClipboardContractID].getService(kClipboardIID); } function createTransferable() { const kTransferableContractID = "@mozilla.org/widget/transferable;1"; const kTransferableIID = Components.interfaces.nsITransferable return Components.classes[kTransferableContractID].createInstance(kTransferableIID); } function createSupportsArray() { const kSuppArrayContractID = "@mozilla.org/supports-array;1"; const kSuppArrayIID = Components.interfaces.nsISupportsArray; return Components.classes[kSuppArrayContractID].createInstance(kSuppArrayIID); } // Should we use (wide)String only, or no (wide)Strings for compatibility? function createSupportsCString() { const kSuppStringContractID = "@mozilla.org/supports-cstring;1"; const kSuppStringIID = Components.interfaces.nsISupportsCString; return Components.classes[kSuppStringContractID].createInstance(kSuppStringIID); } function createSupportsString() { const kSuppStringContractID = "@mozilla.org/supports-string;1"; const kSuppStringIID = Components.interfaces.nsISupportsString; return Components.classes[kSuppStringContractID].createInstance(kSuppStringIID); } function createSupportsWString() { const kSuppStringContractID = "@mozilla.org/supports-wstring;1"; const kSuppStringIID = Components.interfaces.nsISupportsWString; return Components.classes[kSuppStringContractID].createInstance(kSuppStringIID); } /** * Test if the clipboard has items that can be pasted into Calendar. * This must be of type "text/calendar" or "text/unicode" */ function canPaste() { const kClipboardIID = Components.interfaces.nsIClipboard; var clipboard = getClipboard(); var flavourArray = createSupportsArray(); var flavours = ["text/calendar", "text/unicode"]; for (var i = 0; i < flavours.length; ++i) { const kSuppString = createSupportsCString(); kSuppString.data = flavours[i]; flavourArray.AppendElement(kSuppString); } return clipboard.hasDataMatchingFlavors(flavourArray, kClipboardIID.kGlobalClipboard); } /** * Copy iCalendar data to the Clipboard, and delete the selected events. * Does not use eventarray parameter, because DeletCcommand delete selected events. */ function cutToClipboard( /* calendarEventArray */) { // if( !calendarEventArray) var calendarEventArray = gCalendarWindow.EventSelection.selectedEvents; if( copyToClipboard( calendarEventArray ) ) { deleteEventCommand( true ); // deletes all selected events without prompting. } } /** * Copy iCalendar data to the Clipboard. The data is copied to three types: * 1) text/calendar. Found that name somewhere in mail code. not used outside * Calendar as far as I know, so this can be customized for internal use. * 2) text/unicode. Plaintext iCalendar data, tested on Windows for Outlook 2000 * and Lotus Organizer. * 3) text/html. Not for parsing, only pretty looking calendar data. * **/ function copyToClipboard( calendarEventArray ) { if( !calendarEventArray) { var calendarEventArray = new Array( 0 ); calendarEventArray = gCalendarWindow.EventSelection.selectedEvents; } if(calendarEventArray.length == 0) alert("No events selected"); var calendarEvent; var sTextiCalendar = eventArrayToICalString( calendarEventArray ); var sTextiCalendarExport = eventArrayToICalString( calendarEventArray, true ); var sTextHTML = eventArrayToHTML( calendarEventArray ); // 1. get the clipboard service var clipboard = getClipboard(); // 2. create the transferable var trans = createTransferable(); if ( trans && clipboard) { // 3. register the data flavors trans.addDataFlavor("text/calendar"); trans.addDataFlavor("text/unicode"); trans.addDataFlavor("text/html"); // 4. create the data objects var icalWrapper = createSupportsString(); var textWrapper = createSupportsString(); var htmlWrapper = createSupportsString(); if ( icalWrapper && textWrapper && htmlWrapper ) { // get the data icalWrapper.data = sTextiCalendar; // plainTextRepresentation; textWrapper.data = sTextiCalendarExport; // plainTextRepresentation; htmlWrapper.data = sTextHTML; // htmlRepresentation; // 5. add data objects to transferable // Both Outlook 2000 client and Lotus Organizer use text/unicode when pasting iCalendar data trans.setTransferData ( "text/calendar", icalWrapper, icalWrapper.data.length*2 ); // double byte data trans.setTransferData ( "text/unicode", textWrapper, textWrapper.data.length*2 ); trans.setTransferData ( "text/html", htmlWrapper, htmlWrapper.data.length*2 ); clipboard.setData( trans, null, Components.interfaces.nsIClipboard.kGlobalClipboard ); return true; } } return true; } /** * Paste iCalendar events from the clipboard, * or paste clipboard text into description of new event */ function pasteFromClipboard() { const kClipboardIID = Components.interfaces.nsIClipboard; if( canPaste() ) { // 1. get the clipboard service var clipboard = getClipboard(); // 2. create the transferable var trans = createTransferable(); if ( trans && clipboard) { // 3. register the data flavors you want, highest fidelity first! trans.addDataFlavor("text/calendar"); trans.addDataFlavor("text/unicode"); // 4. get transferable from clipboard clipboard.getData ( trans, kClipboardIID.kGlobalClipboard); // 5. ask transferable for the best flavor. Need to create new JS // objects for the out params. var flavour = { }; var data = { }; var length = { }; trans.getAnyTransferData(flavour, data, length); data = data.value.QueryInterface(Components.interfaces.nsISupportsString).data; //DEBUG alert("clipboard type: " + flavour.value); var calendarEventArray; var startDate; var endDateTime; var MinutesToAddOn; switch (flavour.value) { case "text/calendar": calendarEventArray = parseIcalData( data ); //change the date of all the events to now startDate = gCalendarWindow.currentView.getNewEventDate(); var categoriesStringBundle = srGetStrBundle("chrome://calendar/locale/calendar.properties"); MinutesToAddOn = getIntPref(gCalendarWindow.calendarPreferences.calendarPref, "event.defaultlength", categoriesStringBundle.GetStringFromName("defaultEventLength" ) ); endDateTime = startDate.getTime() + ( 1000 * 60 * MinutesToAddOn ); for( var i = 0; i < calendarEventArray.length; i++ ) { calendarEventArray[i].start.setTime( startDate ); calendarEventArray[i].end.setTime( endDateTime ); } addEventsToCalendar( calendarEventArray ); break; case "text/unicode": if ( data.indexOf("BEGIN:VEVENT") == -1 ) { // no iCalendar data, paste clipboard text into description of new event calendarEvent = createEvent(); initCalendarEvent( calendarEvent ); calendarEvent.description = data; editNewEvent( calendarEvent ); } else { calendarEventArray = parseIcalData( data ); //change the date of all the events to now startDate = gCalendarWindow.currentView.getNewEventDate(); MinutesToAddOn = getIntPref(gCalendarWindow.calendarPreferences.calendarPref, "event.defaultlength", 60 ); endDateTime = startDate.getTime() + ( 1000 * 60 * MinutesToAddOn ); for( i = 0; i < calendarEventArray.length; i++ ) { calendarEventArray[i].start.setTime( startDate ); calendarEventArray[i].end.setTime( endDateTime ); } addEventsToCalendar( calendarEventArray ); } break; default: alert("Unknown clipboard type: " + flavour.value); } } } else alert( "No iCalendar or text on the clipboard." ); }