commit d3349dac1e0acc801c707002d97ebef3cb8642bd
Author: Francois Marier <francois@catalyst.net.nz>
Date:   Tue Oct 21 17:00:00 2008 +1300

    Front page: Add a new setting for displaying course categories in a collapsable tree

diff --git a/admin/settings/frontpage.php b/admin/settings/frontpage.php
index 4481d6b..6da70c1 100644
--- a/admin/settings/frontpage.php
+++ b/admin/settings/frontpage.php
@@ -40,6 +40,7 @@ if (get_site()) { //do not use during installation
                    '9' => '9',
                    '10' => '10')));
         $temp->add(new admin_setting_configtext('coursesperpage', get_string('coursesperpage', 'admin'), get_string('configcoursesperpage', 'admin'), 20, PARAM_INT));
+        $temp->add(new admin_setting_configcheckbox('collapsingcategorytree', get_string('collapsingcategorytree', 'admin'), get_string('configcollapsingcategorytree', 'admin'), 0));
         $temp->add(new admin_setting_configcheckbox('allowvisiblecoursesinhiddencategories', get_string('allowvisiblecoursesinhiddencategories', 'admin'), get_string('configvisiblecourses', 'admin'), 0));
 
         // front page default role
diff --git a/course/lib.php b/course/lib.php
index 9c99939..73337b4 100644
--- a/course/lib.php
+++ b/course/lib.php
@@ -1643,13 +1643,15 @@ function make_categories_list(&$list, &$parents, $category=NULL, $path="") {
 }
 
 
-function print_whole_category_list($category=NULL, $displaylist=NULL, $parentslist=NULL, $depth=-1, $files = true) {
+function print_whole_category_list($category=NULL, $displaylist=NULL, $parentslist=NULL, $depth=-1, $files = true, $categoryid=0) {
 /// Recursive function to print out all the categories in a nice format
 /// with or without courses included
     global $CFG;
 
+    $categoryid += 1;
+
     if (isset($CFG->max_category_depth) && ($depth >= $CFG->max_category_depth)) {
-        return;
+        return $categoryid;
     }
 
     if (!$displaylist) {
@@ -1658,9 +1660,13 @@ function print_whole_category_list($category=NULL, $displaylist=NULL, $parentsli
 
     if ($category) {
         if ($category->visible or has_capability('moodle/course:update', get_context_instance(CONTEXT_SYSTEM))) {
-            print_category_info($category, $depth, $files);
+            $onclick = '';
+            if (!empty($CFG->collapsingcategorytree) && get_child_categories($category->id)) {
+                $onclick = 'onclick="togglecategory('.$categoryid.');return false"';
+            }
+            print_category_info($category, $depth, $files, $onclick, $categoryid);
         } else {
-            return;  // Don't bother printing children of invisible categories
+            return $categoryid;  // Don't bother printing children of invisible categories
         }
 
     } else {
@@ -1668,6 +1674,16 @@ function print_whole_category_list($category=NULL, $displaylist=NULL, $parentsli
     }
 
     if ($categories = get_child_categories($category->id)) {   // Print all the children recursively
+        $spanid = 0;
+        if ($category->id != 0) { // category 0 is a fake root category
+            $spanid = $categoryid;
+            $style = '';
+            if (!empty($CFG->collapsingcategorytree)) {
+                $style = 'style="display: none"';
+            }
+            echo "\n\n<div id=\"category_$spanid\" $style>";
+        }
+
         $countcats = count($categories);
         $count = 0;
         $first = true;
@@ -1681,9 +1697,14 @@ function print_whole_category_list($category=NULL, $displaylist=NULL, $parentsli
             $down = $last ? false : true;
             $first = false;
 
-            print_whole_category_list($cat, $displaylist, $parentslist, $depth + 1, $files);
+            $categoryid = print_whole_category_list($cat, $displaylist, $parentslist, $depth + 1, $files, $categoryid);
+        }
+        if ($spanid != 0) {
+            echo "\n\n</div>\n";
         }
     }
+
+    return $categoryid; // returns the highest category id of the children
 }
 
 // this function will return $options array for choose_from_menu, with whitespace to denote nesting.
@@ -1702,7 +1723,7 @@ function make_categories_options() {
     return $cats;
 }
 
-function print_category_info($category, $depth, $files = false) {
+function print_category_info($category, $depth, $files = false, $onclick = '', $categoryid = 0) {
 /// Prints the category info in indented fashion
 /// This function is only used by print_whole_category_list() above
 
@@ -1786,6 +1807,14 @@ function print_category_info($category, $depth, $files = false) {
             echo '</td>';
         }
 
+        echo '<td valign="top" class="category image">';
+        if ($onclick != '') {
+            echo '<a '.$onclick.'><img height="16" width="16" id="arrow_'. $categoryid.'" src="'.$CFG->pixpath.'/i/arw_off.gif" alt="expand/collapse" /></a> ';
+        } else {
+            echo $catimage;
+        }
+        print '</td>';
+
         echo '<td valign="top" class="category name">';
         echo '<a '.$catlinkcss.' href="'.$CFG->wwwroot.'/course/category.php?id='.$category->id.'">'. format_string($category->name).'</a>';
         echo '</td>';
diff --git a/index.php b/index.php
index 81d3e78..e391532 100644
--- a/index.php
+++ b/index.php
@@ -276,6 +276,13 @@
   </tr>
 </table>
 
+<script type="text/javascript">
+//<![CDATA[
+var pixpath = "<?php echo $CFG->pixpath; ?>";
+//]]>
+</script>
+
 <?php
+    require_js($CFG->wwwroot .'/lib/collapsing_categories.js');
     print_footer('home');     // Please do not modify this line
 ?>
diff --git a/lang/en_utf8/admin.php b/lang/en_utf8/admin.php
index 0494e37..61e020d 100755
--- a/lang/en_utf8/admin.php
+++ b/lang/en_utf8/admin.php
@@ -48,6 +48,7 @@ $string['checkboxno'] = 'No';
 $string['choosefiletoedit'] = 'Choose file to edit';
 $string['clamfailureonupload'] = 'On clam AV failure';
 $string['cleanup'] = 'Cleanup';
+$string['collapsingcategorytree'] = 'Collapsing categories';
 $string['commonsettings'] = 'Common settings';
 $string['componentinstalled'] = 'Component Installed';
 $string['computedfromlogs'] = 'Computed from logs since $a.';
@@ -74,6 +75,7 @@ $string['configcachetype'] = 'Select a type of cache for Moodle to use. This wil
 $string['configclamactlikevirus'] = 'Treat files like viruses';
 $string['configclamdonothing'] = 'Treat files as OK';
 $string['configclamfailureonupload'] = 'If you have configured clam to scan uploaded files, but it is configured incorrectly or fails to run for some unknown reason, how should it behave?  If you choose \'Treat files like viruses\', they\'ll be moved into the quarantine area, or deleted. If you choose \'Treat files as OK\', the files will be moved to the destination directory like normal. Either way, admins will be alerted that clam has failed.  If you choose \'Treat files like viruses\' and for some reason clam fails to run (usually because you have entered an invalid pathtoclam), ALL files that are uploaded will be moved to the given quarantine area, or deleted. Be careful with this setting.';
+$string['configcollapsingcategorytree'] = 'Show course categories in a collapsing tree.';
 $string['configcookiehttponly'] = 'Enables new PHP 5.2.0 feature - browsers are instructed to send cookie with real http requests only, cookies should not be accessible by scripting languages. This is not supported in all browsers and it may not be fully compatible with current code. It helps to prevent some types of XSS attacks.';
 $string['configcookiesecure'] = 'If server is accepting only https connections it is recommended to enable sending of secure cookies. If enabled please make sure that web server is not accepting http:// or set up permanent redirection to https:// address. When <em>wwwroot</em> address does not start with https:// this setting is turned off automatically.';
 $string['configcountry'] = 'If you set a country here, then this country will be selected by default on new user accounts.  To force users to choose a country, just leave this unset.';
diff --git a/lib/collapsing_categories.js b/lib/collapsing_categories.js
new file mode 100644
index 0000000..880c0d8
--- /dev/null
+++ b/lib/collapsing_categories.js
@@ -0,0 +1,14 @@
+function togglecategory(spanid) {
+    var span = document.getElementById("category_" + String(spanid));
+    var arrow = document.getElementById("arrow_" + String(spanid));
+
+    if (span.style.display == "none") {
+        // Expand category
+        span.style.display = "";
+        arrow.src = pixpath + '/i/arw_on.gif';
+    } else {
+        // Collapse category
+        span.style.display = "none";
+        arrow.src = pixpath + '/i/arw_off.gif';
+    }
+}

