A few patches



Hi guys,

It's been a while since I've worked on planner, but now that I use it in
my day to day work again I've found renewed interest in it.

Attached are some patches that I don't think anyone will disagree with and
that I'd like to ask anyone with SVN access to commit. The first one
will cause some conflicts with nr 4 though.

1) planner-fix-tabs.patch

  This patch cleans up some of the indenting in the .xsl files. 
  It replaces tabs with spaces.

2) planner-drag-completion.patch

  This patch allows dragging of the completion for a task. Just hover
  over the end of the completion bar and the hand cursor will tell you
  when you're over the spot where you can drag it.

  This version of the patch also fixes dragging of the duration of a
  task. It will now scroll the gantt if you drag over the edge of
  the window (just like it does for dragging relations).

3) planner-fix-makefile.patch

  This escapes the newlines in the definition of ALL_LINGUAS in
  configure.in. Without them the build will fail because ALL_LINGUAS
  does not have quotes around its value in the makefiles.
  
4) planner-html-layout.patch

  This patch fixes the layout of gantt charts exported to HTML.
  The headers (week and day numbers) now line up correctly with the 
  gantt bars even if the width of all bars in the gantt is less than a
  browser page width.

  In order to fix this for IE, I had to put in some conditional CSS
  that overrides the widths of certain elements (because of the
  different box model in IE).

  It also now displays the long name of a resource if it doesn't have a
  short name. ("resource 1, res2" instead of ", res2" next to the bars).

Finally, I was wondering what it would take to get commit access. 
I'm not someone who will just make intrusive changes all over the place
without consensus on the list, but I would like to be able to apply
fixes like patches 1, 3 and 4, especially since planner development is so
slow at the moment (no offense).

Regards,
Maurice.

-- 
Maurice van der Pot

Gentoo Linux Developer   griffon26 gentoo org     http://www.gentoo.org
Creator of BiteMe!       griffon26 kfk4ever com   http://www.kfk4ever.com

Index: data/dtd/mrproject-0.6.dtd
===================================================================
--- data/dtd/mrproject-0.6.dtd	(revision 842)
+++ data/dtd/mrproject-0.6.dtd	(working copy)
@@ -6,8 +6,8 @@
                   company           CDATA #IMPLIED
                   manager           CDATA #IMPLIED
                   project-start     CDATA #REQUIRED
-		  calendar          CDATA #IMPLIED
-		  phase             CDATA #IMPLIED>
+                  calendar          CDATA #IMPLIED
+                  phase             CDATA #IMPLIED>
 
 <!ELEMENT properties (property*)>
 
@@ -56,7 +56,7 @@
                effort               CDATA #IMPLIED
                start                CDATA #REQUIRED
                end                  CDATA #REQUIRED
-	       work-start           CDATA #IMPLIED
+               work-start           CDATA #IMPLIED
                duration             CDATA #IMPLIED
                work                 CDATA #IMPLIED
                percent-complete     CDATA #IMPLIED
@@ -111,7 +111,7 @@
 
 <!ELEMENT calendar (default-week,overridden-day-types?,days?,calendar*)>
 <!ATTLIST calendar     name           CDATA #REQUIRED
-		       id             CDATA #REQUIRED>
+                       id             CDATA #REQUIRED>
 
 <!ELEMENT default-week EMPTY>
 <!ATTLIST default-week mon            CDATA #IMPLIED
Index: data/stylesheets/html1_tasks.xsl
===================================================================
--- data/stylesheets/html1_tasks.xsl	(revision 842)
+++ data/stylesheets/html1_tasks.xsl	(working copy)
@@ -4,7 +4,7 @@
               xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                   xmlns="http://www.w3.org/1999/xhtml";
              xmlns:date="http://exslt.org/dates-and-times";
-	     xmlns:I18N="http://www.gnu.org/software/gettext/"; extension-element-prefixes="I18N">
+             xmlns:I18N="http://www.gnu.org/software/gettext/"; extension-element-prefixes="I18N">
 
 <!--
   Copyright (C) 2004-2005 Imendio AB
@@ -22,18 +22,18 @@
   <xsl:choose>
     <xsl:when test="$level = 0">0</xsl:when>
     <xsl:otherwise>
-	  <xsl:variable name="cost">
-	    <xsl:call-template name="calculate-cost">
+      <xsl:variable name="cost">
+        <xsl:call-template name="calculate-cost">
           <xsl:with-param name="std-rates" select="$std-rates"/>
-		  <xsl:with-param name="units" select="$units"/>
-		  <xsl:with-param name="level" select="$level - 1"/>
-		  <xsl:with-param name="work" select="$work"/>
-		</xsl:call-template>
-	  </xsl:variable>
-	  
-	  <xsl:variable name="std-rate" select="$std-rates[position()=$level]"/>
-	  <xsl:variable name="unit" select="$units[position()=$level] div 100"/>
-	  <xsl:value-of select="($std-rate * $unit * $work) + $cost"/>
+          <xsl:with-param name="units" select="$units"/>
+          <xsl:with-param name="level" select="$level - 1"/>
+          <xsl:with-param name="work" select="$work"/>
+        </xsl:call-template>
+      </xsl:variable>
+      
+      <xsl:variable name="std-rate" select="$std-rates[position()=$level]"/>
+      <xsl:variable name="unit" select="$units[position()=$level] div 100"/>
+      <xsl:value-of select="($std-rate * $unit * $work) + $cost"/>
     </xsl:otherwise>
   </xsl:choose>
 </xsl:template>
@@ -81,53 +81,53 @@
         <xsl:variable name="tname">        
         </xsl:variable>
         
-		<xsl:variable name="rowclass">
+        <xsl:variable name="rowclass">
           <xsl:choose>
             <xsl:when test="(position() mod 2) = 0">even</xsl:when>
             <xsl:otherwise>odd</xsl:otherwise>
           </xsl:choose>
         </xsl:variable>
       
-		<xsl:choose>
+        <xsl:choose>
           <xsl:when test="task">
-		    <tr class="{$rowclass}">
+            <tr class="{$rowclass}">
               <td>
-		        <span>
-		          <xsl:for-each select="ancestor-or-self::task">
-			        <xsl:value-of select="count(preceding-sibling::task) + 1"/>
-			        <xsl:if test="not(position() = last())">
-			          <xsl:text>.</xsl:text>
-			        </xsl:if>
-			      </xsl:for-each>
-		        </span>
-		      </td>
-		      <td>
+                <span>
+                  <xsl:for-each select="ancestor-or-self::task">
+                    <xsl:value-of select="count(preceding-sibling::task) + 1"/>
+                    <xsl:if test="not(position() = last())">
+                      <xsl:text>.</xsl:text>
+                    </xsl:if>
+                  </xsl:for-each>
+                </span>
+              </td>
+              <td>
                 <a name="task{ id}" style="font-weight: bold; margin-left: {$indent*$task-indent-pixels}px">
-				  <span>
-				    <xsl:value-of select="@name"/>
-				  </span>
-				</a>
-			  </td>
+                  <span>
+                    <xsl:value-of select="@name"/>
+                  </span>
+                </a>
+              </td>
               <td>
                 <span>
-				  <xsl:value-of select="date:month-abbreviation($start_date)"/>
-			      <xsl:text> </xsl:text>
-				  <xsl:value-of select="date:day-in-month($start_date)"/>
-				</span>
+                  <xsl:value-of select="date:month-abbreviation($start_date)"/>
+                  <xsl:text> </xsl:text>
+                  <xsl:value-of select="date:day-in-month($start_date)"/>
+                </span>
               </td>
               <td>
-			    <span>
-				  <xsl:value-of select="date:month-abbreviation($end_date)"/>
-				  <xsl:text> </xsl:text>
+                <span>
+                  <xsl:value-of select="date:month-abbreviation($end_date)"/>
+                  <xsl:text> </xsl:text>
                   <xsl:value-of select="date:day-in-month($end_date)"/>
-				</span>
-			  </td>
+                </span>
+              </td>
               <td>
                 <span>
-				  <xsl:call-template name="mrproj-duration">
+                  <xsl:call-template name="mrproj-duration">
                     <xsl:with-param name="duration-in-seconds" select="@work"/>
                   </xsl:call-template>
-				</span>
+                </span>
               </td>
               <td>
               </td>
@@ -135,62 +135,62 @@
               </td>
               <td>
                 <span>
-				  <xsl:variable name="std-rates" select="/project/resources/resource[ id=/project/allocations/allocation[ task-id=$tid]/@resource-id]/@std-rate"/>
-				  <xsl:variable name="units" select="/project/allocations/allocation[ task-id=$tid]/@units"/>
-				  <xsl:variable name="cost">
-				    <xsl:call-template name="calculate-cost">
+                  <xsl:variable name="std-rates" select="/project/resources/resource[ id=/project/allocations/allocation[ task-id=$tid]/@resource-id]/@std-rate"/>
+                  <xsl:variable name="units" select="/project/allocations/allocation[ task-id=$tid]/@units"/>
+                  <xsl:variable name="cost">
+                    <xsl:call-template name="calculate-cost">
                       <xsl:with-param name="std-rates" select="$std-rates"/>
-		              <xsl:with-param name="units" select="$units"/>
-					  <xsl:with-param name="level" select="count($std-rates)"/>
-					  <xsl:with-param name="work" select="@work div 3600"/>
-	                </xsl:call-template>
-				  </xsl:variable>
-			      <xsl:if test="not($cost = 0)">
-				    <xsl:value-of select="format-number($cost, '###,###,###,###.##')"/>
-				  </xsl:if>
-				</span>
-			  </td>
+                      <xsl:with-param name="units" select="$units"/>
+                      <xsl:with-param name="level" select="count($std-rates)"/>
+                      <xsl:with-param name="work" select="@work div 3600"/>
+                    </xsl:call-template>
+                  </xsl:variable>
+                  <xsl:if test="not($cost = 0)">
+                    <xsl:value-of select="format-number($cost, '###,###,###,###.##')"/>
+                  </xsl:if>
+                </span>
+              </td>
               <xsl:if test="$hasnotes">
                 <td>
                   <span class="note">
                     <xsl:value-of select="@note"/>
-		  </span>
+          </span>
                 </td>
               </xsl:if>
             </tr>
-		  </xsl:when>
-		  <xsl:when test="@type='milestone'">
+          </xsl:when>
+          <xsl:when test="@type='milestone'">
             <tr class="{$rowclass}">
               <td>
-		        <span>
-		          <xsl:for-each select="ancestor-or-self::task">
-			        <xsl:value-of select="count(preceding-sibling::task) + 1"/>
-			        <xsl:if test="not(position() = last())">
-			          <xsl:text>.</xsl:text>
-			        </xsl:if>
-			      </xsl:for-each>
-		        </span>
-		      </td>
-		      <td>
+                <span>
+                  <xsl:for-each select="ancestor-or-self::task">
+                    <xsl:value-of select="count(preceding-sibling::task) + 1"/>
+                    <xsl:if test="not(position() = last())">
+                      <xsl:text>.</xsl:text>
+                    </xsl:if>
+                  </xsl:for-each>
+                </span>
+              </td>
+              <td>
                 <a name="task{ id}" style="margin-left: {$indent*$task-indent-pixels}px">
-				  <span>
-				    <xsl:value-of select="@name"/>
-				  </span>
-				</a>
-			  </td>
+                  <span>
+                    <xsl:value-of select="@name"/>
+                  </span>
+                </a>
+              </td>
               <td>
                 <span>
-				  <xsl:value-of select="date:month-abbreviation($start_date)"/>
-				  <xsl:text> </xsl:text>
-				  <xsl:value-of select="date:day-in-month($start_date)"/>
-				</span>
-			  </td>
+                  <xsl:value-of select="date:month-abbreviation($start_date)"/>
+                  <xsl:text> </xsl:text>
+                  <xsl:value-of select="date:day-in-month($start_date)"/>
+                </span>
+              </td>
               <td>
-			    <span>
-				  <xsl:value-of select="date:month-abbreviation($end_date)"/>
-				  <xsl:text> </xsl:text>
-				  <xsl:value-of select="date:day-in-month($end_date)"/>
-				</span>
+                <span>
+                  <xsl:value-of select="date:month-abbreviation($end_date)"/>
+                  <xsl:text> </xsl:text>
+                  <xsl:value-of select="date:day-in-month($end_date)"/>
+                </span>
               </td>
               <td>
               </td>
@@ -199,27 +199,27 @@
               <td>
               </td>
               <td>
-			    <span>
-				  <xsl:variable name="std-rates" select="/project/resources/resource[ id=/project/allocations/allocation[ task-id=$tid]/@resource-id]/@std-rate"/>
-				  <xsl:variable name="units" select="/project/allocations/allocation[ task-id=$tid]/@units"/>
-				  <xsl:variable name="cost">
-				    <xsl:call-template name="calculate-cost">
+                <span>
+                  <xsl:variable name="std-rates" select="/project/resources/resource[ id=/project/allocations/allocation[ task-id=$tid]/@resource-id]/@std-rate"/>
+                  <xsl:variable name="units" select="/project/allocations/allocation[ task-id=$tid]/@units"/>
+                  <xsl:variable name="cost">
+                    <xsl:call-template name="calculate-cost">
                       <xsl:with-param name="std-rates" select="$std-rates"/>
-		              <xsl:with-param name="units" select="$units"/>
-					  <xsl:with-param name="level" select="count($std-rates)"/>
-					  <xsl:with-param name="work" select="@work div 3600"/>
-	                </xsl:call-template>
-				  </xsl:variable>
-			      <xsl:if test="not($cost = 0)">
-				    <xsl:value-of select="format-number($cost, '###,###,###,###.##')"/>
-				  </xsl:if>
-				</span>
-			  </td>
+                      <xsl:with-param name="units" select="$units"/>
+                      <xsl:with-param name="level" select="count($std-rates)"/>
+                      <xsl:with-param name="work" select="@work div 3600"/>
+                    </xsl:call-template>
+                  </xsl:variable>
+                  <xsl:if test="not($cost = 0)">
+                    <xsl:value-of select="format-number($cost, '###,###,###,###.##')"/>
+                  </xsl:if>
+                </span>
+              </td>
               <xsl:if test="$hasnotes">
                 <td>
                   <span class="note">
-				    <xsl:value-of select="@note"/>
-				  </span>
+                    <xsl:value-of select="@note"/>
+                  </span>
                 </td>
               </xsl:if>
             </tr>
@@ -227,77 +227,77 @@
           <xsl:otherwise>
             <tr class="{$rowclass}">
               <td>
-		        <span>
-		          <xsl:for-each select="ancestor-or-self::task">
-			        <xsl:value-of select="count(preceding-sibling::task) + 1"/>
-			        <xsl:if test="not(position() = last())">
-			          <xsl:text>.</xsl:text>
-			        </xsl:if>
-			      </xsl:for-each>
-		        </span>
-		      </td>
-		      <td>
+                <span>
+                  <xsl:for-each select="ancestor-or-self::task">
+                    <xsl:value-of select="count(preceding-sibling::task) + 1"/>
+                    <xsl:if test="not(position() = last())">
+                      <xsl:text>.</xsl:text>
+                    </xsl:if>
+                  </xsl:for-each>
+                </span>
+              </td>
+              <td>
                 <a name="task{ id}" style="margin-left: {$indent*$task-indent-pixels}px">
-				  <span>
-				    <xsl:value-of select="@name"/>
-				  </span>
-				</a>
-			  </td>
+                  <span>
+                    <xsl:value-of select="@name"/>
+                  </span>
+                </a>
+              </td>
               <td>
-			    <span>
-				  <xsl:value-of select="date:month-abbreviation($start_date)"/>
-				  <xsl:text> </xsl:text>
+                <span>
+                  <xsl:value-of select="date:month-abbreviation($start_date)"/>
+                  <xsl:text> </xsl:text>
                   <xsl:value-of select="date:day-in-month($start_date)"/>
-				</span>
+                </span>
               </td>
               <td>
                 <span>
-				  <xsl:value-of select="date:month-abbreviation($end_date)"/>
-				  <xsl:text> </xsl:text>
+                  <xsl:value-of select="date:month-abbreviation($end_date)"/>
+                  <xsl:text> </xsl:text>
                   <xsl:value-of select="date:day-in-month($end_date)"/>
-				</span>
+                </span>
               </td>
               <td>
                 <span>
-				  <xsl:call-template name="mrproj-duration">
+                  <xsl:call-template name="mrproj-duration">
                     <xsl:with-param name="duration-in-seconds" select="@work"/>
                   </xsl:call-template>
-				</span>
+                </span>
               </td>
-			  <td align="center">
-			    <span>
-				  <xsl:if test="not(@priority = 0)">
-				    <xsl:value-of select="format-number(@priority, '0')"/>
-				  </xsl:if>
-				</span>
+              <td align="center">
+                <span>
+                  <xsl:if test="not(@priority = 0)">
+                    <xsl:value-of select="format-number(@priority, '0')"/>
+                  </xsl:if>
+                </span>
               </td>
-	      <td align="right">
+              <td align="right">
                 <span>
-		  <xsl:value-of select="@percent-complete"/>%
-		</span>
-	      </td>
+                  <xsl:value-of select="@percent-complete"/>%
+                </span>
+              </td>
               <td align="right">
-		<span>
-		  <xsl:variable name="std-rates" select="/project/resources/resource[ id=/project/allocations/allocation[ task-id=$tid]/@resource-id]/@std-rate"/>
-		  <xsl:variable name="units" select="/project/allocations/allocation[ task-id=$tid]/@units"/>
-		  <xsl:variable name="cost">
-		    <xsl:call-template name="calculate-cost">
+                <span>
+                  <xsl:variable name="std-rates" select="/project/resources/resource[ id=/project/allocations/allocation[ task-id=$tid]/@resource-id]/@std-rate"/>
+                  <xsl:variable name="units" select="/project/allocations/allocation[ task-id=$tid]/@units"/>
+                  <xsl:variable name="cost">
+                    <xsl:call-template name="calculate-cost">
                       <xsl:with-param name="std-rates" select="$std-rates"/>
-		      <xsl:with-param name="units" select="$units"/>
-		      <xsl:with-param name="level" select="count($std-rates)"/>
-		      <xsl:with-param name="work" select="@work div 3600"/>
-	            </xsl:call-template>
-		  </xsl:variable>
-		  <xsl:if test="not($cost = 0)">
-		    <xsl:value-of select="format-number($cost, '###,###,###,###.##')"/>
-		  </xsl:if>
-		</span>
-	      </td>
+                      <xsl:with-param name="units" select="$units"/>
+                      <xsl:with-param name="level" select="count($std-rates)"/>
+                      <xsl:with-param name="work" select="@work div 3600"/>
+                    </xsl:call-template>
+                  </xsl:variable>
+                  <xsl:if test="not($cost = 0)">
+                    <xsl:value-of select="format-number($cost, '###,###,###,###.##')"/>
+                  </xsl:if>
+                </span>
+              </td>
               <xsl:if test="$hasnotes">
                 <td>
                   <span class="note">
-				    <xsl:value-of select="@note"/>
-				  </span>
+                    <xsl:value-of select="@note"/>
+                  </span>
                 </td>
               </xsl:if>
             </tr>
Index: data/stylesheets/html1_css.xsl
===================================================================
--- data/stylesheets/html1_css.xsl	(revision 842)
+++ data/stylesheets/html1_css.xsl	(working copy)
@@ -95,7 +95,7 @@
 
 table {
  width: 100%;
- border-collapse: collapse;	
+ border-collapse: collapse;
  border-style: none;
  border-color: #fff;
  white-space: nowrap;
Index: data/stylesheets/html1_resources.xsl
===================================================================
--- data/stylesheets/html1_resources.xsl	(revision 842)
+++ data/stylesheets/html1_resources.xsl	(working copy)
@@ -4,7 +4,7 @@
               xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                   xmlns="http://www.w3.org/1999/xhtml";
              xmlns:date="http://exslt.org/dates-and-times";
-	     xmlns:I18N="http://www.gnu.org/software/gettext/"; extension-element-prefixes="I18N">	
+             xmlns:I18N="http://www.gnu.org/software/gettext/"; extension-element-prefixes="I18N">
 
 <!--**************************************************************************
     *
@@ -40,14 +40,14 @@
     </tr>
 
     <xsl:for-each select="../resources/resource">
-	  <xsl:sort select="@type"/>
-	  <xsl:sort select="@name"/>
+      <xsl:sort select="@type"/>
+      <xsl:sort select="@name"/>
           
       <xsl:call-template name="resource-row">
         <xsl:with-param name="hasnotes" select="$hasnotes"/>
-	  </xsl:call-template>
+      </xsl:call-template>
           
-	</xsl:for-each>
+    </xsl:for-each>
   </table>
   </div>
 </xsl:template>
@@ -58,56 +58,56 @@
         <xsl:variable name="rid" select="@id"/>
         <xsl:variable name="gid" select="@group"/>
         
-		<xsl:variable name="rowclass">
+        <xsl:variable name="rowclass">
           <xsl:choose>
             <xsl:when test="(position() mod 2) = 0">even</xsl:when>
             <xsl:otherwise>odd</xsl:otherwise>
           </xsl:choose>
         </xsl:variable>
       
-	    <tr class="{$rowclass}">
+        <tr class="{$rowclass}">
           <td>
             <a name="res-{ id}">
-			  <span>
-			    <xsl:value-of select="@name"/>
-			  </span>
-			</a>
+              <span>
+                <xsl:value-of select="@name"/>
+              </span>
+            </a>
           </td>
-	      <td>
+          <td>
             <span>
-			  <xsl:value-of select="@short-name"/>
-			</span>
+              <xsl:value-of select="@short-name"/>
+            </span>
           </td>
           <td>
             <span>
-			  <xsl:choose>
+              <xsl:choose>
                 <xsl:when test="@type = 1"><xsl:value-of select="I18N:gettext('Work')"/></xsl:when>
                 <xsl:otherwise><xsl:value-of select="I18N:gettext('Material')"/></xsl:otherwise>
               </xsl:choose>
-			</span> 
+            </span> 
           </td>
           <td>
-		    <span>
-			  <xsl:value-of select="../../resource-groups/group[ id=$gid]/@name"/>
-		    </span>
-		  </td>
-		  <td>
+            <span>
+              <xsl:value-of select="../../resource-groups/group[ id=$gid]/@name"/>
+            </span>
+          </td>
+          <td>
             <a href="mailto:{ email}">
               <span>
-			    <xsl:value-of select="@email"/>
-			  </span>
+                <xsl:value-of select="@email"/>
+              </span>
             </a>
           </td>
          <td align="right">
            <span>
-		     <xsl:value-of select="@std-rate"/>
-		   </span>
+             <xsl:value-of select="@std-rate"/>
+           </span>
          </td>
          <xsl:if test="$hasnotes">
            <td>
              <span>
-			   <xsl:value-of select="@note"/>
-			 </span>
+               <xsl:value-of select="@note"/>
+             </span>
            </td>
          </xsl:if>
        </tr>
Index: data/stylesheets/msp2planner.xsl
===================================================================
--- data/stylesheets/msp2planner.xsl	(revision 842)
+++ data/stylesheets/msp2planner.xsl	(working copy)
@@ -1,21 +1,21 @@
 <?xml version="1.0"?> 
 <xsl:stylesheet version="1.0"
-	xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
-	xmlns:ms="http://schemas.microsoft.com/project";
-	exclude-result-prefixes="ms">
+        xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
+        xmlns:ms="http://schemas.microsoft.com/project";
+        exclude-result-prefixes="ms">
 
 <!-- ===============================================================
-	msp2planner.xsl
+        msp2planner.xsl
 
-	Conversion between Microsoft Project and Planner XML files
+        Conversion between Microsoft Project and Planner XML files
 
-	Copyright (c) 2004 Kurt Maute (kurt maute us)
+        Copyright (c) 2004 Kurt Maute (kurt maute us)
      ===============================================================-->
 
 <xsl:output method="xml" indent="yes"/>
 
 <!-- ===============================================================
-	Main  -->
+        Main  -->
 
 <xsl:template match="ms:Project">
 
@@ -38,7 +38,7 @@
 <!--  Phases  - not implemented  -->
 
 <!--  Calendars  - only writing standard Planner calendar right now,
-	since the MS Project implementation is painfully dissimilar  -->
+        since the MS Project implementation is painfully dissimilar  -->
   <calendars>
     <day-types>
       <day-type id="0" name="Working" description="A default working day"/>
@@ -70,7 +70,7 @@
 </xsl:template>
 
 <!-- ===============================================================
-	Task Handling Templates  -->
+        Task Handling Templates  -->
 
 <!-- Main Task loop 
      This template loops thru the 1st outline level of task elements
@@ -85,8 +85,8 @@
     <xsl:call-template name="write-task"/>
     <xsl:if test="ms:OutlineLevel &lt; following::ms:Task/ms:OutlineLevel">
       <xsl:call-template name="task">
-	<xsl:with-param name="wbs" select="ms:WBS"/>
-	<xsl:with-param name="lvl" select="ms:OutlineLevel+1"/>
+        <xsl:with-param name="wbs" select="ms:WBS"/>
+        <xsl:with-param name="lvl" select="ms:OutlineLevel+1"/>
       </xsl:call-template>
     </xsl:if>
     </task>
@@ -106,8 +106,8 @@
     <!-- recursion implemented here:  -->
     <xsl:if test="ms:OutlineLevel &lt; following::ms:Task/ms:OutlineLevel">
       <xsl:call-template name="task">
-	<xsl:with-param name="wbs" select="ms:WBS"/>
-	<xsl:with-param name="lvl" select="ms:OutlineLevel+1"/>
+        <xsl:with-param name="wbs" select="ms:WBS"/>
+        <xsl:with-param name="lvl" select="ms:OutlineLevel+1"/>
       </xsl:call-template>
     </xsl:if>
     </task>
@@ -172,7 +172,7 @@
     </xsl:attribute>
     <xsl:attribute name="time">
       <xsl:call-template name="ms2pdate">
-	<xsl:with-param name="thedate" select="ms:ConstraintDate"/>
+        <xsl:with-param name="thedate" select="ms:ConstraintDate"/>
       </xsl:call-template>
     </xsl:attribute>
     </constraint>  
@@ -183,23 +183,23 @@
   <xsl:for-each select="ms:PredecessorLink">
     <predecessor id="{position()}">
       <xsl:attribute name="predecessor-id">
-	<xsl:call-template name="get-task-id">
-	  <xsl:with-param name="uid" select="ms:PredecessorUID"/>
-	</xsl:call-template>
+        <xsl:call-template name="get-task-id">
+          <xsl:with-param name="uid" select="ms:PredecessorUID"/>
+        </xsl:call-template>
       </xsl:attribute>
       <xsl:attribute name="type">
-	<xsl:choose>
-	  <xsl:when test="ms:Type=0">FF</xsl:when>
-	  <xsl:when test="ms:Type=1">FS</xsl:when>
-	  <xsl:when test="ms:Type=2">SF</xsl:when>
-	  <xsl:otherwise>SS</xsl:otherwise>
-	</xsl:choose>
+        <xsl:choose>
+          <xsl:when test="ms:Type=0">FF</xsl:when>
+          <xsl:when test="ms:Type=1">FS</xsl:when>
+          <xsl:when test="ms:Type=2">SF</xsl:when>
+          <xsl:otherwise>SS</xsl:otherwise>
+        </xsl:choose>
       </xsl:attribute>
       <xsl:attribute name="lag">
-	<xsl:value-of select="ms:LinkLag*6"/>
+        <xsl:value-of select="ms:LinkLag*6"/>
       </xsl:attribute>
     </predecessor>
-  </xsl:for-each>	
+  </xsl:for-each>
   </predecessors>
 </xsl:template>
 
@@ -210,7 +210,7 @@
 </xsl:template>
 
 <!-- ===============================================================
-	Resource Handling Template  -->
+        Resource Handling Template  -->
 
 <!-- Resource loop   -->
 <xsl:template match="ms:Resources">
@@ -218,36 +218,36 @@
     <xsl:for-each select="ms:Resource[ms:ID>0]">
       <resource id="{ms:ID}" name="{ms:Name}" short-name="{ms:Initials}">
         <xsl:attribute name="type">
-	  <xsl:choose>
-	    <xsl:when test='ms:Type=0'>2</xsl:when>
-	    <xsl:otherwise>1</xsl:otherwise>
-	  </xsl:choose>
-	</xsl:attribute>
+          <xsl:choose>
+            <xsl:when test='ms:Type=0'>2</xsl:when>
+            <xsl:otherwise>1</xsl:otherwise>
+          </xsl:choose>
+        </xsl:attribute>
         <xsl:attribute name="units">
-	  <xsl:value-of select='ms:MaxUnits'/>
-	</xsl:attribute>
+          <xsl:value-of select='ms:MaxUnits'/>
+        </xsl:attribute>
         <xsl:attribute name="email">
-	  <xsl:value-of select='ms:EmailAddress'/>
-	</xsl:attribute>
+          <xsl:value-of select='ms:EmailAddress'/>
+        </xsl:attribute>
         <xsl:attribute name="note">
-	  <xsl:value-of select='ms:Notes'/>
-	</xsl:attribute>
+          <xsl:value-of select='ms:Notes'/>
+        </xsl:attribute>
         <xsl:attribute name="std-rate">
-	  <xsl:value-of select='ms:StandardRate'/>
-	</xsl:attribute>
+          <xsl:value-of select='ms:StandardRate'/>
+        </xsl:attribute>
         <xsl:attribute name="ovt-rate">
-	  <xsl:value-of select='ms:OvertimeRate'/>
-	</xsl:attribute>
+          <xsl:value-of select='ms:OvertimeRate'/>
+        </xsl:attribute>
         <properties>
-	  <property name="cost" value="{ms:Cost}"/>
-	</properties>
+          <property name="cost" value="{ms:Cost}"/>
+        </properties>
       </resource>
     </xsl:for-each>
   </resources>
 </xsl:template>
 
 <!-- ===============================================================
-	Allocations Handling Template  -->
+        Allocations Handling Template  -->
 
 <!-- Allocations loop   -->
 <xsl:template match="ms:Assignments">
@@ -255,17 +255,17 @@
     <xsl:for-each select="ms:Assignment[ms:ResourceUID>0]">
       <allocation>
       <xsl:attribute name="task-id">
-	<xsl:call-template name="get-task-id">
-	  <xsl:with-param name="uid" select="ms:TaskUID"/>
-	</xsl:call-template>
+        <xsl:call-template name="get-task-id">
+          <xsl:with-param name="uid" select="ms:TaskUID"/>
+        </xsl:call-template>
       </xsl:attribute>
       <xsl:attribute name="resource-id">
-	<xsl:call-template name="get-resource-id">
-	  <xsl:with-param name="uid" select="ms:ResourceUID"/>
-	</xsl:call-template>
+        <xsl:call-template name="get-resource-id">
+          <xsl:with-param name="uid" select="ms:ResourceUID"/>
+        </xsl:call-template>
       </xsl:attribute>
       <xsl:attribute name="units">
-	<xsl:value-of select="ms:Units*100"/>
+        <xsl:value-of select="ms:Units*100"/>
       </xsl:attribute>
       </allocation>
     </xsl:for-each>
@@ -279,7 +279,7 @@
 </xsl:template>
 
 <!-- ===============================================================
-	Global Functions  -->
+        Global Functions  -->
 
 <!-- Convert date from MSP to Planner format -->
 <xsl:template name="ms2pdate">
@@ -301,6 +301,6 @@
 
 
 <!-- ===============================================================
-	End  -->
+        End  -->
 
 </xsl:stylesheet>
Index: data/stylesheets/html1_gantt.xsl
===================================================================
--- data/stylesheets/html1_gantt.xsl	(revision 842)
+++ data/stylesheets/html1_gantt.xsl	(working copy)
@@ -4,7 +4,7 @@
               xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                   xmlns="http://www.w3.org/1999/xhtml";
              xmlns:date="http://exslt.org/dates-and-times";
-	     xmlns:I18N="http://www.gnu.org/software/gettext/"; extension-element-prefixes="I18N">	
+             xmlns:I18N="http://www.gnu.org/software/gettext/"; extension-element-prefixes="I18N">
 
 <!--
   Copyright (c) 2004-2005 Imendio AB
@@ -19,33 +19,33 @@
   <xsl:choose>
     <xsl:when test="date:day-in-week($date) = 2 and $days >= 7">
       <th align="center" colspan="7">
-	<xsl:value-of select="I18N:gettext('Week')"/>&nbsp;<xsl:value-of select="date:week-in-year($date) + 1"/>, <xsl:value-of select="date:year($date)"/>
+        <xsl:value-of select="I18N:gettext('Week')"/>&nbsp;<xsl:value-of select="date:week-in-year($date) + 1"/>, <xsl:value-of select="date:year($date)"/>
       </th>
       <xsl:if test="not($days = 7)">
         <xsl:call-template name="create-week-row">
           <xsl:with-param name="days" select="$days - 7"/>
-	    <xsl:with-param name="date" select="date:add($date, date:duration(604800))"/>
-	  </xsl:call-template>
+            <xsl:with-param name="date" select="date:add($date, date:duration(604800))"/>
+          </xsl:call-template>
       </xsl:if>
     </xsl:when>
     <xsl:when test="not($days >= 7)">
       <th colspan="{$days}"></th>
-	</xsl:when>
-	<xsl:otherwise> 
+        </xsl:when>
+        <xsl:otherwise> 
       <xsl:variable name="colspan">
         <xsl:choose>
-	  <xsl:when test="date:day-in-week($date) = 1">1</xsl:when>
-	  <xsl:otherwise>
-	    <xsl:value-of select="9 - date:day-in-week($date)"/>
-	  </xsl:otherwise>
-	</xsl:choose>
+          <xsl:when test="date:day-in-week($date) = 1">1</xsl:when>
+          <xsl:otherwise>
+            <xsl:value-of select="9 - date:day-in-week($date)"/>
+          </xsl:otherwise>
+        </xsl:choose>
       </xsl:variable>
       <th colspan="{$colspan}"></th>
       <xsl:if test="$days > 1">
         <xsl:call-template name="create-week-row">
           <xsl:with-param name="days" select="$days - $colspan"/>
-	  <xsl:with-param name="date" select="date:add($date, date:duration(86400 * $colspan))"/>
-	</xsl:call-template>
+          <xsl:with-param name="date" select="date:add($date, date:duration(86400 * $colspan))"/>
+        </xsl:call-template>
       </xsl:if>
     </xsl:otherwise>
   </xsl:choose>
@@ -60,7 +60,7 @@
   <xsl:if test="$days > 1">
     <xsl:call-template name="create-day-row">
       <xsl:with-param name="days" select="$days - 1"/>
-	<xsl:with-param name="date" select="date:add($date, date:duration(86400))"/>
+        <xsl:with-param name="date" select="date:add($date, date:duration(86400))"/>
       </xsl:call-template>
   </xsl:if>
 </xsl:template>
@@ -120,57 +120,57 @@
       
       <tr class="{$rowclass}">
         <td>
-	  <span>
-	    <xsl:for-each select="ancestor-or-self::task">
-	      <xsl:value-of select="count(preceding-sibling::task) + 1"/>
-	      <xsl:if test="not(position() = last())">
-	        <xsl:text>.</xsl:text>
-	      </xsl:if>
-	    </xsl:for-each>
-	  </span>
-	</td>
-	<td>
+          <span>
+            <xsl:for-each select="ancestor-or-self::task">
+              <xsl:value-of select="count(preceding-sibling::task) + 1"/>
+              <xsl:if test="not(position() = last())">
+                <xsl:text>.</xsl:text>
+              </xsl:if>
+            </xsl:for-each>
+          </span>
+        </td>
+        <td>
           <xsl:choose>
-  	    <!-- Task has subtasks -->
-	    <xsl:when test="task">
-	      <a name="task-{ id}" style="white-space: nowrap; font-weight: bold; margin-left: {$indent*$task-indent-pixels}px;">
-   	        <span>
-		  <xsl:value-of select="@name"/>
-		</span>
-	      </a>
-	    </xsl:when>
-	    <!-- Task is leaf -->
+            <!-- Task has subtasks -->
+            <xsl:when test="task">
+              <a name="task-{ id}" style="white-space: nowrap; font-weight: bold; margin-left: {$indent*$task-indent-pixels}px;">
+                <span>
+                  <xsl:value-of select="@name"/>
+                </span>
+              </a>
+            </xsl:when>
+            <!-- Task is leaf -->
             <xsl:otherwise>
               <a name="gantt-{ id}" style="white-space: nowrap; margin-left: {$indent*$task-indent-pixels}px;">
                 <span>
-		  <xsl:value-of select="@name"/>
-		</span>
-	      </a>
-	    </xsl:otherwise>
-	  </xsl:choose>
+                  <xsl:value-of select="@name"/>
+                </span>
+              </a>
+            </xsl:otherwise>
+          </xsl:choose>
         </td>
 
-	<td>
-	  <xsl:choose>
-	    <!-- Task has subtasks -->
-	    <xsl:when test="task">
- 	      <span style="white-space: nowrap; font-weight: bold;">
-	        <xsl:call-template name="mrproj-duration">
+        <td>
+          <xsl:choose>
+            <!-- Task has subtasks -->
+            <xsl:when test="task">
+              <span style="white-space: nowrap; font-weight: bold;">
+                <xsl:call-template name="mrproj-duration">
                   <xsl:with-param name="duration-in-seconds" select="@work"/>
-	        </xsl:call-template>
-	       </span>
-	    </xsl:when>
-			
-	    <!-- Task is leaf -->
+                </xsl:call-template>
+               </span>
+            </xsl:when>
+                        
+            <!-- Task is leaf -->
             <xsl:otherwise>
-  	      <span>
-	        <xsl:call-template name="mrproj-duration">
+              <span>
+                <xsl:call-template name="mrproj-duration">
                   <xsl:with-param name="duration-in-seconds" select="@work"/>
-		</xsl:call-template>
-	      </span>
-	    </xsl:otherwise>
-	  </xsl:choose>
-	</td>
+                </xsl:call-template>
+              </span>
+            </xsl:otherwise>
+          </xsl:choose>
+        </td>
       </tr>
     </xsl:for-each>
   </table>
@@ -184,14 +184,14 @@
     <tr class="header" align="left">
       <xsl:call-template name="create-week-row">
         <xsl:with-param name="days" select="$days"/>
-	<xsl:with-param name="date" select="$projstart"/>
+        <xsl:with-param name="date" select="$projstart"/>
       </xsl:call-template>
     </tr>
 
     <tr class="header" align="left">
       <xsl:call-template name="create-day-row">
         <xsl:with-param name="days" select="$days"/>
-	<xsl:with-param name="date" select="$projstart"/>
+        <xsl:with-param name="date" select="$projstart"/>
       </xsl:call-template>
     </tr>
 
@@ -221,61 +221,61 @@
       <xsl:variable name="task-complete" select="floor($task-end * (@percent-complete div 100))"/>
       
       <tr class="{$rowclass}">
-	<td colspan="{$days}">
-	  <div style="width: {$days * 20 + 1}px; white-space: nowrap;">
-	    <xsl:if test="not (task)">
-	      <xsl:if test="$task-start > 0">
-	        <xsl:choose>
-		  <xsl:when test="@type = 'milestone'">
-		    <div class="gantt-empty-begin" style="width: {$task-start - 4}px;"></div>
-		  </xsl:when>
-		  <xsl:otherwise>
-		    <div class="gantt-empty-begin" style="width: {$task-start}px;"></div>
-		  </xsl:otherwise>
- 	        </xsl:choose>
-	      </xsl:if>
-			  
+        <td colspan="{$days}">
+          <div style="width: {$days * 20 + 1}px; white-space: nowrap;">
+            <xsl:if test="not (task)">
+              <xsl:if test="$task-start > 0">
+                <xsl:choose>
+                  <xsl:when test="@type = 'milestone'">
+                    <div class="gantt-empty-begin" style="width: {$task-start - 4}px;"></div>
+                  </xsl:when>
+                  <xsl:otherwise>
+                    <div class="gantt-empty-begin" style="width: {$task-start}px;"></div>
+                  </xsl:otherwise>
+                </xsl:choose>
+              </xsl:if>
+                          
               <xsl:if test="$task-end > 0">
-		<div class="gantt-complete-notdone" style="width: {$task-end}px;">
-		  <xsl:if test="$task-complete > 0">
-		    <div class="gantt-complete-done" style="width: {$task-complete}px;"></div>
-	          </xsl:if>
-		</div>
-	      </xsl:if>
-		  
-	      <xsl:choose>
+                <div class="gantt-complete-notdone" style="width: {$task-end}px;">
+                  <xsl:if test="$task-complete > 0">
+                    <div class="gantt-complete-done" style="width: {$task-complete}px;"></div>
+                  </xsl:if>
+                </div>
+              </xsl:if>
+                  
+              <xsl:choose>
                 <xsl:when test="@type = 'milestone'">
                   <span class="gantt-milestone">&#9670;</span>
                   <span class="gantt-resources">
-		    <xsl:variable name="task-id" select="@id"/>
-		    <xsl:for-each select="/project/allocations/allocation[ task-id=$task-id]">
-		      <xsl:sort data-type="number" select="@resource-id" order="descending"/>
-		      <xsl:variable name="resource-id" select="@resource-id"/>
-		      <xsl:value-of select="/project/resources/resource[ id=$resource-id]/@short-name"/>
-		      <xsl:if test="not(position() = last())">
-		        <xsl:text>, </xsl:text>
-		      </xsl:if>
-		    </xsl:for-each>
+                    <xsl:variable name="task-id" select="@id"/>
+                    <xsl:for-each select="/project/allocations/allocation[ task-id=$task-id]">
+                      <xsl:sort data-type="number" select="@resource-id" order="descending"/>
+                      <xsl:variable name="resource-id" select="@resource-id"/>
+                      <xsl:value-of select="/project/resources/resource[ id=$resource-id]/@short-name"/>
+                      <xsl:if test="not(position() = last())">
+                        <xsl:text>, </xsl:text>
+                      </xsl:if>
+                    </xsl:for-each>
                   </span>
-		</xsl:when>
-		<xsl:otherwise>
-		  <div class="gantt-empty-end"></div>
+                </xsl:when>
+                <xsl:otherwise>
+                  <div class="gantt-empty-end"></div>
                   <span class="gantt-resources">
-	 	    <xsl:variable name="task-id" select="@id"/>
-		    <xsl:for-each select="/project/allocations/allocation[ task-id=$task-id]">
-		      <xsl:sort data-type="number" select="@resource-id" order="descending"/>
-		      <xsl:variable name="resource-id" select="@resource-id"/>
-		      <xsl:value-of select="/project/resources/resource[ id=$resource-id]/@short-name"/>
-		      <xsl:if test="not(position() = last())">
-		        <xsl:text>, </xsl:text>
-		      </xsl:if>
-		    </xsl:for-each>
+                    <xsl:variable name="task-id" select="@id"/>
+                    <xsl:for-each select="/project/allocations/allocation[ task-id=$task-id]">
+                      <xsl:sort data-type="number" select="@resource-id" order="descending"/>
+                      <xsl:variable name="resource-id" select="@resource-id"/>
+                      <xsl:value-of select="/project/resources/resource[ id=$resource-id]/@short-name"/>
+                      <xsl:if test="not(position() = last())">
+                        <xsl:text>, </xsl:text>
+                      </xsl:if>
+                    </xsl:for-each>
                   </span>
-		</xsl:otherwise>
-	      </xsl:choose>
+                </xsl:otherwise>
+              </xsl:choose>
 
             </xsl:if>
-	  </div>
+          </div>
         </td>
       </tr>
     </xsl:for-each>
Index: data/stylesheets/planner2html.xsl
===================================================================
--- data/stylesheets/planner2html.xsl	(revision 842)
+++ data/stylesheets/planner2html.xsl	(working copy)
@@ -4,7 +4,7 @@
               xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                   xmlns="http://www.w3.org/1999/xhtml";
              xmlns:date="http://exslt.org/dates-and-times";
-	     xmlns:I18N="http://www.gnu.org/software/gettext/"; extension-element-prefixes="I18N">
+             xmlns:I18N="http://www.gnu.org/software/gettext/"; extension-element-prefixes="I18N">
 
 <!--
   Copyright (C) 2004-2005 Imendio AB
@@ -220,7 +220,7 @@
 <tr>
   <td class="header"><xsl:value-of select="I18N:gettext('Start:')"/></td>
   <td>
-    <xsl:value-of select="I18N:getdate(date:seconds($projstart))"/>	
+    <xsl:value-of select="I18N:getdate(date:seconds($projstart))"/>
   </td>
 </tr>
 
Index: src/planner-gantt-row.c
===================================================================
--- src/planner-gantt-row.c	(revision 842)
+++ src/planner-gantt-row.c	(working copy)
@@ -55,6 +55,8 @@
 
 #define MILESTONE_SIZE 5
 
+#define FUZZ  3
+
 /* Minimum width for a task to keep it visible. */
 #define MIN_WIDTH 2
 
@@ -97,10 +99,19 @@
 	STATE_NONE          = 0,
 	STATE_DRAG_LINK     = 1 << 0,
 	STATE_DRAG_DURATION = 1 << 1,
+	STATE_DRAG_COMPLETE = 1 << 2,
 
-	STATE_DRAG_ANY = STATE_DRAG_LINK | STATE_DRAG_DURATION
+	STATE_DRAG_ANY = STATE_DRAG_LINK | STATE_DRAG_DURATION | STATE_DRAG_COMPLETE
 } State;
 
+typedef enum
+{
+	DRAG_NONE_SPOT,
+	DRAG_DURATION_SPOT,
+	DRAG_COMPLETE_SPOT,
+	DRAG_RELATION_SPOT
+} DragSpot;
+
 struct _PlannerGanttRowPriv {
 	/* FIXME: Don't need those per gantt row. */
 	GdkGC       *complete_gc;
@@ -2305,14 +2316,49 @@
 	return TRUE;
 }
 
-#define IN_DRAG_DURATION_SPOT(x,y,right,top,ymin,ymax)	\
-	((abs (x - (right)) <= 3) && \
-	 (y > top + ymin) && (y < top + ymax))
+static DragSpot get_drag_spot(gdouble x, gdouble y, PlannerGanttRowPriv *priv)
+{
+	gdouble x2 = priv->x + priv->width;
+	if( (y > priv->y + priv->bar_top) &&
+	    (y < priv->y + priv->bar_bot) &&
+	    (x < x2 + FUZZ) ) {
+		gdouble complete_x2 = priv->x + floor(priv->width * (mrp_task_get_percent_complete (priv->task) / 100.0) + 0.5);
 
-#define IN_DRAG_RELATION_SPOT(x,y,right,top,ymin,ymax)	\
-	((x <= right) && \
-	 (y > top + ymin) && (y < top + ymax))
+		/* if not way left of end of completion bar */
+		if(x > complete_x2 - FUZZ) {
 
+			/* if end of completion bar and end of task bar are not very close together */
+			if(x2 - complete_x2 > 2 * FUZZ) {
+
+				/* if not way right of the completion bar */
+				if(x < complete_x2 + FUZZ) {
+					return DRAG_COMPLETE_SPOT;
+				} else { /* if way right of completion bar and ... */
+
+					/* if less than FUZZ from the end of the task bar */
+					if(x > x2 - FUZZ) {
+						return DRAG_DURATION_SPOT;
+					} else { /* if more than FUZZ left of the end of the task bar */
+						return DRAG_RELATION_SPOT;
+					}
+				}
+			} else { /* if DRAG_DURATION_SPOT and DRAG_COMPLETE_SPOT are connected and ... */
+
+				/* if closer to the end of the task bar than to the end of the completion bar */
+				if(x > complete_x2 + (x2 - complete_x2) / 2) {
+					return DRAG_DURATION_SPOT;
+				} else {
+					return DRAG_COMPLETE_SPOT;
+				}
+			}
+		} else { /* if way left of end of completion bar */
+			return DRAG_RELATION_SPOT;
+		}
+	} else { /* above, below or too far to the right of bar */
+		return DRAG_NONE_SPOT;
+	}
+}
+
 static gboolean
 gantt_row_event (GnomeCanvasItem *item, GdkEvent *event)
 {
@@ -2333,6 +2379,7 @@
 	gboolean                  summary;
 	MrpTaskType               type;
 	gchar                    *message;
+	DragSpot                  drag_spot;
 	
 	row = PLANNER_GANTT_ROW (item);
 	priv = row->priv;
@@ -2345,9 +2392,9 @@
 	case GDK_BUTTON_PRESS:
 		switch (event->button.button) {
 		case 3:
-			if (IN_DRAG_RELATION_SPOT (event->button.x, event->button.y,
-						   priv->x + priv->width, priv->y, 
-						   priv->bar_top, priv->bar_bot)) {
+			drag_spot = get_drag_spot(event->button.x, event->button.y, priv);
+
+			if (drag_spot == DRAG_RELATION_SPOT) {
 				PlannerGanttChart *chart;
 				PlannerTaskTree   *tree;
 				GtkTreePath       *path;
@@ -2395,13 +2442,10 @@
 				break;
 			}
 
+			drag_spot = get_drag_spot(event->button.x, event->button.y, priv);
+
 			if (type != MRP_TASK_TYPE_MILESTONE &&
-			    !summary && IN_DRAG_DURATION_SPOT (event->button.x,
-							       event->button.y,
-							       priv->x + priv->width,
-							       priv->y,
-							       priv->bar_top, 
-							       priv->bar_bot)) {
+			    !summary && drag_spot == DRAG_DURATION_SPOT) {
 				guint rgba;
 				
 				priv->state = STATE_DRAG_DURATION;
@@ -2430,12 +2474,49 @@
 									   NULL);
 					gnome_canvas_item_hide (drag_item);
 				}
-			} else if (IN_DRAG_RELATION_SPOT (event->button.x,
-							  event->button.y,
-							  priv->x + priv->width,
-							  priv->y,
-							  priv->bar_top, 
-							  priv->bar_bot)) {
+
+				/* Start the autoscroll timeout. */
+				priv->scroll_timeout_id = gtk_timeout_add (
+					50,
+					(GSourceFunc) gantt_row_scroll_timeout_cb,
+					row);
+			} else if (type != MRP_TASK_TYPE_MILESTONE &&
+			    !summary && drag_spot == DRAG_COMPLETE_SPOT) {
+				guint rgba;
+
+				priv->state = STATE_DRAG_COMPLETE;
+
+				wx1 = priv->x;
+				wy1 = priv->y + priv->bar_top + 4;
+				wx2 = event->button.x;
+				wy2 = priv->y + priv->bar_bot - 4;
+
+				gnome_canvas_item_i2w (item, &wx1, &wy1);
+				gnome_canvas_item_i2w (item, &wx2, &wy2);
+
+				/*      red            green          blue          alpha */
+				rgba = (0xb7 << 24) | (0xc3 << 16) | (0xc9 << 8) | (127 << 0);
+				
+				if (drag_item == NULL) {
+					drag_item = gnome_canvas_item_new (gnome_canvas_root (item->canvas),
+									   EEL_TYPE_CANVAS_RECT,
+									   "x1", wx1,
+									   "y1", wy1,
+									   "x2", wx2,
+									   "y2", wy2,
+									   "fill_color_rgba", rgba,
+									   "outline_color_rgba", 0,
+									   "width_pixels", 1,
+									   NULL);
+					gnome_canvas_item_hide (drag_item);
+				}
+
+				/* Start the autoscroll timeout. */
+				priv->scroll_timeout_id = gtk_timeout_add (
+					50,
+					(GSourceFunc) gantt_row_scroll_timeout_cb,
+					row);
+			} else if (drag_spot == DRAG_RELATION_SPOT) {
 				priv->state = STATE_DRAG_LINK;
 				if (drag_points == NULL) {
 					drag_points = gnome_canvas_points_new (2);
@@ -2531,18 +2612,24 @@
 		}
 
 		if (!(priv->state & STATE_DRAG_ANY)) {
-			if (type != MRP_TASK_TYPE_MILESTONE &&
-			    !summary && IN_DRAG_DURATION_SPOT (event->button.x,
-							       event->button.y,
-							       priv->x + priv->width,
-							       priv->y,
-							       priv->bar_top, 
-							       priv->bar_bot)) {
-				cursor = gdk_cursor_new (GDK_RIGHT_SIDE);
-				gdk_window_set_cursor (canvas_widget->window, cursor);
-				if (cursor) {
-					gdk_cursor_unref (cursor);
+			drag_spot = get_drag_spot(event->button.x, event->button.y, priv);
+
+			if (type != MRP_TASK_TYPE_MILESTONE && !summary && 
+			    ( (drag_spot == DRAG_DURATION_SPOT) || (drag_spot == DRAG_COMPLETE_SPOT) ) ) {
+				if(drag_spot == DRAG_DURATION_SPOT) {
+					cursor = gdk_cursor_new (GDK_RIGHT_SIDE);
+					gdk_window_set_cursor (canvas_widget->window, cursor);
+					if (cursor) {
+						gdk_cursor_unref (cursor);
+					}
 				}
+				else { /* DRAG_COMPLETE_SPOT */
+					cursor = gdk_cursor_new (GDK_HAND2);
+					gdk_window_set_cursor (canvas_widget->window, cursor);
+					if (cursor) {
+						gdk_cursor_unref (cursor);
+					}
+				}
 			} else { /* Mouse over resource names (or short_name) ? */
  				gint res_index;
 
@@ -2625,6 +2712,24 @@
 			
 			old_target_item = target_item;
 		}
+		else if (priv->state == STATE_DRAG_COMPLETE) {
+			chart = g_object_get_data (G_OBJECT (item->canvas), "chart");
+
+			wx2 = MIN(event->motion.x, priv->x + priv->width);
+			wy2 = priv->y + priv->bar_bot - 4;
+			
+			gnome_canvas_item_i2w (item, &wx2, &wy2);
+
+			gnome_canvas_item_set (drag_item,
+					       "x2", wx2,
+					       "y2", wy2,
+					       NULL);
+			
+			gnome_canvas_item_raise_to_top (drag_item);
+			gnome_canvas_item_show (drag_item);
+
+			planner_gantt_chart_status_updated (chart, NULL);
+		}
 		else if (priv->state == STATE_DRAG_DURATION) {
 			gint         duration;
 			gint         work;
@@ -2709,6 +2814,11 @@
 						"work",
 						&value);
 
+			if (priv->scroll_timeout_id) {
+				g_source_remove (priv->scroll_timeout_id);
+				priv->scroll_timeout_id = 0;
+			}
+
 			/*g_object_set (priv->task,
 				      "work", work,
 				      NULL);
@@ -2718,6 +2828,32 @@
 
 			planner_gantt_chart_status_updated (chart, NULL);
 		}
+		else if (priv->state == STATE_DRAG_COMPLETE) {
+			GValue      value = { 0 };
+			gint        percent_complete = floor((MIN(MAX(0, event->button.x - priv->x), priv->width) * 100.0) / priv->width + 0.5);
+
+			chart = g_object_get_data (G_OBJECT (item->canvas), "chart");
+			tree = planner_gantt_chart_get_view (chart);
+
+			g_value_init (&value, G_TYPE_INT);
+			g_value_set_int (&value, percent_complete);
+
+			task_cmd_edit_property (planner_task_tree_get_window (tree),
+						tree,
+						priv->task,
+						"percent_complete", 
+						&value);
+
+			if (priv->scroll_timeout_id) {
+				g_source_remove (priv->scroll_timeout_id);
+				priv->scroll_timeout_id = 0;
+			}
+
+			gtk_object_destroy (GTK_OBJECT (drag_item));
+			drag_item = NULL;
+
+			planner_gantt_chart_status_updated (chart, NULL);
+		}
 		else if (priv->state == STATE_DRAG_LINK) {
 			if (old_target_item) {
 				g_object_set (old_target_item,
@@ -2835,9 +2971,8 @@
 		
 	case GDK_2BUTTON_PRESS:
 		if (event->button.button == 1) {
-			if (IN_DRAG_RELATION_SPOT (event->button.x, event->button.y,
-						   priv->x + priv->width, priv->y, 
-						   priv->bar_top, priv->bar_bot)) {
+			drag_spot = get_drag_spot(event->button.x, event->button.y, priv);
+			if (drag_spot == DRAG_RELATION_SPOT) {
 				PlannerTaskTree  *tree;
 				GtkTreePath      *path;
 				GtkTreeSelection *selection;
Index: configure.in
===================================================================
--- configure.in	(revision 842)
+++ configure.in	(working copy)
@@ -161,8 +161,8 @@
 AC_SUBST(GETTEXT_PACKAGE)
 AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE, "$GETTEXT_PACKAGE", [The prefix for our gettext translation domains.])
 
-ALL_LINGUAS="am ar az be bg ca cs da de dz el en_CA en_GB es et eu fa fi
-fr hi hr hu id is it ja kn ko lt lv ml mn ms nb ne nl nn pa pl pt pt_BR
+ALL_LINGUAS="am ar az be bg ca cs da de dz el en_CA en_GB es et eu fa fi \
+fr hi hr hu id is it ja kn ko lt lv ml mn ms nb ne nl nn pa pl pt pt_BR \
 ru rw sk sl sq sr sr Latn sv uk vi zh_CN zh_HK zh_TW"
 
 AM_GLIB_GNU_GETTEXT
Index: data/stylesheets/html1_css_ie.xsl
===================================================================
--- data/stylesheets/html1_css_ie.xsl	(revision 0)
+++ data/stylesheets/html1_css_ie.xsl	(revision 0)
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!DOCTYPE xsl:stylesheet [ <!ENTITY nbsp "&#160;"> ]>
+<xsl:stylesheet version="1.0"
+              xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
+                  xmlns="http://www.w3.org/1999/xhtml";>
+<xsl:comment>
+
+/* IE specific overrides to compensate for the different box model used by IE
+ * (see http://en.wikipedia.org/wiki/Internet_Explorer_box_model_bug)
+ */
+
+/*
+div.gantt-empty-begin, div.gantt-empty-end, div.gantt-complete-done, div.gantt-complete-notdone, div.gantt-summary {
+ height: 1.75em;
+}
+
+div.gantt-complete-done {
+ height: 0.75em;
+}
+
+div.gantt-summary {
+ height: 0.3em;
+}
+*/
+th.gantt-1day-header {
+  width: 20px;
+}
+
+th.gantt-2day-header {
+  width: 40px;
+}
+
+th.gantt-3day-header {
+  width: 60px;
+}
+
+th.gantt-4day-header {
+  width: 80px;
+}
+
+th.gantt-5day-header {
+  width: 100px;
+}
+
+th.gantt-6day-header {
+  width: 120px;
+}
+
+th.gantt-week-header {
+ width: 140px;
+}
+
+th.gantt-day-header {
+ width: 20px;
+}
+
+</xsl:comment>
+</xsl:stylesheet>
Index: data/stylesheets/html1_css.xsl
===================================================================
--- data/stylesheets/html1_css.xsl	(revision 842)
+++ data/stylesheets/html1_css.xsl	(working copy)
@@ -186,9 +186,38 @@
  margin-left: 0.5em;
 }
 
+th.gantt-1day-header {
+  width: 19px;
+}
+
+th.gantt-2day-header {
+  width: 38px;
+}
+
+th.gantt-3day-header {
+  width: 57px;
+}
+
+th.gantt-4day-header {
+  width: 76px;
+}
+
+th.gantt-5day-header {
+  width: 95px;
+}
+
+th.gantt-6day-header {
+  width: 114px;
+}
+
+th.gantt-week-header {
+ width: 133px;
+}
+
 th.gantt-day-header {
  margin: 0;
  padding: 0;
+ width: 19px;
 }
 
 </xsl:comment>
Index: data/stylesheets/html1_gantt.xsl
===================================================================
--- data/stylesheets/html1_gantt.xsl	(revision 842)
+++ data/stylesheets/html1_gantt.xsl	(working copy)
@@ -18,7 +18,7 @@
   <xsl:param name="date"/>
   <xsl:choose>
     <xsl:when test="date:day-in-week($date) = 2 and $days >= 7">
-      <th align="center" colspan="7">
+      <th class="gantt-week-header" align="center" colspan="7">
 	<xsl:value-of select="I18N:gettext('Week')"/>&nbsp;<xsl:value-of select="date:week-in-year($date) + 1"/>, <xsl:value-of select="date:year($date)"/>
       </th>
       <xsl:if test="not($days = 7)">
@@ -29,7 +29,8 @@
       </xsl:if>
     </xsl:when>
     <xsl:when test="not($days >= 7)">
-      <th colspan="{$days}"></th>
+      <th class="gantt-{$days}day-header" colspan="{$days}"></th>
+      <th></th>
 	</xsl:when>
 	<xsl:otherwise> 
       <xsl:variable name="colspan">
@@ -40,7 +41,7 @@
 	  </xsl:otherwise>
 	</xsl:choose>
       </xsl:variable>
-      <th colspan="{$colspan}"></th>
+      <th class="gantt-{$colspan}day-header" colspan="{$colspan}"></th>
       <xsl:if test="$days > 1">
         <xsl:call-template name="create-week-row">
           <xsl:with-param name="days" select="$days - $colspan"/>
@@ -54,15 +55,21 @@
 <xsl:template name="create-day-row">
   <xsl:param name="days"/>
   <xsl:param name="date"/>
-  <th class="gantt-day-header" align="center" width="19px">
+  <th class="gantt-day-header" align="center">
   <xsl:value-of select="date:day-in-month($date)"/>
   </th>
-  <xsl:if test="$days > 1">
+  <xsl:choose>
+    <xsl:when test="$days > 1">
     <xsl:call-template name="create-day-row">
       <xsl:with-param name="days" select="$days - 1"/>
 	<xsl:with-param name="date" select="date:add($date, date:duration(86400))"/>
       </xsl:call-template>
-  </xsl:if>
+    </xsl:when>
+    <xsl:otherwise>
+      <th align="center">
+      </th>
+    </xsl:otherwise>
+  </xsl:choose>
 </xsl:template>
 
 <xsl:template name="gantt">
@@ -180,7 +187,7 @@
   <td>
 
   <div class="scroll-div" style="border-color: #aaa #aaa #aaa #fff;">
-  <table cellspacing="0" cellpadding="0" border="1">
+  <table cellspacing="0" cellpadding="0" border="1" style="table-layout: fixed;">
     <tr class="header" align="left">
       <xsl:call-template name="create-week-row">
         <xsl:with-param name="days" select="$days"/>
@@ -221,7 +228,7 @@
       <xsl:variable name="task-complete" select="floor($task-end * (@percent-complete div 100))"/>
       
       <tr class="{$rowclass}">
-	<td colspan="{$days}">
+	<td colspan="{$days + 1}">
 	  <div style="width: {$days * 20 + 1}px; white-space: nowrap;">
 	    <xsl:if test="not (task)">
 	      <xsl:if test="$task-start > 0">
@@ -265,7 +272,15 @@
 		    <xsl:for-each select="/project/allocations/allocation[ task-id=$task-id]">
 		      <xsl:sort data-type="number" select="@resource-id" order="descending"/>
 		      <xsl:variable name="resource-id" select="@resource-id"/>
-		      <xsl:value-of select="/project/resources/resource[ id=$resource-id]/@short-name"/>
+
+		      <xsl:choose>
+			<xsl:when test="/project/resources/resource[ id=$resource-id]/@short-name = ''">
+			  <xsl:value-of select="/project/resources/resource[ id=$resource-id]/@name"/>
+			</xsl:when>
+			<xsl:otherwise>
+			  <xsl:value-of select="/project/resources/resource[ id=$resource-id]/@short-name"/>
+			</xsl:otherwise>
+		      </xsl:choose>
 		      <xsl:if test="not(position() = last())">
 		        <xsl:text>, </xsl:text>
 		      </xsl:if>
Index: data/stylesheets/Makefile.am
===================================================================
--- data/stylesheets/Makefile.am	(revision 842)
+++ data/stylesheets/Makefile.am	(working copy)
@@ -3,6 +3,7 @@
 stylesheet_DATA = \
 	planner2html.xsl		\
 	html1_css.xsl			\
+	html1_css_ie.xsl			\
         html1_gantt.xsl			\
         html1_resources.xsl		\
         html1_tasks.xsl			\
Index: data/stylesheets/planner2html.xsl
===================================================================
--- data/stylesheets/planner2html.xsl	(revision 842)
+++ data/stylesheets/planner2html.xsl	(working copy)
@@ -33,6 +33,7 @@
 
 <!-- CSS file to be included in XHTML output -->
 <xsl:variable name="css-stylesheet-local" select="'html1_css.xsl'"/>
+<xsl:variable name="css-stylesheet-local-ie" select="'html1_css_ie.xsl'"/>
 
 
 <!-- Current date/time at UTC/GMT -->
@@ -145,6 +146,11 @@
     <style type="text/css">
       <xsl:value-of select="document($css-stylesheet-local)"/>
     </style>
+      <xsl:comment>
+        <xsl:text>[if lte IE 6]&gt;&lt;style type="text/css"&gt;</xsl:text>
+        <xsl:value-of select="document($css-stylesheet-local-ie)"/>
+        <xsl:text>&lt;/style&gt;&lt;![endif]</xsl:text>
+      </xsl:comment>
   </head>
 </xsl:template>
 

Attachment: pgpVTYH2NZpsU.pgp
Description: PGP signature



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]