зеркало из https://github.com/mozilla/pjs.git
Bug 393387 - week view is blank; r=mickey
This commit is contained in:
Родитель
fe7c61eb45
Коммит
7869216e45
|
@ -1091,17 +1091,24 @@
|
|||
<parameter name="aEndDate"/>
|
||||
<body><![CDATA[
|
||||
if (this.mTimezone != aStartDate.timezone) {
|
||||
aStartDate = aStartDate.getInTimezone(this.mTimezone);
|
||||
aEndDate = aEndDate.getInTimezone(this.mTimezone);
|
||||
aStartDate = aStartDate.getInTimezone(this.mTimezone);
|
||||
aEndDate = aEndDate.getInTimezone(this.mTimezone);
|
||||
}
|
||||
var startDate = aStartDate.startOfWeek.clone();
|
||||
var endDate = aEndDate.endOfWeek.clone();
|
||||
startDate.day += this.mWeekStartOffset;
|
||||
endDate.day += this.mWeekStartOffset;
|
||||
|
||||
this.mStartDate = aStartDate.startOfWeek;
|
||||
this.mEndDate = aEndDate.endOfWeek;
|
||||
|
||||
this.mStartDate.day += this.mWeekStartOffset;
|
||||
this.mEndDate.day += this.mWeekStartOffset;
|
||||
|
||||
this.refresh();
|
||||
function compareDatetimes(one, two) {
|
||||
return ((!one && !two) ||
|
||||
(one && two && (one.compare(two) == 0)));
|
||||
}
|
||||
if (!compareDatetimes(this.mStartDate, startDate) ||
|
||||
!compareDatetimes(this.mEndDate, endDate)) {
|
||||
this.mStartDate = startDate;
|
||||
this.mEndDate = endDate;
|
||||
this.refresh();
|
||||
}
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
|
@ -1159,15 +1166,21 @@
|
|||
onget="return document.getAnonymousElementByAttribute(this, 'anonid', 'monthgridrows');"/>
|
||||
|
||||
<field name="mRefreshQueue">[]</field>
|
||||
<field name="mRefreshPending">false</field>
|
||||
<field name="mRefreshPending">null</field>
|
||||
|
||||
<method name="popRefreshQueue">
|
||||
<body><![CDATA[
|
||||
if (this.mRefreshPending) {
|
||||
if(this.mRefreshQueue.length > 0) {
|
||||
this.relayout();
|
||||
}
|
||||
return;
|
||||
var pendingRefresh = this.mRefreshPending;
|
||||
if (pendingRefresh) {
|
||||
if (pendingRefresh instanceof Components.interfaces.calIOperation) {
|
||||
this.mRefreshPending = null;
|
||||
pendingRefresh.cancel(null);
|
||||
} else {
|
||||
if(this.mRefreshQueue.length > 0) {
|
||||
this.relayout();
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var refreshJob = this.mRefreshQueue.pop();
|
||||
|
@ -1195,13 +1208,14 @@
|
|||
else
|
||||
filter |= this.mCalendar.ITEM_FILTER_TYPE_EVENT;
|
||||
|
||||
this.mRefreshPending = true;
|
||||
|
||||
this.mCalendar.getItems(filter,
|
||||
0,
|
||||
this.startDate,
|
||||
this.queryEndDate,
|
||||
this.mOperationListener);
|
||||
this.mRefreshPending = this.mCalendar.getItems(filter,
|
||||
0,
|
||||
this.startDate,
|
||||
this.queryEndDate,
|
||||
this.mOperationListener);
|
||||
if (!this.mRefreshPending) { // no support for calIOperation, fallback to bool
|
||||
this.mRefreshPending = true;
|
||||
}
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
|
@ -1498,7 +1512,7 @@
|
|||
|
||||
onOperationComplete: function(aCalendar, aStatus, aOperationType, aId, aDetail) {
|
||||
// signal that the current operation finished.
|
||||
this.calView.mRefreshPending = false;
|
||||
this.calView.mRefreshPending = null;
|
||||
|
||||
// immediately start the next job on the queue.
|
||||
this.calView.popRefreshQueue();
|
||||
|
|
|
@ -2373,7 +2373,7 @@
|
|||
function onOperationComplete(aCalendar, aStatus, aOperationType,
|
||||
aId, aDetail) {
|
||||
// signal that the current operation finished.
|
||||
this.calView.mRefreshPending = false;
|
||||
this.calView.mRefreshPending = null;
|
||||
|
||||
// immediately start the next job on the queue.
|
||||
this.calView.popRefreshQueue();
|
||||
|
@ -2554,29 +2554,36 @@
|
|||
aStartDate = aEndDate = null;
|
||||
|
||||
if (this.mDisplayDaysOff) {
|
||||
startDate.makeImmutable();
|
||||
endDate.makeImmutable();
|
||||
this.mDateList = null;
|
||||
this.mStartDate = startDate;
|
||||
this.mEndDate = endDate;
|
||||
//
|
||||
// For a true multiday view (e.g, 3 days advanced by one day
|
||||
// at a time), a smarter refresh could reuse boxes, comparing
|
||||
// the current date range and add/remove, instead of just
|
||||
// replacing.
|
||||
//
|
||||
this.refresh();
|
||||
} else { // workdays only
|
||||
var dateList = new Array();
|
||||
for (var d = startDate.clone(); d.compare(endDate) <= 0;) {
|
||||
if (this.mDaysOffArray.indexOf(d.weekday) == -1) {
|
||||
var workday = d.clone();
|
||||
workday.makeImmutable();
|
||||
dateList.push(workday);
|
||||
function compareDatetimes(one, two) {
|
||||
return ((!one && !two) ||
|
||||
(one && two && (one.compare(two) == 0)));
|
||||
}
|
||||
d.day += 1;
|
||||
}
|
||||
this.setDateList(dateList.length, dateList);
|
||||
if (!compareDatetimes(this.mStartDate, startDate) ||
|
||||
!compareDatetimes(this.mEndDate, endDate)) {
|
||||
startDate.makeImmutable();
|
||||
endDate.makeImmutable();
|
||||
this.mDateList = null;
|
||||
this.mStartDate = startDate;
|
||||
this.mEndDate = endDate;
|
||||
//
|
||||
// For a true multiday view (e.g, 3 days advanced by one day
|
||||
// at a time), a smarter refresh could reuse boxes, comparing
|
||||
// the current date range and add/remove, instead of just
|
||||
// replacing.
|
||||
//
|
||||
this.refresh();
|
||||
}
|
||||
} else { // workdays only
|
||||
var dateList = new Array();
|
||||
for (var d = startDate.clone(); d.compare(endDate) <= 0;) {
|
||||
if (this.mDaysOffArray.indexOf(d.weekday) == -1) {
|
||||
var workday = d.clone();
|
||||
workday.makeImmutable();
|
||||
dateList.push(workday);
|
||||
}
|
||||
d.day += 1;
|
||||
}
|
||||
this.setDateList(dateList.length, dateList);
|
||||
}
|
||||
]]></body>
|
||||
</method>
|
||||
|
@ -2588,11 +2595,10 @@
|
|||
this.mStartDate = null;
|
||||
this.mEndDate = null;
|
||||
|
||||
if (aCount == 0) {
|
||||
this.mDateList = null;
|
||||
} else {
|
||||
var dateList = null;
|
||||
if (aCount > 0) {
|
||||
aDates.sort (function(a, b) { return a.compare(b); });
|
||||
this.mDateList = aDates.map(
|
||||
dateList = aDates.map(
|
||||
function dateMapper(d) {
|
||||
if (d.isDate && !d.isMutable)
|
||||
return d;
|
||||
|
@ -2604,8 +2610,14 @@
|
|||
}
|
||||
);
|
||||
}
|
||||
|
||||
this.refresh();
|
||||
function compareDatetimes(one, two) {
|
||||
return ((!one && !two) ||
|
||||
(one && two && (one.compare(two) == 0)));
|
||||
}
|
||||
if (!compareArrays(this.mDateList, dateList, compareDatetimes)) {
|
||||
this.mDateList = dateList;
|
||||
this.refresh();
|
||||
}
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
|
@ -2844,15 +2856,21 @@
|
|||
</method>
|
||||
|
||||
<field name="mRefreshQueue">[]</field>
|
||||
<field name="mRefreshPending">false</field>
|
||||
<field name="mRefreshPending">null</field>
|
||||
|
||||
<method name="popRefreshQueue">
|
||||
<body><![CDATA[
|
||||
if (this.mRefreshPending) {
|
||||
if(this.mRefreshQueue.length > 0) {
|
||||
this.relayout();
|
||||
}
|
||||
return;
|
||||
var pendingRefresh = this.mRefreshPending;
|
||||
if (pendingRefresh) {
|
||||
if (pendingRefresh instanceof Components.interfaces.calIOperation) {
|
||||
this.mRefreshPending = null;
|
||||
pendingRefresh.cancel(null);
|
||||
} else {
|
||||
if(this.mRefreshQueue.length > 0) {
|
||||
this.relayout();
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var refreshJob = this.mRefreshQueue.pop();
|
||||
|
@ -2885,13 +2903,14 @@
|
|||
else
|
||||
filter |= this.mCalendar.ITEM_FILTER_TYPE_EVENT;
|
||||
|
||||
this.mRefreshPending = true;
|
||||
|
||||
this.mCalendar.getItems(filter,
|
||||
0,
|
||||
this.startDate,
|
||||
this.queryEndDate,
|
||||
this.mOperationListener);
|
||||
this.mRefreshPending = this.mCalendar.getItems(filter,
|
||||
0,
|
||||
this.startDate,
|
||||
this.queryEndDate,
|
||||
this.mOperationListener);
|
||||
if (!this.mRefreshPending) { // no support for calIOperation, fallback to bool
|
||||
this.mRefreshPending = true;
|
||||
}
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
|
|
|
@ -543,6 +543,24 @@ function compareObjects(aObject, aOtherObject, aIID) {
|
|||
return sip1.data == sip2.data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare two arrays using the passed function.
|
||||
*/
|
||||
function compareArrays(aOne, aTwo, compareFunc) {
|
||||
if (!aOne && !aTwo)
|
||||
return true;
|
||||
if (!aOne || !aTwo)
|
||||
return false;
|
||||
var len = aOne.length;
|
||||
if (len != aTwo.length)
|
||||
return false;
|
||||
for (var i = 0; i < len; ++i) {
|
||||
if (!compareFunc(aOne[i], aTwo[i]))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Many computations want to work only with date-times, not with dates. This
|
||||
* method will return a proper datetime (set to midnight) for a date object. If
|
||||
|
@ -1170,3 +1188,96 @@ function sendMailTo(aRecipient, aSubject, aBody) {
|
|||
protoSvc.loadUrl(ioService.newURI(uriString, null, null));
|
||||
}
|
||||
}
|
||||
|
||||
var gOpGroupPrefix;
|
||||
var gOpGroupId = 0;
|
||||
|
||||
/**
|
||||
* This object implements calIOperation and could group multiple sub
|
||||
* operations into one. You can pass a cancel function which is called once
|
||||
* the operation group is cancelled.
|
||||
* Users must call notifyCompleted() once all sub operations have been
|
||||
* successful, else the operation group will stay pending.
|
||||
* The reason for the latter is that providers currently should (but need
|
||||
* not) implement (and return) calIOperation handles, thus there may be pending
|
||||
* calendar operations (without handle).
|
||||
*/
|
||||
function calOperationGroup(cancelFunc) {
|
||||
if (!gOpGroupPrefix) {
|
||||
gOpGroupPrefix = (getUUID() + "-");
|
||||
}
|
||||
this.mCancelFunc = cancelFunc;
|
||||
this.mId = (gOpGroupPrefix + gOpGroupId);
|
||||
++gOpGroupId;
|
||||
this.mSubOperations = [];
|
||||
}
|
||||
calOperationGroup.prototype = {
|
||||
mCancelFunc: null,
|
||||
mId: null,
|
||||
mIsPending: true,
|
||||
mStatus: Components.results.NS_OK,
|
||||
mSubOperations: null,
|
||||
|
||||
add: function calOperationGroup_add(op) {
|
||||
if (op) {
|
||||
this.mSubOperations.push(op);
|
||||
}
|
||||
},
|
||||
|
||||
remove: function calOperationGroup_remove(op) {
|
||||
if (op) {
|
||||
function filterFunc(op_) {
|
||||
return (op.id != op_.id);
|
||||
}
|
||||
this.mSubOperations = this.mSubOperations.filter(filterFunc);
|
||||
}
|
||||
},
|
||||
|
||||
get isEmpty() {
|
||||
return (this.mSubOperations.length == 0);
|
||||
},
|
||||
|
||||
notifyCompleted: function calOperationGroup_notifyCompleted(status) {
|
||||
this.mIsPending = false;
|
||||
if (status) {
|
||||
this.mStatus = status;
|
||||
}
|
||||
},
|
||||
|
||||
// calIOperation:
|
||||
get id() {
|
||||
return this.mId;
|
||||
},
|
||||
|
||||
get isPending() {
|
||||
return this.mIsPending;
|
||||
},
|
||||
|
||||
get status() {
|
||||
return this.mStatus;
|
||||
},
|
||||
|
||||
get success() {
|
||||
return (!this.isPending && Components.results.isSuccessCode(this.status));
|
||||
},
|
||||
|
||||
cancel: function calOperationGroup_cancel(status) {
|
||||
if (this.isPending) {
|
||||
if (!status) {
|
||||
status = Components.interfaces.calIErrors.OPERATION_CANCELLED;
|
||||
}
|
||||
this.notifyCompleted(status);
|
||||
var subOperations = this.mSubOperations;
|
||||
this.mSubOperations = [];
|
||||
function forEachFunc(op) {
|
||||
op.cancel(null);
|
||||
}
|
||||
subOperations.forEach(forEachFunc);
|
||||
if (this.mCancelFunc) {
|
||||
var cancelFunc = this.mCancelFunc;
|
||||
this.mCancelFunc = null;
|
||||
cancelFunc();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -317,7 +317,9 @@ calCompositeCalendar.prototype = {
|
|||
if (cal.canRefresh) {
|
||||
cal.refresh();
|
||||
}
|
||||
} catch (e) { }
|
||||
} catch (e) {
|
||||
ASSERT(false, e);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
this.mObserverHelper.suppressOnLoad = false;
|
||||
|
@ -336,7 +338,7 @@ calCompositeCalendar.prototype = {
|
|||
throw Components.results.NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
aNewItem.calendar.modifyItem (aNewItem, aOldItem, aListener);
|
||||
return aNewItem.calendar.modifyItem(aNewItem, aOldItem, aListener);
|
||||
},
|
||||
|
||||
// void deleteItem( in string id, in calIOperationListener aListener );
|
||||
|
@ -346,20 +348,25 @@ calCompositeCalendar.prototype = {
|
|||
throw Components.results.NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
aItem.calendar.deleteItem (aItem, aListener);
|
||||
return aItem.calendar.deleteItem(aItem, aListener);
|
||||
},
|
||||
|
||||
// void addItem( in calIItemBase aItem, in calIOperationListener aListener );
|
||||
addItem: function (aItem, aListener) {
|
||||
this.mDefaultCalendar.addItem (aItem, aListener);
|
||||
return this.mDefaultCalendar.addItem(aItem, aListener);
|
||||
},
|
||||
|
||||
// void getItem( in string aId, in calIOperationListener aListener );
|
||||
getItem: function (aId, aListener) {
|
||||
var cmpListener = new calCompositeGetListenerHelper(this.mCalendars.length, aListener);
|
||||
for each (cal in this.mCalendars) {
|
||||
cal.getItem (aId, cmpListener);
|
||||
try {
|
||||
cmpListener.opGroup.add(cal.getItem(aId, cmpListener));
|
||||
} catch (exc) {
|
||||
ASSERT(false, exc);
|
||||
}
|
||||
}
|
||||
return cmpListener.opGroup;
|
||||
},
|
||||
|
||||
// void getItems( in unsigned long aItemFilter, in unsigned long aCount,
|
||||
|
@ -378,8 +385,15 @@ calCompositeCalendar.prototype = {
|
|||
|
||||
var cmpListener = new calCompositeGetListenerHelper(this.mCalendars.length, aListener, aCount);
|
||||
for (cal in this.mCalendars) {
|
||||
this.mCalendars[cal].getItems (aItemFilter, aCount, aRangeStart, aRangeEnd, cmpListener);
|
||||
try {
|
||||
cmpListener.opGroup.add(
|
||||
this.mCalendars[cal].getItems(
|
||||
aItemFilter, aCount, aRangeStart, aRangeEnd, cmpListener));
|
||||
} catch (exc) {
|
||||
ASSERT(false, exc);
|
||||
}
|
||||
}
|
||||
return cmpListener.opGroup;
|
||||
},
|
||||
|
||||
startBatch: function ()
|
||||
|
@ -403,11 +417,29 @@ function calCompositeGetListenerHelper(aNumQueries, aRealListener, aMaxItems) {
|
|||
calCompositeGetListenerHelper.prototype = {
|
||||
mNumQueries: 0,
|
||||
mRealListener: null,
|
||||
mOpGroup: null,
|
||||
mReceivedCompletes: 0,
|
||||
mFinished: false,
|
||||
mMaxItems: 0,
|
||||
mItemsReceived: 0,
|
||||
|
||||
get opGroup() {
|
||||
if (!this.mOpGroup) {
|
||||
var this_ = this;
|
||||
function cancelFunc() { // operation group has been cancelled
|
||||
var listener = this_.mRealListener;
|
||||
this_.mRealListener = null;
|
||||
if (listener) {
|
||||
listener.onOperationComplete(
|
||||
this_, Components.interfaces.calIErrors.OPERATION_CANCELLED,
|
||||
calIOperationListener.GET, null, null);
|
||||
}
|
||||
}
|
||||
this.mOpGroup = new calOperationGroup(cancelFunc);
|
||||
}
|
||||
return this.mOpGroup;
|
||||
},
|
||||
|
||||
QueryInterface: function (aIID) {
|
||||
if (!aIID.equals(Components.interfaces.nsISupports) &&
|
||||
!aIID.equals(Components.interfaces.calIOperationListener))
|
||||
|
@ -419,6 +451,10 @@ calCompositeGetListenerHelper.prototype = {
|
|||
},
|
||||
|
||||
onOperationComplete: function (aCalendar, aStatus, aOperationType, aId, aDetail) {
|
||||
if (!this.mRealListener) {
|
||||
// has been cancelled, ignore any providers firing on this...
|
||||
return;
|
||||
}
|
||||
if (this.mFinished) {
|
||||
dump ("+++ calCompositeGetListenerHelper.onOperationComplete: called with mFinished == true!");
|
||||
return;
|
||||
|
@ -438,15 +474,20 @@ calCompositeGetListenerHelper.prototype = {
|
|||
if (this.mReceivedCompletes == this.mNumQueries) {
|
||||
// we're done here.
|
||||
this.mRealListener.onOperationComplete (this,
|
||||
aOperationType,
|
||||
aStatus,
|
||||
calIOperationListener.GET,
|
||||
null,
|
||||
null);
|
||||
this.mFinished = true;
|
||||
this.opGroup.notifyCompleted();
|
||||
}
|
||||
},
|
||||
|
||||
onGetResult: function (aCalendar, aStatus, aItemType, aDetail, aCount, aItems) {
|
||||
if (!this.mRealListener) {
|
||||
// has been cancelled, ignore any providers firing on this...
|
||||
return;
|
||||
}
|
||||
if (this.mFinished) {
|
||||
dump ("+++ calCompositeGetListenerHelper.onGetResult: called with mFinished == true!");
|
||||
return;
|
||||
|
|
Загрузка…
Ссылка в новой задаче