]> git.mjollnir.org Git - moodle.git/commitdiff
MDL-18083 (including MDL-15680, MDL-17829, MDL-17807, MDL-18004, MDL-12631, MDL-16913)
authornicolasconnault <nicolasconnault>
Mon, 9 Feb 2009 10:49:41 +0000 (10:49 +0000)
committernicolasconnault <nicolasconnault>
Mon, 9 Feb 2009 10:49:41 +0000 (10:49 +0000)
36 files changed:
grade/edit/letter/edit.php
grade/edit/letter/index.php
grade/edit/outcome/course.php
grade/edit/outcome/edit.php
grade/edit/outcome/index.php
grade/edit/scale/edit.php
grade/edit/scale/edit_form.php
grade/edit/scale/index.php
grade/edit/tree/category.php
grade/edit/tree/category_form.php
grade/edit/tree/functions.js [new file with mode: 0755]
grade/edit/tree/index.php
grade/edit/tree/item.php
grade/edit/tree/lib.php [new file with mode: 0755]
grade/edit/tree/outcomeitem.php
grade/edit/tree/tree.css [new file with mode: 0755]
grade/export/ods/index.php
grade/export/txt/index.php
grade/export/xls/index.php
grade/export/xml/index.php
grade/import/csv/index.php
grade/import/xml/index.php
grade/lib.php
grade/report/grader/index.php
grade/report/grader/lib.php
grade/report/grader/preferences.php
grade/report/grader/styles.php
grade/report/grader/styles_ie.css [new file with mode: 0755]
grade/report/grader/styles_ie6.css [new file with mode: 0755]
grade/report/grader/styles_lsu.php [new file with mode: 0755]
grade/report/lib.php
grade/report/outcomes/index.php
grade/report/overview/index.php
grade/report/user/index.php
lang/en_utf8/gradereport_grader.php
lang/en_utf8/grades.php

index 5f9eac8e5992059277bde6306e63ea28f3951983..4636c0871e3d58fc2e096401cf296881550ff78b 100644 (file)
@@ -133,12 +133,7 @@ if ($admin) {
     admin_externalpage_print_header();
 
 } else {
-    $navigation = grade_build_nav(__FILE__, $pagename, $COURSE->id);
-    /// Print header
-    print_header_simple($strgrades.': '.$pagename, ': '.$strgrades, $navigation, '', '', true, '', navmenu($COURSE));
-
-    $currenttab = 'lettersedit';
-    require('tabs.php');
+    print_grade_page_head($COURSE->id, 'letter', 'edit', get_string('editgradeletters', 'grades'));
 }
 
 $mform->display();
index b4a5d060a0ad4d3c5d9e0f7c3b440e8bfdb86276..0a191600ad5e090929bf1ad2e8eddc3c8d82cbd2 100644 (file)
@@ -45,15 +45,7 @@ $gpr = new grade_plugin_return(array('type'=>'edit', 'plugin'=>'letter', 'course
 $strgrades = get_string('grades');
 $pagename  = get_string('letters', 'grades');
 
-$navigation = grade_build_nav(__FILE__, $pagename, $courseid);
-
-/// Print header
-print_header_simple($strgrades.': '.$pagename, ': '.$strgrades, $navigation, '', '', true, '', navmenu($course));
-/// Print the plugin selector at the top
-print_grade_plugin_selector($courseid, 'edit', 'letter');
-
-$currenttab = 'lettersview';
-require('tabs.php');
+print_grade_page_head($courseid, 'letter', 'view', get_string('gradeletters', 'grades'));
 
 $letters = grade_get_letters($context);
 
index e0870f3504db1b2ed8a09e9b7b27b839b740700e..7b1529c45747aba2b88b1e5df8a317dbe3c975ed 100644 (file)
@@ -133,26 +133,8 @@ if ($data = data_submitted()) {
     redirect('course.php?id='.$courseid); // we must redirect to get fresh data
 }
 
-$strgrades = get_string('grades');
-$pagename  = get_string('outcomescourse', 'grades');
-
-$navlinks = array(array('name'=>$strgrades,
-                        'link'=>$CFG->wwwroot.'/grade/index.php?id='.$courseid,
-                        'type'=>'misc'),
-                  array('name'=>$pagename,
-                        'link'=>'',
-                        'type'=>'misc')
-                 );
-$navigation = build_navigation($navlinks);
-$navigation = grade_build_nav(__FILE__, $pagename, $courseid);
 /// Print header
-print_header_simple($strgrades.': '.$pagename, ': '.$strgrades, $navigation, '', '', true, '', navmenu($course));
-
-/// Print the plugin selector at the top
-print_grade_plugin_selector($courseid, 'edit', 'outcome');
-
-$currenttab = 'courseoutcomes';
-require('tabs.php');
+print_grade_page_head($COURSE->id, 'outcome', 'course');
 
 check_theme_arrows();
 require('course_form.html');
index d13e23f0e4bf34fb5b3b5a1585ad11a95387baac..766e7003ee3c925f612bffee019e06eb6c2118d0 100644 (file)
@@ -32,9 +32,12 @@ $courseid = optional_param('courseid', 0, PARAM_INT);
 $id       = optional_param('id', 0, PARAM_INT);
 
 $systemcontext = get_context_instance(CONTEXT_SYSTEM);
+$heading = null;
 
 // a bit complex access control :-O
 if ($id) {
+    $heading = get_string('editoutcome', 'grades');
+
     /// editing existing outcome
     if (!$outcome_rec = $DB->get_record('grade_outcomes', array('id' => $id))) {
         print_error('invalidoutcome');
@@ -61,6 +64,7 @@ if ($id) {
     }
 
 } else if ($courseid){
+    $heading = get_string('addoutcome', 'grades');
     /// adding new outcome from course
     if (!$course = $DB->get_record('course', array('id' => $courseid))) {
         print_error('nocourseid');
@@ -119,14 +123,8 @@ if ($mform->is_cancelled()) {
     redirect($returnurl);
 }
 
-$strgrades       = get_string('grades');
-$strgraderreport = get_string('graderreport', 'grades');
-$stroutcomeedit  = get_string('outcome', 'grades');
-
 if ($courseid) {
-    $navigation = grade_build_nav(__FILE__, $stroutcomeedit, array('courseid' => $courseid));
-    print_header_simple($strgrades.': '.$strgraderreport, ': '.$stroutcomeedit, $navigation, '', '', true, '', navmenu($course));
-
+    print_grade_page_head($courseid, 'outcome', 'edit', $heading);
 } else {
     require_once $CFG->libdir.'/adminlib.php';
     admin_externalpage_setup('outcomes');
index b24c14c46d82f02fd68df305a82e70537db163ac..510cad49c110b7d80d5813dfafc25d6ceedad3bc 100644 (file)
@@ -122,16 +122,9 @@ $systemcontext = get_context_instance(CONTEXT_SYSTEM);
 $caneditsystemscales = has_capability('moodle/course:managescales', $systemcontext);
 
 if ($courseid) {
-    /// Print header
-    print_header_simple($strgrades.': '.$pagename, ': '.$strgrades, $navigation, '', '', true, '', navmenu($course));
-    /// Print the plugin selector at the top
-    print_grade_plugin_selector($courseid, 'edit', 'outcome');
 
     $caneditcoursescales = has_capability('moodle/course:managescales', $context);
 
-    $currenttab = 'outcomes';
-    require('tabs.php');
-
 } else {
     admin_externalpage_print_header();
     $caneditcoursescales = $caneditsystemscales;
@@ -139,10 +132,10 @@ if ($courseid) {
 
 
 $outcomes_tables = array();
+$heading = get_string('outcomes', 'grades');
 
 if ($courseid and $outcomes = grade_outcome::fetch_all_local($courseid)) {
-
-    $return = print_heading($strcustomoutcomes, '', 2, 'main', true);
+    $return = print_heading($strcustomoutcomes, '', 3, 'main', true);
     $data = array();
     foreach($outcomes as $outcome) {
         $line = array();
@@ -195,8 +188,7 @@ if ($courseid and $outcomes = grade_outcome::fetch_all_local($courseid)) {
 
 
 if ($outcomes = grade_outcome::fetch_all_global()) {
-
-    $return = print_heading($strstandardoutcome, '', 2, 'main', true);
+    $return = print_heading($strstandardoutcome, '', 3, 'main', true);
     $data = array();
     foreach($outcomes as $outcome) {
         $line = array();
@@ -250,6 +242,11 @@ if ($outcomes = grade_outcome::fetch_all_global()) {
     $outcomes_tables[] = $return;
 }
 
+if ($courseid) {
+    /// Print header
+    print_grade_page_head($courseid, 'outcome', 'edit', $heading);
+}
+
 foreach($outcomes_tables as $table) {
     print($table);
 }
index dc0517193597ffc1f35de288cacc33c37617093e..b50b1d153bd1776ce24b66ca2d65a7d34385fe75 100644 (file)
@@ -32,9 +32,12 @@ $courseid = optional_param('courseid', 0, PARAM_INT);
 $id       = optional_param('id', 0, PARAM_INT);
 
 $systemcontext = get_context_instance(CONTEXT_SYSTEM);
+$heading = '';
 
 // a bit complex access control :-O
 if ($id) {
+    $heading = get_string('editscale', 'grades');
+
     /// editing existing scale
     if (!$scale_rec = $DB->get_record('scale', array('id' => $id))) {
         print_error('invalidscaleid');
@@ -61,6 +64,7 @@ if ($id) {
     }
 
 } else if ($courseid){
+    $heading = get_string('addscale', 'grades');
     /// adding new scale from course
     if (!$course = $DB->get_record('course', array('id' => $courseid))) {
         print_error('nocourseid');
@@ -112,21 +116,15 @@ if ($mform->is_cancelled()) {
         }
         $scale->update();
     }
-
     redirect($returnurl);
 }
 
-$strgrades       = get_string('grades');
-$strgraderreport = get_string('graderreport', 'grades');
-$strscaleedit    = get_string('scale');
-
 if ($courseid) {
-    $navigation = grade_build_nav(__FILE__, $strscaleedit, $courseid);
-    print_header_simple($strgrades.': '.$strgraderreport, ': '.$strscaleedit, $navigation, '', '', true, '', navmenu($course));
+    print_grade_page_head($course->id, 'scale', 'edit', $heading);
 
 } else {
     require_once $CFG->libdir.'/adminlib.php';
-    admin_externalpage_setup('outcomes');
+    admin_externalpage_setup('scales');
     admin_externalpage_print_header();
 }
 
index a54b81682fae59368319b703fad993f42d0e6c32..b3539933266b5523217c7d97e649ca0dec74b00f 100644 (file)
@@ -141,13 +141,9 @@ class edit_scale_form extends moodleform {
                 }
             }
 
-            if (empty($data['scale'])) {
-                $errors['scale'] = get_string('error');
-            } else {
-                $options = explode(',', $data['scale']);
-                if (count($options) < 1) {   // single-item scales are allowed, see MDL-16474
-                    $errors['scale'] = get_string('error');
-                }
+            $options = explode(',', $data['scale']);
+            if (count($options) < 2) {
+                $errors['scale'] = get_string('badlyformattedscale', 'grades');
             }
         }
 
index da240fd4c0610612f1718bb0e6560598a20afcb0..b2be6a6a93e45c6a0b7c135a8ea0e13ab077597c 100644 (file)
@@ -47,12 +47,6 @@ if ($courseid) {
 /// return tracking object
 $gpr = new grade_plugin_return(array('type'=>'edit', 'plugin'=>'scale', 'courseid'=>$courseid));
 
-
-$strgrades = get_string('grades');
-$pagename  = get_string('scales');
-
-$navigation = grade_build_nav(__FILE__, $pagename, array('courseid' => $courseid));
-
 $strscale          = get_string('scale');
 $strstandardscale  = get_string('scalesstandard');
 $strcustomscales   = get_string('scalescustom');
@@ -88,18 +82,17 @@ switch ($action) {
         break;
 }
 
-if ($courseid) {
-    /// Print header
-    print_header_simple($strgrades.': '.$pagename, ': '.$strgrades, $navigation, '', '', true, '', navmenu($course));
-    /// Print the plugin selector at the top
-    print_grade_plugin_selector($courseid, 'edit', 'scale');
-
-} else {
+if (!$courseid) {
     admin_externalpage_print_header();
 }
 
+$table = null;
+$table2 = null;
+$heading = '';
+
 if ($courseid and $scales = grade_scale::fetch_all_local($courseid)) {
-    print_heading($strcustomscales);
+    $heading = $strcustomscales;
+
     $data = array();
     foreach($scales as $scale) {
         $line = array();
@@ -123,11 +116,11 @@ if ($courseid and $scales = grade_scale::fetch_all_local($courseid)) {
     $table->align = array('left', 'center', 'center');
     $table->width = '90%';
     $table->data  = $data;
-    print_table($table);
 }
 
 if ($scales = grade_scale::fetch_all_global()) {
-    print_heading($strstandardscale);
+    $heading = $strstandardscale;
+
     $data = array();
     foreach($scales as $scale) {
         $line = array();
@@ -148,14 +141,22 @@ if ($scales = grade_scale::fetch_all_global()) {
         $line[] = $buttons;
         $data[] = $line;
     }
-    $table->head  = array($strscale, $strused, $stredit);
-    $table->size  = array('70%', '20%', '10%');
-    $table->align = array('left', 'center', 'center');
-    $table->width = '90%';
-    $table->data  = $data;
-    print_table($table);
+    $table2->head  = array($strscale, $strused, $stredit);
+    $table2->size  = array('70%', '20%', '10%');
+    $table2->align = array('left', 'center', 'center');
+    $table2->width = '90%';
+    $table2->data  = $data;
+}
+
+
+if ($courseid) {
+    print_grade_page_head($courseid, 'scale', null, get_string('coursescales', 'grades'));
 }
 
+print_heading($strcustomscales, '', 3, 'main');
+print_table($table);
+print_heading($strstandardscale, '', 3, 'main');
+print_table($table2);
 echo '<div class="buttons">';
 print_single_button('edit.php', array('courseid'=>$courseid), $srtcreatenewscale);
 echo '</div>';
index a0c77e3c4814c123dc5f79fb7ec34f7f1e1a2a4d..ea84d584b3b0db611bfdcef488dffabbac30263c 100644 (file)
@@ -29,7 +29,8 @@ require_once $CFG->dirroot.'/grade/report/lib.php';
 require_once 'category_form.php';
 
 $courseid = required_param('courseid', PARAM_INT);
-$id       = optional_param('id', 0, PARAM_INT);
+$id       = optional_param('id', 0, PARAM_INT); // grade_category->id
+$grade_item_id       = optional_param('grade_item_id', 0, PARAM_INT); // grade_item->id
 
 if (!$course = $DB->get_record('course', array('id' => $courseid))) {
     print_error('nocourseid');
@@ -45,6 +46,7 @@ $returnurl = $gpr->get_return_url('index.php?id='.$course->id);
 
 
 $mform = new edit_category_form(null, array('gpr'=>$gpr));
+$heading = get_string('categoryedit', 'grades');
 
 if ($id) {
     if (!$grade_category = grade_category::fetch(array('id'=>$id, 'courseid'=>$course->id))) {
@@ -54,19 +56,20 @@ if ($id) {
     $category = $grade_category->get_record_data();
     // Get Category preferences
     $category->pref_aggregationview = grade_report::get_pref('aggregationview', $id);
-    // Load agg coef
-    $grade_item = $grade_category->load_grade_item();
-    $category->aggregationcoef = format_float($grade_item->aggregationcoef, 4);
     // set parent
     $category->parentcategory = $grade_category->parent;
+    $grade_item = $grade_category->load_grade_item();
+    foreach ($grade_item as $key => $value) {
+        $category->{"grade_item_$key"} = $value;
+    }
 
 } else {
+    $heading = get_string('newcategory', 'grades');
     $grade_category = new grade_category(array('courseid'=>$courseid), false);
     $grade_category->apply_default_settings();
     $grade_category->apply_forced_settings();
 
     $category = $grade_category->get_record_data();
-    $category->aggregationcoef = format_float(0, 4);
 }
 
 $mform->set_data($category);
@@ -74,7 +77,7 @@ $mform->set_data($category);
 if ($mform->is_cancelled()) {
     redirect($returnurl);
 
-} else if ($data = $mform->get_data()) {
+} else if ($data = $mform->get_data(false)) {
     // If no fullname is entered for a course category, put ? in the DB
     if (!isset($data->fullname) || $data->fullname == '') {
         $data->fullname = '?';
@@ -88,6 +91,7 @@ if ($mform->is_cancelled()) {
     }
     grade_category::set_properties($grade_category, $data);
 
+    /// CATEGORY
     if (empty($grade_category->id)) {
         $grade_category->insert();
 
@@ -95,6 +99,80 @@ if ($mform->is_cancelled()) {
         $grade_category->update();
     }
 
+    /// GRADE ITEM
+    // grade item data saved with prefix "grade_item_"
+    $itemdata = new stdClass();
+    foreach ($data as $k => $v) {
+        if (preg_match('/grade_item_(.*)/', $k, $matches)) {
+            $itemdata->{$matches[1]} = $v;
+        }
+    }
+
+    if (!isset($itemdata->aggregationcoef)) {
+        $itemdata->aggregationcoef = 0;
+    }
+
+    $hidden      = empty($itemdata->hidden) ? 0: $itemdata->hidden;
+    $hiddenuntil = empty($itemdata->hiddenuntil) ? 0: $itemdata->hiddenuntil;
+    unset($itemdata->hidden);
+    unset($itemdata->hiddenuntil);
+
+    $locked   = empty($itemdata->locked) ? 0: $itemdata->locked;
+    $locktime = empty($itemdata->locktime) ? 0: $itemdata->locktime;
+    unset($itemdata->locked);
+    unset($itemdata->locktime);
+
+    $convert = array('grademax', 'grademin', 'gradepass', 'multfactor', 'plusfactor', 'aggregationcoef');
+    foreach ($convert as $param) {
+        if (array_key_exists($param, $itemdata)) {
+            $itemdata->$param = unformat_float($itemdata->$param);
+        }
+    }
+
+    // When creating a new category, a number of grade item fields are filled out automatically, and are required.
+    // If the user leaves these fields empty during creation of a category, we let the default values take effect
+    // Otherwise, we let the user-entered grade item values take effect
+    $grade_item = $grade_category->load_grade_item();
+    $grade_item_id = $grade_item->id;
+    $grade_item_copy = fullclone($grade_item);
+    grade_item::set_properties($grade_item, $itemdata);
+
+    if (empty($grade_item->id)) {
+        $grade_item->id = $grade_item_copy->id;
+    }
+    if (empty($grade_item->grademax)) {
+        $grade_item->grademax = $grade_item_copy->grademax;
+    }
+    if (empty($grade_item->grademin)) {
+        $grade_item->grademin = $grade_item_copy->grademin;
+    }
+    if (empty($grade_item->gradepass)) {
+        $grade_item->gradepass = $grade_item_copy->gradepass;
+    }
+    if (empty($grade_item->aggregationcoef)) {
+        $grade_item->aggregationcoef = $grade_item_copy->aggregationcoef;
+    }
+
+    $grade_item->outcomeid = null;
+
+    // update hiding flag
+    if ($hiddenuntil) {
+        $grade_item->set_hidden($hiddenuntil, false);
+    } else {
+        $grade_item->set_hidden($hidden, false);
+    }
+
+    $grade_item->set_locktime($locktime); // locktime first - it might be removed when unlocking
+    $grade_item->set_locked($locked, false, true);
+
+
+    // Handle null decimals value
+    if (!array_key_exists('decimals', $itemdata) or $itemdata->decimals < 0) {
+        $grade_item->decimals = null;
+    }
+
+    $grade_item->update(); // We don't need to insert it, it's already created when the category is created
+
     // Handle user preferences
     if (isset($data->pref_aggregationview)) {
         if (!grade_report::set_pref('aggregationview', $data->pref_aggregationview, $grade_category->id)) {
@@ -119,14 +197,7 @@ if ($mform->is_cancelled()) {
 }
 
 
-$strgrades         = get_string('grades');
-$strgraderreport   = get_string('graderreport', 'grades');
-$strcategoriesedit = get_string('categoryedit', 'grades');
-$strcategory       = get_string('category', 'grades');
-
-$navigation = grade_build_nav(__FILE__, $strcategory, array('courseid' => $courseid));
-
-print_header_simple($strgrades . ': ' . $strgraderreport, ': ' . $strcategoriesedit, $navigation, '', '', true, '', navmenu($course));
+print_grade_page_head($courseid, 'edittree', null, $heading);
 
 $mform->display();
 
index 32c72a66288197b167abf3e2d4abbe04b335eb5f..2ad053a89ad1aebb5b9e2ff481c8c49355cfb7e3 100644 (file)
 require_once $CFG->libdir.'/formslib.php';
 
 class edit_category_form extends moodleform {
+    private $aggregation_options = array();
 
     function definition() {
-        global $CFG, $COURSE;
+        global $CFG, $COURSE, $DB;
         $mform =& $this->_form;
 
-        $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'));
+        $this->aggregation_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'));
 
         // visible elements
         $mform->addElement('header', 'headercategory', get_string('gradecategory', 'grades'));
         $mform->addElement('text', 'fullname', get_string('categoryname', 'grades'));
         $mform->addRule('fullname', null, 'required', null, 'client');
 
-        $mform->addElement('select', 'aggregation', get_string('aggregation', 'grades'), $options);
+        $mform->addElement('select', 'aggregation', get_string('aggregation', 'grades'), $this->aggregation_options);
         $mform->setHelpButton('aggregation', array('aggregation', get_string('aggregation', 'grades'), 'grade'));
         if ((int)$CFG->grade_aggregation_flag & 2) {
             $mform->setAdvanced('aggregation');
@@ -97,6 +98,115 @@ class edit_category_form extends moodleform {
         $mform->disabledIf('keephigh', 'droplow', 'noteq', 0);
         $mform->disabledIf('droplow', 'keephigh', 'noteq', 0);
 
+        // Grade item settings
+        $mform->addElement('header', 'general', get_string('gradeitem', 'grades'));
+
+        $mform->addElement('text', 'grade_item_itemname', get_string('itemname', 'grades'));
+        $mform->addElement('text', 'grade_item_iteminfo', get_string('iteminfo', 'grades'));
+        $mform->setHelpButton('grade_item_iteminfo', array('iteminfo', get_string('iteminfo', 'grades'), 'grade'), true);
+
+        $mform->addElement('text', 'grade_item_idnumber', get_string('idnumbermod'));
+        $mform->setHelpButton('grade_item_idnumber', array('idnumber', get_string('idnumber', 'grades'), 'grade'), true);
+
+        $options = array(GRADE_TYPE_NONE=>get_string('typenone', 'grades'),
+                         GRADE_TYPE_VALUE=>get_string('typevalue', 'grades'),
+                         GRADE_TYPE_SCALE=>get_string('typescale', 'grades'),
+                         GRADE_TYPE_TEXT=>get_string('typetext', 'grades'));
+
+        $mform->addElement('select', 'grade_item_gradetype', get_string('gradetype', 'grades'), $options);
+        $mform->setHelpButton('grade_item_gradetype', array('gradetype', get_string('gradetype', 'grades'), 'grade'), true);
+        $mform->setDefault('grade_item_gradetype', GRADE_TYPE_VALUE);
+
+        //$mform->addElement('text', 'calculation', get_string('calculation', 'grades'));
+        //$mform->disabledIf('calculation', 'gradetype', 'eq', GRADE_TYPE_TEXT);
+        //$mform->disabledIf('calculation', 'gradetype', 'eq', GRADE_TYPE_NONE);
+
+        $options = array(0=>get_string('usenoscale', 'grades'));
+        if ($scales = $DB->get_records('scale')) {
+            foreach ($scales as $scale) {
+                $options[$scale->id] = format_string($scale->name);
+            }
+        }
+        $mform->addElement('select', 'grade_item_scaleid', get_string('scale'), $options);
+        $mform->setHelpButton('grade_item_scaleid', array('scaleid', get_string('scaleid', 'grades'), 'grade'), true);
+        $mform->disabledIf('grade_item_scaleid', 'grade_item_gradetype', 'noteq', GRADE_TYPE_SCALE);
+
+        $mform->addElement('text', 'grade_item_grademax', get_string('grademax', 'grades'));
+        $mform->setHelpButton('grade_item_grademax', array('grademax', get_string('grademax', 'grades'), 'grade'), true);
+        $mform->disabledIf('grade_item_grademax', 'grade_item_gradetype', 'noteq', GRADE_TYPE_VALUE);
+
+        $mform->addElement('text', 'grade_item_grademin', get_string('grademin', 'grades'));
+        $mform->setHelpButton('grade_item_grademin', array('grademin', get_string('grademin', 'grades'), 'grade'), true);
+        $mform->disabledIf('grade_item_grademin', 'grade_item_gradetype', 'noteq', GRADE_TYPE_VALUE);
+
+        $mform->addElement('text', 'grade_item_gradepass', get_string('gradepass', 'grades'));
+        $mform->setHelpButton('grade_item_gradepass', array('gradepass', get_string('gradepass', 'grades'), 'grade'), true);
+        $mform->disabledIf('grade_item_gradepass', 'grade_item_gradetype', 'eq', GRADE_TYPE_NONE);
+        $mform->disabledIf('grade_item_gradepass', 'grade_item_gradetype', 'eq', GRADE_TYPE_TEXT);
+
+        $mform->addElement('text', 'grade_item_multfactor', get_string('multfactor', 'grades'));
+        $mform->setHelpButton('grade_item_multfactor', array('multfactor', get_string('multfactor', 'grades'), 'grade'), true);
+        $mform->setAdvanced('grade_item_multfactor');
+        $mform->disabledIf('grade_item_multfactor', 'grade_item_gradetype', 'eq', GRADE_TYPE_NONE);
+        $mform->disabledIf('grade_item_multfactor', 'grade_item_gradetype', 'eq', GRADE_TYPE_TEXT);
+
+        $mform->addElement('text', 'grade_item_plusfactor', get_string('plusfactor', 'grades'));
+        $mform->setHelpButton('grade_item_plusfactor', array('plusfactor', get_string('plusfactor', 'grades'), 'grade'), true);
+        $mform->setAdvanced('grade_item_plusfactor');
+        $mform->disabledIf('grade_item_plusfactor', 'grade_item_gradetype', 'eq', GRADE_TYPE_NONE);
+        $mform->disabledIf('grade_item_plusfactor', 'grade_item_gradetype', 'eq', GRADE_TYPE_TEXT);
+
+        /// grade display prefs
+        $default_gradedisplaytype = grade_get_setting($COURSE->id, 'displaytype', $CFG->grade_displaytype);
+        $options = array(GRADE_DISPLAY_TYPE_DEFAULT            => get_string('default', 'grades'),
+                         GRADE_DISPLAY_TYPE_REAL               => get_string('real', 'grades'),
+                         GRADE_DISPLAY_TYPE_PERCENTAGE         => get_string('percentage', 'grades'),
+                         GRADE_DISPLAY_TYPE_LETTER             => get_string('letter', 'grades'),
+                         GRADE_DISPLAY_TYPE_REAL_PERCENTAGE    => get_string('realpercentage', 'grades'),
+                         GRADE_DISPLAY_TYPE_REAL_LETTER        => get_string('realletter', 'grades'),
+                         GRADE_DISPLAY_TYPE_LETTER_REAL        => get_string('letterreal', 'grades'),
+                         GRADE_DISPLAY_TYPE_LETTER_PERCENTAGE  => get_string('letterpercentage', 'grades'),
+                         GRADE_DISPLAY_TYPE_PERCENTAGE_LETTER  => get_string('percentageletter', 'grades'),
+                         GRADE_DISPLAY_TYPE_PERCENTAGE_REAL    => get_string('percentagereal', 'grades')
+                         );
+
+        asort($options);
+
+        foreach ($options as $key=>$option) {
+            if ($key == $default_gradedisplaytype) {
+                $options[GRADE_DISPLAY_TYPE_DEFAULT] = get_string('defaultprev', 'grades', $option);
+                break;
+            }
+        }
+        $mform->addElement('select', 'grade_item_display', get_string('gradedisplaytype', 'grades'), $options);
+        $mform->setHelpButton('grade_item_display', array('gradedisplaytype', get_string('gradedisplaytype', 'grades'), 'grade'), true);
+
+        $default_gradedecimals = grade_get_setting($COURSE->id, 'decimalpoints', $CFG->grade_decimalpoints);
+        $options = array(-1=>get_string('defaultprev', 'grades', $default_gradedecimals), 0=>0, 1=>1, 2=>2, 3=>3, 4=>4, 5=>5);
+        $mform->addElement('select', 'grade_item_decimals', get_string('decimalpoints', 'grades'), $options);
+        $mform->setHelpButton('grade_item_decimals', array('decimalpoints', get_string('decimalpoints', 'grades'), 'grade'), true);
+        $mform->setDefault('grade_item_decimals', -1);
+        $mform->disabledIf('grade_item_decimals', 'grade_item_display', 'eq', GRADE_DISPLAY_TYPE_LETTER);
+        if ($default_gradedisplaytype == GRADE_DISPLAY_TYPE_LETTER) {
+            $mform->disabledIf('grade_item_decimals', 'grade_item_display', "eq", GRADE_DISPLAY_TYPE_DEFAULT);
+        }
+
+        /// hiding
+        // advcheckbox is not compatible with disabledIf!
+        $mform->addElement('checkbox', 'grade_item_hidden', get_string('hidden', 'grades'));
+        $mform->setHelpButton('grade_item_hidden', array('hidden', get_string('hidden', 'grades'), 'grade'));
+        $mform->addElement('date_time_selector', 'grade_item_hiddenuntil', get_string('hiddenuntil', 'grades'), array('optional'=>true));
+        $mform->setHelpButton('grade_item_hiddenuntil', array('hiddenuntil', get_string('hiddenuntil', 'grades'), 'grade'));
+        $mform->disabledIf('grade_item_hidden', 'grade_item_hiddenuntil[off]', 'notchecked');
+
+        /// locking
+        $mform->addElement('advcheckbox', 'grade_item_locked', get_string('locked', 'grades'));
+        $mform->setHelpButton('grade_item_locked', array('locked', get_string('locked', 'grades'), 'grade'));
+
+        $mform->addElement('date_time_selector', 'grade_item_locktime', get_string('locktime', 'grades'), array('optional'=>true));
+        $mform->setHelpButton('grade_item_locktime', array('lockedafter', get_string('locktime', 'grades'), 'grade'));
+        $mform->disabledIf('grade_item_locktime', 'grade_item_gradetype', 'eq', GRADE_TYPE_NONE);
+
 /// parent category related settings
         $mform->addElement('header', 'headerparent', get_string('parentcategory', 'grades'));
 
@@ -104,6 +214,7 @@ class edit_category_form extends moodleform {
         $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();
@@ -121,16 +232,17 @@ class edit_category_form extends moodleform {
                     $coefstring = 'aggregationcoef';
                 }
             } else {
-                $mform->disabledIf('aggregationcoef', 'parentcategory', 'eq', $cat->id);
+                $mform->disabledIf('grade_item_aggregationcoef', 'parentcategory', 'eq', $cat->id);
             }
         }
         if (count($categories) > 1) {
-            $mform->addElement('select', 'parentcategory', get_string('gradecategory', 'grades'), $options);
+            $mform->addElement('select', 'parentcategory', get_string('parentcategory', 'grades'), $options);
+            $mform->addElement('static', 'currentparentaggregation', get_string('currentparentaggregation', 'grades'));
         }
 
         if ($coefstring !== '') {
-            $mform->addElement('text', 'aggregationcoef', get_string($coefstring, 'grades'));
-            $mform->setHelpButton('aggregationcoef', array('aggregationcoefweight', get_string('aggregationcoef', 'grades'), 'grade'), true);
+            $mform->addElement('text', 'grade_item_aggregationcoef', get_string($coefstring, 'grades'));
+            $mform->setHelpButton('grade_item_aggregationcoef', array('aggregationcoefweight', get_string('aggregationcoef', 'grades'), 'grade'), true);
         }
 
 /// user preferences
@@ -148,7 +260,9 @@ class edit_category_form extends moodleform {
 
         // hidden params
         $mform->addElement('hidden', 'id', 0);
+        $mform->addElement('hidden', 'grade_item_id', 0);
         $mform->setType('id', PARAM_INT);
+        $mform->setType('grade_item_id', PARAM_INT);
 
         $mform->addElement('hidden', 'courseid', 0);
         $mform->setType('courseid', PARAM_INT);
@@ -204,8 +318,11 @@ class edit_category_form extends moodleform {
                 if ($mform->elementExists('parentcategory')) {
                     $mform->removeElement('parentcategory');
                 }
-                if ($mform->elementExists('aggregationcoef')) {
-                    $mform->removeElement('aggregationcoef');
+                if ($mform->elementExists('grade_item_aggregationcoef')) {
+                    $mform->removeElement('grade_item_aggregationcoef');
+                }
+                if ($mform->elementExists('currentparentaggregation')) {
+                    $mform->removeElement('currentparentaggregation');
                 }
 
             } else {
@@ -213,27 +330,8 @@ class edit_category_form extends moodleform {
                 if ($mform->elementExists('parentcategory')) {
                     $mform->hardFreeze('parentcategory');
                 }
-
-                $parent_category = $grade_category->get_parent_category();
-                $parent_category->apply_forced_settings();
-                if (!$parent_category->is_aggregationcoef_used()) {
-                    if ($mform->elementExists('aggregationcoef')) {
-                        $mform->removeElement('aggregationcoef');
-                    }
-                } else {
-                    //fix label if needed
-                    $agg_el =& $mform->getElement('aggregationcoef');
-                    $aggcoef = '';
-                    if ($parent_category->aggregation == GRADE_AGGREGATE_WEIGHTED_MEAN) {
-                        $aggcoef = 'aggregationcoefweight';
-                    } else if ($parent_category->aggregation == GRADE_AGGREGATE_EXTRACREDIT_MEAN) {
-                        $aggcoef = 'aggregationcoefextra';
-                    }
-                    if ($aggcoef !== '') {
-                        $agg_el->setLabel(get_string($aggcoef, 'grades'));
-                        $mform->setHelpButton('aggregationcoef', array('aggregationcoef', get_string('aggregationcoef', 'grades'), 'grade'), true);
-                    }
-                }
+                $parent_cat = $grade_category->get_parent_category();
+                $mform->setDefault('currentparentaggregation', $this->aggregation_options[$parent_cat->aggregation]);
 
             }
 
@@ -277,6 +375,103 @@ class edit_category_form extends moodleform {
             $mform->removeElement('headerparent');
         }
 
+/// GRADE ITEM
+        if ($id = $mform->getElementValue('grade_item_id')) {
+            $grade_item = grade_item::fetch(array('id'=>$id));
+
+            if (!$grade_item->is_raw_used()) {
+                $mform->removeElement('grade_item_plusfactor');
+                $mform->removeElement('grade_item_multfactor');
+            }
+
+            if ($grade_item->is_outcome_item()) {
+                // we have to prevent incompatible modifications of outcomes if outcomes disabled
+                $mform->removeElement('grade_item_grademax');
+                $mform->removeElement('grade_item_grademin');
+                $mform->removeElement('grade_item_gradetype');
+                $mform->removeElement('grade_item_display');
+                $mform->removeElement('grade_item_decimals');
+                $mform->hardFreeze('grade_item_scaleid');
+
+            } else {
+                if ($grade_item->is_external_item()) {
+                    // following items are set up from modules and should not be overrided by user
+                    $mform->hardFreeze('grade_item_itemname,grade_item_idnumber,grade_item_gradetype,grade_item_grademax,grade_item_grademin,grade_item_scaleid');
+                    //$mform->removeElement('calculation');
+                }
+            }
+
+            //remove the aggregation coef element if not needed
+            if ($grade_item->is_course_item()) {
+                if ($mform->elementExists('grade_item_parentcategory')) {
+                    $mform->removeElement('grade_item_parentcategory');
+                }
+                if ($mform->elementExists('grade_item_aggregationcoef')) {
+                    $mform->removeElement('grade_item_aggregationcoef');
+                }
+
+            } else {
+                // if we wanted to change parent of existing item - we would have to verify there are no circular references in parents!!!
+                if ($mform->elementExists('grade_item_parentcategory')) {
+                    $mform->hardFreeze('grade_item_parentcategory');
+                }
+
+                if ($grade_item->is_category_item()) {
+                    $category = $grade_item->get_item_category();
+                    $parent_category = $category->get_parent_category();
+                } else {
+                    $parent_category = $grade_item->get_parent_category();
+                }
+
+                $parent_category->apply_forced_settings();
+
+                if (!$parent_category->is_aggregationcoef_used()) {
+                    if ($mform->elementExists('grade_item_aggregationcoef')) {
+                        $mform->removeElement('grade_item_aggregationcoef');
+                    }
+                } else {
+                    //fix label if needed
+                    $agg_el =& $mform->getElement('grade_item_aggregationcoef');
+                    $aggcoef = '';
+                    if ($parent_category->aggregation == GRADE_AGGREGATE_WEIGHTED_MEAN) {
+                        $aggcoef = 'aggregationcoefweight';
+
+                    } else if ($parent_category->aggregation == GRADE_AGGREGATE_EXTRACREDIT_MEAN) {
+                        $aggcoef = 'aggregationcoefextra';
+
+                    } else if ($parent_category->aggregation == GRADE_AGGREGATE_SUM) {
+                        $aggcoef = 'aggregationcoefextrasum';
+                    }
+
+                    if ($aggcoef !== '') {
+                        $agg_el->setLabel(get_string($aggcoef, 'grades'));
+                        $mform->setHelpButton('grade_item_aggregationcoef', array($aggcoef, get_string($aggcoef, 'grades'), 'grade'), true);
+                    }
+                }
+            }
+
+            if ($category = $grade_item->get_item_category()) {
+                if ($category->aggregation == GRADE_AGGREGATE_SUM) {
+                    if ($mform->elementExists('grade_item_gradetype')) {
+                        $mform->hardFreeze('grade_item_gradetype');
+                    }
+                    if ($mform->elementExists('grade_item_grademin')) {
+                        $mform->hardFreeze('grade_item_grademin');
+                    }
+                    if ($mform->elementExists('grade_item_grademax')) {
+                        $mform->hardFreeze('grade_item_grademax');
+                    }
+                    if ($mform->elementExists('grade_item_scaleid')) {
+                        $mform->removeElement('grade_item_scaleid');
+                    }
+                }
+            }
+
+        } else {
+            // all new items are manual, children of course category
+            $mform->removeElement('grade_item_plusfactor');
+            $mform->removeElement('grade_item_multfactor');
+        }
     }
 }
 
diff --git a/grade/edit/tree/functions.js b/grade/edit/tree/functions.js
new file mode 100755 (executable)
index 0000000..9ef91b3
--- /dev/null
@@ -0,0 +1,28 @@
+/**
+ * Toggles the selection checkboxes of all grade items children of the given eid (a category id)
+ */
+function togglecheckboxes(eid, value) {
+    var rows = YAHOO.util.Dom.getElementsByClassName(eid);
+
+    for (var i = 0; i < rows.length; i++) {
+        var element = new YAHOO.util.Element(rows[i]);
+        var checkboxes = element.getElementsByClassName('itemselect');
+        if (checkboxes[0]) {
+            checkboxes[0].checked=value;
+        }
+    }
+
+}
+
+function toggle_advanced_columns() {
+    var advEls = YAHOO.util.Dom.getElementsByClassName("advanced");
+    var shownAdvEls = YAHOO.util.Dom.getElementsByClassName("advancedshown");
+
+    for (var i = 0; i < advEls.length; i++) {
+        YAHOO.util.Dom.replaceClass(advEls[i], "advanced", "advancedshown");
+    }
+
+    for (var i = 0; i < shownAdvEls.length; i++) {
+        YAHOO.util.Dom.replaceClass(shownAdvEls[i], "advancedshown", "advanced");
+    }
+}
index f3997f4c3e5457cfc897907081d1d5ccf1f0c9fd..3dede7150e10b065fa1879ae53e06fc62f60959f 100644 (file)
 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/tree/lib.php';
 
-$courseid = required_param('id', PARAM_INT);
-$action   = optional_param('action', 0, PARAM_ALPHA);
-$eid      = optional_param('eid', 0, PARAM_ALPHANUM);
+require_js(array('yui_yahoo', 'yui_dom', 'yui_event', 'yui_json', 'yui_connection', 'yui_dragdrop', 'yui_treeview', 'yui_element',
+            $CFG->wwwroot.'/grade/edit/tree/functions.js'));
 
+$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);
+$showadvanced    = optional_param('showadvanced', -1, PARAM_BOOL); // sticky editting mode
 
 /// Make sure they can even access this course
 
@@ -46,6 +52,51 @@ require_capability('moodle/grade:manage', $context);
 $gpr = new grade_plugin_return(array('type'=>'edit', 'plugin'=>'tree', 'courseid'=>$courseid));
 $returnurl = $gpr->get_return_url(null);
 
+/// Build editing on/off buttons
+if (!isset($USER->gradeediting)) {
+    $USER->gradeediting = array();
+}
+
+$current_view = '';
+
+if (has_capability('moodle/grade:manage', $context)) {
+    if (!isset($USER->gradeediting[$course->id])) {
+        $USER->gradeediting[$course->id] = 0;
+    }
+
+    if (($showadvanced == 1) and confirm_sesskey()) {
+        $USER->gradeediting[$course->id] = 1;
+    } else if (($showadvanced == 0) and confirm_sesskey()) {
+        $USER->gradeediting[$course->id] = 0;
+    }
+
+    // page params for the turn editting on
+    $options = $gpr->get_options();
+    $options['sesskey'] = sesskey();
+
+    if ($USER->gradeediting[$course->id]) {
+        $options['showadvanced'] = 0;
+        $current_view = 'fullview';
+    } else {
+        $options['showadvanced'] = 1;
+        $current_view = 'simpleview';
+    }
+
+} else {
+    $USER->gradeediting[$course->id] = 0;
+    $buttons = '';
+}
+
+// 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);
 
@@ -74,10 +125,12 @@ $strcategoriesanditems = get_string('categoriesanditems', 'grades');
 $navigation = grade_build_nav(__FILE__, $strcategoriesanditems, array('courseid' => $courseid));
 $moving = false;
 
+$grade_edit_tree = new grade_edit_tree($gtree, $moving, $gpr);
+
 switch ($action) {
     case 'delete':
         if ($eid) {
-            if (!element_deletable($element)) {
+            if (!$grade_edit_tree->element_deletable($element)) {
                 // no deleting of external activities - they would be recreated anyway!
                 // exception is activity without grading or misconfigured activities
                 break;
@@ -89,7 +142,7 @@ switch ($action) {
                 redirect($returnurl);
 
             } else {
-                print_header_simple($strgrades . ': ' . $strgraderreport, ': ' . $strcategoriesedit, $navigation, '', '', true, '', navmenu($course));
+                print_header_simple($strgrades . ': ' . $strgraderreport, ': ' . $strcategoriesedit, $navigation, '', '', true, null, navmenu($course));
                 $strdeletecheckfull = get_string('deletecheck', '', $object->get_name());
                 $optionsyes = array('eid'=>$eid, 'confirm'=>1, 'sesskey'=>sesskey(), 'id'=>$course->id, 'action'=>'delete');
                 $optionsno  = array('id'=>$course->id);
@@ -111,14 +164,22 @@ switch ($action) {
     case 'move':
         if ($eid and confirm_sesskey()) {
             $moveafter = required_param('moveafter', PARAM_ALPHANUM);
+            $first = optional_param('first', false,  PARAM_BOOL); // If First is set to 1, it means the target is the first child of the category $moveafter
+
             if(!$after_el = $gtree->locate_element($moveafter)) {
                 print_error('invalidelementid', '', $returnurl);
             }
+
             $after = $after_el['object'];
-            $parent = $after->get_parent_category();
             $sortorder = $after->get_sortorder();
 
-            $object->set_parent($parent->id);
+            if (!$first) {
+                $parent = $after->get_parent_category();
+                $object->set_parent($parent->id);
+            } else {
+                $object->set_parent($after->id);
+            }
+
             $object->move_after_sortorder($sortorder);
 
             redirect($returnurl);
@@ -127,7 +188,7 @@ switch ($action) {
 
     case 'moveselect':
         if ($eid and confirm_sesskey()) {
-            $moving = $eid;
+            $grade_edit_tree->moving = $eid;
         }
         break;
 
@@ -135,141 +196,166 @@ switch ($action) {
         break;
 }
 
-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'));
+// Hide advanced columns if moving
+if ($grade_edit_tree->moving) {
+    $original_gradeediting = $USER->gradeediting[$course->id];
+    $USER->gradeediting[$course->id] = 0;
+}
 
+$CFG->stylesheets[] = $CFG->wwwroot.'/grade/edit/tree/tree.css';
 
-print_box_start('gradetreebox generalbox');
-echo '<ul id="grade_tree">';
-print_grade_tree($gtree, $gtree->top_element, $moving, $gpr, $switch);
-echo '</ul>';
-print_box_end();
-
-echo '<div class="buttons">';
-if ($moving) {
-    print_single_button('index.php', array('id'=>$course->id), get_string('cancel'), 'get');
-} else {
-    print_single_button('category.php', array('courseid'=>$course->id), get_string('addcategory', 'grades'), 'get');
-    print_single_button('item.php', array('courseid'=>$course->id), get_string('additem', 'grades'), 'get');
-    if (!empty($CFG->enableoutcomes)) {
-        print_single_button('outcomeitem.php', array('courseid'=>$course->id), get_string('addoutcomeitem', 'grades'), 'get');
+$current_view_str = '';
+if ($current_view != '') {
+    if ($current_view == 'simpleview') {
+        $current_view_str = get_string('simpleview', 'grades');
+    } elseif ($current_view == 'fullview') {
+        $current_view_str = get_string('fullview', 'grades');
     }
-    //print_single_button('index.php', array('id'=>$course->id, 'action'=>'autosort'), get_string('autosort', 'grades'), 'get');
-    print_single_button('index.php', array('id'=>$course->id, 'action'=>'synclegacy'), get_string('synclegacygrades', 'grades'), 'get');
 }
-echo '</div>';
-print_footer($course);
-die;
 
-/**
- * TODO document
- */
-function print_grade_tree(&$gtree, $element, $moving, &$gpr, $switch, $switchedlast=false) {
-    global $CFG, $COURSE;
+print_grade_page_head($courseid, 'edittree', $current_view, get_string('categoriesedit', 'grades') . ': ' . $current_view_str);
 
-/// fetch needed strings
-    $strmove     = get_string('move');
-    $strmovehere = get_string('movehere');
-    $strdelete   = get_string('delete');
+$form_key = optional_param('sesskey', null, PARAM_ALPHANUM);
 
-    $object = $element['object'];
-    $eid    = $element['eid'];
+if ($form_key && $data = data_submitted()) {
+    // Perform bulk actions first
+    if (!empty($data->bulkmove)) {
+        $elements = array();
 
-    $header = $gtree->get_element_header($element, true, true, true);
+        foreach ($data as $key => $value) {
+            if (preg_match('/select_(i[0-9]*)/', $key, $matches)) {
+                $elements[] = $matches[1];
+            }
+        }
 
-    if ($object->is_hidden()) {
-        $header = '<span class="dimmed_text">'.$header.'</span>';
+        $grade_edit_tree->move_elements($elements, $returnurl);
     }
 
-/// prepare actions
-    $actions = $gtree->get_edit_icon($element, $gpr);
-    $actions .= $gtree->get_calculation_icon($element, $gpr);
+    // Category and item field updates
+    foreach ($data as $key => $value) {
+        // Grade category text inputs
+        if (preg_match('/(aggregation|droplow|keephigh)_([0-9]*)/', $key, $matches)) {
+            $value = required_param($matches[0], PARAM_INT);
+            $param = $matches[1];
+            $a->id = $matches[2];
 
-    if ($element['type'] == 'item' or ($element['type'] == 'category' and $element['depth'] > 1)) {
-        if (element_deletable($element)) {
-            $actions .= '<a href="index.php?id='.$COURSE->id.'&amp;action=delete&amp;eid='
-                     . $eid.'&amp;sesskey='.sesskey().'"><img src="'.$CFG->pixpath.'/t/delete.gif" class="iconsmall" alt="'
-                     . $strdelete.'" title="'.$strdelete.'"/></a>';
-        }
-        $actions .= '<a href="index.php?id='.$COURSE->id.'&amp;action=moveselect&amp;eid='
-                 . $eid.'&amp;sesskey='.sesskey().'"><img src="'.$CFG->pixpath.'/t/move.gif" class="iconsmall" alt="'
-                 . $strmove.'" title="'.$strmove.'"/></a>';
-    }
+            if (!$DB->update_record('grade_categories', (object) array('id' => $matches[2], $param => $value))) {
+                print_error('errorupdatinggradecategoryaggregation', 'grades', $a);
+            }
 
-    $actions .= $gtree->get_hiding_icon($element, $gpr);
-    $actions .= $gtree->get_locking_icon($element, $gpr);
-
-/// prepare move target if needed
-    $last = '';
-    $catcourseitem = ($element['type'] == 'courseitem' or $element['type'] == 'categoryitem');
-    $moveto = '';
-    if ($moving) {
-        $actions = ''; // no action icons when moving
-        $moveto = '<li><a href="index.php?id='.$COURSE->id.'&amp;action=move&amp;eid='.$moving.'&amp;moveafter='
-                . $eid.'&amp;sesskey='.sesskey().'"><img class="movetarget" src="'.$CFG->wwwroot.'/pix/movehere.gif" alt="'
-                . $strmovehere.'" title="'.$strmovehere.'" /></a></li>';
-    }
+        // Grade item text inputs
+        } elseif (preg_match('/(aggregationcoef|multfactor|plusfactor)_([0-9]*)/', $key, $matches)) {
+            $value = required_param($matches[0], PARAM_NUMBER);
+            $param = $matches[1];
+            $a->id = $matches[2];
 
-/// print the list items now
-    if ($moving == $eid) {
-        // do not diplay children
-        echo '<li class="'.$element['type'].' moving">'.$header.'('.get_string('move').')</li>';
+            if (!$DB->update_record('grade_items', (object) array('id' => $matches[2], $param => $value))) {
+                print_error('errorupdatinggradeitemaggregationcoef', 'grades', $a);
+            }
 
-    } else if ($element['type'] != 'category') {
-        if ($catcourseitem and $switch) {
-            if ($switchedlast) {
-                echo '<li class="'.$element['type'].'">'.$header.$actions.'</li>';
+        // Grade item checkbox inputs
+        } elseif (preg_match('/extracredit_original_([0-9]*)/', $key, $matches)) { // Sum extra credit checkbox
+            $extracredit = optional_param("extracredit_{$matches[1]}", null, PARAM_BOOL);
+            $original_value = required_param($matches[0], PARAM_BOOL);
+            $a->id = $matches[1];
+            $newvalue = null;
+
+            if ($original_value == 1 && is_null($extracredit)) {
+                $newvalue = 0;
+            } elseif ($original_value == 0 && $extracredit == 1) {
+                $newvalue = 1;
             } else {
-                echo $moveto;
+                continue;
             }
-        } else {
-            echo '<li class="'.$element['type'].'">'.$header.$actions.'</li>'.$moveto;
-        }
 
-    } else {
-        echo '<li class="'.$element['type'].'">'.$header.$actions;
-        echo '<ul class="catlevel'.$element['depth'].'">';
-        $last = null;
-        foreach($element['children'] as $child_el) {
-            if ($switch and empty($last)) {
-                $last = $child_el;
+            if (!$DB->update_record('grade_items', array('id' => $matches[1], 'aggregationcoef' => $newvalue))) {
+                print_error('errorupdatinggradeitemaggregationcoef', 'grades', $a);
+            }
+
+        // Grade category checkbox inputs
+        } 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;
+            } else {
+                continue;
+            }
+
+            if (!$DB->update_record('grade_categories', array('id' => $matches[2], 'aggregate'.$matches[1] => $newvalue))) {
+                print_error('errorupdatinggradecategoryaggregate'.$matches[1], 'grades', $a);
             }
-            print_grade_tree($gtree, $child_el, $moving, $gpr, $switch);
-        }
-        if ($last) {
-            print_grade_tree($gtree, $last, $moving, $gpr, $switch, true);
-        }
-        echo '</ul></li>';
-        if ($element['depth'] > 1) {
-            echo $moveto; // can not move after the top category
         }
     }
 }
 
-function element_deletable($element) {
-    global $COURSE;
+// Print Table of categories and items
+print_box_start('gradetreebox generalbox');
 
-    if ($element['type'] != 'item') {
-        return true;
-    }
+echo '<form id="gradetreeform" method="post" action="'.$returnurl.'">';
+echo '<div>';
+echo '<input type="hidden" name="sesskey" value="'.sesskey().'" />';
 
-    $grade_item = $element['object'];
+// Build up an array of categories for move drop-down (by reference)
+$categories = array();
+echo $grade_edit_tree->build_html_tree($gtree->top_element, true, array(), $categories);
 
-    if ($grade_item->itemtype != 'mod' or $grade_item->is_outcome_item() or $grade_item->gradetype == GRADE_TYPE_NONE) {
-        return true;
-    }
+echo '<div id="gradetreesubmit">';
+if (!$moving) {
+    echo '<input class="advanced" type="submit" value="'.get_string('savechanges').'" />';
+}
+
+if (!$moving) {
+    echo '<br /><br />';
+    echo '<input type="hidden" name="bulkmove" value="0" id="bulkmoveinput" />';
+    echo get_string('moveselectedto', 'grades') . ' : ';
+    echo choose_from_menu($categories, 'moveafter', '', 'choose',
+            'document.getElementById(\'bulkmoveinput\').value=1;document.getElementById(\'gradetreeform\').submit()', 0, true);
+    echo '<div id="noscriptgradetreeform" style="display: inline;">
+            <input type="submit" value="'.get_string('go').'" />
+          </div>
+          <script type="text/javascript">
+            //<![CDATA[
+                document.getElementById("noscriptgradetreeform").style.display= "none";
+            //]]>
+          </script>';
+}
+
+echo '</div>';
 
-    $modinfo = get_fast_modinfo($COURSE);
-    if (!isset($modinfo->instances[$grade_item->itemmodule][$grade_item->iteminstance])) {
-        // module does not exist
-        return true;
+echo '</div></form>';
+
+print_box_end();
+
+// Print action buttons
+echo '<div class="buttons">';
+
+if ($moving) {
+    print_single_button('index.php', array('id'=>$course->id), get_string('cancel'), 'get');
+} else {
+    print_single_button('category.php', array('courseid'=>$course->id), get_string('addcategory', 'grades'), 'get');
+    print_single_button('item.php', array('courseid'=>$course->id), get_string('additem', 'grades'), 'get');
+
+    if (!empty($CFG->enableoutcomes)) {
+        print_single_button('outcomeitem.php', array('courseid'=>$course->id), get_string('addoutcomeitem', 'grades'), 'get');
     }
 
-    return false;
+    print_single_button('index.php', array('id'=>$course->id, 'action'=>'synclegacy'), get_string('synclegacygrades', 'grades'), 'get');
 }
 
+echo '</div>';
+
+print_footer($course);
+
+// Restore original show/hide preference if moving
+if ($moving) {
+    $USER->gradeediting[$course->id] = $original_gradeediting;
+}
+die;
+
 ?>
index ad7d5b3971466fc997cfd27ada0137f81585e322..6db142229b0a057e6b27783c59a3d11d3d489139 100644 (file)
@@ -49,6 +49,8 @@ if ($mform->is_cancelled()) {
     redirect($returnurl);
 }
 
+$heading = get_string('itemsedit', 'grades');
+
 if ($grade_item = grade_item::fetch(array('id'=>$id, 'courseid'=>$courseid))) {
     // redirect if outcomeid present
     if (!empty($grade_item->outcomeid) && !empty($CFG->enableoutcomes)) {
@@ -69,6 +71,7 @@ if ($grade_item = grade_item::fetch(array('id'=>$id, 'courseid'=>$courseid))) {
         $item->parentcategory = $parent_category->id;
     }
 } else {
+    $heading = get_string('newitem', 'grades');
     $grade_item = new grade_item(array('courseid'=>$courseid, 'itemtype'=>'manual'), false);
     $item = $grade_item->get_record_data();
     $parent_category = grade_category::fetch_course_category($courseid);
@@ -159,15 +162,7 @@ if ($data = $mform->get_data()) {
     redirect($returnurl);
 }
 
-$strgrades       = get_string('grades');
-$strgraderreport = get_string('graderreport', 'grades');
-$stritemsedit    = get_string('itemsedit', 'grades');
-$stritem         = get_string('item', 'grades');
-
-$navigation = grade_build_nav(__FILE__, $stritem, array('courseid' => $courseid));
-
-
-print_header_simple($strgrades . ': ' . $strgraderreport, ': ' . $stritemsedit, $navigation, '', '', true, '', navmenu($course));
+print_grade_page_head($courseid, 'edittree', null, $heading);
 
 $mform->display();
 
diff --git a/grade/edit/tree/lib.php b/grade/edit/tree/lib.php
new file mode 100755 (executable)
index 0000000..e0d9086
--- /dev/null
@@ -0,0 +1,914 @@
+<?php  // $Id$
+
+///////////////////////////////////////////////////////////////////////////
+//                                                                       //
+// 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                         //
+//                                                                       //
+///////////////////////////////////////////////////////////////////////////
+
+class grade_edit_tree {
+    public $columns = array();
+
+    /**
+     * @var object $gtree          @see grade/lib.php
+     */
+    public $gtree;
+
+    /**
+     * @var grade_plugin_return @see grade/lib.php
+     */
+    public $gpr;
+
+    /**
+     * @var string              $moving The eid of the category or item being moved
+     */
+    public $moving;
+
+    public $deepest_level;
+
+    /**
+     * Constructor
+     */
+    public function __construct($gtree, $moving=false, $gpr) {
+        $this->gtree = $gtree;
+        $this->moving = $moving;
+        $this->gpr = $gpr;
+        $this->deepest_level = $this->get_deepest_level($this->gtree->top_element);
+
+        $this->columns = array(grade_edit_tree_column::factory('name', array('deepest_level' => $this->deepest_level)),
+                               grade_edit_tree_column::factory('aggregation', array('flag' => true)),
+                               grade_edit_tree_column::factory('weightorextracredit', array('adv' => 'aggregationcoef')),
+                               grade_edit_tree_column::factory('range'), // This is not a setting... How do we deal with it?
+                               grade_edit_tree_column::factory('aggregateonlygraded', array('flag' => true)),
+                               grade_edit_tree_column::factory('aggregatesubcats', array('flag' => true)),
+                               grade_edit_tree_column::factory('aggregateoutcomes', array('flag' => true)),
+                               grade_edit_tree_column::factory('droplow', array('flag' => true)),
+                               grade_edit_tree_column::factory('keephigh', array('flag' => true)),
+                               grade_edit_tree_column::factory('multfactor', array('adv' => true)),
+                               grade_edit_tree_column::factory('plusfactor', array('adv' => true)),
+                               grade_edit_tree_column::factory('actions'),
+                               grade_edit_tree_column::factory('select')
+                               );
+    }
+
+    /**
+     * Recursive function for building the table holding the grade categories and items,
+     * with CSS indentation and styles.
+     *
+     * @param array               $element The current tree element being rendered
+     * @param boolean             $totals Whether or not to print category grade items (category totals)
+     * @param array               $parents An array of parent categories for the current element (used for indentation and row classes)
+     *
+     * @return string HTML
+     */
+    public function build_html_tree($element, $totals, $parents=array(), &$categories=array(), $level=0, &$row_count=0) {
+        global $CFG, $COURSE, $USER;
+
+        $object = $element['object'];
+        $eid    = $element['eid'];
+        $object->name = $this->gtree->get_element_header($element, true, true, false);
+        $object->stripped_name = $this->gtree->get_element_header($element, false, false, false);
+
+        $is_category_item = false;
+        if ($element['type'] == 'categoryitem' || $element['type'] == 'courseitem') {
+            $is_category_item = true;
+        }
+
+        $rowclasses = '';
+        foreach ($parents as $parent_eid) {
+            $rowclasses .= " $parent_eid ";
+        }
+
+        $actions = '';
+
+        if (!$is_category_item) {
+            $actions .= $this->gtree->get_edit_icon($element, $this->gpr);
+        }
+
+        $actions .= $this->gtree->get_calculation_icon($element, $this->gpr);
+
+        if ($element['type'] == 'item' or ($element['type'] == 'category' and $element['depth'] > 1)) {
+            if ($this->element_deletable($element)) {
+                $actions .= '<a href="index.php?id='.$COURSE->id.'&amp;action=delete&amp;eid='
+                         . $eid.'&amp;sesskey='.sesskey().'"><img src="'.$CFG->pixpath.'/t/delete.gif" class="iconsmall" alt="'
+                         . get_string('delete').'" title="'.get_string('delete').'"/></a>';
+            }
+            $actions .= '<a href="index.php?id='.$COURSE->id.'&amp;action=moveselect&amp;eid='
+                     . $eid.'&amp;sesskey='.sesskey().'"><img src="'.$CFG->pixpath.'/t/move.gif" class="iconsmall" alt="'
+                     . get_string('move').'" title="'.get_string('move').'"/></a>';
+        }
+
+        $actions .= $this->gtree->get_hiding_icon($element, $this->gpr);
+        $actions .= $this->gtree->get_locking_icon($element, $this->gpr);
+
+        $mode = ($USER->gradeediting[$COURSE->id]) ? 'advanced' : 'simple';
+
+        $html = '';
+        $root = false;
+
+
+        $id = required_param('id', PARAM_INT);
+
+        /// prepare move target if needed
+        $last = '';
+
+        /// print the list items now
+        if ($this->moving == $eid) {
+
+            // do not diplay children
+            return '<tr><td colspan="12" class="'.$element['type'].' moving">'.$object->name.' ('.get_string('move').')</td></tr>';
+
+        }
+
+        if ($element['type'] == 'category') {
+            $level++;
+            $categories[$object->id] = $object->stripped_name;
+            $category = grade_category::fetch(array('id' => $object->id));
+            $item = $category->get_grade_item();
+
+            // Add aggregation coef input if not a course item and if parent category has correct aggregation type
+            $dimmed = ($item->hidden) ? " dimmed " : "";
+
+            // Before we print the category's row, we must find out how many rows will appear below it (for the filler cell's rowspan)
+            $aggregation_position = grade_get_setting($COURSE->id, 'aggregationposition', $CFG->grade_aggregationposition);
+            $category_total_data = null; // Used if aggregationposition is set to "last", so we can print it last
+
+            $html_children = '';
+
+            $row_count = 0;
+
+            foreach($element['children'] as $child_el) {
+                $moveto = '';
+
+                if (empty($child_el['object']->itemtype)) {
+                    $child_el['object']->itemtype = false;
+                }
+
+                if (($child_el['object']->itemtype == 'course' || $child_el['object']->itemtype == 'category') && !$totals) {
+                    continue;
+                }
+
+                $child_eid    = $child_el['eid'];
+                $first = '';
+
+                if ($child_el['object']->itemtype == 'course' || $child_el['object']->itemtype == 'category') {
+                    $first = '&amp;first=1';
+                    $child_eid = $eid;
+                }
+
+                if ($this->moving && $this->moving != $child_eid) {
+
+                    $strmove     = get_string('move');
+                    $strmovehere = get_string('movehere');
+                    $actions = ''; // no action icons when moving
+
+                    $moveto = '<tr><td colspan="12"><a href="index.php?id='.$COURSE->id.'&amp;action=move&amp;eid='.$this->moving.'&amp;moveafter='
+                            . $child_eid.'&amp;sesskey='.sesskey().$first.'"><img class="movetarget" src="'.$CFG->wwwroot.'/pix/movehere.gif" alt="'
+                            . $strmovehere.'" title="'.$strmovehere.'" /></a></td></tr>';
+                }
+
+                $newparents = $parents;
+                $newparents[] = $eid;
+
+                $row_count++;
+                $child_row_count = 0;
+
+                // If moving, do not print course and category totals, but still print the moveto target box
+                if ($this->moving && ($child_el['object']->itemtype == 'course' || $child_el['object']->itemtype == 'category')) {
+                    $html_children .= $moveto;
+                } elseif ($child_el['object']->itemtype == 'course' || $child_el['object']->itemtype == 'category') {
+                    // We don't build the item yet because we first need to know the deepest level of categories (for category/name colspans)
+                    $category_total_item = $this->build_html_tree($child_el, $totals, $newparents, $categories, $level, $child_row_count);
+                    if (!$aggregation_position) {
+                        $html_children .= $category_total_item;
+                    }
+                } else {
+                    $html_children .= $this->build_html_tree($child_el, $totals, $newparents, $categories, $level, $child_row_count) . $moveto;
+
+                    if ($this->moving) {
+                        $row_count++;
+                    }
+                }
+
+                $row_count += $child_row_count;
+
+                // If the child is a category, increment row_count by one more (for the extra coloured row)
+                if ($child_el['type'] == 'category') {
+                    $row_count++;
+                }
+            }
+
+            // Print category total at the end if aggregation position is "last" (1)
+            if (!empty($category_total_item) && $aggregation_position) {
+                $html_children .= $category_total_item;
+            }
+
+            // now build the header
+            if (isset($element['object']->grade_item) && $element['object']->grade_item->is_course_item()) {
+                // Reduce width if advanced elements are not shown
+                $width_style = '';
+
+                if ($mode == 'simple') {
+                    $width_style = ' style="width:auto;" ';
+                }
+
+                $html .= '<table cellpadding="5" class="generaltable" '.$width_style.'>
+                            <tr>';
+
+                foreach ($this->columns as $column) {
+                    if (!($this->moving && $column->hide_when_moving) && !$column->is_hidden($mode)) {
+                        $html .= $column->get_header_cell();
+                    }
+                }
+
+                $html .= '</tr>';
+                $root = true;
+            }
+
+            $row_count_offset = 0;
+
+            if (empty($category_total_item) && !$this->moving) {
+                $row_count_offset = -1;
+            }
+
+            $levelclass = " level$level ";
+
+            $html .= '
+                    <tr class="category '.$dimmed.$rowclasses.'">
+                      <th scope="row" title="'.$object->stripped_name.'" class="cell rowspan '.$levelclass.'" rowspan="'.($row_count+1+$row_count_offset).'"></th>';
+
+            foreach ($this->columns as $column) {
+                if (!($this->moving && $column->hide_when_moving) && !$column->is_hidden($mode)) {
+                    $html .= $column->get_category_cell($category, $levelclass, array('id' => $id, 'name' => $object->name, 'level' => $level, 'actions' => $actions, 'eid' => $eid));
+                }
+            }
+
+            $html .= '</tr>';
+
+            $html .= $html_children;
+
+            // Print a coloured row to show the end of the category accross the table
+            $html .= '<tr><td colspan="'.(19 - $level).'" class="colspan '.$levelclass.'"></td></tr>';
+
+        } else { // Dealing with a grade item
+
+            $item = grade_item::fetch(array('id' => $object->id));
+            $element['type'] = 'item';
+            $element['object'] = $item;
+
+            // Determine aggregation coef element
+
+            $dimmed = ($item->hidden) ? " dimmed_text " : "";
+            $html .= '<tr class="item'.$dimmed.$rowclasses.'">';
+
+            foreach ($this->columns as $column) {
+                if (!($this->moving && $column->hide_when_moving) && !$column->is_hidden($mode)) {
+                    $html .= $column->get_item_cell($item, array('id' => $id, 'name' => $object->name, 'level' => $level, 'actions' => $actions,
+                                                                 'element' => $element, 'eid' => $eid, 'itemtype' => $object->itemtype));
+                }
+            }
+
+            $html .= '</tr>';
+        }
+
+
+        if ($root) {
+            $html .= "</table>\n";
+        }
+
+        return $html;
+
+    }
+
+    /**
+     * Given a grade_item object, returns a labelled input if an aggregation coefficient (weight or extra credit) applies to it.
+     * @param grade_item $item
+     * @return string HTML
+     */
+    function get_weight_input($item) {
+        if (!is_object($item) || get_class($item) !== 'grade_item') {
+            throw new Exception('grade_edit_tree::get_weight_input($item) was given a variable that is not of the required type (grade_item object)');
+            return false;
+        }
+
+        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 == 'aggregationcoefweight' || $aggcoef == 'aggregationcoefextra') {
+                return '<input type="text" size="6" id="aggregationcoef_'.$item->id.'" name="aggregationcoef_'.$item->id.'"
+                    value="'.format_float($item->aggregationcoef).'" />';
+            } elseif ($aggcoef == 'aggregationcoefextrasum' ) {
+                $checked = ($item->aggregationcoef > 0) ? 'checked="checked"' : '';
+                $extracredit = ($item->aggregationcoef > 0) ? 1 : 0;
+
+                return '<input type="checkbox" id="extracredit_'.$item->id.'" name="extracredit_'.$item->id.'" ' . "$checked />\n"
+                               . '<input type="hidden" name="extracredit_original_'.$item->id.'" value="'.$extracredit.'" />';
+            } else {
+                return '';
+            }
+        }
+    }
+
+    /**
+     * Given an element of the grade tree, returns whether it is deletable or not (only manual grade items are deletable)
+     *
+     * @param array $element
+     * @return bool
+     */
+    function element_deletable($element) {
+        global $COURSE;
+
+        if ($element['type'] != 'item') {
+            return true;
+        }
+
+        $grade_item = $element['object'];
+
+        if ($grade_item->itemtype != 'mod' or $grade_item->is_outcome_item() or $grade_item->gradetype == GRADE_TYPE_NONE) {
+            return true;
+        }
+
+        $modinfo = get_fast_modinfo($COURSE);
+        if (!isset($modinfo->instances[$grade_item->itemmodule][$grade_item->iteminstance])) {
+            // module does not exist
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Given the grade tree and an array of element ids (e.g. c15, i42), and expecting the 'moveafter' URL param,
+     * moves the selected items to the requested location. Then redirects the user to the given $returnurl
+     *
+     * @param object $gtree The grade tree (a recursive representation of the grade categories and grade items)
+     * @param array $eids
+     * @param string $returnurl
+     */
+    function move_elements($eids, $returnurl) {
+        $moveafter = required_param('moveafter', PARAM_INT);
+
+        if (!is_array($eids)) {
+            $eids = array($eids);
+        }
+
+        if(!$after_el = $this->gtree->locate_element("c$moveafter")) {
+            print_error('invalidelementid', '', $returnurl);
+        }
+
+        $after = $after_el['object'];
+        $parent = $after;
+        $sortorder = $after->get_sortorder();
+
+        foreach ($eids as $eid) {
+            if (!$element = $this->gtree->locate_element($eid)) {
+                print_error('invalidelementid', '', $returnurl);
+            }
+            $object = $element['object'];
+
+            $object->set_parent($parent->id);
+            $object->move_after_sortorder($sortorder);
+        }
+
+        redirect($returnurl, '', 0);
+    }
+
+    /**
+     * Recurses through the entire grade tree to find and return the maximum depth of the tree.
+     * This should be run only once from the root element (course category), and is used for the
+     * indentation of the Name column's cells (colspan)
+     *
+     * @param array $element An array of values representing a grade tree's element (all grade items in this case)
+     * @param int $level The level of the current recursion
+     * @param int $deepest_level A value passed to each subsequent level of recursion and incremented if $level > $deepest_level
+     * @return int Deepest level
+     */
+    function get_deepest_level($element, $level=0, $deepest_level=1) {
+        $object = $element['object'];
+
+        $level++;
+
+        if ($element['type'] == 'category') {
+            foreach($element['children'] as $child_el) {
+                if ($level > $deepest_level) {
+                    $deepest_level = $level;
+                }
+                $deepest_level = $this->get_deepest_level($child_el, $level, $deepest_level);
+            }
+        }
+
+        return $deepest_level;
+    }
+}
+
+abstract class grade_edit_tree_column {
+    public $forced;
+    public $hidden;
+    public $forced_hidden;
+    public $advanced_hidden;
+    public $hide_when_moving = true;
+
+    public static function factory($name, $params=array()) {
+        $class_name = "grade_edit_tree_column_$name";
+        if (class_exists($class_name)) {
+            return new $class_name($params);
+        }
+    }
+
+    public abstract function get_header_cell();
+
+    public abstract function get_category_cell($category, $levelclass, $params);
+
+    public abstract function get_item_cell($item, $params);
+
+    public abstract function is_hidden($mode='simple');
+}
+
+abstract class grade_edit_tree_column_category extends grade_edit_tree_column {
+
+    public $forced;
+    public $advanced;
+
+    public function __construct($name) {
+        global $CFG;
+        $this->forced = (int)$CFG->{"grade_$name"."_flag"} & 1;
+        $this->advanced = (int)$CFG->{"grade_$name"."_flag"} & 2;
+    }
+
+    public function is_hidden($mode='simple') {
+        global $CFG;
+        if ($mode == 'simple') {
+            return $this->advanced;
+        } elseif ($mode == 'advanced') {
+            if ($this->forced && $CFG->grade_hideforcedsettings) {
+                return true;
+            } else {
+                return false;
+            }
+        }
+    }
+}
+
+class grade_edit_tree_column_name extends grade_edit_tree_column {
+    public $forced = false;
+    public $hidden = false;
+    public $forced_hidden = false;
+    public $advanced_hidden = false;
+    public $deepest_level = 1;
+    public $hide_when_moving = false;
+
+    public function __construct($params) {
+        if (empty($params['deepest_level'])) {
+            throw new Exception('Tried to instantiate a grade_edit_tree_column_name object without the "deepest_level" param!');
+        }
+
+        $this->deepest_level = $params['deepest_level'];
+    }
+
+    public function get_header_cell() {
+        return '<th class="header name" colspan="'.($this->deepest_level + 1).'" scope="col">'.get_string('name').'</th>';
+    }
+
+    public function get_category_cell($category, $levelclass, $params) {
+        if (empty($params['name']) || empty($params['level'])) {
+            throw new Exception('Array key (name or level) missing from 3rd param of grade_edit_tree_column_name::get_category_cell($category, $levelclass, $params)');
+        }
+
+        return '<td class="cell name '.$levelclass.'" colspan="'.(($this->deepest_level +1) - $params['level']).'"><h4>' . $params['name'] . "</h4></td>\n";
+    }
+
+    public function get_item_cell($item, $params) {
+        global $CFG;
+
+        if (empty($params['element']) || empty($params['name']) || empty($params['level'])) {
+            throw new Exception('Array key (name, level or element) missing from 2nd param of grade_edit_tree_column_name::get_item_cell($item, $params)');
+        }
+
+        $name = $params['name'];
+
+        return '<td class="cell name" colspan="'.(($this->deepest_level + 1) - $params['level']).'">' . $name . '</td>';
+    }
+
+    public function is_hidden($mode='simple') {
+        return false;
+    }
+}
+
+class grade_edit_tree_column_aggregation extends grade_edit_tree_column_category {
+
+    public function __construct($params) {
+        parent::__construct('aggregation');
+    }
+
+    public function get_header_cell() {
+        return '<th class="header" scope="col">'.get_string('aggregation', 'grades').helpbutton('aggregation', 'aggregation', 'grade', true, false, '', true).'</th>';
+    }
+
+    public function get_category_cell($category, $levelclass, $params) {
+        if (empty($params['id'])) {
+            throw new Exception('Array key (id) missing from 3rd param of grade_edit_tree_column_aggregation::get_category_cell($category, $levelclass, $params)');
+        }
+
+        $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'));
+
+        $script = "window.location='index.php?id={$params['id']}&amp;category={$category->id}&amp;aggregationtype='+this.value";
+        $aggregation = choose_from_menu($options, 'aggregation_'.$category->id, $category->aggregation, get_string('choose'), $script, 0, true);
+
+        if ($this->forced) {
+            $aggregation = $options[$category->aggregation];
+        }
+
+        return '<td class="cell '.$levelclass.'">' . $aggregation . '</td>';
+
+    }
+
+    public function get_item_cell($item, $params) {
+          return '<td class="cell"> - </td>';
+    }
+}
+
+class grade_edit_tree_column_weightorextracredit extends grade_edit_tree_column {
+
+    public function get_header_cell() {
+        return '<th class="header" scope="col">'.get_string('weightorextracredit', 'grades').helpbutton('aggregationcoefweight', 'aggregationcoefweight', 'grade', true, false, '', true).'</th>';
+    }
+
+    public function get_category_cell($category, $levelclass, $params) {
+
+        $item = $category->get_grade_item();
+        $aggcoef_input = grade_edit_tree::get_weight_input($item);
+        return '<td class="cell '.$levelclass.'">' . $aggcoef_input . '</td>';
+    }
+
+    public function get_item_cell($item, $params) {
+        if (empty($params['element'])) {
+            throw new Exception('Array key (element) missing from 2nd param of grade_edit_tree_column_weightorextracredit::get_item_cell($item, $params)');
+        }
+
+        $aggcoef_input = grade_edit_tree::get_weight_input($item);
+        $html = '<td class="cell">';
+
+        if ($params['element']['type'] == 'categoryitem' || $params['element']['type'] == 'courseitem') {
+            $html .= $aggcoef_input;
+        }
+
+        return $html.'</td>';
+    }
+
+    public function is_hidden($mode='simple') {
+        global $CFG;
+        if ($mode == 'simple') {
+            return strstr($CFG->grade_item_advanced, 'aggregationcoef');
+        } elseif ($mode == 'advanced') {
+            return false;
+        }
+    }
+}
+
+class grade_edit_tree_column_range extends grade_edit_tree_column {
+
+    public function get_header_cell() {
+        return '<th class="header" scope="col">'.get_string('maxgrade', 'grades').'</th>';
+    }
+
+    public function get_category_cell($category, $levelclass, $params) {
+        return '<td class="cell range '.$levelclass.'"> - </td>';
+    }
+
+    public function get_item_cell($item, $params) {
+        if ($item->gradetype == GRADE_TYPE_SCALE) {
+            $scale = get_record('scale', 'id', $item->scaleid);
+            $scale_items = explode(',', $scale->scale);
+            $grademax = end($scale_items) . ' (' . count($scale_items) . ')';
+        } elseif ($item->is_external_item()) {
+            $grademax = format_float($item->grademax, $item->get_decimals());
+        } else {
+            $grademax = '<input type="text" size="3" id="grademax'.$item->id.'" name="grademax'.$item->id.'" value="'.format_float($item->grademax, $item->get_decimals()).'" />';
+        }
+
+        return '<td class="cell">'.$grademax.'</td>';
+    }
+
+    public function is_hidden($mode='simple') {
+        global $CFG;
+        if ($mode == 'simple') {
+            return strstr($CFG->grade_item_advanced, 'grademax');
+        } elseif ($mode == 'advanced') {
+            return false;
+        }
+    }
+}
+
+class grade_edit_tree_column_aggregateonlygraded extends grade_edit_tree_column_category {
+
+    public function __construct($params) {
+        parent::__construct('aggregateonlygraded');
+    }
+
+    public function get_header_cell() {
+        return '<th class="header" style="width: 40px" scope="col">'.get_string('aggregateonlygraded', 'grades')
+              .helpbutton('aggregateonlygraded', 'aggregateonlygraded', 'grade', true, false, '', true).'</th>';
+    }
+
+    public function get_category_cell($category, $levelclass, $params) {
+        $onlygradedcheck = ($category->aggregateonlygraded == 1) ? 'checked="checked"' : '';
+        $aggregateonlygraded ='<input type="checkbox" id="aggregateonlygraded_'.$category->id.'" name="aggregateonlygraded_'.$category->id.'" '.$onlygradedcheck . ' />';
+        $hidden = '<input type="hidden" name="aggregateonlygraded_original_'.$category->id.'" value="'.$category->aggregateonlygraded.'" />';
+
+        if ($this->forced) {
+            $aggregateonlygraded = ($category->aggregateonlygraded) ? get_string('yes') : get_string('no');
+        }
+
+        return '<td class="cell '.$levelclass.'">' . $aggregateonlygraded . '</td>';
+    }
+
+    public function get_item_cell($item, $params) {
+        return '<td class="cell"> - </td>';
+    }
+}
+
+class grade_edit_tree_column_aggregatesubcats extends grade_edit_tree_column_category {
+
+    public function __construct($params) {
+        parent::__construct('aggregatesubcats');
+    }
+
+    public function get_header_cell() {
+        return '<th class="header" style="width: 40px" scope="col">'.get_string('aggregatesubcats', 'grades')
+              .helpbutton('aggregatesubcats', 'aggregatesubcats', 'grade', true, false, '', true).'</th>';
+    }
+
+    public function get_category_cell($category, $levelclass, $params) {
+        $subcatscheck = ($category->aggregatesubcats == 1) ? 'checked="checked"' : '';
+        $aggregatesubcats = '<input type="checkbox" id="aggregatesubcats_'.$category->id.'" name="aggregatesubcats_'.$category->id.'" ' . $subcatscheck.' />';
+        $hidden = '<input type="hidden" name="aggregatesubcats_original_'.$category->id.'" value="'.$category->aggregatesubcats.'" />';
+
+        if ($this->forced) {
+            $aggregatesubcats = ($category->aggregatesubcats) ? get_string('yes') : get_string('no');
+        }
+
+        return '<td class="cell '.$levelclass.'">' . $aggregatesubcats . $hidden.'</td>';
+
+    }
+
+    public function get_item_cell($item, $params) {
+        return '<td class="cell"> - </td>';
+    }
+}
+
+class grade_edit_tree_column_aggregateoutcomes extends grade_edit_tree_column_category {
+
+    public function __construct($params) {
+        parent::__construct('aggregateoutcomes');
+    }
+
+    public function get_header_cell() {
+        return '<th class="header" style="width: 40px" scope="col">'.get_string('aggregateoutcomes', 'grades')
+              .helpbutton('aggregateoutcomes', 'aggregateoutcomes', 'grade', true, false, '', true).'</th>';
+    }
+
+    public function get_category_cell($category, $levelclass, $params) {
+
+        $outcomescheck = ($category->aggregateoutcomes == 1) ? 'checked="checked"' : '';
+        $aggregateoutcomes = '<input type="checkbox" id="aggregateoutcomes_'.$category->id.'" name="aggregateoutcomes_'.$category->id.'" ' . $outcomescheck.' />';
+        $hidden = '<input type="hidden" name="aggregateoutcomes_original_'.$category->id.'" value="'.$category->aggregateoutcomes.'" />';
+
+        if ($this->forced) {
+            $aggregateoutcomes = ($category->aggregateoutcomes) ? get_string('yes') : get_string('no');
+        }
+
+        return '<td class="cell '.$levelclass.'">' . $aggregateoutcomes . $hidden.'</td>';
+    }
+
+    public function get_item_cell($item, $params) {
+        return '<td class="cell"> - </td>';
+    }
+
+    public function is_hidden($mode='simple') {
+        global $CFG;
+        if ($CFG->enableoutcomes) {
+            return parent::is_hidden($mode);
+        } else {
+            return true;
+        }
+    }
+}
+
+class grade_edit_tree_column_droplow extends grade_edit_tree_column_category {
+
+    public function __construct($params) {
+        parent::__construct('droplow');
+    }
+
+    public function get_header_cell() {
+        return '<th class="header" scope="col">'.get_string('droplow', 'grades').helpbutton('droplow', 'droplow', 'grade', true, false, '', true).'</th>';
+    }
+
+    public function get_category_cell($category, $levelclass, $params) {
+        $droplow = '<input type="text" size="3" id="droplow_'.$category->id.'" name="droplow_'.$category->id.'" value="'.$category->droplow.'" />';
+
+        if ($this->forced) {
+            $droplow = $category->droplow;
+        }
+
+        return '<td class="cell '.$levelclass.'">' . $droplow . '</td>';
+    }
+
+    public function get_item_cell($item, $params) {
+        return '<td class="cell"> - </td>';
+    }
+}
+
+class grade_edit_tree_column_keephigh extends grade_edit_tree_column_category {
+
+    public function __construct($params) {
+        parent::__construct('keephigh');
+    }
+
+    public function get_header_cell() {
+        return '<th class="header" scope="col">'.get_string('keephigh', 'grades').helpbutton('keephigh', 'keephigh', 'grade', true, false, '', true).'</th>';
+    }
+
+    public function get_category_cell($category, $levelclass, $params) {
+        $keephigh = '<input type="text" size="3" id="keephigh_'.$category->id.'" name="keephigh_'.$category->id.'" value="'.$category->keephigh.'" />';
+
+        if ($this->forced) {
+            $keephigh = $category->keephigh;
+        }
+
+        return '<td class="cell '.$levelclass.'">' . $keephigh . '</td>';
+    }
+
+    public function get_item_cell($item, $params) {
+        return '<td class="cell"> - </td>';
+    }
+}
+
+class grade_edit_tree_column_multfactor extends grade_edit_tree_column {
+
+    public function __construct($params) {
+
+    }
+
+    public function get_header_cell() {
+        return '<th class="header" scope="col">'.get_string('multfactor', 'grades').helpbutton('multfactor', 'multfactor', 'grade', true, false, '', true).'</th>';
+    }
+
+    public function get_category_cell($category, $levelclass, $params) {
+
+        return '<td class="cell '.$levelclass.'"> - </td>';
+    }
+
+    public function get_item_cell($item, $params) {
+        $multfactor = '<input type="text" size="3" id="multfactor'.$item->id.'" name="multfactor'.$item->id.'" value="'.format_float($item->multfactor).'" />';
+        return '<td class="cell">'.$multfactor.'</td>';
+    }
+
+    public function is_hidden($mode='simple') {
+        global $CFG;
+        if ($mode == 'simple') {
+            return strstr($CFG->grade_item_advanced, 'multfactor');
+        } elseif ($mode == 'advanced') {
+            return false;
+        }
+    }
+}
+
+class grade_edit_tree_column_plusfactor extends grade_edit_tree_column {
+
+    public function get_header_cell() {
+        return '<th class="header" scope="col">'.get_string('plusfactor', 'grades').helpbutton('plusfactor', 'plusfactor', 'grade', true, false, '', true).'</th>';
+    }
+
+    public function get_category_cell($category, $levelclass, $params) {
+        return '<td class="cell '.$levelclass.'"> - </td>';
+
+    }
+
+    public function get_item_cell($item, $params) {
+        $plusfactor = '<input type="text" size="3" id="plusfactor_'.$item->id.'" name="plusfactor_'.$item->id.'" value="'.format_float($item->plusfactor).'" />';
+        return '<td class="cell">'.$plusfactor.'</td>';
+
+    }
+
+    public function is_hidden($mode='simple') {
+        global $CFG;
+        if ($mode == 'simple') {
+            return strstr($CFG->grade_item_advanced, 'plusfactor');
+        } elseif ($mode == 'advanced') {
+            return false;
+        }
+    }
+}
+
+class grade_edit_tree_column_actions extends grade_edit_tree_column {
+
+    public function __construct($params) {
+
+    }
+
+    public function get_header_cell() {
+        return '<th class="header actions" scope="col">'.get_string('actions').'</th>';
+    }
+
+    public function get_category_cell($category, $levelclass, $params) {
+
+        if (empty($params['actions'])) {
+            throw new Exception('Array key (actions) missing from 3rd param of grade_edit_tree_column_actions::get_category_actions($category, $levelclass, $params)');
+        }
+
+        return '<td class="cell actions '.$levelclass.'">' . $params['actions'] . '</td>';
+    }
+
+    public function get_item_cell($item, $params) {
+        if (empty($params['actions'])) {
+            throw new Exception('Array key (actions) missing from 2nd param of grade_edit_tree_column_actions::get_item_cell($item, $params)');
+        }
+        return '<td class="cell actions">' . $params['actions'] . '</td>';
+    }
+
+    public function is_hidden($mode='simple') {
+        return false;
+    }
+}
+
+class grade_edit_tree_column_select extends grade_edit_tree_column {
+
+    public function get_header_cell() {
+        return '<th class="header selection" scope="col">'.get_string('select').'</th>';
+    }
+
+    public function get_category_cell($category, $levelclass, $params) {
+
+        if (empty($params['eid'])) {
+            throw new Exception('Array key (eid) missing from 3rd param of grade_edit_tree_column_select::get_category_cell($category, $levelclass, $params)');
+        }
+
+        return '<td class="cell last  '.$levelclass.'" style="text-align: center">
+                    <span class="actionlink" onclick="togglecheckboxes(\''.$params['eid'].'\', true);">'.get_string('all').'</span><br />
+                    <span class="actionlink" onclick="togglecheckboxes(\''.$params['eid'].'\', false);">'.get_string('none').'</span>
+                </td>';
+    }
+
+    public function get_item_cell($item, $params) {
+        if (empty($params['itemtype']) || empty($params['eid'])) {
+            throw new Exception('Array key (itemtype or eid) missing from 2nd param of grade_edit_tree_column_select::get_item_cell($item, $params)');
+        }
+        $itemselect = '';
+
+        if ($params['itemtype'] != 'course' && $params['itemtype'] != 'category') {
+            $itemselect = '<input class="itemselect" type="checkbox" name="select_'.$params['eid'].'" />';
+        }
+        return '<td class="cell last selection">' . $itemselect . '</td>';
+    }
+
+    public function is_hidden($mode='simple') {
+        return false;
+    }
+}
+?>
index 8eb27d635413c0bf0bb5da38dae9e78b645f18be..3cab996fdf91de46a779486241363be029bbf964 100644 (file)
@@ -50,6 +50,8 @@ if ($mform->is_cancelled() || empty($CFG->enableoutcomes)) {
     redirect($returnurl);
 }
 
+$heading = get_string('outcomeitemsedit', 'grades');
+
 if ($grade_item = grade_item::fetch(array('id'=>$id, 'courseid'=>$courseid))) {
     // redirect if outcomeid present
     if (empty($grade_item->outcomeid)) {
@@ -69,6 +71,7 @@ if ($grade_item = grade_item::fetch(array('id'=>$id, 'courseid'=>$courseid))) {
     }
 
 } else {
+    $heading = get_string('newoutcomeitem', 'grades');
     $grade_item = new grade_item(array('courseid'=>$courseid, 'itemtype'=>'manual'), false);
     $item = $grade_item->get_record_data();
     $item->cmid = 0;
@@ -206,14 +209,7 @@ if ($data = $mform->get_data()) {
     redirect($returnurl);
 }
 
-$strgrades       = get_string('grades');
-$strgraderreport = get_string('graderreport', 'grades');
-$stroutcomesedit = get_string('outcomeitemsedit', 'grades');
-$stroutcome      = get_string('outcomeitem', 'grades');
-
-$navigation = grade_build_nav(__FILE__, $stroutcome, array('courseid' => $courseid));
-
-print_header_simple($strgrades . ': ' . $strgraderreport, ': ' . $stroutcomesedit, $navigation, '', '', true, '', navmenu($course));
+print_grade_page_head($courseid, 'edittree', null, $heading);
 
 if (!grade_outcome::fetch_all_available($COURSE->id)) {
     notice_yesno(get_string('nooutcomes', 'grades'), $CFG->wwwroot.'/grade/edit/outcome/course.php?id='.$courseid, $returnurl);
diff --git a/grade/edit/tree/tree.css b/grade/edit/tree/tree.css
new file mode 100755 (executable)
index 0000000..c56e6a0
--- /dev/null
@@ -0,0 +1,133 @@
+.gradetreebox {
+    font-size: 0.8em;
+}
+
+.gradetreebox input, .gradetreebox select {
+    font-size: 85%;
+}
+.gradetreebox tr.category td {
+    background-color: #DDDDDD;
+}
+.gradetreebox tr.category th {
+    background-color: #DDDDDD;
+}
+.gradetreebox tr.category td.name {
+    border-left: 0px;
+}
+
+.gradetreebox .category td.name h4 {
+    display: inline;
+}
+
+.gradetreebox td.name, .gradetreebox td.range, .gradetreebox td.actions   {
+    white-space: nowrap;
+}
+
+.gradetreebox th.actions {
+    width: 80px;
+}
+
+.child {
+    background-image: url(img/ln.gif);
+}
+
+.hidden {
+    display: none;
+}
+.shown {
+}
+
+img.iconsmall {
+    margin-left: 4px;
+}
+
+img.icon {
+    margin-right: 5px;
+}
+
+.grade-edit-tree .gradetreebox  {
+    margin-left: auto;
+    margin-right: auto;
+    margin-top: 10px;
+    padding-bottom: 15px;
+    width: auto;
+}
+
+.gradetreebox table {
+    margin-left: auto;
+    margin-right: auto;
+}
+
+.buttons {
+    margin: 20px;
+    text-align: center;
+    width: 100%;
+}
+
+.buttons .singlebutton {
+    display: inline;
+    padding: 5px;
+}
+
+#gradetreesubmit {
+    width: 100%;
+    text-align: center;
+    margin-top: 10px;
+
+}
+
+.gradetreebox span.actionlink {
+ color: blue;
+}
+
+.gradetreebox span.actionlink:hover {
+ text-decoration: underline;
+ cursor: pointer;
+}
+
+.gradetreebox td.colspan {
+    border-left: 1px solid #AAAAAA;
+    border-bottom: 1px solid #AAAAAA;
+    border-top: none;
+    background-color: #DDDDDD;
+}
+
+.gradetreebox tr.category th.rowspan {
+    border-color: #AAAAAA;
+    border-bottom: 0px;
+    border-top: 0px;
+    border-right: 0px !important;
+}
+
+.gradetreebox tr.category th.rowspan:hover {
+    background-color: #EEEEEE !important;
+}
+
+.level1 {
+    background-color: #d0dbf3 !important;
+    width: 10px;
+}
+.level2 {
+    background-color: #f3dfd0 !important;
+    width: 10px;
+}
+.level3 {
+    background-color: #d0f3d6 !important;
+    width: 10px;
+}
+.level4 {
+    background-color: #eae8be !important;
+    width: 10px;
+}
+.level5 {
+    background-color: #ebdef6 !important;
+    width: 10px;
+}
+
+.gradetreebox table.generaltable {
+    border:  1px solid #AAAAAA;
+    width: 100%;
+}
+
+
+
index faf484ac4ab41a8af3c54b52920f09ee46648072..462c7085fa06fff47a831157caf96f02c02e5be6 100755 (executable)
@@ -39,13 +39,7 @@ $context = get_context_instance(CONTEXT_COURSE, $id);
 require_capability('moodle/grade:export', $context);
 require_capability('gradeexport/ods:view', $context);
 
-
-$strgrades = get_string('grades', 'grades');
-$actionstr = get_string('modulename', 'gradeexport_ods');
-$navigation = grade_build_nav(__FILE__, $actionstr, array('courseid' => $course->id));
-
-print_header($course->shortname.': '.get_string('grades'), $course->fullname, $navigation);
-print_grade_plugin_selector($id, 'export', 'ods');
+print_grade_page_head($COURSE->id, 'export', 'ods', get_string('exportto', 'grades') . ' ' . get_string('modulename', 'gradeexport_ods'));
 
 if (!empty($CFG->gradepublishing)) {
     $CFG->gradepublishing = has_capability('gradeexport/ods:publish', $context);
index ea78755adcca7442b362dd6094c324f7bd6cddb6..db4059d94f11f93c92121837df51540f23dcd51c 100755 (executable)
@@ -39,13 +39,7 @@ $context = get_context_instance(CONTEXT_COURSE, $id);
 require_capability('moodle/grade:export', $context);
 require_capability('gradeexport/txt:view', $context);
 
-
-$strgrades = get_string('grades', 'grades');
-$actionstr = get_string('modulename', 'gradeexport_txt');
-$navigation = grade_build_nav(__FILE__, $actionstr, array('courseid' => $course->id));
-
-print_header($course->shortname.': '.get_string('grades'), $course->fullname, $navigation);
-print_grade_plugin_selector($id, 'export', 'txt');
+print_grade_page_head($COURSE->id, 'export', 'txt', get_string('exportto', 'grades') . ' ' . get_string('modulename', 'gradeexport_txt'));
 
 if (!empty($CFG->gradepublishing)) {
     $CFG->gradepublishing = has_capability('gradeexport/txt:publish', $context);
index b2d6eaf916d0ff3d921b6b9781061147c1034a7f..f03d26268718517bc3783392832c28d50927bce3 100755 (executable)
@@ -39,13 +39,7 @@ $context = get_context_instance(CONTEXT_COURSE, $id);
 require_capability('moodle/grade:export', $context);
 require_capability('gradeexport/xls:view', $context);
 
-
-$strgrades = get_string('grades', 'grades');
-$actionstr = get_string('modulename', 'gradeexport_xls');
-$navigation = grade_build_nav(__FILE__, $actionstr, array('courseid' => $course->id));
-
-print_header($course->shortname.': '.get_string('grades'), $course->fullname, $navigation);
-print_grade_plugin_selector($id, 'export', 'xls');
+print_grade_page_head($COURSE->id, 'export', 'xls', get_string('exportto', 'grades') . ' ' . get_string('modulename', 'gradeexport_xls'));
 
 if (!empty($CFG->gradepublishing)) {
     $CFG->gradepublishing = has_capability('gradeexport/xls:publish', $context);
index 8b8dae34a2c21cf4f396ce3c41979b682f0df966..764784c64cc8bdd2b1637659b93b53ad0c85b315 100755 (executable)
@@ -39,13 +39,7 @@ $context = get_context_instance(CONTEXT_COURSE, $id);
 require_capability('moodle/grade:export', $context);
 require_capability('gradeexport/xml:view', $context);
 
-
-$strgrades = get_string('grades', 'grades');
-$actionstr = get_string('modulename', 'gradeexport_xml');
-$navigation = grade_build_nav(__FILE__, $actionstr, array('courseid' => $course->id));
-
-print_header($course->shortname.': '.get_string('grades'), $course->fullname, $navigation);
-print_grade_plugin_selector($id, 'export', 'xml');
+print_grade_page_head($COURSE->id, 'export', 'xml', get_string('exportto', 'grades') . ' ' . get_string('modulename', 'gradeexport_xml'));
 
 if (!empty($CFG->gradepublishing)) {
     $CFG->gradepublishing = has_capability('gradeexport/xml:publish', $context);
index ace73d7e4bf27afb5463aedad7cf214eca092e25..639f97df5ceb2486fd06bfd6746b112c7ed11b3e 100755 (executable)
@@ -59,12 +59,7 @@ if (isset($CFG->CSV_DELIMITER)) {
     $csv_encode = '/\&\#44/';
 }
 
-$strgrades = get_string('grades', 'grades');
-$actionstr = get_string('csv', 'grades');
-$navigation = grade_build_nav(__FILE__, $actionstr, array('courseid' => $course->id));
-
-print_header($course->shortname.': '.get_string('grades'), $course->fullname, $navigation);
-print_grade_plugin_selector($id, 'import', 'csv');
+print_grade_page_head($course->id, 'import', 'csv', get_string('importcsv', 'grades'));
 
 // set up import form
 $mform = new grade_import_form(null, array('includeseparator'=>!isset($CFG->CSV_DELIMITER), 'verbosescales'=>true));
@@ -379,7 +374,7 @@ if ($formdata = $mform->get_data()) {
                                 } else {
                                     $scale = $gradeitem->load_scale();
                                     $scales = explode(',', $scale->scale);
-                                    $scales = array_map('trim', $scales); //hack - trim whitespace around scale options 
+                                    $scales = array_map('trim', $scales); //hack - trim whitespace around scale options
                                     array_unshift($scales, '-'); // scales start at key 1
                                     $key = array_search($value, $scales);
                                     if ($key === false) {
@@ -396,7 +391,7 @@ if ($formdata = $mform->get_data()) {
                             } else {
                                 if ($value === '' or $value == '-') {
                                     $value = null; // no grade
-    
+
                                 } else if (!is_numeric($value)) {
                                 // non numeric grade value supplied, possibly mapped wrong column
                                     echo "<br/>t0 is $t0";
index 662deca097f485b88b472ceaca4bf2bb7495ad96..ca77c5a09b3c85932bbff1b6d04199cb32b1eacb 100755 (executable)
@@ -41,7 +41,6 @@ require_capability('gradeimport/xml:view', $context);
 // print header
 $strgrades = get_string('grades', 'grades');
 $actionstr = get_string('modulename', 'gradeimport_xml');
-$navigation = grade_build_nav(__FILE__, $actionstr, array('courseid' => $course->id));
 
 if (!empty($CFG->gradepublishing)) {
     $CFG->gradepublishing = has_capability('gradeimport/xml:publish', $context);
@@ -60,8 +59,7 @@ if ($data = $mform->get_data()) {
     }
 
     if ($text = $mform->get_file_content('userfile')) {
-        print_header($course->shortname.': '.get_string('grades'), $course->fullname, $navigation);
-        print_grade_plugin_selector($id, 'import', 'xml');
+        print_grade_page_head($COURSE->id, 'import', 'xml', get_string('importxml', 'grades'));
 
         $error = '';
         $importcode = import_xml_grades($text, $course, $error);
@@ -84,8 +82,7 @@ if ($data = $mform->get_data()) {
             $data->key = create_user_key('grade/import', $USER->id, $course->id, $data->iprestriction, $data->validuntil);
         }
 
-        print_header($course->shortname.': '.get_string('grades'), $course->fullname, $navigation);
-        print_grade_plugin_selector($id, 'import', 'xml');
+        print_grade_page_head($COURSE->id, 'import', 'xml', get_string('importxml', 'grades'));
 
         echo '<div class="gradeexportlink">';
         $link = $CFG->wwwroot.'/grade/import/xml/fetch.php?id='.$id.'&amp;feedback='.(int)($data->feedback).'&amp;url='.urlencode($data->url).'&amp;key='.$data->key;
@@ -96,8 +93,7 @@ if ($data = $mform->get_data()) {
     }
 }
 
-print_header($course->shortname.': '.get_string('grades'), $course->fullname, $navigation);
-print_grade_plugin_selector($id, 'import', 'xml');
+print_grade_page_head($COURSE->id, 'import', 'xml', get_string('importxml', 'grades'));
 
 $mform->display();
 
index d4352e3523e3e0419991901c07ccc083a4487dbb..0fc3150582e8c87aceabcf30c8bfa593be04ecb7 100644 (file)
@@ -312,14 +312,132 @@ function print_graded_users_selector($course, $actionpage, $userid=null, $return
  * @param boolean $return return as string
  * @return nothing or string if $return true
  */
-function print_grade_plugin_selector($courseid, $active_type, $active_plugin, $return=false) {
+function print_grade_plugin_selector($plugin_info, $return=false) {
+    global $CFG;
+
+    $menu = array();
+    $count = 0;
+    $active = '';
+
+    foreach ($plugin_info as $plugin_type => $plugins) {
+        if ($plugin_type == 'strings') {
+            continue;
+        }
+
+        $menu[$plugin_type.'group'] = '--'.$plugin_info['strings'][$plugin_type];
+
+        if (!empty($plugins['id'])) {
+            $menu[$plugins['link']] = $plugins['string'];
+        } else {
+            foreach ($plugins as $plugin) {
+                $menu[$plugin['link']] = $plugin['string'];
+                $count++;
+            }
+        }
+    }
+
+/// finally print/return the popup form
+    if ($count > 1) {
+        return popup_form('', $menu, 'choosepluginreport', '', get_string('chooseaction', 'grades'), '', '', $return, 'self');
+    } else {
+        // only one option - no plugin selector needed
+        return '';
+    }
+}
+
+/**
+ * Print grading plugin selection tab-based navigation.
+ *
+ * @param int $courseid id of course
+ * @param string $active_type type of plugin on current page - import, export, report or edit
+ * @param string $active_plugin active plugin type - grader, user, cvs, ...
+ * @param boolean $return return as string
+ * @param string $preferences_page_url Unless false, the link to a preferences page to print in the second row of tabs next to the current link. If true, we are ON the preferences page
+ * @return nothing or string if $return true
+ */
+function grade_print_tabs($active_type, $active_plugin, $plugin_info, $return=false, $preferences_page_url=false) {
+    global $CFG, $COURSE;
+
+    if (!isset($currenttab)) {
+        $currenttab = '';
+    }
+
+    $tabs = array();
+    $top_row  = array();
+    $bottom_row = array();
+    $inactive = array($active_plugin);
+    $activated = array();
+
+    $count = 0;
+    $active = '';
+
+    foreach ($plugin_info as $plugin_type => $plugins) {
+        if ($plugin_type == 'strings') {
+            continue;
+        }
+
+        // If $plugins is actually the definition of a child-less parent link:
+        if (!empty($plugins['id'])) {
+            $top_row[] = new tabobject($plugin_type, $plugins['link'], $plugins['string']);
+            continue;
+        }
+
+        $first_plugin = reset($plugins);
+        $url = $first_plugin['link'];
+
+        if ($plugin_type == 'report') {
+            $url = $CFG->wwwroot.'/grade/report/index.php?id='.$COURSE->id;
+        }
+
+        $top_row[] = new tabobject($plugin_type, $url, $plugin_info['strings'][$plugin_type]);
+
+        if ($active_type == $plugin_type) {
+            foreach ($plugins as $plugin) {
+                $bottom_row[] = new tabobject($plugin['id'], $plugin['link'], $plugin['string']);
+                if ($plugin['id'] == $active_plugin) {
+                    $inactive = array($plugin['id']);
+
+                    // Add preferences link if setup
+                    if ($preferences_page_url) {
+                        $bottom_row[] = new tabobject('preferences', $preferences_page_url, get_string('preferences'));
+                        if ($preferences_page_url === true) {
+                            $inactive = array('preferences');
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    $tabs[] = $top_row;
+    $tabs[] = $bottom_row;
+
+    if ($return) {
+        return print_tabs($tabs, $active_type, $inactive, $activated, true);
+    } else {
+        print_tabs($tabs, $active_type, $inactive, $activated);
+    }
+}
+
+function grade_get_plugin_info($courseid, $active_type, $active_plugin) {
     global $CFG;
 
     $context = get_context_instance(CONTEXT_COURSE, $courseid);
 
-    $menu = array();
+    $plugin_info = array();
     $count = 0;
     $active = '';
+    $url_prefix = $CFG->wwwroot . '/grade/';
+
+    // Language strings
+    $plugin_info['strings'] = array(
+        'report' => get_string('view'),
+        'edittree' => get_string('edittree', 'grades'),
+        'scale' => get_string('scales'),
+        'outcome' => get_string('outcomes', 'grades'),
+        'letter' => get_string('letters', 'grades'),
+        'export' => get_string('export', 'grades'),
+        'import' => get_string('import'));
 
 /// report plugins with its special structure
     if ($reports = get_list_of_plugins('grade/report', 'CVS')) {         // Get all installed reports
@@ -332,18 +450,105 @@ function print_grade_plugin_selector($courseid, $active_type, $active_plugin, $r
     $reportnames = array();
     if (!empty($reports)) {
         foreach ($reports as $plugin) {
-            $url = 'report/'.$plugin.'/index.php?id='.$courseid;
+            $url = $url_prefix.'report/'.$plugin.'/index.php?id='.$courseid;
             if ($active_type == 'report' and $active_plugin == $plugin ) {
                 $active = $url;
             }
-            $reportnames[$url] = get_string('modulename', 'gradereport_'.$plugin);
+            $reportnames[$plugin] = array('id' => $plugin, 'link' => $url, 'string' => get_string('modulename', 'gradereport_'.$plugin));
             $count++;
         }
         asort($reportnames);
     }
     if (!empty($reportnames)) {
-        $menu['reportgroup']='--'.get_string('view');
-        $menu = $menu+$reportnames;
+        $plugin_info['report']=$reportnames;
+    }
+
+/// editing scripts - not real plugins
+    if (has_capability('moodle/grade:manage', $context)
+      or has_capability('moodle/grade:manageletters', $context)
+      or has_capability('moodle/course:managescales', $context)
+      or has_capability('moodle/course:update', $context)) {
+
+        if (has_capability('moodle/grade:manage', $context)) {
+            $url = $url_prefix.'edit/tree/index.php?sesskey='.sesskey().'&amp;showadvanced=0&amp;id='.$courseid;
+            $url_adv = $url_prefix.'edit/tree/index.php?sesskey='.sesskey().'&amp;showadvanced=1&amp;id='.$courseid;
+
+            if ($active_type == 'edittree' and $active_plugin == 'simpleview') {
+                $active = $url;
+            } elseif ($active_type == 'edittree' and $active_plugin == 'fullview') {
+                $active = $url_adv;
+            }
+
+            $plugin_info['edittree'] = array();
+            $plugin_info['edittree']['simpleview'] = array('id' => 'simpleview', 'link' => $url, 'string' => get_string('simpleview', 'grades'));
+            $plugin_info['edittree']['fullview'] = array('id' => 'fullview', 'link' => $url_adv, 'string' => get_string('fullview', 'grades'));
+            $count++;
+        }
+
+        if (has_capability('moodle/course:managescales', $context)) {
+            $url = $url_prefix.'edit/scale/index.php?id='.$courseid;
+            if ($active_type == 'scale' and is_null($active_plugin)) {
+                $active = $url;
+            }
+            $plugin_info['scale'] = array('id' => 'scale', 'link' => $url, 'string' => get_string('scales'));
+            $count++;
+        }
+
+        if (!empty($CFG->enableoutcomes) && (has_capability('moodle/grade:manage', $context) or
+                                             has_capability('moodle/course:update', $context))) {
+
+            $url_course = $url_prefix.'edit/outcome/course.php?id='.$courseid;
+            $url_edit = $url_prefix.'edit/outcome/index.php?id='.$courseid;
+
+            $plugin_info['outcome'] = array();
+
+            if (has_capability('moodle/course:update', $context)) {  // Default to course assignment
+                $plugin_info['outcome']['course'] = array('id' => 'course', 'link' => $url_course, 'string' => get_string('outcomescourse', 'grades'));
+                $plugin_info['outcome']['edit'] = array('id' => 'edit', 'link' => $url_edit, 'string' => get_string('editoutcomes', 'grades'));
+            } else {
+                $plugin_info['outcome'] = array('id' => 'edit', 'link' => $url_course, 'string' => get_string('outcomescourse', 'grades'));
+            }
+
+            if ($active_type == 'outcome' and is_null($active_plugin)) {
+                $active = $url_edit;
+            } elseif ($active_type == 'outcome' and $active_plugin == 'course' ) {
+                $active = $url_course;
+            } elseif ($active_type == 'outcome' and $active_plugin == 'edit' ) {
+                $active = $url_edit;
+            }
+
+            $count++;
+        }
+
+        if (has_capability('moodle/grade:manage', $context) or has_capability('moodle/grade:manageletters', $context)) {
+            $course_context = get_context_instance(CONTEXT_COURSE, $courseid);
+            $url = $url_prefix.'edit/letter/index.php?id='.$courseid;
+            $url_edit = $url_prefix.'edit/letter/edit.php?id='.$course_context->id;
+
+            if ($active_type == 'letter' and $active_plugin == 'view' ) {
+                $active = $url;
+            } elseif ($active_type == 'letter' and $active_plugin == 'edit' ) {
+                $active = $url_edit;
+            }
+
+            $plugin_info['letter'] = array();
+            $plugin_info['letter']['view'] = array('id' => 'view', 'link' => $url, 'string' => get_string('view'));
+            $plugin_info['letter']['edit'] = array('id' => 'edit', 'link' => $url_edit, 'string' => get_string('edit'));
+            $count++;
+        }
+
+        /**
+         * Moving to Course settings
+         *
+        if (has_capability('moodle/grade:manage', $context)) {
+            $url = $url_prefix.'edit/settings/index.php?id='.$courseid;
+            if ($active_type == 'edit' and $active_plugin == 'settings' ) {
+                $active = $url;
+            }
+            $plugin_info['edit'][] = array('id' => $plugin, 'link' => $url, 'string' => get_string('coursesettings', 'grades'));
+            $count++;
+        }
+        */
     }
 
 /// standard import plugins
@@ -357,18 +562,17 @@ function print_grade_plugin_selector($courseid, $active_type, $active_plugin, $r
     $importnames = array();
     if (!empty($imports)) {
         foreach ($imports as $plugin) {
-            $url = 'import/'.$plugin.'/index.php?id='.$courseid;
+            $url = $url_prefix.'import/'.$plugin.'/index.php?id='.$courseid;
             if ($active_type == 'import' and $active_plugin == $plugin ) {
                 $active = $url;
             }
-            $importnames[$url] = get_string('modulename', 'gradeimport_'.$plugin);
+            $importnames[$plugin] = array('id' => $plugin, 'link' => $url, 'string' => get_string('modulename', 'gradeimport_'.$plugin));
             $count++;
         }
         asort($importnames);
     }
     if (!empty($importnames)) {
-        $menu['importgroup']='--'.get_string('importfrom', 'grades');
-        $menu = $menu+$importnames;
+        $plugin_info['import']=$importnames;
     }
 
 /// standard export plugins
@@ -382,94 +586,80 @@ function print_grade_plugin_selector($courseid, $active_type, $active_plugin, $r
     $exportnames = array();
     if (!empty($exports)) {
         foreach ($exports as $plugin) {
-            $url = 'export/'.$plugin.'/index.php?id='.$courseid;
+            $url = $url_prefix.'export/'.$plugin.'/index.php?id='.$courseid;
             if ($active_type == 'export' and $active_plugin == $plugin ) {
                 $active = $url;
             }
-            $exportnames[$url] = get_string('modulename', 'gradeexport_'.$plugin);
+            $exportnames[$plugin] = array('id' => $plugin, 'link' => $url, 'string' => get_string('modulename', 'gradeexport_'.$plugin));
             $count++;
         }
         asort($exportnames);
     }
+
     if (!empty($exportnames)) {
-        $menu['exportgroup']='--'.get_string('exportto', 'grades');
-        $menu = $menu+$exportnames;
+        $plugin_info['export']=$exportnames;
     }
 
-/// editing scripts - not real plugins
-    if (has_capability('moodle/grade:manage', $context)
-      or has_capability('moodle/grade:manageletters', $context)
-      or has_capability('moodle/course:managescales', $context)
-      or has_capability('moodle/course:update', $context)) {
-        $menu['edit']='--'.get_string('edit');
-
-        if (has_capability('moodle/grade:manage', $context)) {
-            $url = 'edit/tree/index.php?id='.$courseid;
-            if ($active_type == 'edit' and $active_plugin == 'tree' ) {
-                $active = $url;
-            }
-            $menu[$url] = get_string('edittree', 'grades');
-            $count++;
+    foreach ($plugin_info as $plugin_type => $plugins) {
+        if (!empty($plugins['id']) && $active_plugin == $plugins['id']) {
+            $plugin_info['strings']['active_plugin_str'] = $plugins['string'];
+            break;
         }
-
-        if (has_capability('moodle/course:managescales', $context)) {
-            $url = 'edit/scale/index.php?id='.$courseid;
-            if ($active_type == 'edit' and $active_plugin == 'scale' ) {
-                $active = $url;
+        foreach ($plugins as $plugin) {
+            if ($active_plugin == $plugin['id']) {
+                $plugin_info['strings']['active_plugin_str'] = $plugin['string'];
             }
-            $menu[$url] = get_string('scales');
-            $count++;
         }
+    }
 
-        if (!empty($CFG->enableoutcomes) && (has_capability('moodle/grade:manage', $context) or
-                                             has_capability('moodle/course:update', $context))) {
-            if (has_capability('moodle/course:update', $context)) {  // Default to course assignment
-                $url = 'edit/outcome/course.php?id='.$courseid;
-            } else {
-                $url = 'edit/outcome/index.php?id='.$courseid;
-            }
-            if ($active_type == 'edit' and $active_plugin == 'outcome' ) {
-                $active = $url;
-            }
-            $menu[$url] = get_string('outcomes', 'grades');
-            $count++;
-        }
+    return $plugin_info;
+}
 
-        if (has_capability('moodle/grade:manage', $context) or has_capability('moodle/grade:manageletters', $context)) {
-            $url = 'edit/letter/index.php?id='.$courseid;
-            if ($active_type == 'edit' and $active_plugin == 'letter' ) {
-                $active = $url;
-            }
-            $menu[$url] = get_string('letters', 'grades');
-            $count++;
-        }
+function print_grade_page_head($courseid, $active_type, $active_plugin=null, $heading = false, $return=false, $meta='', $preferences_page_url=false, $buttons=false) {
+    global $CFG, $COURSE;
+    $strgrades = get_string('grades');
+    $plugin_info = grade_get_plugin_info($courseid, $active_type, $active_plugin);
 
-        if (has_capability('moodle/grade:manage', $context)) {
-            $url = 'edit/settings/index.php?id='.$courseid;
-            if ($active_type == 'edit' and $active_plugin == 'settings' ) {
-                $active = $url;
-            }
-            $menu[$url] = get_string('coursesettings', 'grades');
-            $count++;
-        }
+    // Determine the string of the active plugin
+    $stractive_plugin = ($active_plugin) ? $plugin_info['strings']['active_plugin_str'] : $heading;
+    $stractive_type = $plugin_info['strings'][$active_type];
 
-        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++;
-        }
+    $navlinks = array();
+    $navlinks[] = array('name' => $strgrades,
+                        'link' => $CFG->wwwroot.'/grade/index.php?id='.$COURSE->id,
+                        'type' => 'misc');
+
+    $active_type_link = '';
+
+    if (!empty($plugin_info[$active_type]['link'])) {
+        $active_type_link = $plugin_info[$active_type]['link'];
     }
 
-/// finally print/return the popup form
-    if ($count > 1) {
-        return popup_form($CFG->wwwroot.'/grade/', $menu, 'choosepluginreport', '',
-                get_string('chooseaction', 'grades'), '', '', $return, 'self');
+    $navlinks[] = array('name' => $stractive_type, 'link' => $active_type_link, 'type' => 'misc');
+
+    if ($preferences_page_url === true) {
+        $navlinks[] = array('name' => $stractive_plugin, 'link' => $plugin_info[$active_type][$active_plugin]['link'], 'type' => 'misc');
+        $navlinks[] = array('name' => get_string('preferences'), 'link' => null, 'type' => 'misc');
     } else {
-        // only one option - no plugin selector needed
-        return '';
+        $navlinks[] = array('name' => $stractive_plugin, 'link' => null, 'type' => 'misc');
+    }
+
+    $navigation = build_navigation($navlinks);
+
+    $returnval = print_header_simple($strgrades . ': ' . $stractive_type, ': ' . $stractive_type . ': ' . $stractive_plugin, $navigation, '',
+            $meta, true, $buttons, navmenu($COURSE), false, '', $return);
+
+    // Guess heading if not given explicitly
+    if (!$heading) {
+        $heading = $stractive_plugin;
+    }
+
+    $returnval .= print_grade_plugin_selector($plugin_info, $return);
+    $returnval .= print_heading($heading);
+    $returnval .= grade_print_tabs($active_type, $active_plugin, $plugin_info, $return, $preferences_page_url);
+
+    if ($return) {
+        return $returnval;
     }
 }
 
@@ -802,7 +992,8 @@ class grade_structure {
             case 'courseitem':
             case 'categoryitem':
                 if ($element['object']->is_calculated()) {
-                    return '<img src="'.$CFG->pixpath.'/i/calc.gif" class="icon itemicon" alt="'.get_string('calculation', 'grades').'"/>';
+                    $strcalc = get_string('calculatedgrade', 'grades');
+                    return '<img src="'.$CFG->pixpath.'/i/calc.gif" class="icon itemicon" title="'.$strcalc.'" alt="'.$strcalc.'"/>';
 
                 } else if (($element['object']->is_course_item() or $element['object']->is_category_item())
                   and ($element['object']->gradetype == GRADE_TYPE_SCALE or $element['object']->gradetype == GRADE_TYPE_VALUE)) {
@@ -813,27 +1004,32 @@ class grade_structure {
                             case GRADE_AGGREGATE_WEIGHTED_MEAN:
                             case GRADE_AGGREGATE_WEIGHTED_MEAN2:
                             case GRADE_AGGREGATE_EXTRACREDIT_MEAN:
-                                return '<img src="'.$CFG->pixpath.'/i/agg_mean.gif" class="icon itemicon" alt="'.get_string('aggregation', 'grades').'"/>';
+                                $stragg = get_string('aggregation', 'grades');
+                                return '<img src="'.$CFG->pixpath.'/i/agg_mean.gif" class="icon itemicon" title="'.$stragg.'" alt="'.$stragg.'"/>';
                             case GRADE_AGGREGATE_SUM:
-                                return '<img src="'.$CFG->pixpath.'/i/agg_sum.gif" class="icon itemicon" alt="'.get_string('aggregation', 'grades').'"/>';
+                                $stragg = get_string('aggregation', 'grades');
+                                return '<img src="'.$CFG->pixpath.'/i/agg_sum.gif" class="icon itemicon" title="'.$stragg.'" alt="'.$stragg.'"/>';
                         }
                     }
 
                 } else if ($element['object']->itemtype == 'mod') {
-                    return '<img src="'.$CFG->modpixpath.'/'.$element['object']->itemmodule.'/icon.gif" class="icon itemicon" alt="'
-                           .get_string('modulename', $element['object']->itemmodule).'"/>';
+                    $strmodname = get_string('modulename', $element['object']->itemmodule);
+                    return '<img src="'.$CFG->modpixpath.'/'.$element['object']->itemmodule.'/icon.gif" class="icon itemicon" title="' .$strmodname.'" alt="' .$strmodname.'"/>';
 
                 } else if ($element['object']->itemtype == 'manual') {
                     if ($element['object']->is_outcome_item()) {
-                        return '<img src="'.$CFG->pixpath.'/i/outcomes.gif" class="icon itemicon" alt="'.get_string('outcome', 'grades').'"/>';
+                        $stroutcome = get_string('outcome', 'grades');
+                        return '<img src="'.$CFG->pixpath.'/i/outcomes.gif" class="icon itemicon" title="'.$stroutcome.'" alt="'.$stroutcome.'"/>';
                     } else {
-                        return '<img src="'.$CFG->pixpath.'/t/manual_item.gif" class="icon itemicon" alt="'.get_string('manualitem', 'grades').'"/>';
+                        $strmanual = get_string('manualitem', 'grades');
+                        return '<img src="'.$CFG->pixpath.'/t/manual_item.gif" class="icon itemicon" title="'.$strmanual.'" alt="'.$strmanual.'"/>';
                     }
                 }
                 break;
 
             case 'category':
-                return '<img src="'.$CFG->pixpath.'/f/folder.gif" class="icon itemicon" alt="'.get_string('category', 'grades').'"/>';
+                $strcat = get_string('category', 'grades');
+                return '<img src="'.$CFG->pixpath.'/f/folder.gif" class="icon itemicon" title="'.$strcat.'" alt="'.$strcat.'" />';
         }
 
         if ($spacerifnone) {
@@ -860,8 +1056,7 @@ class grade_structure {
             $header .= $this->get_element_icon($element, $spacerifnone);
         }
 
-        $title = $element['object']->get_name();
-        $header .= $title;
+        $header .= $element['object']->get_name();
 
         if ($element['type'] != 'item' and $element['type'] != 'categoryitem' and $element['type'] != 'courseitem') {
             return $header;
@@ -874,6 +1069,8 @@ class grade_structure {
         if ($withlink and $itemtype=='mod' and $iteminstance and $itemmodule) {
             if ($cm = get_coursemodule_from_instance($itemmodule, $iteminstance, $this->courseid)) {
 
+                $a->name = get_string('modulename', $element['object']->itemmodule);
+                $title = get_string('linktoactivity', 'grades', $a);
                 $dir = $CFG->dirroot.'/mod/'.$itemmodule;
 
                 if (file_exists($dir.'/grade.php')) {
index 478b3b2cf136dcfa8445883c4cdbcb2e84d1ffc9..7b6edc084b01350c9453761303a68dc8a126de4e 100644 (file)
@@ -60,13 +60,6 @@ if (!isset($USER->grade_last_report)) {
 }
 $USER->grade_last_report[$course->id] = 'grader';
 
-/// Build navigation
-
-$strgrades  = get_string('grades');
-$reportname = get_string('modulename', 'gradereport_grader');
-
-$navigation = grade_build_nav(__FILE__, $reportname, $courseid);
-
 /// Build editing on/off buttons
 
 if (!isset($USER->gradeediting)) {
@@ -113,40 +106,14 @@ if (!is_null($toggle) && !empty($toggle_type)) {
 //first make sure we have proper final grades - this must be done before constructing of the grade tree
 grade_regrade_final_grades($courseid);
 
-// Perform actions.
+// Perform actions
 if (!empty($target) && !empty($action) && confirm_sesskey()) {
     grade_report_grader::process_action($target, $action);
 }
 
-$bodytags = '';
+// Initialise the grader report object
 $report = new grade_report_grader($courseid, $gpr, $context, $page, $sortitemid);
 
-// Initialise the grader report object
-if (ajaxenabled() && $report->get_pref('enableajax')) {
-    require_once $CFG->dirroot.'/grade/report/grader/ajaxlib.php';
-
-    require_js(array('yui_yahoo',
-                     'yui_dom',
-                     'yui_event',
-                     'yui_json',
-                     'yui_connection',
-                     'yui_dragdrop',
-                     'yui_animation'));
-
-    if (debugging('', DEBUG_DEVELOPER)) {
-        require_js(array('yui_logger'));
-
-        $bodytags = 'onload = "javascript:
-        show_logger = function() {
-            var logreader = new YAHOO.widget.LogReader();
-            logreader.newestOnTop = false;
-            logreader.setTitle(\'Moodle Debug: YUI Log Console\');
-        };
-        show_logger();
-        "';
-    }
-    $report = new grade_report_grader_ajax($courseid, $gpr, $context, $page, $sortitemid);
-}
 
 /// processing posted grades & feedback here
 if ($data = data_submitted() and confirm_sesskey() and has_capability('moodle/grade:edit', $context)) {
@@ -167,18 +134,19 @@ $numusers = $report->get_numusers();
 $report->load_final_grades();
 
 /// Print header
-print_header_simple($strgrades.': '.$reportname, ': '.$strgrades, $navigation, '', '', true, $buttons, navmenu($course), false, $bodytags);
+$meta = '<!--[if IE]><link rel="stylesheet" type="text/css" href="styles_ie.css" />'.
+             '<![endif]--><!--[if IE 6]><link rel="stylesheet" type="text/css" href="styles_ie6.css"'.
+             '/><![endif]-->';
+
+
+$reportname = get_string('modulename', 'gradereport_grader');
 
-/// Print the plugin selector at the top
-print_grade_plugin_selector($courseid, 'report', 'grader');
+print_grade_page_head($COURSE->id, 'report', 'grader', $reportname, false, $meta, $report->preferences_page, $buttons);
 
-// Add tabs
-$currenttab = 'graderreport';
-require('tabs.php');
 
 echo $report->group_selector;
 echo '<div class="clearer"></div>';
-echo $report->get_toggles_html();
+// echo $report->get_toggles_html();
 
 //show warnings if any
 foreach($warnings as $warning) {
@@ -191,20 +159,16 @@ if (!empty($studentsperpage)) {
     print_paging_bar($numusers, $report->page, $studentsperpage, $report->pbarurl);
 }
 
-require_js('grade/report/grader/functions.js');
-
-$reporthtml = '<div id="grader_report_message"></div>' . "\n";
-$reporthtml .= '<table id="user-grades" class="gradestable flexible boxaligncenter generaltable">';
-$reporthtml .= '<thead>';
+$reporthtml = '<script src="functions.js" type="text/javascript"></script>';
+$reporthtml .= '<div class="gradeparent">';
+$reporthtml .= $report->get_studentnameshtml();
 $reporthtml .= $report->get_headerhtml();
 $reporthtml .= $report->get_iconshtml();
+$reporthtml .= $report->get_studentshtml();
 $reporthtml .= $report->get_rangehtml();
-$reporthtml .= "</thead>\n<tfoot>";
 $reporthtml .= $report->get_avghtml(true);
 $reporthtml .= $report->get_avghtml();
-$reporthtml .= "</tfoot>\n<tbody>";
-$reporthtml .= $report->get_studentshtml();
-$reporthtml .= "</tbody>\n</table>";
+$reporthtml .= "</tbody></table></div></div>";
 
 // print submit button
 if ($USER->gradeediting[$course->id] and !$report->get_pref('enableajax')) {
index b7246054d4a2203c8c87460a202b2c2c7fc17cf8..89b7624b93c50e1a3c25ef71b8856092ec896b7b 100644 (file)
@@ -502,31 +502,8 @@ class grade_report_grader extends grade_report {
     public function get_headerhtml() {
         global $CFG, $USER;
 
-        $strsortasc   = $this->get_lang_string('sortasc', 'grades');
-        $strsortdesc  = $this->get_lang_string('sortdesc', 'grades');
-        $strfirstname = $this->get_lang_string('firstname');
-        $strlastname  = $this->get_lang_string('lastname');
-        $showuseridnumber = $this->get_pref('showuseridnumber');
-
-        if ($this->sortitemid === 'lastname') {
-            if ($this->sortorder == 'ASC') {
-                $lastarrow = print_arrow('up', $strsortasc, true);
-            } else {
-                $lastarrow = print_arrow('down', $strsortdesc, true);
-            }
-        } else {
-            $lastarrow = '';
-        }
+        $this->rowcount = 0;
 
-        if ($this->sortitemid === 'firstname') {
-            if ($this->sortorder == 'ASC') {
-                $firstarrow = print_arrow('up', $strsortasc, true);
-            } else {
-                $firstarrow = print_arrow('down', $strsortdesc, true);
-            }
-        } else {
-            $firstarrow = '';
-        }
         // Prepare Table Headers
         $headerhtml = '';
 
@@ -542,37 +519,8 @@ class grade_report_grader extends grade_report {
                 // continue;
             }
 
-            $headerhtml .= '<tr class="heading r'.$this->rowcount++.'">';
+            $headerhtml .= '<tr class="heading_name_row">';
 
-            if ($key == $numrows - 1) {
-                $headerhtml .= '<th class="header c'.$columncount++.'" scope="col"><a href="'.$this->baseurl.'&amp;sortitemid=firstname">'
-                            . $strfirstname . '</a> '
-                            . $firstarrow. '/ <a href="'.$this->baseurl.'&amp;sortitemid=lastname">' . $strlastname . '</a>'. $lastarrow .'</th>';
-                if ($showuseridnumber) {
-                    if ('idnumber' == $this->sortitemid) {
-                        if ($this->sortorder == 'ASC') {
-                            $idnumberarrow = print_arrow('up', $strsortasc, true);
-                        } else {
-                            $idnumberarrow = print_arrow('down', $strsortdesc, true);
-                        }
-                    } else {
-                        $idnumberarrow = '';
-                    }
-                    $headerhtml .= '<th class="header c'.$columncount++.' useridnumber" scope="col"><a href="'.$this->baseurl.'&amp;sortitemid=idnumber">'
-                            . get_string('idnumber') . '</a> ' . $idnumberarrow . '</th>';
-                }
-             } else {
-                $colspan='';
-                if ($showuseridnumber) {
-                    $colspan = 'colspan="2" ';
-                }
-
-                $headerhtml .= '<td '.$colspan.'class="cell c'.$columncount++.' topleft">&nbsp;</td>';
-
-                if ($showuseridnumber) {
-                    $columncount++;
-                }
-            }
 
             foreach ($row as $columnkey => $element) {
                 $sort_link = '';
@@ -662,17 +610,15 @@ class grade_report_grader extends grade_report {
         $strfeedback  = $this->get_lang_string("feedback");
         $strgrade     = $this->get_lang_string('grade');
         $gradetabindex = 1;
-        $showuserimage = $this->get_pref('showuserimage');
-        $showuseridnumber = $this->get_pref('showuseridnumber');
         $numusers      = count($this->users);
 
         // Preload scale objects for items with a scaleid
-        $scales_list = array();
+        $scales_list = '';
         $tabindices = array();
 
         foreach ($this->gtree->get_items() as $item) {
             if (!empty($item->scaleid)) {
-                $scales_list[] = $item->scaleid;
+                $scales_list .= "$item->scaleid,";
             }
 
             $tabindices[$item->id]['grade'] = $gradetabindex;
@@ -682,6 +628,7 @@ class grade_report_grader extends grade_report {
         $scales_array = array();
 
         if (!empty($scales_list)) {
+            $scales_list = substr($scales_list, 0, -1);
             $scales_array = $DB->get_records_list('scale', 'id', $scales_list);
         }
 
@@ -702,24 +649,10 @@ class grade_report_grader extends grade_report {
             }
 
             $columncount = 0;
-            // Student name and link
-            $user_pic = null;
-            if ($showuserimage) {
-                $user_pic = '<div class="userpic">' . print_user_picture($user, $this->courseid, null, 0, true) . '</div>';
-            }
-
-            $studentshtml .= '<tr class="r'.$this->rowcount++ . $row_classes[$this->rowcount % 2] . '">'
-                          .'<th class="header c'.$columncount++.' user" scope="row" onclick="set_row(this.parentNode.rowIndex);">'.$user_pic
-                          .'<a href="'.$CFG->wwwroot.'/user/view.php?id='.$user->id.'&amp;course='.$this->course->id.'">'
-                          .fullname($user).'</a></th>';
-
-            if ($showuseridnumber) {
-                $studentshtml .= '<th class="header c'.$columncount++.' useridnumber" onclick="set_row(this.parentNode.rowIndex);">'.
-                        $user->idnumber.'</th>';
-            }
+            $studentshtml .= '<tr class="r'.$this->rowcount++ . $row_classes[$this->rowcount % 2] . '">';
 
-            foreach ($this->gtree->get_items() as $itemid=>$unused) {
-                $item =& $this->gtree->get_item($itemid);
+            foreach ($this->gtree->items as $itemid=>$unused) {
+                $item =& $this->gtree->items[$itemid];
                 $grade = $this->grades[$userid][$item->id];
 
                 // Get the decimal points preference for this item
@@ -761,13 +694,13 @@ class grade_report_grader extends grade_report {
                 }
 
                 if ($grade->is_excluded()) {
-                    $cellclasses .= ' excluded';
+                    // $cellclasses .= ' excluded';
                 }
 
                 $studentshtml .= '<td class="'.$cellclasses.'">';
 
                 if ($grade->is_excluded()) {
-                    $studentshtml .= get_string('excluded', 'grades') . ' ';
+                    $studentshtml .= '<span class="excludedfloater">'.get_string('excluded', 'grades') . '</span> ';
                 }
 
                 // Do not show any icons if no grade (no record in DB to match)
@@ -851,9 +784,7 @@ class grade_report_grader extends grade_report {
 
                     // If quickfeedback is on, print an input element
                     if ($this->get_pref('showquickfeedback') and $grade->is_editable()) {
-                        if ($this->get_pref('quickgrading')) {
-                            $studentshtml .= '<br />';
-                        }
+
                         $studentshtml .= '<input type="hidden" name="oldfeedback_'
                                       .$userid.'_'.$item->id.'" value="' . s($grade->feedback) . '" />';
                         $studentshtml .= '<input class="quickfeedback" tabindex="' . $tabindices[$item->id]['feedback']
@@ -897,6 +828,133 @@ class grade_report_grader extends grade_report {
         return $studentshtml;
     }
 
+    function get_studentnameshtml() {
+        global $CFG, $USER;
+        $studentshtml = '';
+
+        $showuserimage = $this->get_pref('showuserimage');
+        $showuseridnumber = $this->get_pref('showuseridnumber');
+
+        $strsortasc   = $this->get_lang_string('sortasc', 'grades');
+        $strsortdesc  = $this->get_lang_string('sortdesc', 'grades');
+        $strfirstname = $this->get_lang_string('firstname');
+        $strlastname  = $this->get_lang_string('lastname');
+
+        if ($this->sortitemid === 'lastname') {
+            if ($this->sortorder == 'ASC') {
+                $lastarrow = print_arrow('up', $strsortasc, true);
+            } else {
+                $lastarrow = print_arrow('down', $strsortdesc, true);
+            }
+        } else {
+            $lastarrow = '';
+        }
+
+        if ($this->sortitemid === 'firstname') {
+            if ($this->sortorder == 'ASC') {
+                $firstarrow = print_arrow('up', $strsortasc, true);
+            } else {
+                $firstarrow = print_arrow('down', $strsortdesc, true);
+            }
+        } else {
+            $firstarrow = '';
+        }
+
+        $row_classes = array(' even ', ' odd ');
+
+        $row_classes = array(' even ', ' odd ');
+
+        $studentshtml .= '<div class="left_scroller">
+            <table id="fixed_column" class="fixed_grades_column">
+                <tbody class="leftbody">';
+
+        $colspan = '';
+        if ($showuseridnumber) {
+            $colspan = 'colspan="2"';
+        }
+
+        $levels = count($this->gtree->levels) - 1;
+
+
+        for ($i = 0; $i < $levels; $i++) {
+            $studentshtml .= '
+                    <tr class="heading name_row">
+                        <td '.$colspan.' class="fixedcolumn cell c0 topleft"> </td>
+                    </tr>
+                    ';
+        }
+
+        $studentshtml .= '<tr class="heading"><th class="header c0" scope="col"><a href="'.$this->baseurl.'&amp;sortitemid=firstname">'
+                    . $strfirstname . '</a> '
+                    . $firstarrow. '/ <a href="'.$this->baseurl.'&amp;sortitemid=lastname">' . $strlastname . '</a>'. $lastarrow .'</th>';
+
+        if ($showuseridnumber) {
+            if ('idnumber' == $this->sortitemid) {
+                if ($this->sortorder == 'ASC') {
+                    $idnumberarrow = print_arrow('up', $strsortasc, true);
+                } else {
+                    $idnumberarrow = print_arrow('down', $strsortdesc, true);
+                }
+            } else {
+                $idnumberarrow = '';
+            }
+            $studentshtml .= '<th class="header c0 useridnumber" scope="col"><a href="'.$this->baseurl.'&amp;sortitemid=idnumber">'
+                    . get_string('idnumber') . '</a> ' . $idnumberarrow . '</th>';
+        }
+
+        $studentshtml .= '</tr>';
+
+        if ($USER->gradeediting[$this->courseid]) {
+            $studentshtml .= '<tr class="controls"><th class="header c0 controls" scope="row" '.$colspan.'>'.$this->get_lang_string('controls','grades').'</th></tr>';
+        }
+
+        foreach ($this->users as $userid => $user) {
+
+            $user_pic = null;
+            if ($showuserimage) {
+                $user_pic = '<div class="userpic">' . print_user_picture($user, $this->courseid, NULL, 0, true) . "</div>\n";
+            }
+
+            $studentshtml .= '<tr class="r'.$this->rowcount++ . $row_classes[$this->rowcount % 2] . '">'
+                          .'<th class="header c0 user" scope="row" onclick="set_row(this.parentNode.rowIndex);">'.$user_pic
+                          .'<a href="'.$CFG->wwwroot.'/user/view.php?id='.$user->id.'&amp;course='.$this->course->id.'">'
+                          .fullname($user)."</a></th>\n";
+
+            if ($showuseridnumber) {
+                $studentshtml .= '<th class="header c0 useridnumber" onclick="set_row(this.parentNode.rowIndex);">'. $user->idnumber."</th>\n";
+            }
+            $studentshtml .= "</tr>\n";
+        }
+
+        if ($this->get_pref('showranges')) {
+            $studentshtml .= '<tr class="range r'.$this->rowcount++.'">' . '<th class="header c0 range " '.$colspan.' scope="row">'.$this->get_lang_string('range','grades').'</th></tr>';
+        }
+
+        // Averages heading
+
+        $straverage_group = get_string('groupavg', 'grades');
+        $showaverages_group = $this->currentgroup && $this->get_pref('showgroups');
+        $straverage = get_string('overallaverage', 'grades');
+        $showaverages = $this->get_pref('showaverages');
+
+        if ($showaverages_group) {
+            $studentshtml .= '<tr class="groupavg r'.$this->rowcount++.'"><th class="header c0" '.$colspan.'scope="row">'.$straverage_group.'</th></tr>';
+        }
+
+        if ($showaverages) {
+            $studentshtml .= '<tr class="avg r'.$this->rowcount++.'"><th class="header c0" '.$colspan.'scope="row">'.$straverage.'</th></tr>';
+        }
+
+        $studentshtml .= '</tbody>
+            </table>
+        </div>
+        <div class="right_scroller">
+            <table id="user-grades" class="">
+                <tbody class="righttest">';
+
+        return $studentshtml;
+    }
+
     /**
      * Builds and return the HTML row of column totals.
      * @param  bool $grouponly Whether to return only group averages or all averages.
@@ -915,7 +973,6 @@ class grade_report_grader extends grade_report {
         $averagesdecimalpoints = $this->get_pref('averagesdecimalpoints');
         $meanselection         = $this->get_pref('meanselection');
         $shownumberofgrades    = $this->get_pref('shownumberofgrades');
-        $showuseridnumber      = $this->get_pref('showuseridnumber');
 
         $avghtml = '';
         $avgcssclass = 'avg';
@@ -967,16 +1024,7 @@ class grade_report_grader extends grade_report {
             }
 
             $columncount=0;
-            $colspan='';
-            if ($showuseridnumber) {
-                $colspan = 'colspan="2" ';
-            }
-
-            $avghtml = '<tr class="' . $avgcssclass . ' r'.$this->rowcount++.'"><th class="header c0" '.$colspan.'scope="row">'.$straverage.'</th>';
-
-            if ($showuseridnumber) {
-                $columncount++;
-            }
+            $avghtml = '<tr class="' . $avgcssclass . ' r'.$this->rowcount++.'">';
 
             // MDL-10875 Empty grades must be evaluated as grademin, NOT always 0
             // This query returns a count of ungraded grades (NULL finalgrade OR no matching record in grade_grades table)
@@ -1068,7 +1116,6 @@ class grade_report_grader extends grade_report {
      */
     public function get_rangehtml() {
         global $USER;
-        $showuseridnumber      = $this->get_pref('showuseridnumber');
 
         $scalehtml = '';
         if ($this->get_pref('showranges')) {
@@ -1076,20 +1123,12 @@ class grade_report_grader extends grade_report {
             $rangesdecimalpoints = $this->get_pref('rangesdecimalpoints');
 
             $columncount=0;
-            $colspan='';
-            if ($showuseridnumber) {
-                $colspan = 'colspan="2" ';
-            }
+            $scalehtml = '<tr class="range r'.$this->rowcount++.' heading">';
 
-            $scalehtml = '<tr class="r'.$this->rowcount++.'">'
-                       . '<th class="header c0 range" '.$colspan.'scope="row">'.$this->get_lang_string('range','grades').'</th>';
 
-            if ($showuseridnumber) {
-                $columncount++;
-            }
+            foreach ($this->gtree->items as $itemid=>$unused) {
+                $item =& $this->gtree->items[$itemid];
 
-            foreach ($this->gtree->get_items() as $itemid=>$unused) {
-                $item =& $this->gtree->get_item($itemid);
 
                 $hidden = '';
                 if ($item->is_hidden()) {
@@ -1099,6 +1138,7 @@ class grade_report_grader extends grade_report {
                 $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>';
         }
@@ -1115,23 +1155,17 @@ class grade_report_grader extends grade_report {
         $iconshtml = '';
         if ($USER->gradeediting[$this->courseid]) {
 
-            $colspan='';
-            if ($this->get_pref('showuseridnumber')) {
-                $colspan = 'colspan="2" ';
-            }
-
-            $iconshtml = '<tr class="r'.$this->rowcount++.'">'
-                       . '<th class="header c0 range" scope="row" '.$colspan.'>'.$this->get_lang_string('controls','grades').'</th>';
+            $iconshtml = '<tr class="controls">';
 
-            $columncount = 1;
-            foreach ($this->gtree->get_items() as $itemid=>$unused) {
+            $columncount = 0;
+            foreach ($this->gtree->items as $itemid=>$unused) {
                 // emulate grade element
                 $item =& $this->gtree->get_item($itemid);
 
                 $eid = $this->gtree->get_item_eid($item);
                 $element = $this->gtree->locate_element($eid);
 
-                $iconshtml .= '<td class="cell c'.$columncount++.' icons">' . $this->get_icons($element) . '</td>';
+                $iconshtml .= '<td class="controls cell c'.$columncount++.' icons">' . $this->get_icons($element) . '</td>';
             }
             $iconshtml .= '</tr>';
         }
@@ -1154,7 +1188,12 @@ class grade_report_grader extends grade_report {
         }
 
         // Init all icons
-        $edit_icon             = $this->gtree->get_edit_icon($element, $this->gpr);
+        $edit_icon = '';
+
+        if ($element['type'] != 'categoryitem' && $element['type'] != 'courseitem') {
+            $edit_icon             = $this->gtree->get_edit_icon($element, $this->gpr);
+        }
+
         $edit_calculation_icon = '';
         $show_hide_icon        = '';
         $lock_unlock_icon      = '';
index 3dd93db9a4db6934072e4c465ab8ab83d984176b..0233ce4db9a9912c744dd924cfe5f65f50f1015e 100644 (file)
@@ -66,21 +66,7 @@ if ($data = $mform->get_data()) {
     exit;
 }
 
-$strgrades = get_string('grades');
-$strgraderreport = get_string('modulename', 'gradereport_grader');
-$strgradepreferences = get_string('gradepreferences', 'grades');
-
-$navigation = grade_build_nav(__FILE__, $strgradepreferences, $courseid);
-
-print_header_simple($strgrades.': '.$strgraderreport . ': ' . $strgradepreferences,': '.$strgradepreferences, $navigation,
-                    '', '', true, '', navmenu($course));
-
-/// Print the plugin selector at the top
-print_grade_plugin_selector($course->id, 'report', 'grader');
-
-// Add tabs
-$currenttab = 'preferences';
-include('tabs.php');
+print_grade_page_head($courseid, 'report', 'grader', get_string('preferences', 'gradereport_grader'), false, '', true);
 
 // If USER has admin capability, print a link to the site config page for this report
 if (has_capability('moodle/site:config', $systemcontext)) {
index 524b8f7d5c4cd948f15e27ad3e29c6507c2d666e..add4f5a78fe75537ccac0d5df2d68d9dcd57c131 100644 (file)
 
 .grade-report-grader table#user-grades tr.odd td.cell {
     background-color: #efefef;
+    white-space: nowrap;
 }
 
 .grade-report-grader table#user-grades tr.even td.overridden {
-  background-color: #F3E4C0; 
+  background-color: #F3E4C0;
 }
 
 .grade-report-grader table#user-grades tr.odd td.overridden {
 }
 
 .grade-report-grader table#user-grades tr.even td.excluded {
-  background-color: #EABFFF; 
+  background-color: #EABFFF;
 }
 
 .grade-report-grader table#user-grades tr.odd td.excluded {
   background-color: #E5AFFF;
 }
 
-.grade-report-grader table#user-grades tr.odd th.header { 
+.grade-report-grader table#user-grades tr.odd th.header {
     background-color: #efefef;
     background-image: none;
 }
@@ -64,7 +65,7 @@
 
 .grade-report-grader table#user-grades td.hmarked.vmarked, .grade-report-grader table#user-grades tr.odd td.hmarked.vmarked{
     background-color: #ffcc99;
-} 
+}
 
 .grade-report-grader table#user-grades tr.groupavg td.cell {
     background-color: #efffef;
@@ -96,7 +97,7 @@
 }
 
 .grade-report-grader #overDiv table {
-  margin: 0;  
+  margin: 0;
 }
 
 .grade-report-grader #overDiv table td.feedback {
   color: #000000;
   font-family: Verdana;
   font-size: 70%;
-  font-weight: normal;  
+  font-weight: normal;
 }
 
 .grade-report-grader #overDiv .caption {
 }
 
 .grade-report-grader table#participants th {
-  vertical-align: top; 
+  vertical-align: top;
 }
 
 .grade-report-grader table#user-grades td.fillerfirst {
   padding-left: 5px;
   padding-right: 5px;
 }
+
+/**
+ * Author: Robert Russo
+ */
+
+.grade-report-grader table {
+  border-collapse: collapse;
+  background-color: #ffffff;
+  font-size: 10px;
+  border-color: #cecece;
+}
+
+
+.grade-report-grader .r1 {
+  background-color: #ffffff;
+}
+
+.grade-report-grader .flexible th, .grade-report-grader .flexible td {
+  white-space: nowrap;
+}
+
+.grade-report-grader .flexible th a, .grade-report-grader .flexible td a {
+  white-space: nowrap;
+}
+
+.grade-report-grader th {
+  padding: 10px;
+}
+
+.grade-report-grader span.inclusion-links {
+   margin: 0 5px 0 10px;
+}
+
+.grade-report-grader .gradestable th.user, .grade-report-grader .gradestable th.range, .grade-report-grader td {
+    white-space: nowrap;
+}
+
+.grade-report-grader table#user-grades .catlevel1 {
+  background-color: #ffffff;
+}
+
+.grade-report-grader table#user-grades .catlevel2 {
+  background-color: #f9f9f9;
+}
+
+.grade-report-grader table#user-grades .catlevel3 {
+  background-color: #efefef;
+}
+
+.grade-report-grader table#user-grades .item {
+  background-color: #e9e9e9;
+}
+
+.grade-report-grader table#user-grades td.overridden {
+  background-color: #dddddd;
+}
+
+.grade-report-grader table tr.odd td.cell {
+    background-color: #efefef;
+}
+
+.grade-report-grader table tr.even td.cell {
+    background-color: #ffffff;
+}
+
+.grade-report-grader table tr.even th {
+    background-color: #ffffff;
+}
+
+.grade-report-grader table tr.odd th.header {
+    background-color: #efefef;
+    border-width: 0px 0px 1px 0px;
+    background-image: none;
+}
+
+.grade-report-grader table tr.heading th.header {
+    border-top: 1px solid #cecece;
+}
+
+.grade-report-grader table#user-grades tr.heading th.categoryitem,
+.grade-report-grader table#user-grades tr.heading th.courseitem {
+  border-width: 0px 0px 0px 1px;
+}
+
+.grade-report-grader table#user-grades td.vmarked, .grade-report-grader table#user-grades tr.odd td.vmarked {
+    background-color: #ffcc33;
+}
+
+.grade-report-grader table#user-grades td.hmarked, .grade-report-grader table#user-grades tr.odd td.hmarked {
+    background-color: #ffff99;
+}
+
+.grade-report-grader table#user-grades td.hmarked.vmarked, .grade-report-grader table#user-grades tr.odd td.hmarked.vmarked{
+    background-color: #ffcc99;
+}
+
+.grade-report-grader table tr.avg td.cell {
+background-color: #f3ead8;
+}
+
+.grade-report-grader table#user-grades tr.groupavg td.cell {
+  font-weight: bold;
+  color: #006400;
+}
+
+.grade-report-grader table#user-grades tr.avg td.cell {
+  font-weight: bold;
+  color: #00008B;
+}
+
+.grade-report-grader table#user-grades td.cat,
+.grade-report-grader table#user-grades td.course {
+  font-weight: bold;
+}
+
+.grade-report-grader table#user-grades {
+  border-width: 1px;
+  border-style: solid;
+  font-size: 10px;
+  margin: 0;
+  margin-top: 20px;
+  width: auto;
+  background-color: transparent;
+}
+
+.grade-report-grader #overDiv table {
+  margin: 0;
+}
+
+.grade-report-grader #overDiv table td.feedback {
+  border: 0px;
+}
+.grade-report-grader #overDiv .feedback {
+  background-color: #AABBFF;
+  color: #000000;
+  font-family: Verdana;
+  font-weight: normal;
+}
+
+.grade-report-grader #overDiv .caption {
+  background-color: #5566CC;
+  color: #CCCCFF;
+  font-family: Arial;
+  font-weight: bold;
+}
+
+.grade-report-grader div.submit {
+  margin-top: 20px;
+ text-align: center;
+}
+
+.grade-report-grader table#user-grades td {
+  border-width: 0px 1px 1px 0px;
+  border-style:solid;
+}
+
+.grade-report-grader table#user-grades tr.heading {
+  border-width:0px 0px 0px 0px;
+  border-style:solid;
+}
+
+.grade-report-grader table#user-grades .heading td {
+  border-width:0px 0px 0px 0px;
+  border-style:solid;
+}
+
+.grade-report-grader table#user-grades th.category {
+  border-width:1px 1px 0px 1px;
+  border-style:solid;
+  vertical-align: top;
+}
+
+.grade-report-grader table#user-grades th.category.header.catlevel1 {
+  border-width: 1px 1px 0px 0px;
+  border-style:solid;
+  vertical-align: top;
+}
+
+.grade-report-grader table#user-grades th.user {
+  border-width:0px 0px 1px 0px;
+  border-style:solid;
+}
+
+.grade-report-grader table#user-grades th.useridnumber {
+  border-width:0px 0px 1px 1px;
+  border-style:solid;
+}
+
+.grade-report-grader div.left_scroller tr {
+  height: 4em;
+  font-size: 10px;
+}
+
+.grade-report-grader div.right_scroller tr {
+  height: 4em;
+  font-size: 10px;
+}
+
+.grade-report-grader div.left_scroller td {
+  height: 4em;
+  font-size: 10px;
+}
+
+.grade-report-grader div.right_scroller td {
+  height: 4em;
+  font-size: 10px;
+}
+
+.grade-report-grader div.left_scroller th {
+  height: 4em;
+  font-size: 10px;
+}
+
+.grade-report-grader div.left_scroller th.user a {
+  vertical-align: middle;
+  margin: 0;
+  padding: 0;
+}
+
+.grade-report-grader div.right_scroller th {
+  height: 4em;
+  font-size: 10px;
+}
+
+.grade-report-grader table#user-grades th.categoryitem,
+.grade-report-grader table#user-grades th.courseitem,
+.grade-report-grader table td.topleft {
+  border-width: 0px 1px 1px 1px;
+  border-style: solid;
+  border-color: #cecece;
+  vertical-align: top;
+}
+
+.grade-report-grader table#user-grades td.topleft {
+  background-color: transparent;
+}
+
+.grade-report-grader table#participants th {
+  vertical-align: top;
+  width: auto;
+}
+
+.grade-report-grader table#user-grades td.fillerfirst {
+  border-width:0px 0px 0px 1px;
+  border-style:solid;
+}
+
+.grade-report-grader table#user-grades td.fillerlast {
+  border-width:0px 1px 0px 0px;
+  border-style:solid;
+}
+
+.grade-report-grader table#user-grades th.item {
+  border-width:1px 1px 1px 1px;
+  border-style:solid;
+  vertical-align: top;
+}
+
+.grade-report-grader div.gradertoggle {
+  display: inline;
+  margin-left: 20px;
+}
+
+.grade-report-grader table#user-grades th {
+ text-align: left;
+}
+
+.grade-report-grader table th.user {
+ text-align: left;
+  vertical-align: middle;
+}
+
+.grade-report-grader table td.useridnumber {
+ text-align:left;
+  vertical-align: middle;
+}
+
+.grade-report-grader table#user-grades td {
+ text-align: right;
+}
+
+.grade-report-grader table#user-grades th.range {
+  border-width:1px 1px 1px 1px;
+  border-style:solid;
+  text-align: right;
+}
+
+.grade-report-grader div.userpic {
+  margin-right: 10px;
+  float: left;
+}
+
+.grade-report-grader div.userpic img {
+  border: 3px double #cecece;
+  vertical-align: middle;
+  width: 2.7em;
+  height: 2.7em;
+}
+
+
+.grade-report-grader table#user-grades .quickfeedback {
+  border: #000000 1px dashed;
+}
+
+.grade-report-grader #siteconfiglink {
+ text-align: right;
+}
+
+.grade-report-grader table#user-grades .hidden,
+.grade-report-grader table#user-grades .hidden a {
+  color:#aaaaaa;
+}
+
+.grade-report-grader table#user-grades .datesubmitted {
+  font-size: 0.7em;
+}
+
+.grade-report-grader table#user-grades td.controls {
+  background-color: #f3ead8;
+}
+
+.grade-report-grader table#user-grades td.cell {
+  padding-left: 5px;
+  padding-right: 5px;
+  vertical-align: middle;
+}
+
+.grade-report-grader a.quickedit {
+  line-height: 1em;
+  display: block;
+  float: right;
+  margin: .1em 0 0 0;
+  clear: none;
+  font-size: 9px;
+  background-color: transparent;
+}
+
+.grade-report-grader a.quickedit2 {
+  display: block;
+  float: right;
+  margin: 1.3em 0 0 0;
+  clear: none;
+  background-color: transparent;
+}
+
+.grade-report-grader table#quick_edit {
+  margin: 0 auto 0 auto;
+  border: 1px solid #cecece;
+}
+
+.grade-report-grader table#quick_edit td {
+  vertical-align: middle;
+  padding: 0;
+  margin: 0;
+  border: 1px solid #cecece;
+  text-align: left;
+}
+
+.grade-report-grader table#quick_edit td img {
+  border: 3px double #cecece;
+  padding: 0;
+  vertical-align: middle;
+}
+
+.grade-report-grader td input {
+  border: 1px solid #666666;
+  margin-left: 10px;
+  margin-right: 10px;
+}
+
+.grade-report-grader table#quick_edit td {
+  padding: 5px;
+  padding-top: 5px;
+  padding-bottom: 5px;
+}
+
+.grade-report-grader table#quick_edit td.fullname {
+border-left: none;
+padding-left: 5px;
+}
+
+.grade-report-grader table#quick_edit td.picture {
+border-right: none;
+}
+
+.grade-report-grader table#quick_edit td.finalgrade input {
+width: 5em;
+}
+
+.grade-report-grader h1 {
+ text-align: center;
+  clear: both;
+}
+
+.grade-report-grader form {
+text-align: center;
+}
+
+.grade-report-grader input.center {
+  margin: 10px auto 0 auto;
+}
+
+.grade-report-grader .lefttbody {
+  width: auto;
+  vertical-align: middle;
+}
+
+.grade-report-grader table#user-grades th.fixedcolumn {
+  border: 1px solid #cecece;
+  vertical-align: middle;
+}
+
+.grade-report-grader table#fixed_column th {
+  border: 1px solid #cecece;
+  vertical-align: middle;
+}
+
+.grade-report-grader table#fixed_column {
+  padding-top: 20px;
+  border-top: 1px solid #cecece;
+  background-color: #ffffff;
+}
+
+.grade-report-grader .left_scroller {
+  float: left;
+  clear: none;
+  padding-top: 20px;
+}
+
+.grade-report-grader .right_scroller {
+  width: auto;
+  clear: none;
+  overflow-x: auto;
+}
+
+.grade-report-grader th {
+  padding-top: 2px;
+  padding-bottom: 0;
+}
+
+.grade-report-grader table tr.avg, .grade-report-grader table tr.groupavg td, .grade-report-grader table tr.avg td, .grade-report-grader table tr.groupavg th, .grade-report-grader table tr.avg th, .grade-report-grader table tr.controls_row, .grade-report-grader table tr.controls_row th, .grade-report-grader table tr.range_row, .grade-report-grader table tr.range_row th, div.right_scroller tr  {
+  height: 2em;
+}
+
+.grade-report-grader table tr.avg, .grade-report-grader table tr.avg td, .grade-report-grader table tr.avg th {
+background-color: #f3ead8;
+}
+
+.grade-report-grader table#user-grades tr.groupavg td.cell, .grade-report-grader tr.groupavg th.header {
+    background-color: #efffef;
+}
+
+.grade-report-grader div.gradeparent {
+ text-align: left;
+}
+
+.grade-report-grader form td.excluded {
+  color: #ff0000;
+}
+
+.grade-report-grader form .excludedfloater {
+  float: left;
+}
+
+.grade-report-grader .excludedfloater {
+  font-weight: bold;
+  color: #ff0000;
+  font-size: 9px;
+}
+
+.grade-report-grader span.gradepass {
+    color: #298721;
+}
+
+.grade-report-grader span.gradefail {
+    color: #890d0d;
+}
+
+.gradeweight {
+color: #461d7c;
+font-weight: bold;
+}
+
+.grade-report-grader td select {
+font-size: 100%;
+padding: 0;
+}
+
+.grade-report-grader .righttest td select {
+font-size: 86%;
+padding: 0;
+}
+
+.grade-report-grader tr.avg, tr.controls, td.controls, th.controls, .grade-report-grader tr.groupavg, tr.range, th.range, td.range, tr.heading th.range {
+    height: 2em !important;
+    white-space: nowrap;
+}
+
+.heading_name_row th {
+    white-space: nowrap;
+    width: 2000px;
+}
diff --git a/grade/report/grader/styles_ie.css b/grade/report/grader/styles_ie.css
new file mode 100755 (executable)
index 0000000..b2c718b
--- /dev/null
@@ -0,0 +1,12 @@
+/**
+ * Author: Robert Russo
+ */
+
+.grade-report-grader .right_scroller {
+  padding-bottom: 15px;
+  overflow-y: hidden;
+}
+
+.grade-report-grader div.left_scroller td {
+    height: 43px;
+}
diff --git a/grade/report/grader/styles_ie6.css b/grade/report/grader/styles_ie6.css
new file mode 100755 (executable)
index 0000000..e84961e
--- /dev/null
@@ -0,0 +1,20 @@
+/**
+ * Author: Robert Russo
+ */
+.grade-report-grader form {
+  text-align: left;
+}
+
+.grade-report-grader div.left_scroller {
+  margin-top: 40px;
+}
+
+.grade-report-grader div.right_scroller {
+  margin-top: 40px;
+  width: auto;
+  position: absolute;
+}
+
+.excludedfloater {
+  font-size: 7px;
+}
diff --git a/grade/report/grader/styles_lsu.php b/grade/report/grader/styles_lsu.php
new file mode 100755 (executable)
index 0000000..9831a74
--- /dev/null
@@ -0,0 +1,516 @@
+/**
+ * Author: Robert Russo
+ */
+
+.grade-report-simple_grader table {
+  border-collapse: collapse;
+  background-color: #ffffff;
+  font-size: 10px;
+  border-color: #cecece;
+}
+
+
+.grade-report-simple_grader .r1 {
+  background-color: #ffffff;
+}
+
+.grade-report-simple_grader .flexible th, .grade-report-simple_grader .flexible td {
+  white-space: nowrap;
+}
+
+.grade-report-simple_grader .flexible th a, .grade-report-simple_grader .flexible td a {
+  white-space: nowrap;
+}
+
+.grade-report-simple_grader th {
+  padding: 10px;
+}
+
+.grade-report-simple_grader span.inclusion-links {
+   margin: 0 5px 0 10px;
+}
+
+.grade-report-simple_grader .gradestable th.user, .grade-report-simple_grader .gradestable th.range, .grade-report-simple_grader td {
+    white-space: nowrap;
+}
+
+.grade-report-simple_grader table#user-grades .catlevel1 {
+  background-color: #ffffff;
+}
+
+.grade-report-simple_grader table#user-grades .catlevel2 {
+  background-color: #f9f9f9;
+}
+
+.grade-report-simple_grader table#user-grades .catlevel3 {
+  background-color: #efefef;
+}
+
+.grade-report-simple_grader table#user-grades .item {
+  background-color: #e9e9e9;
+}
+
+.grade-report-simple_grader table#user-grades td.overridden {
+  background-color: #dddddd;
+}
+
+.grade-report-simple_grader table tr.odd td.cell {
+    background-color: #efefef;
+}
+
+.grade-report-simple_grader table tr.even td.cell {
+    background-color: #ffffff;
+}
+
+.grade-report-simple_grader table tr.even th {
+    background-color: #ffffff;
+}
+
+.grade-report-simple_grader table tr.odd th.header { 
+    background-color: #efefef;
+    border-width: 0px 0px 1px 0px;
+    background-image: none;
+}
+
+.grade-report-simple_grader table tr.heading th.header {
+    border-top: 1px solid #cecece;
+}
+
+.grade-report-simple_grader table#user-grades tr.heading th.categoryitem,
+.grade-report-simple_grader table#user-grades tr.heading th.courseitem {
+  border-width: 0px 0px 0px 1px;
+}
+
+.grade-report-simple_grader table#user-grades td.vmarked, .grade-report-simple_grader table#user-grades tr.odd td.vmarked {
+    background-color: #ffcc33;
+}
+
+.grade-report-simple_grader table#user-grades td.hmarked, .grade-report-simple_grader table#user-grades tr.odd td.hmarked {
+    background-color: #ffff99;
+}
+
+.grade-report-simple_grader table#user-grades td.hmarked.vmarked, .grade-report-simple_grader table#user-grades tr.odd td.hmarked.vmarked{
+    background-color: #ffcc99;
+} 
+
+.grade-report-simple_grader table tr.avg td.cell {
+background-color: #f3ead8;
+}   
+    
+.grade-report-simple_grader table#user-grades tr.groupavg td.cell {
+  font-weight: bold;
+  color: #006400;
+}
+
+.grade-report-simple_grader table#user-grades tr.avg td.cell {
+  font-weight: bold;
+  color: #00008B;
+}
+
+.grade-report-simple_grader table#user-grades td.cat,
+.grade-report-simple_grader table#user-grades td.course {
+  font-weight: bold;
+}
+
+.grade-report-simple_grader table#user-grades {
+  border-width: 1px;
+  border-style: solid;
+  font-size: 10px;
+  margin: 0;
+  margin-top: 20px;
+  width: auto;
+  background-color: transparent;
+}
+
+.grade-report-simple_grader #overDiv table {
+  margin: 0;  
+}
+
+.grade-report-simple_grader #overDiv table td.feedback {
+  border: 0px;
+}
+.grade-report-simple_grader #overDiv .feedback {
+  background-color: #AABBFF;
+  color: #000000;
+  font-family: Verdana;
+  font-weight: normal;  
+}
+
+.grade-report-simple_grader #overDiv .caption {
+  background-color: #5566CC;
+  color: #CCCCFF;
+  font-family: Arial;
+  font-weight: bold;
+}
+
+.grade-report-simple_grader div.submit {
+  margin-top: 20px;
+ text-align: center;
+}
+
+.grade-report-simple_grader table#user-grades td {
+  border-width: 0px 1px 1px 0px;
+  border-style:solid;
+}
+
+.grade-report-simple_grader table#user-grades tr.heading {
+  border-width:0px 0px 0px 0px;
+  border-style:solid;
+}
+
+.grade-report-simple_grader table#user-grades .heading td {
+  border-width:0px 0px 0px 0px;
+  border-style:solid;
+}
+
+.grade-report-simple_grader table#user-grades th.category {
+  border-width:1px 1px 0px 1px;
+  border-style:solid;
+  vertical-align: top;
+}
+
+.grade-report-simple_grader table#user-grades th.category.header.catlevel1 {
+  border-width: 1px 1px 0px 0px;
+  border-style:solid;
+  vertical-align: top;
+}
+
+.grade-report-simple_grader table#user-grades th.user {
+  border-width:0px 0px 1px 0px;
+  border-style:solid;
+}
+
+.grade-report-simple_grader table#user-grades th.useridnumber {
+  border-width:0px 0px 1px 1px;
+  border-style:solid;
+}
+
+.grade-report-simple_grader div.left_scroller tr {
+  height: 4em;
+  font-size: 10px;
+}
+
+.grade-report-simple_grader div.right_scroller tr {
+  height: 4em;
+  font-size: 10px;
+}
+
+.grade-report-simple_grader div.left_scroller td {
+  height: 4em;
+  font-size: 10px;
+}
+
+.grade-report-simple_grader div.right_scroller td {
+  height: 4em;
+  font-size: 10px;
+}
+
+.grade-report-simple_grader div.left_scroller th {
+  height: 4em;
+  font-size: 10px;
+}
+
+.grade-report-simple_grader div.left_scroller th.user a {
+  vertical-align: middle;
+  margin: 0;
+  padding: 0;
+}
+
+.grade-report-simple_grader div.right_scroller th {
+  height: 4em;
+  font-size: 10px;
+}
+
+.grade-report-simple_grader table#user-grades th.categoryitem,
+.grade-report-simple_grader table#user-grades th.courseitem,
+.grade-report-simple_grader table td.topleft {
+  border-width: 0px 1px 1px 1px;
+  border-style: solid;
+  border-color: #cecece;
+  vertical-align: top;
+}
+
+.grade-report-simple_grader table#user-grades td.topleft {
+  background-color: transparent;
+}
+
+.grade-report-simple_grader table#participants th {
+  vertical-align: top; 
+  width: auto;
+}
+
+.grade-report-simple_grader table#user-grades td.fillerfirst {
+  border-width:0px 0px 0px 1px;
+  border-style:solid;
+}
+
+.grade-report-simple_grader table#user-grades td.fillerlast {
+  border-width:0px 1px 0px 0px;
+  border-style:solid;
+}
+
+.grade-report-simple_grader table#user-grades th.item {
+  border-width:1px 1px 1px 1px;
+  border-style:solid;
+  vertical-align: top;
+}
+
+.grade-report-simple_grader div.gradertoggle {
+  display: inline;
+  margin-left: 20px;
+}
+
+.grade-report-simple_grader table#user-grades th {
+ text-align: left;
+}
+
+.grade-report-simple_grader table th.user {
+ text-align: left;
+  vertical-align: middle;
+}
+
+.grade-report-simple_grader table td.useridnumber {
+ text-align:left;
+  vertical-align: middle;
+}
+
+.grade-report-simple_grader table#user-grades td {
+ text-align: right;
+}
+
+.grade-report-simple_grader table#user-grades th.range {
+  border-width:1px 1px 1px 1px;
+  border-style:solid;
+}
+
+.grade-report-simple_grader div.userpic {
+  margin-right: 10px;
+  float: left;
+}
+
+.grade-report-simple_grader div.userpic img {
+  border: 3px double #cecece;
+  vertical-align: middle;
+  width: 2.7em;
+  height: 2.7em;
+}
+
+
+.grade-report-simple_grader table#user-grades .quickfeedback {
+  border: #000000 1px dashed;
+}
+
+.grade-report-simple_grader #siteconfiglink {
+ text-align: right;
+}
+
+.grade-report-simple_grader table#user-grades .hidden,
+.grade-report-simple_grader table#user-grades .hidden a {
+  color:#aaaaaa;
+}
+
+.grade-report-simple_grader table#user-grades .datesubmitted {
+  font-size: 0.7em;
+}
+
+.grade-report-simple_grader table#user-grades td.cell {
+  padding-left: 5px;
+  padding-right: 5px;
+  vertical-align: middle;
+}
+
+.grade-report-simple_grader a.quickedit {
+  line-height: 1em;
+  display: block;
+  float: right;
+  margin: .1em 0 0 0;
+  clear: none;
+  font-size: 9px;
+  background-color: transparent;
+}
+
+.grade-report-simple_grader a.quickedit2 {
+  display: block;
+  float: right;
+  margin: 1.3em 0 0 0;
+  clear: none;
+  background-color: transparent;
+}
+
+.grade-report-simple_grader table#quick_edit {
+  margin: 0 auto 0 auto;
+  border: 1px solid #cecece;
+}
+
+.grade-report-simple_grader table#quick_edit td {
+  vertical-align: middle;
+  padding: 0;
+  margin: 0;
+  border: 1px solid #cecece;
+  text-align: left;
+}
+
+.grade-report-simple_grader table#quick_edit td img {
+  border: 3px double #cecece;
+  padding: 0;
+  vertical-align: middle;
+}
+
+.grade-report-simple_grader td input {
+  border: 1px solid #666666;
+  margin-left: 10px;
+  margin-right: 10px;
+}
+
+.grade-report-simple_grader table#quick_edit td {
+  padding: 5px;
+  padding-top: 5px;
+  padding-bottom: 5px;
+}
+
+.grade-report-simple_grader table#quick_edit td.fullname {
+border-left: none;
+padding-left: 5px;
+}
+
+.grade-report-simple_grader table#quick_edit td.picture {
+border-right: none;
+}
+
+.grade-report-simple_grader table#quick_edit td.finalgrade input {
+width: 5em;
+}
+
+.grade-report-simple_grader h1 {
+ text-align: center;
+  clear: both;
+}
+
+.grade-report-simple_grader form {
+text-align: center;
+}
+
+.grade-report-simple_grader input.center {
+  margin: 10px auto 0 auto;
+}
+
+.grade-report-simple_grader .lefttbody {
+  width: auto;
+  vertical-align: middle;
+}
+
+.grade-report-simple_grader table#user-grades th.fixedcolumn {
+  border: 1px solid #cecece;
+  vertical-align: middle;
+}
+
+.grade-report-simple_grader table#fixes_column th {
+  border: 1px solid #cecece;
+  vertical-align: middle;
+}
+
+.grade-report-simple_grader table#fixes_column {
+  padding-top: 20px;
+  border-top: 1px solid #cecece;
+  background-color: #ffffff;
+}
+
+.grade-report-simple_grader .left_scroller {
+  float: left;
+  clear: none;
+  padding-top: 20px;
+}
+
+.grade-report-simple_grader .right_scroller {
+  width: auto;
+  clear: none;
+  overflow-x: auto;
+}
+
+.grade-report-simple_grader th {
+  padding-top: 2px;
+  padding-bottom: 0;
+}
+
+.grade-report-simple_grader .controls_row th {
+  background-color: #f3ead8;
+}
+
+.grade-report-simple_grader table tr.avg, .grade-report-simple_grader table tr.avg td, .grade-report-simple_grader table tr.avg th, .grade-report-simple_grader table tr.controls_row, .grade-report-simple_grader table tr.controls_row th, .grade-report-simple_grader table tr.range_row, .grade-report-simple_grader table tr.range_row th {
+  height: 2em;
+}
+
+.grade-report-simple_grader table tr.avg, .grade-report-simple_grader table tr.avg td, .grade-report-simple_grader table tr.avg th {
+background-color: #f3ead8;
+}
+
+.grade-report-simple_grader table#user-grades tr.groupavg td.cell, .grade-report-simple_grader tr.groupavg th.header {
+    background-color: #efffef;
+}
+
+.grade-report-simple_grader div.gradeparent {
+ text-align: left;
+}
+
+.grade-report-simple_grader form td.excluded {
+  color: #ff0000;
+}
+
+.grade-report-simple_grader form .excludedfloater {
+  float: left;
+}
+
+.grade-report-simple_grader .excludedfloater {
+  font-weight: bold;
+  color: #ff0000;
+  font-size: 9px;
+}
+
+.grade-report-simple_grader span.gradepass {
+    color: #298721;
+}
+
+.grade-report-simple_grader span.gradefail {
+    color: #890d0d;
+}
+
+.gradeweight {
+color: #461d7c;
+font-weight: bold;
+}
+
+.biguserpic {
+width: 100%;
+}
+
+.fullgradestable {
+    font-size: 120%;
+}
+
+
+.grade-report-simple_grader td select {
+font-size: 100%;
+padding: 0;
+}
+
+.grade-report-simple_grader .righttest td select {
+font-size: 86%;
+padding: 0;
+}
+
+table#quick_edit {
+width: 90%;
+}
+
+#grade-report-simple_grader-quick_edit div.addnew {
+  margin-top: 10px;
+}
+
+#quick_edit th.header {
+  white-space: normal;
+  font-size: 90%;
+}
+
+#quick_edit td.item_weight input {
+width: 50px;
+}
index f1e2556ca4662479602dcd5a79cee781d2b3ace2..b733d80104f0f29c449a2eccaa7e31a0872b5753 100755 (executable)
@@ -162,6 +162,9 @@ abstract class grade_report {
         // roles to be displayed in the gradebook
         $this->gradebookroles = $CFG->gradebookroles;
 
+        // Set up link to preferences page
+        $this->preferences_page = $CFG->wwwroot.'/grade/report/grader/preferences.php?id='.$courseid;
+
         // init gtree in child class
     }
 
@@ -312,10 +315,11 @@ abstract class grade_report {
      * @param string HTML
      */
     protected function get_sort_arrow($direction='move', $sort_link=null) {
-        $matrix = array('up' => 'asc', 'down' => 'desc', 'move' => 'desc');
+        $matrix = array('up' => 'desc', 'down' => 'asc', 'move' => 'desc');
         $strsort = $this->get_lang_string('sort' . $matrix[$direction]);
+
         $arrow = print_arrow($direction, $strsort, true);
-        $html = '<a href="'.$sort_link .'">' . $arrow . '</a>';
+        $html = '<a href="'.$sort_link .'" alt="'.$strsort.'" title="'.$strsort.'">' . $arrow . '</a>';
         return $html;
     }
 }
index 87d12629d6a055e5721055954d179664eb20fce0..2223ef23e990861ed93729499386d6f63deafcc6 100644 (file)
@@ -38,16 +38,6 @@ $context = get_context_instance(CONTEXT_COURSE, $course->id);
 
 require_capability('gradereport/outcomes:view', $context);
 
-// Build navigation
-$strgrades = get_string('grades');
-$stroutcomes = get_string('outcomes', 'grades');
-
-$navigation = grade_build_nav(__FILE__, $stroutcomes, $course->id);
-
-/// Print header
-print_header_simple($strgrades.':'.$stroutcomes, ':'.$strgrades, $navigation, '', '', true);
-print_grade_plugin_selector($courseid, 'report', 'outcomes');
-
 //first make sure we have proper final grades
 grade_regrade_final_grades($courseid);
 
@@ -165,7 +155,9 @@ foreach ($report_info as $outcomeid => $outcomedata) {
 
 
 $html .= '</table>';
-print_heading($stroutcomes);
+
+print_grade_page_head($courseid, 'report', 'outcomes');
+
 
 echo $html;
 print_footer($course);
index 83570ca2bef90d3ffff7735931618ddf5b18a266..7aa93baf028a62bd71da8b722b078c191d673770 100644 (file)
@@ -67,18 +67,6 @@ if (!isset($USER->grade_last_report)) {
 }
 $USER->grade_last_report[$course->id] = 'overview';
 
-/// Build navigation
-$strgrades  = get_string('grades');
-$reportname = get_string('modulename', 'gradereport_overview');
-
-$navigation = grade_build_nav(__FILE__, $reportname, $course->id);
-
-/// Print header
-print_header_simple($strgrades.': '.$reportname, ': '.$strgrades, $navigation,
-                    '', '', true, '', navmenu($course));
-
-/// Print the plugin selector at the top
-print_grade_plugin_selector($course->id, 'report', 'overview');
 
 if ($access) {
 
@@ -87,9 +75,7 @@ if ($access) {
 
     // Create a report instance
     $report = new grade_report_overview($userid, $gpr, $context);
-
-    // print the page
-    print_heading(get_string('modulename', 'gradereport_overview'). ' - '.fullname($report->user));
+    print_grade_page_head($courseid, 'report', 'overview', get_string('modulename', 'gradereport_overview'). ' - '.fullname($report->user));
 
     if ($report->fill_table()) {
         echo $report->print_table(true);
@@ -97,6 +83,15 @@ if ($access) {
 
 } else {
     // no access to grades!
+    /// Print header
+    /// Build navigation
+    $strgrades  = get_string('grades');
+    $reportname = get_string('modulename', 'gradereport_overview');
+
+    $navigation = grade_build_nav(__FILE__, $reportname, $course->id);
+    print_header_simple($strgrades.': '.$reportname, ': '.$strgrades, $navigation,
+                        '', '', true, '', navmenu($course));
+
     echo "Can not view grades."; //TODO: localize
 }
 print_footer($course);
index cff513c4a68636215ff224ce508ea319a7140793..8ebaaf7ed0effdb771982b19a89b2ffd04d47c7b 100644 (file)
@@ -72,18 +72,6 @@ if (!isset($USER->grade_last_report)) {
 }
 $USER->grade_last_report[$course->id] = 'user';
 
-/// Build navigation
-$strgrades  = get_string('grades');
-$reportname = get_string('modulename', 'gradereport_user');
-
-$navigation = grade_build_nav(__FILE__, $reportname, $courseid);
-
-/// Print header
-print_header_simple($strgrades.': '.$reportname, ': '.$strgrades, $navigation,
-                    '', '', true, '', navmenu($course));
-
-/// Print the plugin selector at the top
-print_grade_plugin_selector($courseid, 'report', 'user');
 
 if ($access) {
 
@@ -92,29 +80,35 @@ if ($access) {
 
     if (has_capability('moodle/grade:viewall', $context)) { //Teachers will see all student reports
         /// Print graded user selector at the top
-        echo '<div id="graded_users_selector">';
-        print_graded_users_selector($course, 'report/user/index.php?id=' . $course->id, $userid);
-        echo '</div>';
-        echo "<p style = 'page-break-after: always;'></p>";
+        $user_selector = '<div id="graded_users_selector">';
+        $user_selector .= print_graded_users_selector($course, 'report/user/index.php?id=' . $course->id, $userid, true);
+        $user_selector .= '</div>';
+        $user_selector .= "<p style = 'page-break-after: always;'></p>";
 
         if ($userid === 0) {
             $gui = new graded_users_iterator($course);
             $gui->init();
+            // Add tabs
+            print_grade_page_head($courseid, 'report', 'user');
+
+            echo $user_selector.'<br />';
             while ($userdata = $gui->next_user()) {
                 $user = $userdata->user;
                 $report = new grade_report_user($courseid, $gpr, $context, $user->id);
                 print_heading(get_string('modulename', 'gradereport_user'). ' - '.fullname($report->user));
+
                 if ($report->fill_table()) {
-                    echo $report->print_table(true);
+                    echo '<br />'.$report->print_table(true);
                 }
                 echo "<p style = 'page-break-after: always;'></p>";
             }
             $gui->close();
         } elseif ($userid) { // Only show one user's report
             $report = new grade_report_user($courseid, $gpr, $context, $userid);
-            print_heading(get_string('modulename', 'gradereport_user'). ' - '.fullname($report->user));
+            print_grade_page_head($courseid, 'report', 'user', get_string('modulename', 'gradereport_user'). ' - '.fullname($report->user));
+            echo $user_selector;
             if ($report->fill_table()) {
-                echo $report->print_table(true);
+                echo '<br />'.$report->print_table(true);
             }
         }
     } else { //Students will see just their own report
@@ -123,10 +117,11 @@ if ($access) {
         $report = new grade_report_user($courseid, $gpr, $context, $userid);
 
         // print the page
-        print_heading(get_string('modulename', 'gradereport_user'). ' - '.fullname($report->user));
+        print_grade_page_head($courseid, 'report', 'user', get_string('modulename', 'gradereport_user'). ' - '.fullname($report->user));
+        echo $user_selector;
 
         if ($report->fill_table()) {
-            echo $report->print_table(true);
+            echo '<br />'.$report->print_table(true);
         }
     }
 
index 42ea331ca8240e855717ea5a04b1ad7f2535e3a2..52f5f859c44f0221da303c3c98fee7b4ecc9ff35 100644 (file)
@@ -1,7 +1,8 @@
-<?PHP // $Id$ 
+<?PHP // $Id$
 
 $string['modulename'] = 'Grader report';
 $string['grader:manage'] = 'Manage the grader report';
 $string['grader:view'] = 'View the grader report';
+$string['preferences'] = 'Grader report preferences';
 
 ?>
index 6e536f3b0cb8c9fe1970e2b1be5575e3bdaef2d8..9c147b54d3effa296cf10a8eee2efb8326d93e7b 100644 (file)
@@ -10,6 +10,8 @@ $string['addgradeletter'] = 'Add a grade letter';
 $string['addidnumbers'] = 'Add id numbers';
 $string['additem'] = 'Add grade item';
 $string['addoutcomeitem'] = 'Add outcome item';
+$string['addoutcome'] = 'Add an outcome';
+$string['addscale'] = 'Add a scale';
 $string['aggregateextracreditmean'] = 'Mean of grades (with extra credits)';
 $string['aggregatemean'] = 'Mean of grades';
 $string['aggregatemedian'] = 'Median of grades';
@@ -47,9 +49,11 @@ $string['averagesdecimalpoints'] = 'Decimals in column averages';
 $string['averagesdisplaytype'] = 'Column averages display type';
 $string['backupwithoutgradebook'] = 'Backup does not contain Gradebook configuration';
 $string['badgrade'] = 'Supplied grade is invalid';
+$string['badlyformattedscale'] = 'Please enter a comma-separated list of values (at least two values required).';
 $string['baduser'] = 'Supplied user is invalid';
 $string['bonuspoints'] = 'Bonus points';
 $string['bulkcheckboxes'] = 'Bulk checkboxes';
+$string['calculatedgrade'] = 'Calculated grade';
 $string['calculation'] = 'Calculation';
 $string['calculationadd'] = 'Add calculation';
 $string['calculationedit'] = 'Edit calculation';
@@ -116,11 +120,13 @@ $string['coursegradecategory'] = 'Course grade category';
 $string['coursegradedisplaytype'] = 'Course grade display type';
 $string['coursegradedisplayupdated'] = 'The course grade display type has been updated.';
 $string['coursename'] = 'Course name';
+$string['coursescales'] = 'Course scales';
 $string['coursesettings'] = 'Course settings';
 $string['coursetotal'] = 'Course total';
 $string['createcategory'] = 'Create category';
 $string['createcategoryerror'] = 'Could not create a new category';
 $string['creatinggradebooksettings'] = 'Creating gradebook settings';
+$string['currentparentaggregation'] = 'Current parent aggregation';
 $string['csv'] = 'CSV';
 $string['curveto'] = 'Curve to';
 $string['decimalpoints'] = 'Overall decimal points';
@@ -143,7 +149,10 @@ $string['editcalculation'] = 'Edit calculation';
 $string['editcalculationverbose'] = 'Edit calculation for $a->category$a->itemmodule $a->itemname';
 $string['editfeedback'] = 'Edit feedback';
 $string['editgrade'] = 'Edit grade';
+$string['editgradeletters'] = 'Edit grade letters';
+$string['editoutcome'] = 'Edit outcome';
 $string['editoutcomes'] = 'Edit outcomes';
+$string['editscale'] = 'Edit scale';
 $string['edittree'] = 'Categories and items';
 $string['editverbose'] = 'Edit $a->category$a->itemmodule $a->itemname';
 $string['enableajax'] = 'Enable AJAX';
@@ -187,6 +196,7 @@ $string['forelementtypes'] = ' for the selected $a';
 $string['forstudents'] = 'For students';
 $string['full'] = 'Full';
 $string['fullmode'] = 'Full view';
+$string['fullview'] = 'Full view';
 $string['generalsettings'] = 'General settings';
 $string['grade'] = 'Grade';
 $string['gradebook'] = 'Gradebook';
@@ -309,6 +319,7 @@ $string['letterreal'] = 'Letter (real)';
 $string['letters'] = 'Letters';
 $string['linkedactivity'] = 'Linked activity';
 $string['linkedactivityhelp'] = 'Specifies an optional activity to which this outcome item is linked. This is used to measure student performance on criteria not assessed by the activity grade.';
+$string['linktoactivity'] = 'Link to $a->name activity';
 $string['lock'] = 'Lock';
 $string['locked'] = 'Locked';
 $string['locktime'] = 'Lock after';
@@ -330,12 +341,15 @@ $string['min'] = 'Lowest';
 $string['missingscale'] = 'Scale must be selected';
 $string['mode'] = 'Mode';
 $string['morethanmax'] = 'The grade entered for $a->itemname for $a->username is more than the maximum allowed';
+$string['moveselectedto'] = 'Move selected items to:';
 $string['movingelement'] = 'Moving $a';
 $string['multfactor'] = 'Multiplicator';
 $string['multfactorhelp'] = 'Factor by which all grades for this grade item will be multiplied.';
 $string['myreportpreferences'] = 'My report preferences';
 $string['neverdeletehistory'] = 'Never delete history';
 $string['newcategory'] = 'New category';
+$string['newitem'] = 'New grade item';
+$string['newoutcomeitem'] = 'New outcome item';
 $string['newuserkey'] = 'New user key';
 $string['no'] = 'No';
 $string['nocategories'] = 'Grade categories could not be added or found for this course';
@@ -479,6 +493,7 @@ $string['showrank'] = 'Show rank';
 $string['showuseridnumber'] = 'Show user idnumber';
 $string['showuserimage'] = 'Show user profile images';
 $string['showverbose'] = 'Show $a->category$a->itemmodule $a->itemname';
+$string['simpleview'] = 'Simple view';
 $string['sitewide'] = 'Site-wide';
 $string['sort'] = 'sort';
 $string['sortasc'] = 'Sort in ascending order';
@@ -493,6 +508,8 @@ $string['studentsperpage'] = 'Students per page';
 $string['subcategory'] = 'Normal category';
 $string['submissions'] = 'Submissions';
 $string['submittedon'] = 'Submitted: $a';
+$string['switchtofullview'] = 'Switch to full view';
+$string['switchtosimpleview'] = 'Switch to simple view';
 $string['synclegacygrades'] = 'Synchronise legacy grades';
 $string['topcategory'] = 'Super category';
 $string['total'] = 'Total';