? grade/edit/weights/img/lm.gif
? grade/edit/weights/img/lmh.gif
? grade/edit/weights/img/ln.gif
? grade/edit/weights/img/loading.gif
? grade/edit/weights/img/lp.gif
? grade/edit/weights/img/lph.gif
? grade/edit/weights/img/tm.gif
? grade/edit/weights/img/tmh.gif
? grade/edit/weights/img/tn.gif
? grade/edit/weights/img/tp.gif
? grade/edit/weights/img/tph.gif
? grade/edit/weights/img/vline.gif
? pix/t/nonempty.gif
? pix/t/sigmaplus.gif
Index: grade/lib.php
===================================================================
RCS file: /cvsroot/moodle/moodle/grade/lib.php,v
retrieving revision 1.120.2.21
diff -u -r1.120.2.21 lib.php
--- grade/lib.php	11 Mar 2008 23:58:51 -0000	1.120.2.21
+++ grade/lib.php	9 Oct 2008 13:11:02 -0000
@@ -442,6 +442,16 @@
             $count++;
         }

+        if (has_capability('moodle/grade:manage', $context)) {
+            $url = 'edit/weights/index.php?id='.$courseid;
+            if ($active_type == 'edit' and $active_plugin == 'weights' ) {
+                $active = $url;
+            }
+            $menu[$url] = get_string('weights', 'grades');
+            $count++;
+        }
+
+
     }

 /// finally print/return the popup form
Index: grade/edit/tree/item_form.php
===================================================================
RCS file: /cvsroot/moodle/moodle/grade/edit/tree/item_form.php,v
retrieving revision 1.20.2.18
diff -u -r1.20.2.18 item_form.php
--- grade/edit/tree/item_form.php	22 Mar 2008 21:25:39 -0000	1.20.2.18
+++ grade/edit/tree/item_form.php	9 Oct 2008 13:11:02 -0000
@@ -136,15 +136,13 @@
         $mform->addElement('header', 'headerparent', get_string('parentcategory', 'grades'));

         $options = array();
-        $default = '';
         $coefstring = '';
         $categories = grade_category::fetch_all(array('courseid'=>$COURSE->id));
+
         foreach ($categories as $cat) {
             $cat->apply_forced_settings();
             $options[$cat->id] = $cat->get_name();
-            if ($cat->is_course_category()) {
-                $default = $cat->id;
-            }
+
             if ($cat->is_aggregationcoef_used()) {
                 if ($cat->aggregation == GRADE_AGGREGATE_WEIGHTED_MEAN) {
                     $coefstring = ($coefstring=='' or $coefstring=='aggregationcoefweight') ? 'aggregationcoefweight' : 'aggregationcoef';
@@ -231,7 +229,7 @@

             } else {
                 if ($grade_item->is_external_item()) {
-                    // following items are set up from modules and should not be overrided by user
+                    // following items are set up from modules and should not be overridden by user
                     $mform->hardFreeze('itemname,idnumber,gradetype,grademax,grademin,scaleid');
                     //$mform->removeElement('calculation');
                 }
Index: grade/edit/weights/ajax.php
===================================================================
RCS file: grade/edit/weights/ajax.php
diff -N grade/edit/weights/ajax.php
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ grade/edit/weights/ajax.php	9 Oct 2008 13:11:02 -0000
@@ -0,0 +1,71 @@
+<script type="text/javascript">
+//<![CDATA[
+
+// If the mouse is clicked outside this element, the edit is CANCELLED (even if the mouse clicks another grade/feedback cell)
+// If ctrl-arrow is used, or if [tab] or [enter] are pressed, the edit is RECORDED and the row is updated. The previous element returns to normal
+
+YAHOO.namespace("grade_edit_weights");
+YAHOO.grade_edit_weights.courseid = <?php echo $COURSE->id; ?>;
+YAHOO.grade_edit_weights.wwwroot = '<?php echo $CFG->wwwroot; ?>';
+YAHOO.grade_edit_weights.tree = null;
+YAHOO.grade_edit_weights.treedata = <?php echo $tree_json; ?>;
+
+YAHOO.grade_edit_weights.buildTreeNode = function(element, parentNode) {
+    var gew = YAHOO.grade_edit_weights;
+
+    if (parentNode === undefined) {
+        parentNode = gew.tree.getRoot();
+    }
+
+    if (element === undefined) {
+        element = gew.treedata;
+    }
+
+    if (element.item.table == 'grade_categories') {
+        var aggregation_types = '<select name="aggregation_'+element.item.id+'">';
+
+        for (var i = 0; i < gew.options.length; i++) {
+            aggregation_types += '<option>' + gew.options[i] + '</option>';
+        }
+
+        var gradecategory = '<span class="gradecategory">'+element.item.name+' '+aggregation_types+'<'+'/span>';
+        var tmpNode = new YAHOO.widget.TextNode(gradecategory, parentNode, parentNode.isRoot());
+        // var tmpNode = new YAHOO.widget.TextNode(element.item.name, parentNode, parentNode.isRoot());
+        for (var i = 0; i < element.children.length; i++) {
+            gew.buildTreeNode(element.children[i], tmpNode, false);
+        }
+    } else if (element.item.itemtype == 'mod') {
+        var gradeitem = '<span class="gradeitem"><input type="text" size="6" name="weight_'+element.item.id+'" value="'+element.item.aggregationcoef+'"/>'+
+                        element.item.name + '<'+'/span>';
+        var tmpNode = new YAHOO.widget.HTMLNode(gradeitem, parentNode, false);
+    }
+};
+
+YAHOO.grade_edit_weights.init = function() {
+    var gew = YAHOO.grade_edit_weights;
+    var div = document.getElementById('weightstree');
+    gew.tree = new YAHOO.widget.TreeView('gradetree');
+
+    //handler for expanding all nodes
+    YAHOO.util.Event.on("expand", "click", function(e) {
+        YAHOO.log("Expanding all TreeView  nodes.", "info", "example");
+        gew.tree.expandAll();
+        YAHOO.util.Event.preventDefault(e);
+    });
+
+    //handler for collapsing all nodes
+    YAHOO.util.Event.on("collapse", "click", function(e) {
+        YAHOO.log("Collapsing all TreeView  nodes.", "info", "example");
+        gew.tree.collapseAll();
+        YAHOO.util.Event.preventDefault(e);
+    });
+
+    // gew.buildTreeNode();
+    gew.tree.render();
+    gew.tree.expandAll();
+};
+
+YAHOO.util.Event.onDOMReady(YAHOO.grade_edit_weights.init);
+
+// ]]>
+</script>
Index: grade/edit/weights/index.php
===================================================================
RCS file: grade/edit/weights/index.php
diff -N grade/edit/weights/index.php
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ grade/edit/weights/index.php	9 Oct 2008 13:11:02 -0000
@@ -0,0 +1,155 @@
+<?php  // $Id: index.php,v 1.12.2.5 2008/02/17 19:11:29 skodak Exp $
+
+///////////////////////////////////////////////////////////////////////////
+//                                                                       //
+// NOTICE OF COPYRIGHT                                                   //
+//                                                                       //
+// Moodle - Modular Object-Oriented Dynamic Learning Environment         //
+//          http://moodle.com                                            //
+//                                                                       //
+// Copyright (C) 1999 onwards  Martin Dougiamas  http://moodle.com       //
+//                                                                       //
+// This program is free software; you can redistribute it and/or modify  //
+// it under the terms of the GNU General Public License as published by  //
+// the Free Software Foundation; either version 2 of the License, or     //
+// (at your option) any later version.                                   //
+//                                                                       //
+// This program is distributed in the hope that it will be useful,       //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of        //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         //
+// GNU General Public License for more details:                          //
+//                                                                       //
+//          http://www.gnu.org/copyleft/gpl.html                         //
+//                                                                       //
+///////////////////////////////////////////////////////////////////////////
+
+require_once '../../../config.php';
+require_once $CFG->dirroot.'/grade/lib.php';
+require_once $CFG->dirroot.'/grade/report/lib.php'; // for preferences
+require_once $CFG->dirroot.'/grade/edit/weights/lib.php';
+
+$courseid        = required_param('id', PARAM_INT);
+$action          = optional_param('action', 0, PARAM_ALPHA);
+$eid             = optional_param('eid', 0, PARAM_ALPHANUM);
+$category        = optional_param('category', null, PARAM_INT);
+$aggregationtype = optional_param('aggregationtype', null, PARAM_INT);
+
+require_js(array('yui_yahoo', 'yui_dom', 'yui_event', 'yui_json', 'yui_connection', 'yui_dragdrop', 'yui_treeview'));
+
+/// Make sure they can even access this course
+
+if (!$course = get_record('course', 'id', $courseid)) {
+    print_error('nocourseid');
+}
+
+require_login($course);
+$context = get_context_instance(CONTEXT_COURSE, $course->id);
+require_capability('moodle/grade:manage', $context);
+
+/// return tracking object
+$gpr = new grade_plugin_return(array('type'=>'edit', 'plugin'=>'weights', 'courseid'=>$courseid));
+$returnurl = $gpr->get_return_url(null);
+
+// Change category aggregation if requested
+if (!is_null($category) && !is_null($aggregationtype)) {
+    if (!$grade_category = grade_category::fetch(array('id'=>$category, 'courseid'=>$courseid))) {
+        error('Incorrect category id!');
+    }
+    $data->aggregation = $aggregationtype;
+    grade_category::set_properties($grade_category, $data);
+    $grade_category->update();
+}
+
+//first make sure we have proper final grades - we need it for locking changes
+grade_regrade_final_grades($courseid);
+
+// get the grading tree object
+// note: total must be first for moving to work correctly, if you want it last moving code must be rewritten!
+$gtree = new grade_tree($courseid, false, false);
+
+$switch = grade_get_setting($course->id, 'aggregationposition', $CFG->grade_aggregationposition);
+
+$strgrades             = get_string('grades');
+$strgraderreport       = get_string('graderreport', 'grades');
+$strcategoriesedit     = get_string('categoriesedit', 'grades');
+$strcategoriesanditems = get_string('categoriesanditems', 'grades');
+
+$navigation = grade_build_nav(__FILE__, $strcategoriesanditems, array('courseid' => $courseid));
+$moving = false;
+
+$CFG->stylesheets[] = $CFG->wwwroot.'/grade/edit/weights/tree.css';
+print_header_simple($strgrades . ': ' . $strgraderreport, ': ' . $strcategoriesedit, $navigation, '', '', true, '', navmenu($course));
+
+/// Print the plugin selector at the top
+print_grade_plugin_selector($courseid, 'edit', 'tree');
+
+print_heading(get_string('categoriesedit', 'grades'));
+$tree_json = json_encode(get_tree_json($gtree, $gtree->top_element));
+
+$form_key = optional_param('sesskey', null, PARAM_ALPHANUM);
+
+if ($form_key) {
+    $data = data_submitted();
+
+    foreach ($data as $key => $value) {
+        if (preg_match('/aggregation_type_([0-9]*)/', $key, $matches)) {
+            $aggtype = required_param($matches[0], PARAM_INT);
+            $a->id = $matches[1];
+
+            if (!update_record('grade_categories', array('id' => $matches[1], 'aggregation' => $aggtype))) {
+                print_error('errorupdatinggradecategoryaggregation', 'grades', $a);
+            }
+
+        } elseif (preg_match('/weight_([0-9]*)/', $key, $matches)) {
+            $weight = required_param($matches[0], PARAM_NUMBER);
+            $a->id = $matches[1];
+
+            if (!update_record('grade_items', array('id' => $matches[1], 'aggregationcoef' => $weight))) {
+                print_error('errorupdatinggradeitemaggregationcoef', 'grades', $a);
+            }
+
+        } elseif (preg_match('/aggregate(onlygraded|subcats|outcomes)_original_([0-9]*)/', $key, $matches)) {
+            $setting = optional_param('aggregate'.$matches[1].'_'.$matches[2], null, PARAM_BOOL);
+            $original_value = required_param($matches[0], PARAM_BOOL);
+            $a->id = $matches[2];
+
+            $newvalue = null;
+            if ($original_value == 1 && is_null($setting)) {
+                $newvalue = 0;
+            } elseif ($original_value == 0 && $setting == 1) {
+                $newvalue = 1;
+            }
+
+            if (!is_null($newvalue)) {
+                if (!update_record('grade_categories', array('id' => $matches[2], 'aggregate'.$matches[1] => $newvalue))) {
+                    print_error('errorupdatinggradecategoryaggregate'.$matches[1], 'grades');
+                }
+            }
+        }
+    }
+}
+
+// AJAX interface not really needed: adds nice tree functions but not very useful
+// require_once('ajax.php');
+
+print_box_start('gradetreebox generalbox');
+
+// echo '<div id="expandcontractdiv"> <a id="expand" href="#">Expand all</a> <a id="collapse" href="#">Collapse all</a> </div> ';
+
+echo '<form method="post" action="'.$returnurl.'">';
+echo '<input type="hidden" name="sesskey" value="'.sesskey().'" />';
+echo '<div id="gradetree">';
+echo build_html_tree(get_tree_json($gtree, $gtree->top_element), null, $returnurl);
+
+// print_grade_tree($gtree, $gtree->top_element, $gpr, $switch);
+//
+echo '</div><div>';
+
+echo '<input type="submit" value="Update weights" />';
+echo '</div></form>';
+print_box_end();
+
+print_footer($course);
+die;
+
+?>
Index: grade/edit/weights/lib.php
===================================================================
RCS file: grade/edit/weights/lib.php
diff -N grade/edit/weights/lib.php
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ grade/edit/weights/lib.php	9 Oct 2008 13:11:02 -0000
@@ -0,0 +1,187 @@
+<?php  // $Id: index.php,v 1.12.2.5 2008/02/17 19:11:29 skodak Exp $
+
+///////////////////////////////////////////////////////////////////////////
+//                                                                       //
+// NOTICE OF COPYRIGHT                                                   //
+//                                                                       //
+// Moodle - Modular Object-Oriented Dynamic Learning Environment         //
+//          http://moodle.com                                            //
+//                                                                       //
+// Copyright (C) 1999 onwards  Martin Dougiamas  http://moodle.com       //
+//                                                                       //
+// This program is free software; you can redistribute it and/or modify  //
+// it under the terms of the GNU General Public License as published by  //
+// the Free Software Foundation; either version 2 of the License, or     //
+// (at your option) any later version.                                   //
+//                                                                       //
+// This program is distributed in the hope that it will be useful,       //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of        //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         //
+// GNU General Public License for more details:                          //
+//                                                                       //
+//          http://www.gnu.org/copyleft/gpl.html                         //
+//                                                                       //
+///////////////////////////////////////////////////////////////////////////
+
+function get_tree_json(&$gtree, $element, $totals=false) {
+
+    $return_array = array();
+
+    $object = $element['object'];
+    $eid    = $element['eid'];
+    $object->name = $gtree->get_element_header($element, false, false, false);
+
+    $return_array['item'] = $object;
+
+    if ($element['type'] == 'category') {
+        foreach($element['children'] as $child_el) {
+            if (!empty($child_el['object']->itemtype) && ($child_el['object']->itemtype == 'course' || $child_el['object']->itemtype == 'category') && !$totals) {
+                continue;
+            }
+            $return_array['children'][] = get_tree_json($gtree, $child_el);
+        }
+    }
+
+    return $return_array;
+}
+
+function build_html_tree($tree, $element=null) {
+    global $CFG;
+
+    $options = array(GRADE_AGGREGATE_MEAN            =>get_string('aggregatemean', 'grades'),
+                     GRADE_AGGREGATE_WEIGHTED_MEAN   =>get_string('aggregateweightedmean', 'grades'),
+                     GRADE_AGGREGATE_WEIGHTED_MEAN2  =>get_string('aggregateweightedmean2', 'grades'),
+                     GRADE_AGGREGATE_EXTRACREDIT_MEAN=>get_string('aggregateextracreditmean', 'grades'),
+                     GRADE_AGGREGATE_MEDIAN          =>get_string('aggregatemedian', 'grades'),
+                     GRADE_AGGREGATE_MIN             =>get_string('aggregatemin', 'grades'),
+                     GRADE_AGGREGATE_MAX             =>get_string('aggregatemax', 'grades'),
+                     GRADE_AGGREGATE_MODE            =>get_string('aggregatemode', 'grades'),
+                     GRADE_AGGREGATE_SUM             =>get_string('aggregatesum', 'grades'));
+
+    $html = '';
+    $root = false;
+
+    if (is_null($element)) {
+        $html .= "<ul>\n";
+        $element = $tree;
+        $root = true;
+    }
+
+
+    $id = required_param('id', PARAM_INT);
+
+    if (!empty($element['children'])) { // Grade category
+        $category = grade_category::fetch(array('id' => $element['item']->id));
+        $item = $category->get_grade_item();
+
+        $html .= "<li class=\"category\">\n";
+        $script = "window.location='index.php?id=$id&amp;category={$category->id}&amp;aggregationtype='+this.value";
+        $aggregation_type = choose_from_menu($options, 'aggregation_type_'.$category->id, $category->aggregation, get_string('choose'), $script, 0, true);
+
+        $onlygradedcheck = ($category->aggregateonlygraded == 1) ? 'checked="checked"' : '';
+        $subcatscheck = ($category->aggregatesubcats == 1) ? 'checked="checked"' : '';
+        $outcomescheck = ($category->aggregateoutcomes == 1) ? 'checked="checked"' : '';
+
+        $aggregateonlygraded = '<label for="aggregateonlygraded_'.$category->id.'">'
+                           . '<img src="'.$CFG->pixpath.'/t/nonempty.gif" class="icon caticon" alt="'.get_string('aggregateonlygraded', 'grades').'" '
+                                . 'title="'.get_string('aggregateonlygraded', 'grades').'" /></label>'
+                           . '<input type="checkbox" id="aggregateonlygraded_'.$category->id.'" name="aggregateonlygraded_'.$category->id.'" '
+                                . $onlygradedcheck . ' />';
+
+        $aggregatesubcats = '<label for="aggregatesubcats_'.$category->id.'">'
+                           . '<img src="'.$CFG->pixpath.'/t/sigmaplus.gif" class="icon caticon" alt="'.get_string('aggregatesubcats', 'grades').'" '
+                                . 'title="'.get_string('aggregatesubcats', 'grades').'" /></label>'
+                           . '<input type="checkbox" id="aggregatesubcats_'.$category->id.'" name="aggregatesubcats_'.$category->id.'" '
+                                . $subcatscheck.' />';
+
+        $aggregateoutcomes = '<label for="aggregateoutcomes_'.$category->id.'">'
+                           . '<img src="'.$CFG->pixpath.'/t/outcomes.gif" class="icon caticon" alt="'.get_string('aggregateoutcomes', 'grades').'" '
+                                . 'title="'.get_string('aggregateoutcomes', 'grades').'" /></label>'
+                           . '<input type="checkbox" id="aggregateoutcomes_'.$category->id.'" name="aggregateoutcomes_'.$category->id.'" '
+                                . $outcomescheck.' />';
+
+        $hidden = '<input type="hidden" name="aggregateonlygraded_original_'.$category->id.'" value="'.$category->aggregateonlygraded.'" />';
+        $hidden .= '<input type="hidden" name="aggregatesubcats_original_'.$category->id.'" value="'.$category->aggregatesubcats.'" />';
+        $hidden .= '<input type="hidden" name="aggregateoutcomes_original_'.$category->id.'" value="'.$category->aggregateoutcomes.'" />';
+
+        // Add aggregation coef input if not a course item and if parent category has correct aggregation type
+        $aggcoef_input = get_weight_input($item);
+
+        $html .= '<span class="name">' . $element['item']->name . '</span>'
+              . $aggregation_type . $aggregateonlygraded . $aggregatesubcats . $aggregateoutcomes . $aggcoef_input . $hidden . "<ul>\n";
+
+        foreach ($element['children'] as $child) {
+            $html .= build_html_tree($tree, $child);
+        }
+
+        $html .= "</ul>\n";
+
+    } else { // Dealing with a grade item
+        $html .= "<li>\n";
+
+        $item = grade_item::fetch(array('id' => $element['item']->id));
+        $element['type'] = 'item';
+        $element['object'] = $item;
+
+        $element['item']->name = grade_structure::get_element_icon($element). $element['item']->name;
+
+        if ($cm = get_coursemodule_from_instance($item->itemmodule, $item->iteminstance, $item->courseid)) {
+
+            $dir = $CFG->dirroot.'/mod/'.$item->itemmodule;
+
+            if (file_exists($dir.'/grade.php')) {
+                $url = $CFG->wwwroot.'/mod/'.$item->itemmodule.'/grade.php?id='.$cm->id;
+            } else {
+                $url = $CFG->wwwroot.'/mod/'.$item->itemmodule.'/view.php?id='.$cm->id;
+            }
+
+            $element['item']->name = '<a href="'.$url.'">'.$element['item']->name.'</a>';
+        }
+
+        // Determine aggregation coef element
+        $aggcoef_input = get_weight_input($item);
+        $html .= '<span class="gradeitem">' . "\n$aggcoef_input\n{$element['item']->name} (" . $item->get_formatted_range() . ")</span>\n";
+    }
+
+    $html .= "</li>\n";
+
+    if ($root) {
+        $html .= "</ul>\n";
+    }
+
+    return $html;
+}
+
+function get_weight_input($item) {
+    if ($item->is_course_item()) {
+        return '';
+    }
+
+    $parent_category = $item->get_parent_category();
+
+    if ($item->is_category_item()) {
+        $parent_category = $parent_category->get_parent_category();
+    }
+
+    $parent_category->apply_forced_settings();
+
+    if ($parent_category->is_aggregationcoef_used()) {
+        $aggcoef = '';
+
+        if ($parent_category->aggregation == GRADE_AGGREGATE_WEIGHTED_MEAN) {
+            $aggcoef = 'aggregationcoefweight';
+        } elseif ($parent_category->aggregation == GRADE_AGGREGATE_EXTRACREDIT_MEAN) {
+            $aggcoef = 'aggregationcoefextra';
+        } elseif ($parent_category->aggregation == GRADE_AGGREGATE_SUM) {
+            $aggcoef = 'aggregationcoefextrasum';
+        }
+
+        if ($aggcoef !== '') {
+            return '<label class="weight" for="weight_'.$item->id.'">'.get_string($aggcoef, 'grades').'</label>'
+                           . '<input type="text" size="6" id="weight_'.$item->id.'" name="weight_'.$item->id.'" value="'.$item->aggregationcoef.'" />';
+        } else {
+            return '';
+        }
+    }
+}
+?>
Index: grade/edit/weights/tree.css
===================================================================
RCS file: grade/edit/weights/tree.css
diff -N grade/edit/weights/tree.css
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ grade/edit/weights/tree.css	9 Oct 2008 13:11:02 -0000
@@ -0,0 +1,171 @@
+/* Copyright (c) 2006 Yahoo! Inc. All rights reserved. */
+
+/* first or middle sibling, no children */
+.ygtvtn {
+    background: url(img/tn.gif) 0 0 no-repeat;
+    width:17px;
+    height:22px;
+}
+
+/* first or middle sibling, collapsable */
+.ygtvtm {
+    background: url(img/tm.gif) 0 0 no-repeat;
+    width:34px;
+    height:22px; cursor:pointer
+}
+
+/* first or middle sibling, collapsable, hover */
+.ygtvtmh {
+    background: url(img/tmh.gif) 0 0 no-repeat;
+    width:34px;
+    height:22px;
+    cursor:pointer
+}
+
+/* first or middle sibling, expandable */
+.ygtvtp {
+    background: url(img/tp.gif) 0 0 no-repeat;
+    width:34px;
+    height:22px;
+    cursor:pointer
+}
+
+/* first or middle sibling, expandable, hover */
+.ygtvtph {
+    background: url(img/tph.gif) 0 0 no-repeat;
+    width:34px;
+    height:22px;
+    cursor:pointer
+}
+
+/* last sibling, no children */
+.ygtvln {
+    background: url(img/ln.gif) 0 0 no-repeat;
+    width:17px;
+    height:22px;
+}
+
+/* Last sibling, collapsable */
+.ygtvlm {
+    background: url(img/lm.gif) 0 0 no-repeat;
+
+   width:34px;
+   height:22px;
+   cursor:pointer
+}
+
+/* Last sibling, collapsable, hover */
+.ygtvlmh {
+    background: url(img/lmh.gif) 0 0 no-repeat;
+    width:34px;
+    height:22px;
+    cursor:pointer
+}
+
+/* Last sibling, expandable */
+.ygtvlp {
+    background: url(img/lp.gif) 0 0 no-repeat;
+    width:34px;
+    height:22px;
+    cursor:pointer
+}
+
+/* Last sibling, expandable, hover */
+.ygtvlph {
+    background: url(img/lph.gif) 0 0 no-repeat;
+    width:34px;
+    height:22px;
+    cursor:pointer
+}
+
+/* Loading icon */
+.ygtvloading {
+    background: url(img/loading.gif) 0 0 no-repeat;
+    width:16px;
+    height:22px;
+}
+
+/* the style for the empty cells that are used for rendering the depth
+ * of the node */
+.ygtvdepthcell {
+    background: url(img/vline.gif) 0 0 no-repeat;
+    width:17px;
+    height:22px;
+}
+
+.ygtvblankdepthcell {
+    width:17px;
+    height:22px;
+}
+
+/* the style of the div around each node */
+.ygtvitem { }
+
+.ygtvitem table{
+    margin-bottom:0;
+}
+.ygtvitem td {
+    border:none;padding:0;
+}
+
+
+
+/* the style of the div around each node's collection of children */
+.ygtvchildren { }
+* html .ygtvchildren {
+    height:1%;
+}
+
+/* the style of the text label in ygTextNode */
+.ygtvlabel, .ygtvlabel:link, .ygtvlabel:visited, .ygtvlabel:hover {
+ margin-left:2px;
+ text-decoration: none;
+}
+
+#expandcontractdiv {
+    border:1px dotted #dedede;
+    background-color:#EBE4F2;
+    margin:0 0 .5em 0;
+    padding:0.4em;
+}
+
+#weightstree {
+    background: #fff;
+    padding:1em;
+    margin-top:1em;
+}
+
+span.gradeitem input {
+    margin-right: 10px;
+}
+
+span.gradeitem label,
+li.category label.weight {
+    margin-right: 10px;
+}
+
+li.category label.weight {
+    margin-left: 5px;
+}
+
+li.category span.name {
+    font-weight: bold;
+}
+
+img.caticon {
+    width: 11px;
+    height: 11px;
+    margin: 0px -1px 3px 5px;
+}
+
+#gradetree select {
+    margin-left: 10px;
+}
+
+li.category {
+    margin-top: 10px;
+}
+
+li.category ul {
+    margin-top: 10px;
+}
Index: grade/report/grader/lib.php
===================================================================
RCS file: /cvsroot/moodle/moodle/grade/report/grader/lib.php,v
retrieving revision 1.98.2.46
diff -u -r1.98.2.46 lib.php
--- grade/report/grader/lib.php	9 Sep 2008 02:49:01 -0000	1.98.2.46
+++ grade/report/grader/lib.php	9 Oct 2008 13:11:03 -0000
@@ -1073,40 +1073,14 @@
             foreach ($this->gtree->items as $itemid=>$unused) {
                 $item =& $this->gtree->items[$itemid];

-                // Determine which display type to use for this average
-                if ($USER->gradeediting[$this->courseid]) {
-                    $displaytype = GRADE_DISPLAY_TYPE_REAL;
-
-                } else if ($rangesdisplaytype == GRADE_REPORT_PREFERENCE_INHERIT) { // no ==0 here, please resave report and user prefs
-                    $displaytype = $item->get_displaytype();
-
-                } else {
-                    $displaytype = $rangesdisplaytype;
-                }
-
-                // Override grade_item setting if a display preference (not default) was set for the averages
-                if ($rangesdecimalpoints == GRADE_REPORT_PREFERENCE_INHERIT) {
-                    $decimalpoints = $item->get_decimals();
-
-                } else {
-                    $decimalpoints = $rangesdecimalpoints;
-                }
-
-                if ($displaytype == GRADE_DISPLAY_TYPE_PERCENTAGE) {
-                    $grademin = "0 %";
-                    $grademax = "100 %";
-
-                } else {
-                    $grademin = grade_format_gradevalue($item->grademin, $item, true, $displaytype, $decimalpoints);
-                    $grademax = grade_format_gradevalue($item->grademax, $item, true, $displaytype, $decimalpoints);
-                }
-
                 $hidden = '';
                 if ($item->is_hidden()) {
                     $hidden = ' hidden ';
                 }

-                $scalehtml .= '<th class="header c'.$columncount++.' range"><span class="rangevalues'.$hidden.'">'. $grademin.'&ndash;'. $grademax.'</span></th>';
+                $formatted_range = $item->get_formatted_range($rangesdisplaytype, $rangesdecimalpoints);
+
+                $scalehtml .= '<th class="header c'.$columncount++.' range"><span class="rangevalues'.$hidden.'">'. $formatted_range .'</span></th>';
             }
             $scalehtml .= '</tr>';
         }
Index: lang/en_utf8/grades.php
===================================================================
RCS file: /cvsroot/moodle/moodle/lang/en_utf8/grades.php,v
retrieving revision 1.111.2.56
diff -u -r1.111.2.56 grades.php
--- lang/en_utf8/grades.php	8 Oct 2008 10:56:10 -0000	1.111.2.56
+++ lang/en_utf8/grades.php	9 Oct 2008 13:11:11 -0000
@@ -157,6 +157,11 @@
 $string['errornocategorisedid'] = 'Could not get an uncategorised id!';
 $string['errornocourse'] = 'Could not get course information';
 $string['errorreprintheadersnonnumeric'] = 'Received non-numeric value for reprint-headers';
+$string['errorupdatinggradecategoryaggregateonlygraded'] = 'Error updating the \"Aggregate only graded items\" setting of of grade category ID $a->id';
+$string['errorupdatinggradecategoryaggregateoutcomes'] = 'Error updating the \"Aggregate outcomes\" setting of of grade category ID $a->id';
+$string['errorupdatinggradecategoryaggregatesubcats'] = 'Error updating the \"Aggregate sub-categories\" setting of of grade category ID $a->id';
+$string['errorupdatinggradecategoryaggregation'] = 'Error updating the aggregation type of grade category ID $a->id';
+$string['errorupdatinggradeitemaggregationcoef'] = 'Error updating the aggregation coefficient (weight or extra credit) of grade item ID $a->id';
 $string['exceptions'] = 'Exceptions';
 $string['excluded'] = 'Excluded';
 $string['excludedhelp'] = 'If -excluded- is switched on, this grade will be excluded from any aggregation performed by any parent grade item or category.';
@@ -517,6 +522,7 @@
 $string['weighteddescending'] = 'Sort by weighted percent descending';
 $string['weightedpct'] = 'weighted %%';
 $string['weightedpctcontribution'] = 'weighted %% contribution';
+$string['weights'] = 'Weights';
 $string['writinggradebookinfo'] = 'Writing gradebook settings';
 $string['xml'] = 'XML';
 $string['yes'] = 'Yes';
Index: lib/grade/grade_item.php
===================================================================
RCS file: /cvsroot/moodle/moodle/lib/grade/grade_item.php,v
retrieving revision 1.130.2.26
diff -u -r1.130.2.26 grade_item.php
--- lib/grade/grade_item.php	27 Mar 2008 17:13:01 -0000	1.130.2.26
+++ lib/grade/grade_item.php	9 Oct 2008 13:11:31 -0000
@@ -1866,5 +1866,40 @@
             return $this->decimals;
         }
     }
+
+    function get_formatted_range($rangesdisplaytype=null, $rangesdecimalpoints=null) {
+
+        global $USER;
+
+        // Determine which display type to use for this average
+        if ($USER->gradeediting[$this->courseid]) {
+            $displaytype = GRADE_DISPLAY_TYPE_REAL;
+
+        } else if ($rangesdisplaytype == GRADE_REPORT_PREFERENCE_INHERIT) { // no ==0 here, please resave report and user prefs
+            $displaytype = $this->get_displaytype();
+
+        } else {
+            $displaytype = $rangesdisplaytype;
+        }
+
+        // Override grade_item setting if a display preference (not default) was set for the averages
+        if ($rangesdecimalpoints == GRADE_REPORT_PREFERENCE_INHERIT) {
+            $decimalpoints = $this->get_decimals();
+
+        } else {
+            $decimalpoints = $rangesdecimalpoints;
+        }
+
+        if ($displaytype == GRADE_DISPLAY_TYPE_PERCENTAGE) {
+            $grademin = "0 %";
+            $grademax = "100 %";
+
+        } else {
+            $grademin = grade_format_gradevalue($this->grademin, $this, true, $displaytype, $decimalpoints);
+            $grademax = grade_format_gradevalue($this->grademax, $this, true, $displaytype, $decimalpoints);
+        }
+
+        return $grademin.'&ndash;'. $grademax;
+    }
 }
 ?>
