Fix bug 476227 - Drop shadow for multiday events has incorrect length (regression). r=philipp
authorDecathlon <bv1578@gmail.com>
Thu, 18 Feb 2010 16:10:12 +0100
changeset 4959 33bd686be5274b15d68cb1e3975113ddd9d11cbc
parent 4958 e402614509a529253a8d72e8a3bbab832f789781
child 4960 98ab90c0d060e0b06d7fdd95bf7e9037c108554c
push id3859
push usermozilla@kewis.ch
push dateThu, 18 Feb 2010 15:10:20 +0000
treeherdercomm-central@33bd686be527 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersphilipp
bugs476227
Fix bug 476227 - Drop shadow for multiday events has incorrect length (regression). r=philipp
calendar/base/content/calendar-base-view.xml
calendar/base/content/calendar-month-view.xml
calendar/base/content/calendar-multiday-view.xml
calendar/base/content/calendar-view-core.xml
calendar/base/content/widgets/calendar-widgets.xml
--- a/calendar/base/content/calendar-base-view.xml
+++ b/calendar/base/content/calendar-base-view.xml
@@ -63,16 +63,19 @@
       <field name="mDisplayDaysOff">true</field>
       <field name="mDaysOffArray">[0,6]</field>
       <field name="mTimezone">null</field>
       <field name="mFlashingEvents">new Object()</field>
       <field name="mSelectedItems">[]</field>
       <field name="mBatchCount">0</field>
       <field name="mLongWeekdayTotalPixels">-1</field>
       <field name="mResizeHandler">null</field>
+      <field name="mDropShadowsLength">null</field>
+      <field name="mShadowOffset">null</field>
+      <field name="mDropShadows">null</field>
       <field name="mPrefObserver"><![CDATA[
       ({ calView: this,
          observe: function calViewPrefChange(subj, topic, pref) {
              this.calView.handlePreference(subj, topic, pref);
              return;
          }
       })
       ]]></field>
--- a/calendar/base/content/calendar-month-view.xml
+++ b/calendar/base/content/calendar-month-view.xml
@@ -154,19 +154,16 @@
             icon.setAttribute("type", "todo");
           }
 
           this.setEditableLabel();
           this.setCSSClasses();
           return val;
         ]]></setter>
       </property>
-      <property name="parentBox"
-                onget="return this.mParentBox;"
-                onset="this.mParentBox = val;"/>
     </implementation>
   </binding>
 
   <binding id="calendar-month-day-box" extends="chrome://calendar/content/widgets/calendar-widgets.xml#dragndropContainer">
     <content orient="vertical">
       <xul:label anonid="day-label" 
                  crop="end"
                  mousethrough="always"
--- a/calendar/base/content/calendar-multiday-view.xml
+++ b/calendar/base/content/calendar-multiday-view.xml
@@ -1828,16 +1828,17 @@
                      this.calendarView.getAttribute("context");
           itemBox.setAttribute("context", ctxt);
 
           if (aItem.hashId in this.calendarView.mFlashingEvents) {
             itemBox.setAttribute("flashing", "true");
           }
 
           this.mItemBoxes.push(itemBox);
+          itemBox.parentBox = this;
         ]]></body>
       </method>
 
       <method name="deleteEvent">
         <parameter name="aItem"/>
         <body><![CDATA[
           for (var i in this.mItemBoxes) {
             if (this.mItemBoxes[i].occurrence.hashId == aItem.hashId) {
@@ -2972,16 +2973,24 @@
           for each (var col in this.mDateColumns) {
               if (col.date.compare(aDate) == 0)
                   return col;
           }
           return null;
         ]]></body>
       </method>
 
+      <method name="findDayBoxForDate">
+        <parameter name="aDate"/>
+        <body><![CDATA[
+            let col = this.findColumnForDate(aDate);
+            return (col && col.header);
+        ]]></body>
+      </method>
+
       <method name="selectColumnHeader">
         <parameter name="aDate"/>
         <body><![CDATA[
           let child = this.labeldaybox.firstChild;
           while (child) {
               if (child.date.compare(aDate) == 0) {
                   child.setAttribute("selected", "true");
               } else {
--- a/calendar/base/content/calendar-view-core.xml
+++ b/calendar/base/content/calendar-view-core.xml
@@ -127,16 +127,20 @@
          this.eventNameTextbox.onmousedown = stopPropagationIfEditing;
          this.eventNameTextbox.onmouseup = stopPropagationIfEditing;
       ]]></constructor>
 
       <field name="mOccurrence">null</field>
       <field name="mSelected">false</field>
       <field name="mCalendarView">null</field>
 
+      <property name="parentBox"
+                onget="return this.mParentBox;"
+                onset="this.mParentBox = val;"/>
+
       <property name="selected">
         <getter><![CDATA[
           return this.mSelected;
         ]]></getter>
         <setter><![CDATA[
           if (val && !this.mSelected) {
               this.mSelected = true;
               this.setAttribute("selected", "true");
--- a/calendar/base/content/widgets/calendar-widgets.xml
+++ b/calendar/base/content/widgets/calendar-widgets.xml
@@ -348,37 +348,51 @@
       </method>
 
       <!-- Adds the dropshadows to the children of the binding. The dropshadows
            are added at the first position of the children -->
       <method name="addDropShadows">
         <body><![CDATA[
           if (this.mDropShadows) {
               if (this.getElementsByAttribute("class", "dropshadow").length == 0) {
-                  for (let i = 0; i < this.mDropShadows.length; i++) {
-                      let dropshadow =  createXULElement("box");
+                  let offset = this.calendarView.mShadowOffset;
+                  let shadowStartDate = this.date.clone();
+                  shadowStartDate.addDuration(offset);
+                  this.calendarView.mDropShadows = [];
+                  for (let i = 0; i < this.calendarView.mDropShadowsLength; i++) {
+                      let box = this.calendarView.findDayBoxForDate(shadowStartDate);
+                      if (!box) {
+                          // Dragging to the end or beginning of a view
+                          shadowStartDate.day += 1;
+                          continue;
+                      }
+                      let dropshadow = createXULElement("box");
                       dropshadow.setAttribute("class", "dropshadow");
-                      if (this.hasChildNodes()) {
-                          this.insertBefore(dropshadow, this.firstChild);
+                      if (box.hasChildNodes()) {
+                          box.insertBefore(dropshadow, box.firstChild);
                       } else {
-                          this.appendChild(dropshadow);
+                          box.appendChild(dropshadow);
                       }
+                      shadowStartDate.day += 1;
+                      this.calendarView.mDropShadows.push(box);
                   }
               }
           }
         ]]></body>
       </method>
 
       <!-- removes all dropShadows from the binding. Dropshadows are recognized
            as such by carrying an attribute "dropshadow" -->
       <method name="removeDropShadows">
         <body><![CDATA[
             // method that may be overwritten by derived bindings...
-            cal.removeChildElementsByAttribute(this, "class", "dropshadow");
-            this.mDropShadows = null;
+            for each (shadow in this.calendarView.mDropShadows) {
+                cal.removeChildElementsByAttribute(shadow, "class", "dropshadow");
+            }
+            this.calendarView.mDropShadows = null;
         ]]></body>
       </method>
 
       <!-- By setting the attribute "dropbox" to "true" or "false" the
            dropshadows are added or removed -->
       <method name="setAttribute">
         <parameter name="aAttr"/>
         <parameter name="aVal"/>
@@ -397,16 +411,34 @@
           }
           return XULElement.prototype.setAttribute.call(this, aAttr, aVal);
         ]]></body>
       </method>
 
     </implementation>
 
     <handlers>
+      <handler event="dragstart"><![CDATA[
+         let draggedDOMNode = event.target;
+         if (!draggedDOMNode || draggedDOMNode.parentNode != this) {
+             return;
+         }
+         let item = draggedDOMNode.occurrence.clone();
+         let beginMoveDate = draggedDOMNode.mParentBox.date;
+         let itemStartDate = (item.entryDate || item.startDate).getInTimezone(calendarView.mTimezone);
+         let itemEndDate = (item.dueDate || item.endDate).getInTimezone(calendarView.mTimezone);
+         let oneMoreDay = (itemEndDate.hour > 0 || itemEndDate.minute > 0);
+         itemStartDate.isDate = true;
+         itemEndDate.isDate = true;
+         let offset = itemStartDate.subtractDate(beginMoveDate);
+         let len = itemEndDate.subtractDate(itemStartDate).days;
+         this.calendarView.mShadowOffset = offset;
+         this.calendarView.mDropShadowsLength = oneMoreDay ? len + 1 : len;
+      ]]></handler>
+
       <handler event="dragover"><![CDATA[
          let session = cal.getDragService().getCurrentSession();
          if (!session || !session.sourceNode || !session.sourceNode.sourceObject) {
             // No source item? Then this is not for us.
             return;
          }
 
          // We handled the event
@@ -461,20 +493,23 @@
          session.getData(transfer, 0);
          let flavor = {};
          let data = {};
          // nsITransferable sucks when it comes to trying to add extra flavors.
          // This will throw NS_ERROR_FAILURE, so as a workaround, we use the
          // sourceNode property and get the event that way
          //transfer.getAnyTransferData(flavor, data, {});
 
-         let item = session.sourceNode.sourceObject;
+         item = session.sourceNode.sourceObject;
          let newItem = this.onDropItem(item).clone();
          let newStart = newItem.startDate || newItem.entryDate;
          let newEnd = newItem.endDate || newItem.dueDate;
+         let offset = this.calendarView.mShadowOffset;
+         newStart.addDuration(offset);
+         newEnd.addDuration(offset);
          this.calendarView.controller.modifyOccurrence(item, newStart, newEnd);
 
          // We handled the event
          event.stopPropagation();
       ]]></handler>
 
       <handler event="dragend"><![CDATA[
           currentView().removeDropShadows();