Index: grade/report/grader/lib.php
=========================================================
--- grade/report/grader/lib.php	(revision 1.98.2.54)
+++ grade/report/grader/lib.php	Mon May 04 14:11:42 CEST 2009
@@ -87,6 +87,8 @@
 
     var $preferences_page=false;
 
+    var $categories_with_hidden_grades = array();
+
     /**
      * Constructor. Sets local copies of user preferences and initialises grade_tree.
      * @param int $courseid
@@ -101,8 +103,8 @@
 
         $this->canviewhidden = has_capability('moodle/grade:viewhidden', get_context_instance(CONTEXT_COURSE, $this->course->id));
 
-        // load collapsed settings for this report
-        if ($collapsed = get_user_preferences('grade_report_grader_collapsed_categories')) {
+        // load collapsed settings for this report unless user cannot view hidden items
+        if ($this->canviewhidden && ($collapsed = get_user_preferences('grade_report_grader_collapsed_categories'))) {
             $this->collapsed = unserialize($collapsed);
         } else {
             $this->collapsed = array('aggregatesonly' => array(), 'gradesonly' => array());
@@ -1039,7 +1041,7 @@
             $straverage = get_string('overallaverage', 'grades');
             $showaverages = $this->get_pref('showaverages');
             $showaverages_group = $this->currentgroup && $showaverages;
-            
+
             if ($showaverages_group) {
                 $studentshtml .= '<tr class="groupavg r'.$this->rowcount++.'"><th class="header c0" '.$colspan.'scope="row">'.$straverage_group.'</th></tr>';
             }
@@ -1086,12 +1088,6 @@
     function get_avghtml($grouponly=false) {
         global $CFG, $USER;
 
-        if (!$this->canviewhidden) {
-            // totals might be affected by hiding, if user can not see hidden grades the aggregations might be altered
-            // better not show them at all if user can not see all hideen grades
-            return;
-        }
-
         $averagesdisplaytype   = $this->get_pref('averagesdisplaytype');
         $averagesdecimalpoints = $this->get_pref('averagesdecimalpoints');
         $meanselection         = $this->get_pref('meanselection');
@@ -1217,7 +1213,21 @@
                     $decimalpoints = $averagesdecimalpoints;
                 }
 
-                if (!isset($sum_array[$item->id]) || $mean_count == 0) {
+                $hide_category_average = false;
+
+                $item_has_hidden_grades = $item->is_hidden() || $item->has_hidden_grades($this->groupsql, $this->groupwheresql) || $item->is_calculated();
+
+                $parent_category = $item->load_parent_category();
+                if ($item_has_hidden_grades) {
+                    $this->categories_with_hidden_grades[] = $parent_category->id;
+                }
+
+                if (($item->itemtype == 'course' || $item->itemtype == 'category') && in_array($parent_category->id, $this->categories_with_hidden_grades)) {
+                    $hide_category_average = true;
+                }
+
+                if ((!$this->canviewhidden && ($hide_category_average || $item_has_hidden_grades))
+                    || !isset($sum_array[$item->id]) || $mean_count == 0) {
                     $avghtml .= '<td class="cell c' . $columncount++.'">-</td>';
                 } else {
                     $sum = $sum_array[$item->id];
@@ -1373,7 +1383,7 @@
 
         $contract_expand_icon = '';
         // If object is a category, display expand/contract icon
-        if ($element['type'] == 'category') {
+        if ($element['type'] == 'category' && $this->canviewhidden) { // Users who can't see hidden items shouldn't collapse columns, it complicates things too much :)
             // Load language strings
             $strswitch_minus = $this->get_lang_string('aggregatesonly', 'grades');
             $strswitch_plus  = $this->get_lang_string('gradesonly', 'grades');
