зеркало из https://github.com/mozilla/gecko-dev.git
Fixing problem with changing start date not changing end date of event.
This commit is contained in:
Родитель
fe8e9ebb2a
Коммит
f29a4e8bce
|
@ -530,496 +530,6 @@ function getPreviewText( calendarEventDisplay )
|
|||
return ( HolderBox );
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------
|
||||
* C A L E N D A R C L A S S E S
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------
|
||||
* CalendarWindow Class
|
||||
*
|
||||
* Maintains the three calendar views and the selection.
|
||||
*
|
||||
* PROPERTIES
|
||||
* eventSource - the event source, an instance of CalendarEventDataSource
|
||||
* dateFormater - a date formatter, an instance of DateFormater
|
||||
*
|
||||
* monthView - an instance of MonthView
|
||||
* weekView - an instance of WeekView
|
||||
* dayView - an instance of DayView
|
||||
*
|
||||
* currentView - the currently active view, one of the above three instances
|
||||
*
|
||||
* selectedEvent - the selected event, instance of CalendarEvent
|
||||
* selectedDate - selected date, instance of Date
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* CalendarWindow Constructor.
|
||||
*
|
||||
* PARAMETERS
|
||||
* calendarDataSource - The data source with all of the calendar events.
|
||||
*
|
||||
* NOTES
|
||||
* There is one instance of CalendarWindow
|
||||
*/
|
||||
|
||||
function CalendarWindow( calendarDataSource )
|
||||
{
|
||||
this.eventSource = calendarDataSource;
|
||||
|
||||
//setup the preferences
|
||||
this.calendarPreferences = new calendarPreferences( this );
|
||||
|
||||
this.EventSelection = new CalendarEventSelection( this );
|
||||
|
||||
this.dateFormater = new DateFormater( this );
|
||||
|
||||
this.monthView = new MonthView( this );
|
||||
this.weekView = new WeekView( this );
|
||||
this.dayView = new DayView( this );
|
||||
|
||||
// we keep track of the selected date and the selected
|
||||
// event, start with selecting today.
|
||||
|
||||
this.selectedEvent = null;
|
||||
this.selectedDate = new Date();
|
||||
|
||||
// set up the current view - we assume that this.currentView is NEVER null
|
||||
// after this
|
||||
|
||||
this.currentView = null;
|
||||
this.switchToMonthView();
|
||||
|
||||
// now that all is set up we can start to observe the data source
|
||||
|
||||
// make the observer, the calendarEventDataSource calls into the
|
||||
// observer when things change in the data source.
|
||||
|
||||
var calendarWindow = this;
|
||||
|
||||
this.calendarEventDataSourceObserver =
|
||||
{
|
||||
|
||||
onLoad : function()
|
||||
{
|
||||
// called when the data source has finished loading
|
||||
|
||||
calendarWindow.currentView.refreshEvents( );
|
||||
},
|
||||
onStartBatch : function()
|
||||
{
|
||||
},
|
||||
onEndBatch : function()
|
||||
{
|
||||
calendarWindow.currentView.refreshEvents( );
|
||||
},
|
||||
|
||||
onAddItem : function( calendarEvent )
|
||||
{
|
||||
if( !gICalLib.batchMode )
|
||||
{
|
||||
if( calendarEvent )
|
||||
{
|
||||
calendarWindow.currentView.refreshEvents( );
|
||||
|
||||
calendarWindow.setSelectedEvent( calendarEvent );
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
onModifyItem : function( calendarEvent, originalEvent )
|
||||
{
|
||||
if( !gICalLib.batchMode )
|
||||
{
|
||||
if( calendarEvent )
|
||||
{
|
||||
calendarWindow.setSelectedEvent( calendarEvent );
|
||||
|
||||
}
|
||||
calendarWindow.currentView.refreshEvents( );
|
||||
}
|
||||
},
|
||||
|
||||
onDeleteItem : function( calendarEvent, nextEvent )
|
||||
{
|
||||
calendarWindow.clearSelectedEvent( calendarEvent );
|
||||
|
||||
if( !gICalLib.batchMode )
|
||||
{
|
||||
calendarWindow.currentView.refreshEvents( );
|
||||
|
||||
if ( nextEvent )
|
||||
{
|
||||
calendarWindow.setSelectedEvent( nextEvent );
|
||||
}
|
||||
else
|
||||
{
|
||||
var eventStartDate = new Date( calendarEvent.start.getTime() );
|
||||
calendarWindow.setSelectedDate( eventStartDate );
|
||||
|
||||
if( calendarWindow.currentView == calendarWindow.monthView )
|
||||
{
|
||||
calendarWindow.currentView.hiliteSelectedDate( );
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
onAlarm : function( calendarEvent )
|
||||
{
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
// add the observer to the event source
|
||||
|
||||
gICalLib.addObserver( this.calendarEventDataSourceObserver );
|
||||
}
|
||||
|
||||
|
||||
/** PUBLIC
|
||||
*
|
||||
* You must call this when you have finished with the CalendarWindow.
|
||||
* Removes the observer from the data source.
|
||||
*/
|
||||
|
||||
CalendarWindow.prototype.close = function( )
|
||||
{
|
||||
// this.eventSource.removeObserver( this.calendarEventDataSourceObserver );
|
||||
}
|
||||
|
||||
|
||||
/** PUBLIC
|
||||
*
|
||||
* Switch to the day view if it isn't already the current view
|
||||
*/
|
||||
|
||||
CalendarWindow.prototype.switchToDayView = function( )
|
||||
{
|
||||
this.switchToView( this.dayView )
|
||||
}
|
||||
|
||||
|
||||
/** PUBLIC
|
||||
*
|
||||
* Switch to the week view if it isn't already the current view
|
||||
*/
|
||||
|
||||
CalendarWindow.prototype.switchToWeekView = function( )
|
||||
{
|
||||
this.switchToView( this.weekView )
|
||||
}
|
||||
|
||||
|
||||
/** PUBLIC
|
||||
*
|
||||
* Switch to the month view if it isn't already the current view
|
||||
*/
|
||||
|
||||
CalendarWindow.prototype.switchToMonthView = function( )
|
||||
{
|
||||
this.switchToView( this.monthView )
|
||||
}
|
||||
|
||||
/** PUBLIC
|
||||
*
|
||||
* Display today in the current view
|
||||
*/
|
||||
|
||||
CalendarWindow.prototype.goToToday = function( )
|
||||
{
|
||||
this.clearSelectedEvent( );
|
||||
|
||||
this.currentView.goToDay( new Date() )
|
||||
}
|
||||
|
||||
|
||||
/** PUBLIC
|
||||
*
|
||||
* Go to the next period in the current view
|
||||
*/
|
||||
|
||||
CalendarWindow.prototype.goToNext = function( value )
|
||||
{
|
||||
if(value){
|
||||
this.currentView.goToNext( value );
|
||||
}else{
|
||||
this.currentView.goToNext();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** PUBLIC
|
||||
*
|
||||
* Go to the previous period in the current view
|
||||
*/
|
||||
|
||||
CalendarWindow.prototype.goToPrevious = function( value )
|
||||
{
|
||||
if(value){
|
||||
this.currentView.goToPrevious( value );
|
||||
}else{
|
||||
this.currentView.goToPrevious( );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** PUBLIC
|
||||
*
|
||||
* Go to today in the current view
|
||||
*/
|
||||
|
||||
CalendarWindow.prototype.goToDay = function( newDate )
|
||||
{
|
||||
this.currentView.goToDay( newDate );
|
||||
}
|
||||
|
||||
|
||||
/** PACKAGE
|
||||
*
|
||||
* Change the selected event
|
||||
*
|
||||
* PARAMETERS
|
||||
* selectedEvent - an instance of CalendarEvent, MUST be from the CalendarEventDataSource
|
||||
*
|
||||
*/
|
||||
|
||||
CalendarWindow.prototype.setSelectedEvent = function( selectedEvent )
|
||||
{
|
||||
this.EventSelection.replaceSelection( selectedEvent );
|
||||
}
|
||||
|
||||
|
||||
/** PACKAGE
|
||||
*
|
||||
* Clear the selected event
|
||||
*
|
||||
* PARAMETERS
|
||||
* unSelectedEvent - if null: deselect the selected event.
|
||||
* - if a CalendarEvent: only deselect if it is the currently selected one.
|
||||
*
|
||||
*/
|
||||
|
||||
CalendarWindow.prototype.clearSelectedEvent = function( unSelectedEvent )
|
||||
{
|
||||
var undefined;
|
||||
|
||||
gCalendarWindow.EventSelection.emptySelection( );
|
||||
|
||||
if( unSelectedEvent === undefined ||
|
||||
unSelectedEvent == null )
|
||||
{
|
||||
this.currentView.clearSelectedEvent( );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** PUBLIC
|
||||
*
|
||||
* Set the selected date
|
||||
*/
|
||||
|
||||
CalendarWindow.prototype.setSelectedDate = function( date )
|
||||
{
|
||||
// Copy the date because we might mess with it in place
|
||||
|
||||
this.selectedDate = new Date( date );
|
||||
}
|
||||
|
||||
/** PUBLIC
|
||||
*
|
||||
* Get the selected date
|
||||
*/
|
||||
|
||||
CalendarWindow.prototype.getSelectedDate = function( )
|
||||
{
|
||||
// Copy the date because we might mess with it in place
|
||||
|
||||
return new Date( this.selectedDate );
|
||||
}
|
||||
|
||||
|
||||
/** PUBLIC
|
||||
*
|
||||
* Change the hour of the selected date
|
||||
*/
|
||||
|
||||
CalendarWindow.prototype.setSelectedHour = function( hour )
|
||||
{
|
||||
var selectedDate = this.getSelectedDate();
|
||||
|
||||
selectedDate.setHours( hour );
|
||||
selectedDate.setMinutes( 0 );
|
||||
selectedDate.setSeconds( 0 );
|
||||
|
||||
this.setSelectedDate( selectedDate );
|
||||
}
|
||||
|
||||
/** PRIVATE
|
||||
*
|
||||
* Helper function to switch to a view
|
||||
*
|
||||
* PARAMETERS
|
||||
* newView - MUST be one of the three CalendarView instances created in the constructor
|
||||
*/
|
||||
|
||||
CalendarWindow.prototype.switchToView = function( newView )
|
||||
{
|
||||
// only switch if not already there
|
||||
|
||||
if( this.currentView !== newView )
|
||||
{
|
||||
// call switch from for the view we are leaving
|
||||
|
||||
if( this.currentView )
|
||||
{
|
||||
this.currentView.switchFrom();
|
||||
}
|
||||
|
||||
// change the current view
|
||||
|
||||
this.currentView = newView;
|
||||
|
||||
// switch to and refresh the view
|
||||
|
||||
newView.switchTo();
|
||||
|
||||
newView.refresh();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** PUBLIC
|
||||
*
|
||||
* This changes the text for the popuptooltip text
|
||||
* This is the same for any view.
|
||||
*/
|
||||
|
||||
CalendarWindow.prototype.mouseOverInfo = function( calendarEvent, event )
|
||||
{
|
||||
var Html = document.getElementById( "savetip" );
|
||||
|
||||
while( Html.hasChildNodes() )
|
||||
{
|
||||
Html.removeChild( Html.firstChild );
|
||||
}
|
||||
|
||||
var HolderBox = getPreviewText( event.currentTarget.calendarEventDisplay );
|
||||
|
||||
Html.appendChild( HolderBox );
|
||||
}
|
||||
|
||||
/** PRIVATE
|
||||
*
|
||||
* This returns the lowest element not in the array
|
||||
* eg. array(0, 0, 1, 3) would return 2
|
||||
* Used to figure out where to put the day events.
|
||||
*
|
||||
*/
|
||||
|
||||
CalendarWindow.prototype.getLowestElementNotInArray = function( InputArray )
|
||||
{
|
||||
var Temp = 1;
|
||||
var AllZero = true; //are all the elements in the array 0?
|
||||
//CAUTION: Watch the scope here. This function is called from inside a nested for loop.
|
||||
//You can't have the index variable named anything that is used in those for loops.
|
||||
|
||||
for ( Mike = 0; Mike < InputArray.length; Mike++ )
|
||||
{
|
||||
|
||||
if ( InputArray[Mike] > Temp )
|
||||
{
|
||||
return (Temp);
|
||||
}
|
||||
if ( InputArray[Mike] > 0)
|
||||
{
|
||||
AllZero = false;
|
||||
Temp++; //don't increment if the array value is 0, otherwise add 1.
|
||||
}
|
||||
}
|
||||
if ( AllZero )
|
||||
{
|
||||
return (1);
|
||||
}
|
||||
return (Temp);
|
||||
}
|
||||
|
||||
|
||||
/** PRIVATE
|
||||
*
|
||||
* Use this function to compare two numbers. Returns the difference.
|
||||
* This is used to sort an array, and sorts it in ascending order.
|
||||
*
|
||||
*/
|
||||
|
||||
CalendarWindow.prototype.compareNumbers = function (a, b) {
|
||||
return a - b
|
||||
}
|
||||
|
||||
/** PUBLIC
|
||||
* The resize handler, used to set the size of the views so they fit the screen.
|
||||
*/
|
||||
window.onresize = CalendarWindow.prototype.doResize = function(){
|
||||
gCalendarWindow.currentView.refresh();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------
|
||||
* CalendarView Class
|
||||
*
|
||||
* Abstract super class for the three view classes
|
||||
*
|
||||
* PROPERTIES
|
||||
* calendarWindow - instance of CalendarWindow that owns this view
|
||||
*
|
||||
*/
|
||||
|
||||
function CalendarView( calendarWindow )
|
||||
{
|
||||
this.calendarWindow = calendarWindow;
|
||||
}
|
||||
|
||||
/** A way for subclasses to invoke the super constructor */
|
||||
|
||||
CalendarView.prototype.superConstructor = CalendarView;
|
||||
|
||||
/** PUBLIC
|
||||
*
|
||||
* Select the date and show it in the view
|
||||
* Params: newDate: the new date to go to.
|
||||
* ShowEvent: Do we show an event being highlighted, or do we show a day being highlighted.
|
||||
*/
|
||||
|
||||
CalendarView.prototype.goToDay = function( newDate, ShowEvent )
|
||||
{
|
||||
this.calendarWindow.setSelectedDate( newDate );
|
||||
|
||||
this.refresh( ShowEvent )
|
||||
}
|
||||
|
||||
/** PUBLIC
|
||||
*
|
||||
* Refresh display of events and the selection in the view
|
||||
*/
|
||||
|
||||
CalendarView.prototype.refresh = function( ShowEvent )
|
||||
{
|
||||
this.refreshDisplay( ShowEvent )
|
||||
|
||||
this.refreshEvents()
|
||||
|
||||
if(this.calendarWindow.currentView.doResize)
|
||||
this.calendarWindow.currentView.doResize();
|
||||
}
|
||||
|
||||
function alertCalendarVersion()
|
||||
{
|
||||
alert( "This calendar was made on "+gDateMade+". Please include this in your bug report." );
|
||||
|
@ -1039,3 +549,132 @@ function playSound( ThisURL )
|
|||
|
||||
sample.play( url );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
**
|
||||
*/
|
||||
function openImportFileDialog()
|
||||
{
|
||||
const nsIFilePicker = Components.interfaces.nsIFilePicker;
|
||||
|
||||
const nsILocalFile = Components.interfaces.nsILocalFile;
|
||||
|
||||
var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
|
||||
|
||||
// caller can force disable of sand box, even if ON globally
|
||||
|
||||
fp.init(window, "Open File", nsIFilePicker.modeOpen);
|
||||
|
||||
fp.defaultString = "My Mozilla Calendar.ics";
|
||||
|
||||
fp.appendFilter( "Calendar Files", "*.ics" );
|
||||
|
||||
/*
|
||||
* Setup the initial directory to be the home directory
|
||||
*/
|
||||
const dirSvc = Components
|
||||
.classes["@mozilla.org/file/directory_service;1"]
|
||||
.getService(Components.interfaces.nsIProperties);
|
||||
|
||||
var baseFile = dirSvc.get("Home", nsILocalFile);
|
||||
|
||||
const dir = baseFile.clone().QueryInterface(nsILocalFile);
|
||||
|
||||
fp.displayDirectory = dir;
|
||||
|
||||
try {
|
||||
fp.show();
|
||||
/* need to handle cancel (uncaught exception at present) */
|
||||
}
|
||||
catch (ex) {
|
||||
dump("filePicker.chooseInputFile threw an exception\n");
|
||||
}
|
||||
/* This checks for already open window and activates it...
|
||||
* note that we have to test the native path length
|
||||
* since fileURL.spec will be "file:///" if no filename picked (Cancel button used)
|
||||
*/
|
||||
if (fp.file && fp.file.path.length > 0)
|
||||
{
|
||||
doImportEvents( fp.file.path );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
function doImportEvents( FilePath )
|
||||
{
|
||||
alert( "I should import files to "+FilePath );
|
||||
}
|
||||
|
||||
function openExportFileDialog()
|
||||
{
|
||||
const nsIFilePicker = Components.interfaces.nsIFilePicker;
|
||||
|
||||
const nsILocalFile = Components.interfaces.nsILocalFile;
|
||||
|
||||
var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
|
||||
|
||||
// caller can force disable of sand box, even if ON globally
|
||||
|
||||
fp.init(window, "Open File", nsIFilePicker.modeSave);
|
||||
|
||||
fp.defaultString = "My Mozilla Calendar.ics";
|
||||
|
||||
fp.appendFilter( "Calendar Files", "*.ics" );
|
||||
|
||||
/*
|
||||
* Setup the initial directory to be the home directory
|
||||
*/
|
||||
const dirSvc = Components
|
||||
.classes["@mozilla.org/file/directory_service;1"]
|
||||
.getService(Components.interfaces.nsIProperties);
|
||||
|
||||
var baseFile = dirSvc.get("Home", nsILocalFile);
|
||||
|
||||
const dir = baseFile.clone().QueryInterface(nsILocalFile);
|
||||
|
||||
fp.displayDirectory = dir;
|
||||
|
||||
try {
|
||||
fp.show();
|
||||
/* need to handle cancel (uncaught exception at present) */
|
||||
}
|
||||
catch (ex) {
|
||||
dump("filePicker.chooseInputFile threw an exception\n");
|
||||
}
|
||||
/* This checks for already open window and activates it...
|
||||
* note that we have to test the native path length
|
||||
* since fileURL.spec will be "file:///" if no filename picked (Cancel button used)
|
||||
*/
|
||||
if (fp.file && fp.file.path.length > 0)
|
||||
{
|
||||
doExportEvents( fp.file.path );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
function doExportEvents( FilePath )
|
||||
{
|
||||
//get all the selected events;
|
||||
var SelectedEvents = gCalendarWindow.EventSelection.selectedEvents;
|
||||
|
||||
//send this to the back end, it should return a string.
|
||||
|
||||
|
||||
//write that string out to the new file with path 'FilePath';
|
||||
var aFile = Components.classes["@mozilla.org/file/local;1"].createInstance();
|
||||
|
||||
aLocalFile=aFile.QueryInterface(Components.interfaces.nsILocalFile);
|
||||
|
||||
aLocalFile.initWithPath( FilePath );
|
||||
|
||||
aLocalFile.create( 0, 0755 );
|
||||
|
||||
//write to the file.
|
||||
|
||||
alert( "I should export files to "+FilePath );
|
||||
}
|
||||
|
|
|
@ -112,6 +112,7 @@
|
|||
<script type="application/x-javascript" src="chrome://calendar/content/calendar.js"/>
|
||||
<script type="application/x-javascript" src="chrome://calendar/content/calendarEvent.js"/>
|
||||
<script type="application/x-javascript" src="chrome://calendar/content/calendarSelection.js"/>
|
||||
<script type="application/x-javascript" src="chrome://calendar/content/calendarWindow.js"/>
|
||||
<script type="application/x-javascript" src="chrome://calendar/content/pref/rootCalendarPref.js"/>
|
||||
|
||||
<!-- Pop up menus -->
|
||||
|
|
|
@ -430,7 +430,6 @@ function onTimePick( timepopup )
|
|||
|
||||
if ( newEndDate.getDate() != timepopup.value.getDate() ) //if this moves us to tomorrow...
|
||||
{
|
||||
|
||||
//put us back at today, with a time of 11:55 PM.
|
||||
newEndDate = new Date( timepopup.value.getFullYear(),
|
||||
timepopup.value.getMonth(),
|
||||
|
@ -439,13 +438,10 @@ function onTimePick( timepopup )
|
|||
55,
|
||||
0);
|
||||
}
|
||||
|
||||
formattedEndTime = formatTime( newEndDate );
|
||||
if( timepopup.timeField.id != "end-time-text" )
|
||||
{
|
||||
setFieldValue( "end-time-text", formattedEndTime, "value" );
|
||||
|
||||
setFieldValue( "end-time-text", newEndDate, "editDate" );
|
||||
setTimeFieldValue( "end-time-text", newEndDate );
|
||||
}
|
||||
|
||||
|
||||
|
@ -472,7 +468,6 @@ function onTimePick( timepopup )
|
|||
// remember the new date in a property, "editDate". we created on the time textbox
|
||||
|
||||
timepopup.timeField.editDate = timepopup.value;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -98,6 +98,9 @@
|
|||
<menubar id="main-menubar" class="chromeclass-menubar">
|
||||
<menu id="menu_File">
|
||||
<menupopup id="menu_FilePopup">
|
||||
<menuitem id="calendar-import-menu" label="Import ..." oncommand="openImportFileDialog()"/>
|
||||
<menuitem id="calendar-export-menu" label="Export ..." oncommand="openExportFileDialog()"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="calendar-about-menu-item" label="About Calendar" oncommand="alertCalendarVersion()"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
|
|
|
@ -430,7 +430,6 @@ function onTimePick( timepopup )
|
|||
|
||||
if ( newEndDate.getDate() != timepopup.value.getDate() ) //if this moves us to tomorrow...
|
||||
{
|
||||
|
||||
//put us back at today, with a time of 11:55 PM.
|
||||
newEndDate = new Date( timepopup.value.getFullYear(),
|
||||
timepopup.value.getMonth(),
|
||||
|
@ -439,13 +438,10 @@ function onTimePick( timepopup )
|
|||
55,
|
||||
0);
|
||||
}
|
||||
|
||||
formattedEndTime = formatTime( newEndDate );
|
||||
if( timepopup.timeField.id != "end-time-text" )
|
||||
{
|
||||
setFieldValue( "end-time-text", formattedEndTime, "value" );
|
||||
|
||||
setFieldValue( "end-time-text", newEndDate, "editDate" );
|
||||
setTimeFieldValue( "end-time-text", newEndDate );
|
||||
}
|
||||
|
||||
|
||||
|
@ -472,7 +468,6 @@ function onTimePick( timepopup )
|
|||
// remember the new date in a property, "editDate". we created on the time textbox
|
||||
|
||||
timepopup.timeField.editDate = timepopup.value;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -98,6 +98,9 @@
|
|||
<menubar id="main-menubar" class="chromeclass-menubar">
|
||||
<menu id="menu_File">
|
||||
<menupopup id="menu_FilePopup">
|
||||
<menuitem id="calendar-import-menu" label="Import ..." oncommand="openImportFileDialog()"/>
|
||||
<menuitem id="calendar-export-menu" label="Export ..." oncommand="openExportFileDialog()"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="calendar-about-menu-item" label="About Calendar" oncommand="alertCalendarVersion()"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
|
|
Загрузка…
Ссылка в новой задаче