]> git.mjollnir.org Git - moodle.git/commitdiff
A new feature to allow teachers to browse course files to
authormoodler <moodler>
Sun, 12 Oct 2003 17:12:02 +0000 (17:12 +0000)
committermoodler <moodler>
Sun, 12 Oct 2003 17:12:02 +0000 (17:12 +0000)
find images to insert into Richtext editor windows.

This hack was started by Janne Mikkonen, and I further refined it
to fit better into Moodle.

See:  http://moodle.org/mod/forum/discuss.php?d=2126

lib/rte/README_MOODLE
lib/rte/courseimages.php [new file with mode: 0644]
lib/rte/dlg_ins_image.php [new file with mode: 0644]
lib/rte/richedit.php [new file with mode: 0644]
lib/rte/rte.php [new file with mode: 0644]
lib/weblib.php

index d42a940a88f3faaa33ed0543f0c7dd77053d984d..b8d4a9035b4e41f073b41f96336136521458f970 100644 (file)
@@ -1,7 +1,26 @@
+10/10/2002:
+
 This version of the Richtext editor started out as 0.3 beta 1,
 and I've hacked richedit.html to make the toolbars more compact.
 
 I've also changed the smilies to refer to Moodle smilies, and 
 added/removed some.
 
-Martin Dougiamas, 10/10/2002
+
+
+12/10/2003:
+
+I've just added and further hacked some changes from Janne 
+Mikkonen (http://moodle.org/mod/forum/discuss.php?d=2126)
+to allow a popup so that images can be selected from the 
+course files area.
+
+This includes these PHP files in this folder:
+
+ -- courseimages.php
+ -- dlg_ins_image.php
+ -- richedit.php
+ -- rte.php
+
+
+Martin Dougiamas
diff --git a/lib/rte/courseimages.php b/lib/rte/courseimages.php
new file mode 100644 (file)
index 0000000..67e55b9
--- /dev/null
@@ -0,0 +1,851 @@
+<?PHP // $Id$
+
+//  Manage all uploaded files in a course file area
+
+//  This file is a hack to files/index.php that removes
+//  the headers and adds some controls so that images
+//  can be selected within the Richtext editor.  
+
+//  All the Moodle-specific stuff is in this top section
+//  Configuration and access control occurs here.
+//  Must define:  USER, basedir, baseweb, html_header and html_footer
+//  USER is a persistent variable using sessions
+
+    require("../../config.php");
+    require("../../files/mimetypes.php");
+
+    require_variable($id);
+    optional_variable($file, "");
+    optional_variable($wdir, "");
+    optional_variable($action, "");
+
+    if (! $course = get_record("course", "id", $id) ) {
+        error("That's an invalid course id");
+    }
+
+    require_login($course->id);
+
+    if (! isteacher($course->id) ) {
+        error("Only teachers can edit files");
+    }
+
+    function html_footer() {
+        echo "</td></tr></table></body></html>";
+    }
+    
+    function html_header($course, $wdir, $formfield=""){
+
+        global $CFG;
+
+        if (! $site = get_site()) {
+            error("Invalid site!");
+        }
+
+        if ($course->id == $site->id) {
+            $strfiles = get_string("sitefiles");
+        } else {
+            $strfiles = get_string("files");
+        }
+    
+        if ($wdir == "/") {
+            $fullnav = "$strfiles";
+        } else {
+            $dirs = explode("/", $wdir);
+            $numdirs = count($dirs);
+            $link = "";
+            $navigation = "";
+            for ($i=1; $i<$numdirs; $i++) {
+               $navigation .= " -> ";
+               $link .= "/".urlencode($dirs[$i]);
+               $navigation .= "<a href=\"".$_SERVER['PHP_SELF']."?id=$course->id&wdir=$link\">".$dirs[$i]."</a>";
+            }
+            $fullnav = "<a href=\"".$_SERVER['PHP_SELF']."?id=$course->id&wdir=/\">$strfiles</a> $navigation";
+        }
+
+        print_header();
+        ?>
+           <script language="javscript" type="text/javascript">
+           <!--
+           function set_value(url) {
+                   txt = url;
+                   opener.url.value = txt;
+                   window.close();
+           }
+        -->
+           </script>
+        <?php
+
+        echo '<table border="0" cellpadding="3" cellspacing="0" width="100%">';
+        echo '<tr>';
+        echo '<td bgcolor="'.$THEME->cellheading.'" class="navbar">';
+        echo '<font size="2"><b>'."$course->shortname -> $fullnav".'</b></font>';
+        echo '</td>';
+        echo '</tr>';
+        echo '</table>';
+
+        if ($course->id == $site->id) {
+            print_heading(get_string("publicsitefileswarning"), "center", 2);
+        }
+
+        echo "<table border=0 align=center cellspacing=3 cellpadding=3 width=640>";
+        echo "<tr>";
+        echo "<td colspan=\"2\">";
+    }
+
+    if (! $basedir = make_upload_directory("$course->id")) {
+        error("The site administrator needs to fix the file permissions");
+    }
+
+    $baseweb = $CFG->wwwroot;
+
+//  End of configuration and access control
+
+
+    $regexp="\\.\\.";
+    if (ereg( $regexp, $file, $regs )| ereg( $regexp, $wdir,$regs )) {           
+        $message = "Error: Directories can not contain \"..\"";
+        $wdir = "/";
+        $action = "";
+    }    
+
+    if (!$wdir) {
+        $wdir="/";
+    }
+
+
+    switch ($action) {
+
+        case "upload":
+            html_header($course, $wdir);
+
+            if (!empty($_FILES['userfile'])) {
+                $userfile = $_FILES['userfile'];
+            } else {
+                $save = false;
+            }
+            if (!empty($save)) {
+                if (!is_uploaded_file($userfile['tmp_name']) or $userfile['size'] == 0) {
+                    notify(get_string("uploadnofilefound"));
+                } else {
+                    $userfile_name = clean_filename($userfile['name']);
+                    if ($userfile_name) {
+                        $newfile = "$basedir$wdir/$userfile_name";
+                        if (move_uploaded_file($userfile['tmp_name'], $newfile)) {
+                            chmod($newfile, 0666);
+                            $a = NULL;
+                            $a->file = "$userfile_name (".$userfile['type'].")";
+                            $a->directory = $wdir;
+                            print_string("uploadedfileto", "", $a);
+                        } else {
+                            notify(get_string("uploadproblem", "", $userfile_name));
+                        }
+                    }
+                }
+                displaydir($wdir);
+                    
+            } else {
+                $upload_max_filesize = get_max_upload_file_size();
+                $filesize = display_size($upload_max_filesize);
+
+                $struploadafile = get_string("uploadafile");
+                $struploadthisfile = get_string("uploadthisfile");
+                $strmaxsize = get_string("maxsize", "", $filesize);
+                $strcancel = get_string("cancel");
+
+                echo "<P>$struploadafile ($strmaxsize) --> <B>$wdir</B>";
+                echo "<TABLE><TR><TD COLSPAN=2>";
+                echo "<FORM ENCTYPE=\"multipart/form-data\" METHOD=\"post\" ACTION=\"".$_SERVER['PHP_SELF']."\">";
+                echo " <INPUT TYPE=hidden NAME=MAX_FILE_SIZE value=\"$upload_max_filesize\">";
+                echo " <INPUT TYPE=hidden NAME=id VALUE=$id>";
+                echo " <INPUT TYPE=hidden NAME=wdir VALUE=$wdir>";
+                echo " <INPUT TYPE=hidden NAME=action VALUE=upload>";
+                echo " <INPUT NAME=\"userfile\" TYPE=\"file\" size=\"60\">";
+                echo " </TD><TR><TD WIDTH=10>";
+                echo " <INPUT TYPE=submit NAME=save VALUE=\"$struploadthisfile\">";
+                echo "</FORM>";
+                echo "</TD><TD WIDTH=100%>";
+                echo "<FORM ACTION=\"".$_SERVER['PHP_SELF']."\" METHOD=\"get\">";
+                echo " <INPUT TYPE=hidden NAME=id VALUE=$id>";
+                echo " <INPUT TYPE=hidden NAME=wdir VALUE=$wdir>";
+                echo " <INPUT TYPE=hidden NAME=action VALUE=cancel>";
+                echo " <INPUT TYPE=submit VALUE=\"$strcancel\">";
+                echo "</FORM>";
+                echo "</TD></TR></TABLE>";
+            }
+            html_footer();
+            break;
+
+        case "delete":
+            if (!empty($confirm)) {
+                html_header($course, $wdir);
+                foreach ($USER->filelist as $file) {
+                    $fullfile = $basedir.$file;
+                    if (! fulldelete($fullfile)) {
+                        echo "<BR>Error: Could not delete: $fullfile";
+                    }
+                }
+                clearfilelist();
+                displaydir($wdir);
+                html_footer();
+
+            } else {
+                html_header($course, $wdir);
+                if (setfilelist($_POST)) {
+                    echo "<p align=center>".get_string("deletecheckwarning").":</p>";
+                    print_simple_box_start("center");
+                    printfilelist($USER->filelist);
+                    print_simple_box_end();
+                    echo "<br />";
+                    notice_yesno (get_string("deletecheckfiles"), 
+                                "".basename($_SERVER['PHP_SELF'])."?id=$id&wdir=$wdir&action=delete&confirm=1",
+                                "".basename($_SERVER['PHP_SELF'])."?id=$id&wdir=$wdir&action=cancel");
+                } else {
+                    displaydir($wdir);
+                }
+                html_footer();
+            }
+            break;
+
+        case "move":
+            html_header($course, $wdir);
+            if ($count = setfilelist($_POST)) {
+                $USER->fileop     = $action;
+                $USER->filesource = $wdir;
+                echo "<p align=center>";
+                print_string("selectednowmove", "moodle", $count);
+                echo "</p>";
+            }
+            displaydir($wdir);
+            html_footer();
+            break;
+
+        case "paste":
+            html_header($course, $wdir);
+            if (isset($USER->fileop) and $USER->fileop == "move") {
+                foreach ($USER->filelist as $file) {
+                    $shortfile = basename($file);
+                    $oldfile = $basedir.$file;
+                    $newfile = $basedir.$wdir."/".$shortfile;
+                    if (!rename($oldfile, $newfile)) {
+                        echo "<P>Error: $shortfile not moved";
+                    }
+                }
+            }
+            clearfilelist();
+            displaydir($wdir);
+            html_footer();
+            break;
+
+        case "rename":
+            if (!empty($name)) {
+                html_header($course, $wdir);
+                $name = clean_filename($name);
+                if (file_exists($basedir.$wdir."/".$name)) {
+                    echo "Error: $name already exists!";
+                } else if (!rename($basedir.$wdir."/".$oldname, $basedir.$wdir."/".$name)) {
+                    echo "Error: could not rename $oldname to $name";
+                }
+                displaydir($wdir);
+                    
+            } else {
+                $strrename = get_string("rename");
+                $strcancel = get_string("cancel");
+                $strrenamefileto = get_string("renamefileto", "moodle", $file);
+                html_header($course, $wdir, "form.name");
+                echo "<P>$strrenamefileto:";
+                echo "<TABLE><TR><TD>";
+                echo "<FORM ACTION=\"".$_SERVER['PHP_SELF']."\" METHOD=\"post\" NAME=\"form\">";
+                echo " <INPUT TYPE=hidden NAME=id VALUE=$id>";
+                echo " <INPUT TYPE=hidden NAME=wdir VALUE=$wdir>";
+                echo " <INPUT TYPE=hidden NAME=action VALUE=rename>";
+                echo " <INPUT TYPE=hidden NAME=oldname VALUE=\"$file\">";
+                echo " <INPUT TYPE=text NAME=name SIZE=35 VALUE=\"$file\">";
+                echo " <INPUT TYPE=submit VALUE=\"$strrename\">";
+                echo "</FORM>";
+                echo "</TD><TD>";
+                echo "<FORM ACTION=\"".$_SERVER['PHP_SELF']."\" METHOD=get>";
+                echo " <INPUT TYPE=hidden NAME=id VALUE=$id>";
+                echo " <INPUT TYPE=hidden NAME=wdir VALUE=$wdir>";
+                echo " <INPUT TYPE=hidden NAME=action VALUE=cancel>";
+                echo " <INPUT TYPE=submit VALUE=\"$strcancel\">";
+                echo "</FORM>";
+                echo "</TD></TR></TABLE>";
+            }
+            html_footer();
+            break;
+
+        case "mkdir":
+            if (!empty($name)) {
+                html_header($course, $wdir);
+                $name = clean_filename($name);
+                if (file_exists("$basedir$wdir/$name")) {
+                    echo "Error: $name already exists!";
+                } else if (! make_upload_directory("$course->id/$wdir/$name")) {
+                    echo "Error: could not create $name";
+                }
+                displaydir($wdir);
+                    
+            } else {
+                $strcreate = get_string("create");
+                $strcancel = get_string("cancel");
+                $strcreatefolder = get_string("createfolder", "moodle", $wdir);
+                html_header($course, $wdir, "form.name");
+                echo "<P>$strcreatefolder:";
+                echo "<TABLE><TR><TD>";
+                echo "<FORM ACTION=\"".$_SERVER['PHP_SELF']."\" METHOD=post NAME=form>";
+                echo " <INPUT TYPE=hidden NAME=id VALUE=$id>";
+                echo " <INPUT TYPE=hidden NAME=wdir VALUE=$wdir>";
+                echo " <INPUT TYPE=hidden NAME=action VALUE=mkdir>";
+                echo " <INPUT TYPE=text NAME=name SIZE=35>";
+                echo " <INPUT TYPE=submit VALUE=\"$strcreate\">";
+                echo "</FORM>";
+                echo "</TD><TD>";
+                echo "<FORM ACTION=\"".$_SERVER['PHP_SELF']."\" METHOD=get>";
+                echo " <INPUT TYPE=hidden NAME=id VALUE=$id>";
+                echo " <INPUT TYPE=hidden NAME=wdir VALUE=$wdir>";
+                echo " <INPUT TYPE=hidden NAME=action VALUE=cancel>";
+                echo " <INPUT TYPE=submit VALUE=\"$strcancel\">";
+                echo "</FORM>";
+                echo "</TD></TR></TABLE>";
+            }
+            html_footer();
+            break;
+
+        case "edit":
+            html_header($course, $wdir);
+            if (isset($text)) {
+                $fileptr = fopen($basedir.$file,"w");
+                fputs($fileptr, stripslashes($text));
+                fclose($fileptr);
+                displaydir($wdir);
+                    
+            } else {
+                $streditfile = get_string("edit", "", "<B>$file</B>");
+                $fileptr  = fopen($basedir.$file, "r");
+                $contents = fread($fileptr, filesize($basedir.$file));
+                fclose($fileptr);
+
+                if (mimeinfo("type", $file) == "text/html") {
+                    if ($usehtmleditor = can_use_richtext_editor()) {
+                        $onsubmit = "onsubmit=\"copyrichtext(document.form.text);\"";
+                    } else {
+                        $onsubmit = "";
+                    }
+                } else {
+                    $usehtmleditor = false;
+                    $onsubmit = "";
+                }
+
+                print_heading("$streditfile");
+
+                echo "<TABLE><TR><TD COLSPAN=2>";
+                echo "<FORM ACTION=\"".$_SERVER['PHP_SELF']."\" METHOD=\"post\" NAME=\"form\" $onsubmit>";
+                echo " <INPUT TYPE=hidden NAME=id VALUE=$id>";
+                echo " <INPUT TYPE=hidden NAME=wdir VALUE=\"$wdir\">";
+                echo " <INPUT TYPE=hidden NAME=file VALUE=\"$file\">";
+                echo " <INPUT TYPE=hidden NAME=action VALUE=edit>";
+                print_textarea($usehtmleditor, 25, 80, 680, 400, "text", $contents);
+                echo "</TD></TR><TR><TD>";
+                echo " <INPUT TYPE=submit VALUE=\"".get_string("savechanges")."\">";
+                echo "</FORM>";
+                echo "</TD><TD>";
+                echo "<FORM ACTION=\"".$_SERVER['PHP_SELF']."\" METHOD=get>";
+                echo " <INPUT TYPE=hidden NAME=id VALUE=$id>";
+                echo " <INPUT TYPE=hidden NAME=wdir VALUE=$wdir>";
+                echo " <INPUT TYPE=hidden NAME=action VALUE=cancel>";
+                echo " <INPUT TYPE=submit VALUE=\"".get_string("cancel")."\">";
+                echo "</FORM>";
+                echo "</TD></TR></TABLE>";
+
+                if ($usehtmleditor) { 
+                    print_richedit_javascript("form", "text", "yes");
+                }
+
+
+            }
+            html_footer();
+            break;
+
+        case "zip":
+            if (!empty($name)) {
+                html_header($course, $wdir);
+                $name = clean_filename($name);
+                if (empty($CFG->zip)) {    // Use built-in php-based zip function
+                    $files = array();
+                    foreach ($USER->filelist as $file) {
+                        $files[] = "$basedir/$file";
+                    }
+                    include_once('../pclzip/pclzip.lib.php');
+                    $archive = new PclZip("$basedir/$wdir/$name");
+                    if (($list = $archive->create($files,'',"$basedir/$wdir/")) == 0) {
+                        error($archive->errorInfo(true));
+                    }
+                } else {                   // Use external zip program
+                    $files = "";
+                    foreach ($USER->filelist as $file) {
+                        $files .= basename($file);
+                        $files .= " ";
+                    }
+                    $command = "cd $basedir/$wdir ; $CFG->zip -r $name $files";
+                    Exec($command);
+                }
+                clearfilelist();
+                displaydir($wdir);
+                    
+            } else {
+                html_header($course, $wdir, "form.name");
+
+                if (setfilelist($_POST)) {
+                    echo "<P ALIGN=CENTER>".get_string("youareabouttocreatezip").":</P>";
+                    print_simple_box_start("center");
+                    printfilelist($USER->filelist);
+                    print_simple_box_end();
+                    echo "<BR>";
+                    echo "<P ALIGN=CENTER>".get_string("whattocallzip");
+                    echo "<TABLE><TR><TD>";
+                    echo "<FORM ACTION=\"".$_SERVER['PHP_SELF']."\" METHOD=post NAME=form>";
+                    echo " <INPUT TYPE=hidden NAME=id VALUE=$id>";
+                    echo " <INPUT TYPE=hidden NAME=wdir VALUE=\"$wdir\">";
+                    echo " <INPUT TYPE=hidden NAME=action VALUE=zip>";
+                    echo " <INPUT TYPE=text NAME=name SIZE=35 VALUE=\"new.zip\">";
+                    echo " <INPUT TYPE=submit VALUE=\"".get_string("createziparchive")."\">";
+                    echo "</FORM>";
+                    echo "</TD><TD>";
+                    echo "<FORM ACTION=\"".$_SERVER['PHP_SELF']."\" METHOD=get>";
+                    echo " <INPUT TYPE=hidden NAME=id VALUE=$id>";
+                    echo " <INPUT TYPE=hidden NAME=wdir VALUE=$wdir>";
+                    echo " <INPUT TYPE=hidden NAME=action VALUE=cancel>";
+                    echo " <INPUT TYPE=submit VALUE=\"".get_string("cancel")."\">";
+                    echo "</FORM>";
+                    echo "</TD></TR></TABLE>";
+                } else {
+                    displaydir($wdir);
+                    clearfilelist();
+                }
+            }
+            html_footer();
+            break;
+
+        case "unzip":
+            html_header($course, $wdir);
+            if (!empty($file)) {
+                $strname = get_string("name");
+                $strsize = get_string("size");
+                $strmodified = get_string("modified");
+                $strstatus = get_string("status");
+                $strok = get_string("ok");
+                $strunpacking = get_string("unpacking", "", $file);
+
+                echo "<P ALIGN=CENTER>$strunpacking:</P>";
+
+                $file = basename($file);
+
+                if (empty($CFG->unzip)) {    // Use built-in php-based unzip function
+                    include_once('../pclzip/pclzip.lib.php');
+                    $archive = new PclZip("$basedir/$wdir/$file");
+                    if (!$list = $archive->extract("$basedir/$wdir")) {
+                        error($archive->errorInfo(true));
+                    } else {  // print some output
+                        echo "<table cellpadding=\"4\" cellspacing=\"2\" border=\"0\" width=640>";
+                        echo "<tr><th align=left>$strname</th>";
+                        echo "<th align=right>$strsize</th>";
+                        echo "<th align=right>$strmodified</th>";
+                        echo "<th align=right>$strstatus</th></tr>";
+                        foreach ($list as $item) {
+                            echo "<tr>";
+                            $item['filename'] = str_replace("$basedir/$wdir/", "", $item['filename']);
+                            print_cell("left", $item['filename']);
+                            if (! $item['folder']) {
+                                print_cell("right", display_size($item['size']));
+                            } else {
+                                echo "<td>&nbsp;</td>";
+                            }
+                            $filedate  = userdate($item['mtime'], get_string("strftimedatetime"));
+                            print_cell("right", $filedate);
+                            print_cell("right", $item['status']);
+                            echo "</tr>";
+                        }
+                        echo "</table>";
+                    }
+                    
+                } else {                     // Use external unzip program
+                    print_simple_box_start("center");
+                    echo "<PRE>";
+                    $command = "cd $basedir/$wdir ; $CFG->unzip -o $file 2>&1";
+                    passthru($command);
+                    echo "</PRE>";
+                    print_simple_box_end();
+                }
+
+                echo "<CENTER><FORM ACTION=\"".$_SERVER['PHP_SELF']."\" METHOD=get>";
+                echo " <INPUT TYPE=hidden NAME=id VALUE=$id>";
+                echo " <INPUT TYPE=hidden NAME=wdir VALUE=$wdir>";
+                echo " <INPUT TYPE=hidden NAME=action VALUE=cancel>";
+                echo " <INPUT TYPE=submit VALUE=\"$strok\">";
+                echo "</FORM>";
+                echo "</CENTER>";
+            } else {
+                displaydir($wdir);
+            }
+            html_footer();
+            break;
+
+        case "listzip":
+            html_header($course, $wdir);
+            if (!empty($file)) {
+                $strname = get_string("name");
+                $strsize = get_string("size");
+                $strmodified = get_string("modified");
+                $strok = get_string("ok");
+                $strlistfiles = get_string("listfiles", "", $file);
+
+                echo "<P ALIGN=CENTER>$strlistfiles:</P>";
+                $file = basename($file);
+
+                include_once('../lib/pclzip/pclzip.lib.php');
+                $archive = new PclZip("$basedir/$wdir/$file");
+                if (!$list = $archive->listContent("$basedir/$wdir")) {
+                    notify($archive->errorInfo(true));
+
+                } else {
+                    echo "<table cellpadding=\"4\" cellspacing=\"2\" border=\"0\" width=640>";
+                    echo "<tr><th align=left>$strname</th><th align=right>$strsize</th><th align=right>$strmodified</th></tr>";
+                    foreach ($list as $item) {
+                        echo "<tr>";
+                        print_cell("left", $item['filename']);
+                        if (! $item['folder']) {
+                            print_cell("right", display_size($item['size']));
+                        } else {
+                            echo "<td>&nbsp;</td>";
+                        }
+                        $filedate  = userdate($item['mtime'], get_string("strftimedatetime"));
+                        print_cell("right", $filedate);
+                        echo "</tr>";
+                    }
+                    echo "</table>";
+                }
+                echo "<br><center><form action=\"".$_SERVER['PHP_SELF']."\" method=get>";
+                echo " <INPUT TYPE=hidden NAME=id VALUE=$id>";
+                echo " <INPUT TYPE=hidden NAME=wdir VALUE=$wdir>";
+                echo " <INPUT TYPE=hidden NAME=action VALUE=cancel>";
+                echo " <INPUT TYPE=submit VALUE=\"$strok\">";
+                echo "</FORM>";
+                echo "</CENTER>";
+            } else {
+                displaydir($wdir);
+            }
+            html_footer();
+            break;
+
+        case "torte":
+               if($_POST)
+               {
+                       while(list($key, $val) = each($_POST))
+                       {
+                               if(ereg("file([0-9]+)", $key, $regs))
+                               {
+                                       $file = $val;
+                               }
+                       }
+                       if(@filetype($CFG->dataroot ."/". $course->id . $file) == "file")
+                       {
+                               if(mimeinfo("icon", $file) == "image.gif")
+                               {
+                                       $url = $CFG->wwwroot ."/file.php?file=/" .$course->id . $file;
+                                       runjavascript($url);
+                               }
+                               else
+                               {
+                                       print "File is not a image!";
+                               }
+                       }
+                       else
+                       {
+                               print "You cannot insert FOLDER into richtext editor!!!";
+                       }
+               }
+               break;
+        case "cancel";
+            clearfilelist();
+
+        default:
+            html_header($course, $wdir);
+            displaydir($wdir);
+            html_footer();
+            break;
+}
+
+
+/// FILE FUNCTIONS ///////////////////////////////////////////////////////////
+
+
+function fulldelete($location) { 
+    if (is_dir($location)) {
+        $currdir = opendir($location);
+        while ($file = readdir($currdir)) { 
+            if ($file <> ".." && $file <> ".") {
+                $fullfile = $location."/".$file;
+                if (is_dir($fullfile)) { 
+                    if (!fulldelete($fullfile)) {
+                        return false;
+                    }
+                } else {
+                    if (!unlink($fullfile)) {
+                        return false;
+                    }
+                } 
+            }
+        } 
+        closedir($currdir);
+        if (! rmdir($location)) {
+            return false;
+        }
+
+    } else {
+        if (!unlink($location)) {
+            return false;
+        }
+    }
+    return true;
+}
+
+
+
+function setfilelist($VARS) {
+    global $USER;
+
+    $USER->filelist = array ();
+    $USER->fileop = "";
+
+    $count = 0;
+    foreach ($VARS as $key => $val) {
+        if (substr($key,0,4) == "file") {
+            $count++;
+            $USER->filelist[] = rawurldecode($val);
+        }
+    }
+    return $count;
+}
+
+function clearfilelist() {
+    global $USER;
+
+    $USER->filelist = array ();
+    $USER->fileop = "";
+}
+
+
+function printfilelist($filelist) {
+    global $basedir, $CFG;
+
+    foreach ($filelist as $file) {
+        if (is_dir($basedir.$file)) {
+            echo "<IMG SRC=\"$CFG->wwwroot/files/pix/folder.gif\" HEIGHT=16 WIDTH=16> $file<BR>";
+            $subfilelist = array();
+            $currdir = opendir($basedir.$file);
+            while ($subfile = readdir($currdir)) { 
+                if ($subfile <> ".." && $subfile <> ".") {
+                    $subfilelist[] = $file."/".$subfile;
+                }
+            }
+            printfilelist($subfilelist);
+
+        } else { 
+            $icon = mimeinfo("icon", $file);
+            echo "<IMG SRC=\"$CFG->wwwroot/files/pix/$icon\"  HEIGHT=16 WIDTH=16> $file<BR>";
+        }
+    }
+}
+
+
+function print_cell($alignment="center", $text="&nbsp;") {
+    echo "<TD ALIGN=\"$alignment\" NOWRAP>";
+    echo "<FONT SIZE=\"-1\" FACE=\"Arial, Helvetica\">";
+    echo "$text";
+    echo "</FONT>";
+    echo "</TD>\n";
+}
+
+function displaydir ($wdir) {
+//  $wdir == / or /a or /a/b/c/d  etc
+
+    global $basedir;
+    global $id;
+    global $USER, $CFG;
+
+    $fullpath = $basedir.$wdir;
+
+    $directory = opendir($fullpath);             // Find all files
+    while ($file = readdir($directory)) {
+        if ($file == "." || $file == "..") {
+            continue;
+        }
+        
+        if (is_dir($fullpath."/".$file)) {
+            $dirlist[] = $file;
+        } else {
+            $filelist[] = $file;
+        }
+    }
+    closedir($directory);
+
+    $strname = get_string("name");
+    $strsize = get_string("size");
+    $strmodified = get_string("modified");
+    $straction = get_string("action");
+    $strmakeafolder = get_string("makeafolder");
+    $struploadafile = get_string("uploadafile");
+    $strwithchosenfiles = get_string("withchosenfiles");
+    $strmovetoanotherfolder = get_string("movetoanotherfolder");
+    $strmovefilestohere = get_string("movefilestohere");
+    $strdeletecompletely = get_string("deletecompletely");
+    $strcreateziparchive = get_string("createziparchive");
+    $strrename = get_string("rename");
+    $stredit   = get_string("edit");
+    $strunzip  = get_string("unzip");
+    $strlist   = get_string("list");
+    $strchoose   = get_string("choose");
+
+
+    echo "<FORM ACTION=\"".$_SERVER['PHP_SELF']."\" METHOD=post NAME=dirform>";
+    echo "<TABLE BORDER=0 cellspacing=2 cellpadding=2 width=640>";    
+    echo "<TR>";
+    echo "<TH WIDTH=5></TH>";
+    echo "<TH ALIGN=left>$strname</TH>";
+    echo "<TH ALIGN=right>$strsize</TH>";
+    echo "<TH ALIGN=right>$strmodified</TH>";
+    echo "<TH ALIGN=right>$straction</TH>";
+    echo "</TR>\n";
+
+    if ($wdir == "/") {
+        $wdir = "";
+    }
+
+    $count = 0;
+
+    if (!empty($dirlist)) {
+        asort($dirlist);
+        foreach ($dirlist as $dir) {
+
+            $count++;
+
+            $filename = $fullpath."/".$dir;
+            $fileurl  = rawurlencode($wdir."/".$dir);
+            $filesafe = rawurlencode($dir);
+            $filedate = userdate(filectime($filename), "%d %b %Y, %I:%M %p");
+    
+            echo "<TR>";
+
+            print_cell("center", "<INPUT TYPE=checkbox NAME=\"file$count\" VALUE=\"$fileurl\">");
+            print_cell("left", "<A HREF=\"".basename($_SERVER['PHP_SELF'])."?id=$id&wdir=$fileurl\"><IMG SRC=\"$CFG->wwwroot/files/pix/folder.gif\" HEIGHT=16 WIDTH=16 BORDER=0 ALT=\"Folder\"></A> <A HREF=\"".basename($_SERVER['PHP_SELF'])."?id=$id&wdir=$fileurl\">".htmlspecialchars($dir)."</A>");
+            print_cell("right", "-");
+            print_cell("right", $filedate);
+            print_cell("right", "<A HREF=\"".basename($_SERVER['PHP_SELF'])."?id=$id&wdir=$wdir&file=$filesafe&action=rename\">$strrename</A>");
+    
+            echo "</TR>";
+        }
+    }
+
+
+    if (!empty($filelist)) {
+        asort($filelist);
+        foreach ($filelist as $file) {
+
+            $icon = mimeinfo("icon", $file);
+
+            $count++;
+            $filename    = $fullpath."/".$file;
+            $fileurl     = "$wdir/$file";
+            $filesafe    = rawurlencode($file);
+            $fileurlsafe = rawurlencode($fileurl);
+            $filedate    = userdate(filectime($filename), "%d %b %Y, %I:%M %p");
+
+            echo "<tr>";
+
+            print_cell("center", "<INPUT TYPE=\"checkbox\" NAME=\"file$count\" VALUE=\"$fileurl\">");
+            echo "<td align=left nowrap>";
+            if ($CFG->slasharguments) {
+                $ffurl = "/file.php/$id$fileurl";
+            } else {
+                $ffurl = "/file.php?file=/$id$fileurl";
+            }
+            link_to_popup_window ($ffurl, "display", 
+                                  "<IMG SRC=\"$CFG->wwwroot/files/pix/$icon\" HEIGHT=16 WIDTH=16 BORDER=0 ALT=\"File\">", 
+                                  480, 640);
+            echo "<font size=\"-1\" face=\"Arial, Helvetica\">";
+            link_to_popup_window ($ffurl, "display", 
+                                  htmlspecialchars($file),
+                                  480, 640);
+            echo "</font></td>";
+
+            $file_size = filesize($filename);
+            print_cell("right", display_size($file_size));
+            print_cell("right", $filedate);
+
+            if ($icon == "text.gif" || $icon == "html.gif") {
+                $edittext = "<a href=\"".basename($_SERVER['PHP_SELF'])."?id=$id&wdir=$wdir&file=$fileurl&action=edit\">$stredit</a>";
+            } else if ($icon == "zip.gif") {
+                $edittext = "<a href=\"".basename($_SERVER['PHP_SELF'])."?id=$id&wdir=$wdir&file=$fileurl&action=unzip\">$strunzip</a>&nbsp;";
+                $edittext .= "<a href=\"".basename($_SERVER['PHP_SELF'])."?id=$id&wdir=$wdir&file=$fileurl&action=listzip\">$strlist</a> ";
+            } else if ($icon == "image.gif") {
+                $edittext = "<b><a onMouseDown=\"return set_value('$CFG->wwwroot/$ffurl')\" href=\"\">$strchoose</a></b>";
+            } else {
+                $edittext = "";
+            }
+            print_cell("right", "$edittext <A HREF=\"".basename($_SERVER['PHP_SELF'])."?id=$id&wdir=$wdir&file=$filesafe&action=rename\">$strrename</A>");
+    
+            echo "</TR>";
+        }
+    }
+    echo "</TABLE>";
+    echo "<hr width=640 align=center noshade size=1>";
+
+    if (empty($wdir)) {
+        $wdir = "/";
+    }
+
+    echo "<TABLE BORDER=0 cellspacing=2 cellpadding=2 width=640>";    
+    echo "<TR><TD>";
+    echo "<INPUT TYPE=hidden NAME=id VALUE=\"$id\">";
+    echo "<INPUT TYPE=hidden NAME=wdir VALUE=\"$wdir\"> ";
+    $options = array (
+                   "move" => "$strmovetoanotherfolder",
+                   "delete" => "$strdeletecompletely",
+                   "zip" => "$strcreateziparchive"
+               );
+    if (!empty($count)) {
+        choose_from_menu ($options, "action", "", "$strwithchosenfiles...", "javascript:document.dirform.submit()");
+    }
+
+    echo "</FORM>";
+    echo "<TD ALIGN=center>";
+    if (!empty($USER->fileop) and ($USER->fileop == "move") and ($USER->filesource <> $wdir)) {
+        echo "<FORM ACTION=\"".$_SERVER['PHP_SELF']."\" METHOD=get>";
+        echo " <INPUT TYPE=hidden NAME=id VALUE=$id>";
+        echo " <INPUT TYPE=hidden NAME=wdir VALUE=\"$wdir\">";
+        echo " <INPUT TYPE=hidden NAME=action VALUE=paste>";
+        echo " <INPUT TYPE=submit VALUE=\"$strmovefilestohere\">";
+        echo "</FORM>";
+    }
+    echo "<TD ALIGN=right>";
+        echo "<FORM ACTION=\"".$_SERVER['PHP_SELF']."\" METHOD=get>";
+        echo " <INPUT TYPE=hidden NAME=id VALUE=$id>";
+        echo " <INPUT TYPE=hidden NAME=wdir VALUE=\"$wdir\">";
+        echo " <INPUT TYPE=hidden NAME=action VALUE=mkdir>";
+        echo " <INPUT TYPE=submit VALUE=\"$strmakeafolder\">";
+        echo "</FORM>";
+    echo "</TD>";
+    echo "<TD ALIGN=right>";
+        echo "<FORM ACTION=\"".$_SERVER['PHP_SELF']."\" METHOD=get>";
+        echo " <INPUT TYPE=hidden NAME=id VALUE=$id>";
+        echo " <INPUT TYPE=hidden NAME=wdir VALUE=\"$wdir\">";
+        echo " <INPUT TYPE=hidden NAME=action VALUE=upload>";
+        echo " <INPUT TYPE=submit VALUE=\"$struploadafile\">";
+        echo "</FORM>";
+    echo "</TD></TR>";
+    echo "</TABLE>";
+    echo "<HR WIDTH=640 ALIGN=CENTER NOSHADE SIZE=1>";
+
+}
+
+?>
diff --git a/lib/rte/dlg_ins_image.php b/lib/rte/dlg_ins_image.php
new file mode 100644 (file)
index 0000000..240b9b2
--- /dev/null
@@ -0,0 +1,214 @@
+<!--
+#################################################################################
+##
+## HTML Text Editing Component for hosting in Web Pages
+## Copyright (C) 2001  Ramesys (Contracting Services) Limited
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public
+## License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+##
+## This library 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
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU LesserGeneral Public License
+## along with this program; if not a copy can be obtained from
+##
+##    http://www.gnu.org/copyleft/lesser.html
+##
+## or by writing to:
+##
+##    Free Software Foundation, Inc.
+##    59 Temple Place - Suite 330,
+##    Boston,
+##    MA  02111-1307,
+##    USA.
+##
+## Original Developer:
+##
+##     Austin David France
+##     Ramesys (Contracting Services) Limited
+##     Mentor House
+##     Ainsworth Street
+##     Blackburn
+##     Lancashire
+##     BB1 6AY
+##     United Kingdom
+##  email: Austin.France@Ramesys.com
+##
+## Home Page:    http://richtext.sourceforge.net/
+## Support:      http://richtext.sourceforge.net/
+##
+#################################################################################
+## Authors & Contributers:
+##
+##      BC             Bill Chalmers           [bill_paula@btinternet.com]
+##                      Font Selection
+##
+## History:
+##
+##   BC      24-07-2002
+##         Billy fixed the bug relating to picking up the current image
+##         I fixed a small bug as a result of the above fix, nothing wrong
+##         with billys code, if statment evaluated to true even though it shouldn't
+##         also fixed the border attribute not being applied on insert of image
+##         and picking up all the properties of an image being edited.
+#################################################################################
+-->
+<?php  
+    include("../../config.php"); 
+
+    require_variable($id);
+
+    if (!$course = get_record("course", "id", $id)) {
+        $course->fullname = "";   // Just to keep display happy, though browsing may fail
+    }
+
+?>
+<html>
+<head>
+<meta name=vs_targetSchema content="HTML 4.0">
+<meta name="GENERATOR" content="Microsoft Visual Studio 7.0">
+<LINK rel="stylesheet" type="text/css" href="dialog.css">
+<script language="JavaScript">
+function attr(name, value) {
+       if (!value || value == "") return "";
+       return ' ' + name + '="' + value + '"';
+}
+function insertImage() {
+       window.returnValue = '<IMG' + attr("alt", alt.value) + attr("src", url.value)
+                                                       + attr("align", align[align.selectedIndex].value)
+                                                       + ((width.value)?attr("width", width.value):"")
+                                                       + ((height.value)?attr("height", height.value):"")
+                                                       + ((vspace.value)?attr("vspace", vspace.value):"")
+                                                       + ((hspace.value)?attr("hspace", hspace.value):"")
+                                                       + ((border.value)?attr("border", border.value):attr("border",0))
+                                                       + '/>';
+       window.close();
+}
+function cancel() {
+       window.returnValue = null;
+       window.close();
+}
+
+
+function setDefaults() {
+   if (dialogArguments.RichEditor.selectedImage != null) {
+      image = dialogArguments.RichEditor.selectedImage;
+      editmode = true;
+      fm = document.forms[0];
+      if (image.src)
+                url.value = image.src
+         if  (image.alt)
+                alt.value = image.alt
+         if (image.width)
+         width.value = image.width
+      if (image.height)
+         height.value = image.height
+      if (image.vspace)
+         vspace.value = image.vspace
+      if (image.hspace)
+         hspace.value = image.hspace
+      if (image.border)
+         border.value = image.border
+      if (image.align) {
+         for (var i = 0; i < align.options.length; i++) {
+            if (align.options[i].value == image.align) {
+               align.options[i].selected = true;
+               break;
+            }
+         }        
+      }
+   }
+}
+
+function updateImage() {
+   image.width = width.value;
+   image.height = height.value;
+   image.vspace = vspace.value;
+   image.hspace = hspace.value;
+   image.border = border.value;
+   image.align = align.options[ align.selectedIndex ].value;
+   window.returnValue = null
+   window.close();
+}
+
+var image = null     // selected image if there is one
+
+// we need to set 
+var editmode = false // are we editing an image?
+if (dialogArguments.RichEditor.selectedImage != null) {
+   editmode = true;
+   document.write("<title>Edit Image</title>");
+} else {
+   document.write("<title>Insert Image</title>");
+
+}
+
+function openWindow()
+{
+       var url = "<?php echo "courseimages.php?id=$id" ?>";
+       window.open(url,'my_new_window','toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=yes, resizable=yes, copyhistory=yes, width=750, height=500');
+}
+
+</script>
+
+</head>
+
+<body topmargin="0" leftmargin="0" style="border: 0; margin: 0;" scroll="no" onLoad="setDefaults()">
+<table class="dlg" cellpadding="0" cellspacing="2" width="100%" height="100%">
+<tr><td colspan="5"><table width="100%"><tr><td nowrap>Picture Info&nbsp;</td><td valign="middle" width="100%"><hr width="100%"></td></tr></table></td></tr>
+<tr>
+ <td width="10">&nbsp;</td>
+ <td width="70">Url:</td><td valign="middle" colspan="3"><input type="text" name="url" value="images/em.icon.smile.gif" size="60"></td>
+</tr>
+<tr>
+ <td height="10">&nbsp;</td>
+ <td width="70">Alt Text:</td><td valign="middle"><input type="text" name="alt" value="" size="25"></td>
+ <td width="70">Align:</td><td valign="middle">
+       <select name="align">
+               <option value="left">Left</option>
+               <option value="absBottom">Abs Bottom</option>
+               <option value="absMiddle">Abs Middle</option>
+               <option value="baseline">Baseline</option>
+               <option value="bottom">Bottom</option>
+               <option value="middle">Middle</option>
+               <option value="right">Right</option>
+               <option value="textTop">Text Top</option>
+               <option value="top">Top</option>
+       </select></td>
+</tr>
+ <td>&nbsp;</td>
+ <td colspan="4" align="center" valign="top">
+ <table width="300" border="0" align="left"><tr>
+ <td width="70">Border:</td><td> <input type="text" name="border" value="0" size="2"></td>
+ <td width="70">Width:</td><td valign="middle"><input type="text" name="width" value="" size="3"></td>
+ <td width="70">Height:</td><td valign="middle"><input type="text" name="height" value="" size="3"></td>
+ <td width="70">Vspace:</td><td valign="middle"><input type="text" name="vspace" value="0" size="2"></td>
+ <td width="70">Hspace:</td><td valign="middle"><input type="text" name="hspace" value="0" size="2"></td>
+ </tr></table>
+ </td>
+
+
+</tr>
+<tr><td colspan="5"><table width="100%"><tr><td valign="middle" width="100%" colspan="2"><hr width="100%"></td></tr></table></td></tr>
+<tr>
+ <td>&nbsp;</td>
+ <td><td colspan="4" align="right">
+<script language="JavaScript">
+if (editmode) {
+   document.write("<input class=\"button\" type=\"button\" value=\"Browse\" title=\"<?php echo $course->fullname ?>\" onclick=\"openWindow()\">&nbsp;&nbsp;&nbsp;&nbsp; ");
+   document.write("<input class=\"button\" type=\"button\" value=\"Update\" title=\"Update Image\" onclick=\"updateImage()\">");
+} else {
+   document.write("<input class=\"button\" type=\"button\" value=\"Browse\" title=\"<?php echo $course->fullname ?>\" onclick=\"openWindow()\">&nbsp;&nbsp;&nbsp;&nbsp; ");
+   document.write("<input class=\"button\" type=\"button\" value=\"Insert\" title=\"Insert Image\" onclick=\"insertImage()\">");
+}
+</script>
+<input class="button" type="button" value="Cancel" title="Cancel Dialog" onclick="cancel()"></td>
+</tr>
+</table>
+</body>
+</html>
diff --git a/lib/rte/richedit.php b/lib/rte/richedit.php
new file mode 100644 (file)
index 0000000..275b682
--- /dev/null
@@ -0,0 +1,340 @@
+<!--
+################################################################################
+##
+## HTML Text Editing Component for hosting in Web Pages
+## Copyright (C) 2001  Ramesys (Contracting Services) Limited
+##
+## This library is free software; you can redistribute it and/or
+## modify it under the terms of the GNU Lesser General Public
+## License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+##
+## This library 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
+## Lesser General Public License for more details.
+##
+## You should have received a copy of the GNU LesserGeneral Public License
+## along with this program; if not a copy can be obtained from
+##
+##    http://www.gnu.org/copyleft/lesser.html
+##
+## or by writing to:
+##
+##    Free Software Foundation, Inc.
+##    59 Temple Place - Suite 330,
+##    Boston,
+##    MA  02111-1307,
+##    USA.
+##
+## Original Developer:
+##
+##     Austin David France
+##     Ramesys (Contracting Services) Limited
+##     Mentor House
+##     Ainsworth Street
+##     Blackburn
+##     Lancashire
+##     BB1 6AY
+##     United Kingdom
+##  email: Austin.France@Ramesys.com
+##
+## Home Page:    http://richtext.sourceforge.net/
+## Support:      http://richtext.sourceforge.net/
+##
+################################################################################
+##
+## Authors & Contributers:
+##
+##     OZ              Austin David France             [austin.france@ramesys.com]
+##                             Primary Developer
+##
+##     LEON    Leon Reinders                   [leonreinders@hetnet.nl]
+##                             Author of View Source & History Functions
+##
+##     DIRK    Dirk Datzert                    [Dirk.Datzert@rasselstein-hoesch.de]
+##                             Justify Full Option
+##
+##     GE              Herfurth, Gerrit                [gerrit.herfurth@gs-druckfarben.de]
+##                             Translator
+##
+##     BC              Bill chalmers                   [bill_paula@btinternet.com]
+##                             General Geek
+##
+## History:
+##
+##     OZ              08-01-2002
+##                     Extended the richeditor interface to include an options property.
+##                     This property can be set to enable/disable functionality in the
+##                     editor.
+##
+##     OZ              22-01-2002
+##                     Disable drag-drop into the editor window and from toolbar buttons.
+##
+##     OZ              10-02-2002
+##                     Added new Full Justify toolbar button.  Implementation of
+##                     a mod to the editor made by Dirk Datzert who supplied the code and
+##                     the Image.
+##
+##     OZ              11-02-2002
+##                     Startup with text area set to contenteditable="false".  The content
+##                     is made editable when the editor has been initialised.
+##
+##     OZ              11-02-2002
+##                     Include debug routines script (rte_debug.js)
+##
+##     OZ              14-02-2002
+##                     Fix removing of color from text.  This actually removes all formatting
+##                     and is equivelent to selecting the remove formatting option.
+##
+##     OZ              14-02-2002
+##                     Reset Fill/Text color buttons once event has fired so they no longer
+##                     appear pressed.
+##
+##     GE              05-06-2002
+##                     Add language translation support for table edit option.
+##
+##     OZ              01-07-2002
+##                     Update table editing html (toolbar) with translation support.
+##
+##     OZ              01-07-2002
+##                     Move language translation (rte_lang.js) below attaching of the
+##                     initEditor() window onload event to ensure translation is done
+##                     before the editor becomes visible.
+##
+##     BC              10-07-2002
+##                     Made the font selection more "web style" with multiple font face attributes.
+##                                             
+## WC    06-08-2002
+##       Testing to ensure code was branched properly for 0.3.0 release
+-->
+<?php  
+    include("../../config.php"); 
+?>
+<html><head>
+<meta content="HTML 4.0" name="vs_targetSchema">
+<meta content="Microsoft FrontPage 5.0" name="GENERATOR">
+<link rel="StyleSheet" type="text/css" href="richedit.css">
+<link rel="StyleSheet" type="text/css" href="syntax.css">
+<link rel="StyleSheet" type="text/css" href="custom.css">
+<script language="JavaScript" src="rte_xhtml.js"></script>
+<script language="JavaScript" src="rte_interface.js"></script>
+<script language="JavaScript" src="rte_debug.js"></script>
+<script language="JavaScript" src="rte.php?id=<?php echo $id ?>"></script>
+<script language="JavaScript" src="rte_codesweep.js"></script>
+<script language="JavaScript" src="rte_editmode.js"></script>
+<script language="JavaScript" src="rte_history.js"></script>
+<SCRIPT language="JavaScript" src="tableEditor.js"></SCRIPT>
+<script language="JavaScript">
+// This defines the scriptlets public interface.  See rte_interface.js for
+// the actual interface definition.
+var public_description =  new RichEditor();
+// Initialise the editor as soon as the window is loaded.
+window.attachEvent("onload", initEditor);
+// Initialise the tEdit var
+var tEdit = null;
+</script>
+<script language="JavaScript" src="rte_lang.js"></script>
+</head>
+<body leftMargin="0" topMargin="0" scroll="no" unselectable="on"
+       onload="tEdit = new tableEditor('doc', 'textedit');"
+       onMouseMove="if (tEdit) { tEdit.changePos(); tEdit.resizeCell() }" >
+
+<!-- Loading Layer ----------------------------------->
+<div id="loading" style="position: absolute; top: 0px; left: 0px; height: 100%; z-index: -1">
+       <table width="100%" height="100%"><tr><td align="center" valign="middle">
+       <font size="+2">Loading ...</font>
+       </td></tr></table>
+</div>
+
+<!-- Editor Layer -------------------------------------->
+<table id="editor" unselectable="on" height="100%" cellspacing="0" cellpadding="0" width="100%" bgcolor="buttonface" border="0">
+  <tr ondragstart="handleDrag(0)" onmouseup="press(false)" onmousedown="press(true)" onmouseover="hover(true)" onmouseout="hover(false)">
+    <td class="rebar"><nobr><span class="toolbar">
+               <img class="spacer" src="images/spacer.gif" width="2"><span class="start"></span>
+               <img id="btnBold"     onclick="doStyle('bold')" alt="@{Bold}" src="images/icon_bold.gif" align="absMiddle" width="20" height="20">
+               <img id="btnItalic"   onclick="doStyle('italic')" alt="@{Italic}" src="images/icon_italic.gif" align="absMiddle" width="20" height="20">
+               <img id="btnUnderline"  onclick="doStyle('underline')" alt="@{Underline}" src="images/icon_underline.gif" align="absMiddle" width="20" height="20">
+               <img id="btnStrikethrough"  onclick="doStyle('strikethrough')" alt="@{Strikethrough}" src="images/icon_strikethrough.gif" align="absMiddle" width="20" height="20">
+               <img class="spacer" src="images/spacer.gif" width="2"><span class="sep"></span>
+               <img id="btnLeftJustify"  onclick="doStyle('JustifyLeft')" alt="@{AlignLeft}" src="images/icon_left.gif" align="absMiddle" width="20" height="20">
+               <img id="btnCenter"   onclick="doStyle('JustifyCenter')" alt="@{Center}" src="images/icon_center.gif" align="absMiddle" width="20" height="20">
+               <img id="btnRightJustify"  onclick="doStyle('JustifyRight')" alt="@{AlignRight}" src="images/icon_right.gif" align="absMiddle" width="20" height="20">
+               <img id="btnFullJustify" onclick="doStyle('JustifyFull')" alt="@{AlignBlock}" src="images/icon_block.gif" align="absMiddle" width="20" height="20">
+               <img class="spacer" src="images/spacer.gif" width="2"><span class="sep"></span>
+               <img id="btnNumList"  onclick="doStyle('InsertOrderedList')" alt="@{NumberedList}" src="images/icon_numlist.gif" align="absMiddle" width="20" height="20">
+               <img id="btnBulList"  onclick="doStyle('InsertUnorderedList')" alt="@{BulettedList}" src="images/icon_bullist.gif" align="absMiddle" width="20" height="20">
+               <img class="spacer" src="images/spacer.gif" width="2"><span class="sep"></span>
+               <img id="btnOutdent"  onmousedown="doStyle('Outdent')" alt="@{DecreaseIndent}" src="images/icon_outdent.gif" align="absMiddle" width="20" height="20">
+               <img id="btnIndent"   onmousedown="doStyle('Indent')" alt="@{IncreaseIndent}" src="images/icon_indent.gif" align="absMiddle" width="20" height="20">
+               <img id="btnSelect" onclick="doStyle('SelectAll')" alt="@{SelectAll}" src="images/icon_select_all.gif" align="absMiddle" width="20" height="20">
+               <span id="featureHistory">
+               <img class="spacer" src="images/spacer.gif" width="10"><span class="sep"></span>
+               <img id="btnPrev" onmousedown="document.execCommand('Undo')" alt="@{HistoryBack}"    src="images/icon_undo.gif" align="absMiddle" width="20" height="20">
+               <img id="btnNext" onmousedown="document.execCommand('Redo')"  alt="@{HistoryForward}" src="images/icon_redo.gif" align="absMiddle" width="20" height="20">
+       </span></nobr></td>
+
+    <td class="rebar"><nobr><span class="toolbar">
+               <img class="spacer" src="images/spacer.gif" width="2"><span class="start"></span>
+               <img id="btnLink"   onclick="link(true)" alt="@{InsertLink}" src="images/icon_ins_link.gif" align="absMiddle" width="20" height="20">
+               <img id="btnRemLink" onclick="link(false)" alt="@{RemoveLink}" src="images/icon_rem_link.gif" align="absMiddle" width="20" height="20">
+               <img class="spacer" src="images/spacer.gif" width="2"><span class="sep"></span>
+               <img id="btnImage"  onclick="insert('image')" alt="@{InsertImage}" src="images/icon_ins_image.gif" align="absMiddle" width="20" height="20">
+               <img id="btnTable"  onclick="insert('table')" alt="@{InsertTable}" src="images/icon_ins_table.gif" align="absMiddle" width="20" height="20">
+               <img id="btnTable"  onclick="document.getElementById('tblCtrl').style.visibility = 'visible';" alt="@{EditTable}" src="images/icon_edt_table.gif" align="absMiddle" width="20" height="20">
+               <img id="btnRule"   onclick="doStyle('InsertHorizontalRule')" alt="@{InsertLine}" src="images/icon_rule.gif" align="absMiddle" width="20" height="20">
+               <img id="btnSmile"  onclick="insert('smile')" alt="@{InsertSmily}" src="images/em.icon.smile.gif" align="absMiddle" width="15" height="15">
+               <img id="btnChar"       onclick="insert('char')" alt="@{InsertCharacter}" src="images/icon_ins_char.gif" align="absMiddle" width="20" height="20" border="0">
+       <span id="featureSource">
+               <img class="spacer" src="images/spacer.gif" width="2"><span class="start"></span>&nbsp;
+               <input title="@{SourceTitle}" class="checkbox" hidefocus type="checkbox" name="switchMode"
+                               onclick="tEdit.stopCellResize(true); tEdit.unSetTableElements(); setEditMode(switchMode)">
+               <span class="label">@{Source}</span>
+    </span>
+       </span>
+    </nobr></td></tr>
+       <tr id="featureStyleBar" ondragstart="handleDrag(0)" onmouseup="press(false)" onmousedown="press(true)" onmouseover="hover(true)" onmouseout="hover(false)">
+    <td colspan=2 class="rebar"><nobr><span class="toolbar">
+               <img class="spacer" src="images/spacer.gif" width="2"><span class="start"></span>&nbsp;
+               <span id="featureStyle">
+                       <span class="label">@{Style}</span>
+                       <select name="" id="ctlStyle" class="fontstyle" onchange="addTag(this)">
+                       </select>
+                       <span class="sep"></span>
+               </span>
+               <span id="featureFont">
+                       <span class="label">@{Font}</span>
+                       <select hidefocus class="fontselect" id="ctlFont"  onchange="sel(this)">
+                               <option selected></option>
+                               <option id="Arial" value="Arial, Helvetica, sans-serif">Arial, Helvetica, sans-serif</option>
+                               <option id="Times New Roman" value="Times New Roman, Times, serif">Times New Roman, Times, serif</option>
+                               <option id="Courier New" value="Courier New, Courier, mono">Courier New, Courier, mono</option>
+                               <option id="Georgia" value="Georgia, Times New Roman, Times, serif">Georgia, Times New Roman, Times, serif</option>
+                               <option id="Verdana" value="Verdana, Arial, Helvetica, sans-serif">Verdana, Arial, Helvetica, sans-serif</option>
+                               <option id="Geneva" value="Geneva, Arial, Helvetica, sans-serif">Geneva, Arial, Helvetica, sans-serif</option>
+                       </select>
+               </span>
+               <span id="featureFontSize">
+                       <span class="sep"></span>
+                       <span class="label">@{Size}</span>
+                       <select hidefocus class="fontsize" id="ctlSize"  onchange="sel(this)">
+                               <option selected></option>
+                               <option value="1">xx-small</option>
+                               <option value="2">x-small</option>
+                               <option value="3">small</option>
+                               <option value="4">medium</option>
+                               <option value="5">large</option>
+                               <option value="6">x-large</option>
+                               <option value="7">xx-large</option>
+                       </select>
+               </span>
+               <span id="featureColour">
+                       <span class="sep"></span>
+                       <img id="btnText"  onclick="pickColor('ForeColor')" alt="@{TextColor}" src="images/icon_color_text.gif" align="absMiddle" width="36" height="20">
+                       <img id="btnFill"  onclick="pickColor('BackColor')" alt="@{BackgroundColor}" src="images/icon_color_fill.gif" align="absMiddle" width="36" height="20">
+               </span>
+       </span></nobr></td>
+</tr>
+<!-- Fields are inserted here -->
+<tr id="rebarBottom">
+    <td colspan=2 class="spacer" height="2"><img height="1" src="images/spacer.gif" align="left"></td></tr>
+  <tr>
+    <td colspan=2 class="textedit" id="textedit" valign="top" height="100%">
+               <div class="document" id="doc" onkeyup="reset(); markSelectedElement(); tEdit.setTableElements(); tEdit.repositionArrows();" contenteditable="false" style="OVERFLOW: auto; WIDTH: 100%; HEIGHT: 100%" onclick="reset(); markSelectedElement()"  onmouseup="markSelectedElement(); tEdit.setTableElements(); tEdit.stopCellResize(false);" onscroll="tEdit.repositionArrows()" height="100%" width="100%">
+         </div>
+       </td></tr>
+</table>
+<object id="color" data="colorchooser.html" type="text/x-scriptlet" VIEWASTEXT>
+</object>
+<script for="color" event="onscriptletevent(name, data)">
+       setColor(name, data);
+</script>
+
+<!-- Table Editing Layer ----------------------------------->
+<div id="tblCtrl" style="position:absolute; visibility:hidden; left:200; top:200; z-index: 5">
+<table border="0" cellpadding="0" cellspacing="0" width="68" bgcolor="buttonface">
+  <tr ondragstart="handleDrag(0)">
+   <td><img src="images/spacer.gif" width="8" height="1" border="0"></td>
+   <td><img src="images/spacer.gif" width="5" height="1" border="0"></td>
+   <td><img src="images/spacer.gif" width="18" height="1" border="0"></td>
+   <td><img src="images/spacer.gif" width="2" height="1" border="0"></td>
+   <td><img src="images/spacer.gif" width="22" height="1" border="0"></td>
+   <td><img src="images/spacer.gif" width="4" height="1" border="0"></td>
+   <td><img src="images/spacer.gif" width="9" height="1" border="0"></td>
+   <td><img src="images/spacer.gif" width="1" height="1" border="0"></td>
+  </tr>
+
+  <tr ondragstart="handleDrag(0)">
+   <td colspan="2" onClick="document.getElementById('tblCtrl').style.visibility = 'hidden';"><img name="CloseWindow" src="images/CloseWindow.gif" width="13" height="16" border="0"></td>
+   <td colspan="3" onmousedown="tEdit.setDrag( document.getElementById('tblCtrl') )" onmouseup="tEdit.setDrag( document.getElementById('tblCtrl') )"><img name="toolbar" src="images/toolbar.gif" width="42" height="16" border="0"></td>
+   <td colspan="2"><img name="minimize" src="images/minimize.gif" width="13" height="16" border="0"></td>
+   <td><img src="images/spacer.gif" width="1" height="16" border="0"></td>
+  </tr>
+  <tr ondragstart="handleDrag(0)">
+         <td colspan="7"><img name="hdr_tables" src="@{hdr_tables}" width="68" height="15" border="0"></td>
+   <td><img src="images/spacer.gif" width="1" height="15" border="0"></td>
+  </tr>
+  <tr ondragstart="handleDrag(0)">
+   <td colspan="7"><img name="plt_hdr" src="images/plt_hdr.gif" width="68" height="9" border="0"></td>
+   <td><img src="images/spacer.gif" width="1" height="9" border="0"></td>
+  </tr>
+
+  <tr ondragstart="handleDrag(0)" onmouseup="press(false)" onmousedown="press(true)" onmouseover="hover(true)" onmouseout="hover(false)">
+   <td rowspan="8"><img class="spacer" name="Editor_r4_c1" src="images/Editor_r4_c1.gif" width="8" height="112" border="0"></td>
+   <td colspan="2" class="tbl"><img name="rmv_colspan"  onclick="tEdit.splitCell();" src="images/rmv_colspan.gif" width="21" height="24" alt="@{RemoveColspan}"></td>
+   <td rowspan="8"><img class="spacer" name="Editor_r4_c4" src="images/Editor_r4_c4.gif" width="2" height="112" border="0"></td>
+   <td colspan="2" class="tbl"><img name="rmv_rowspan"  onclick="tEdit.unMergeDown();" src="images/rmv_rowspan.gif" width="24" height="24" alt="@{RemoveRowspan}"></td>
+   <td rowspan="8"><img class="spacer" name="Editor_r4_c7" src="images/Editor_r4_c7.gif" width="9" height="112" border="0"></td>
+   <td><img class="spacer" src="images/spacer.gif" width="1" height="26" border="0"></td>
+  </tr>
+
+  <tr ondragstart="handleDrag(0)">
+   <td colspan="2"><img class="spacer" name="Editor_r5_c2" src="images/Editor_r5_c2.gif" width="23" height="2" border="0"></td>
+   <td colspan="2"><img class="spacer" name="Editor_r5_c5" src="images/Editor_r5_c5.gif" width="26" height="2" border="0"></td>
+   <td><img class="spacer" src="images/spacer.gif" width="1" height="2" border="0"></td>
+  </tr>
+
+  <tr ondragstart="handleDrag(0)" onmouseup="press(false)" onmousedown="press(true)" onmouseover="hover(true)" onmouseout="hover(false)">
+         <td colspan="2" class="tbl"><img name="incr_colspan"  onclick="tEdit.mergeRight();" src="images/incr_colspan.gif" width="21" height="24" alt="@{IncreaseColspan}"  border="0"></td> 
+         <td colspan="2" class="tbl"><img name="incr_rowspan" onclick="tEdit.mergeDown();" src="images/incr_rowspan.gif" width="24" height="24" alt="@{IncreaseRowspan}"  border="0"></td>
+   <td><img class="spacer" src="images/spacer.gif" width="1" height="26" border="0"></td>
+  </tr>
+
+  <tr ondragstart="handleDrag(0)">
+   <td colspan="2"><img class="spacer"  name="Editor_r7_c2" src="images/Editor_r7_c2.gif" width="23" height="2" border="0"></td>
+   <td colspan="2"><img class="spacer" name="Editor_r7_c5" src="images/Editor_r7_c5.gif" width="26" height="2" border="0"></td>
+   <td><img class="spacer" src="images/spacer.gif" width="1" height="2" border="0"></td>
+  </tr>
+
+  <tr ondragstart="handleDrag(0)" onmouseup="press(false)" onmousedown="press(true)" onmouseover="hover(true)" onmouseout="hover(false)">
+         <td colspan="2" class="tbl"><img name="add_col" onclick="tEdit.processColumn('add');"  src="images/add_col.gif" width="21" height="22" alt="@{AddColumn}" border="0" ></td> 
+         <td colspan="2" class="tbl"><img name="add_row"  onclick="tEdit.processRow('add');" src="images/add_row.gif" width="24" height="22" alt="@{AddRow}" border="0" ></td>
+   <td><img src="images/spacer.gif" width="1" height="24" border="0"></td>
+  </tr>
+
+  <tr ondragstart="handleDrag(0)">
+   <td colspan="2"><img class="spacer" name="Editor_r9_c2" src="images/Editor_r9_c2.gif" width="23" height="4" border="0"></td>
+   <td colspan="2"><img class="spacer" name="Editor_r9_c5" src="images/Editor_r9_c5.gif" width="26" height="4" border="0"></td>
+   <td><img class="spacer" src="images/spacer.gif" width="1" height="4" border="0"></td>
+  </tr>
+
+  <tr ondragstart="handleDrag(0)" onmouseup="press(false)" onmousedown="press(true)" onmouseover="hover(true)" onmouseout="hover(false)">
+         <td colspan="2" class="tbl"><img name="rmv_col" onclick="tEdit.processColumn('remove');" src="images/rmv_col.gif" width="21" height="22" alt="@{RemoveColumn}" border="0" ></td> 
+         <td colspan="2" class="tbl"><img name="rmv_row" onclick="tEdit.processRow('remove');" src="images/rmv_row.gif" width="24" height="22" alt="@{RemoveRow}" border="0" ></td>
+   <td><img src="images/spacer.gif" width="1" height="24" border="0"></td>
+  </tr>
+
+  <tr ondragstart="handleDrag(0)">
+   <td colspan="2"><img name="Editor_r11_c2" src="images/Editor_r11_c2.gif" width="23" height="4" border="0"></td>
+   <td colspan="2"><img name="Editor_r11_c5" src="images/Editor_r11_c5.gif" width="26" height="4" border="0"></td>
+   <td><img class="spacer" src="images/spacer.gif" width="1" height="4" border="0"></td>
+  </tr>
+
+  <tr ondragstart="handleDrag(0)">
+   <td colspan="7"><img name="plt_ftr" src="images/plt_ftr.gif" width="68" height="8" border="0"></td>
+   <td><img class="spacer" src="images/spacer.gif" width="1" height="8" border="0"></td>
+  </tr>
+</table>
+</div>
+
+</body></html>
diff --git a/lib/rte/rte.php b/lib/rte/rte.php
new file mode 100644 (file)
index 0000000..ec214c6
--- /dev/null
@@ -0,0 +1,633 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// HTML Text Editing Component for hosting in Web Pages
+// Copyright (C) 2001  Ramesys (Contracting Services) Limited
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU LesserGeneral Public License
+// along with this program; if not a copy can be obtained from
+//
+//    http://www.gnu.org/copyleft/lesser.html
+//
+// or by writing to:
+//
+//    Free Software Foundation, Inc.
+//    59 Temple Place - Suite 330,
+//    Boston,
+//    MA  02111-1307,
+//    USA.
+//
+// Original Developer:
+//
+//   Austin David France
+//   Ramesys (Contracting Services) Limited
+//   Mentor House
+//   Ainsworth Street
+//   Blackburn
+//   Lancashire
+//   BB1 6AY
+//   United Kingdom
+//  email: Austin.France@Ramesys.com
+//
+// Home Page:    http://richtext.sourceforge.net/
+// Support:      http://richtext.sourceforge.net/
+//
+////////////////////////////////////////////////////////////////////////////////
+//
+// Authors & Contributers:
+//
+//   OZ      Austin David France      [austin.france@ramesys.com]
+//            Primary Developer
+//
+//   LEON   Leon Reinders         [leonreinders@hetnet.nl]
+//            Author of View Source, History and Extended Style Functions
+//
+//   DIRK   Dirk Datzert         [Dirk.Datzert@rasselstein-hoesch.de]
+//            Justify Full Option
+//
+//      BC             Bill Chalmers           [bill_paula@btinternet.com]
+//                      Font Selection
+//
+// History:
+//
+//   OZ      21-01-2002
+//         Fix a bug in applyOptions() that was not detecting a truth setting
+//         properly.  Changed substr(eq) to substr(eq+1).  Also, set the
+//         runtime style property, not the style property.
+//
+//   OZ      22-01-2002
+//         Moved initEditor() function into here from richedit.html
+//
+//   OZ      22-01-2002
+//         Added handleDrag() method to handle drag and drop events within the
+//         html of the editor.  Drag and drop is currently disabled until we
+//         can find a practicle use for it.
+//
+//   OZ      10-02-2002
+//         Added code to handle the new Full Justify Option.  Implementation of
+//         a mod to the editor made by Dirk Datzert who supplied the code and
+//         the Image.
+//
+//   OZ      11-02-2002
+//         Startup with text area set to contenteditable="false".  The content
+//         is made editable when the editor has been initialised.
+//
+//   OZ      12-02-2002
+//         Fix handling of mouse hover when hover over a button that is in the
+//         down state.  The down state of the button was being lost.  This is
+//         a re-introduction of an earlier bug which I thought was fixed.
+//         The bug also occured when the button was pressed in some 
+//         circumstances.  The fix implemented is to have a button state 
+//         property which is set when the state of a button is set in the
+//         setState() routine and this is used to restore the button state when
+//         the button is released or mouse moves out.
+//
+//     OZ              12-06-2002 [richtext-Bugs-567960] Text area of editor window not get focus
+//                     Ensure the doc element (the DIV) has focus once initialisation is
+//                     complete.  This ensures that when no HTML is supplied via the docHtml
+//                     property, that focus is where the user expects.
+//
+//     BC           10-07-2002
+//                      added getfontface() function to retrieve the new "web style" font selection
+//                      this function is called from reset() in the same way as getStyle()
+//
+////////////////////////////////////////////////////////////////////////////////
+
+// Internal (private) properties.  
+// RichEditor is the global RichEditor object (function) of which there is only
+// 1 instance.
+RichEditor.txtView = true;         // WYSIWYG mode.  false == View Source
+
+// initEditor(): Initialise the editor (called on window load, see below)
+function initEditor()
+{
+       // Apply style data if supplied
+       if (!public_description.styleData) {
+         public_description.put_styleData(null);
+       }
+
+       // Apply default editor options
+       var strDefaults = 'dragdrop=no;source=yes';
+       strDefaults += ';history=' + (document.queryCommandSupported('Undo') ? 'yes' : 'no');
+       applyOptions(strDefaults);
+
+       // Prepare the editable region
+       loading.style.display = 'none';
+    doc.contentEditable = "true";
+    editor.style.visibility = 'visible';
+
+       // OZ - 12-06-2002
+       // Put focus into the document (required when no HTML is supplied via docHtml property)
+       doc.focus();
+}
+
+// checkRange(): make sure our pretend document (the content editable
+// DIV with id of "doc") has focus and that a text range exists (which
+// is what execCommand() operates on).
+function checkRange()
+{
+   RichEditor.selectedImage = null;
+   if (!RichEditor.txtView) return;      // Disabled in View Source mode
+   doc.focus();
+   if (document.selection.type == "None") {
+      document.selection.createRange();
+   }
+var r = document.selection.createRange();
+   DBG(1, 'RANGE Bounding('
+            + 'top='+r.boundingHeight
+            + ', left='+r.boundingHeight
+            + ', width='+r.boundingWidth
+            + ', height='+r.boundingHeight + ')'
+         + ', Offset('
+            + 'top='+r.offsetTop
+            + ', left='+r.offsetLeft + ')'
+         + ', Text=(' + r.text + ')'
+         + ', HTML=(' + r.htmlText + ')'
+      );
+}
+
+// post(): Called in response to clicking the post button in the
+// toolbar. It fires an event in the container named post, passing the
+// HTML of our newly edited document as the data argument.
+function post()
+{
+   DBG(1, 'Raise "post" event');
+   window.external.raiseEvent("post", doc.innerHTML);
+}
+
+// insert(): called in response to clicking the insert table, image,
+// smily icons in the toolbar.  Loads up an appropriate dialog to
+// prompt for information, the dialog then returns the HTML code or
+// NULL.  We paste the HTML code into the document.
+function insert(what)
+{
+   if (!RichEditor.txtView) return;      // Disabled in View Source mode
+
+   DBG(1, 'insert(' + what + ')');
+
+   // Chose action based on what is being inserted.
+   switch(what)
+   {
+   case "table":
+      strPage = "dlg_ins_table.html";
+      strAttr = "status:no;dialogWidth:340px;dialogHeight:360px;help:no";
+      break;
+   case "smile":
+      strPage = "dlg_ins_smile.html";
+      strAttr = "status:no;dialogWidth:300px;dialogHeight:350px;help:no";
+      break;
+   case "char":
+      strPage = "dlg_ins_char.html";
+      strAttr = "status:no;dialogWidth:450px;dialogHeight:290px;help:no";
+      break;
+   case "image":
+      strPage = "dlg_ins_image.php?id=<?php echo $id ?>";
+      strAttr = "status:no;dialogWidth:400px;dialogHeight:200px;help:no";' '
+      break;
+   case "about":
+      strPage = "dlg_about.html";
+      strAttr = "status:no;dialogWidth:500px;dialogHeight:405px;help:no";' '
+      break;
+   }
+
+   // run the dialog that implements this type of element
+   html = showModalDialog(strPage, window, strAttr);
+
+   // and insert any result into the document.
+   if (html) {
+      insertHtml(html);
+   }
+}
+
+// insertHtml(): Insert the supplied HTML into the current position
+// within the document.
+function insertHtml(html)
+{
+   doc.focus();
+   var sel = document.selection.createRange();
+   // don't try to insert HTML into a control selection (ie. image or table)
+   if (document.selection.type == 'Control') {
+      return;
+   }
+   sel.pasteHTML(html);
+}
+
+// doStyle(): called to handle the simple style commands such a bold,
+// italic etc.  These require no special handling, just a call to
+// execCommand().  We also call reset so that the toolbar represents
+// the state of the current text.
+//
+// 2002-07-30 Updated based on patch submitted by Michael Keck (mkkeck) 
+//
+function doStyle(s){ 
+   if(!RichEditor.txtView) return; 
+   /* Disabled in View Source mode */ 
+   DBG(1, 'doStyle(' + s + ')'); 
+   checkRange(); 
+   if(s!='InsertHorizontalRule'){ 
+      /* what command string? */ 
+      document.execCommand(s); 
+   } else if( s=='InsertHorizontalRule') { 
+      /* if s=='InsertHorizontalRule then use this command */ 
+      document.execCommand(s,false, null); 
+
+      /* Note: 
+      In your source view the <HR> has an ID like this 
+      <HR id=null> 
+      */ 
+   } 
+   reset(); 
+} 
+
+
+// link(): called to insert a hyperlink.  It will use the selected text
+// if there is some, or the URL entered if not.  If clicked when over a
+// link, that link is allowed to be edited.
+function link(on)
+{
+   if (!RichEditor.txtView) return;      // Disabled in View Source mode
+
+   var strURL = "http://";
+   var strText;
+
+   // First, pick up the current selection.
+   doc.focus();
+   var r = document.selection.createRange();
+   var el = r.parentElement();
+
+   // Is this aready a link?
+   if (el && el.nodeName == "A") {
+      r.moveToElementText(el);
+      if (!on) {      // If removing the link, then replace all with
+         r.pasteHTML(el.innerHTML);
+         return;
+      }
+      strURL = el.href;
+   }
+
+   // Get the text associated with this link
+   strText = r.text;
+
+   // Prompt for the URL
+   strURL = window.prompt("Enter URL", strURL);
+   if (strURL) {
+      // Default the TEXT to the url if non selected
+      if (!strText || !strText.length) {
+         strText = strURL;
+      }
+
+      // Replace with new URL
+      r.pasteHTML('<A href=' + strURL + ' target=_new>' + strText + '</a>');
+   }
+
+   reset();
+}
+
+// sel(); similar to doStyle() but called from the dropdown list boxes
+// for font and style commands.
+function sel(el)
+{
+   if (!RichEditor.txtView) return;      // Disabled in View Source mode
+   checkRange();
+   switch(el.id)
+   {
+   case "ctlFont":
+      document.execCommand('FontName', false, el[el.selectedIndex].value);
+      break;
+   case "ctlSize":
+      document.execCommand('FontSize', false, el[el.selectedIndex].value);
+      break;
+   case "ctlStyle":
+      document.execCommand('FormatBlock', false, el[el.selectedIndex].text);
+      break;
+   }
+   doc.focus();
+   reset();
+}
+
+// pickColor(): called when the text or fill color icons are clicked.  Displays
+// the color chooser control.  The color setting is completed by the event
+// handler of this control (see richedit.html)
+function pickColor(fg)
+{
+   if (!RichEditor.txtView) return;      // Disabled in View Source mode
+   checkRange();
+   var el = window.event.srcElement;
+   if (el && el.nodeName == "IMG") {
+      setState(el, true);
+   }
+   color.style.top = window.event.clientY + 10;
+   color.style.left = window.event.clientX - 250;
+   color.style.display = 'block';
+   color._fg = fg;
+}
+
+// setColor(): called from the fore/back color selection dialog event handler
+// to set/reset the fore/background color.
+function setColor(name, data)
+{
+   color.style.display = 'none';
+   checkRange();
+   if (!data) {
+      removeFormat(document.selection.createRange(), color._fg);
+   } else {
+      document.execCommand(color._fg, false, data);
+   }
+   setState(btnText, false);
+   setState(btnFill, false);
+   doc.focus();
+}
+
+// removeFormat(): Called to remove specific formats from the selected text.
+// The 'removeFormat' command removes all formatting.  The principle behind
+// this routine is to have a list of the possible formats the selection may
+// have, check the selection for the current formats, ignoreing the one we
+// want to use, then remove all formatting and then re-apply all but the
+// one we wanted to remove.
+function removeFormat(r, name)
+{
+   var cmd = [ "Bold", "Italic", "Underline", "Strikethrough", "FontName", "FontSize", "ForeColor", "BackColor" ];
+   var on = new Array(cmd.length);
+   for (var i = 0; i < cmd.length; i++) {
+      on[i] = name == cmd[i] ? null : r.queryCommandValue(cmd[i]);
+   }
+   r.execCommand('RemoveFormat');
+   for (var i = 0; i < cmd.length; i++) {
+      if (on[i]) r.execCommand(cmd[i], false, on[i]);
+   }
+}
+
+// setValue(): called from reset() to make a select list show the current font
+// or style attributes
+function selValue(el, str)
+{
+   if (!RichEditor.txtView) return;      // Disabled in View Source mode
+   for (var i = 0; i < el.length; i++) {
+      if ((!el[i].value && el[i].text == str) || el[i].value == str) {
+         el.selectedIndex = i;
+         return;
+      }
+   }
+   el.selectedIndex = 0;
+}
+
+// setState(): called from reset() to make a button represent the state
+// of the current text.  Pressed is on, unpressed is off.
+function setState(el, on)
+{
+   if (!RichEditor.txtView) return;      // Disabled in View Source mode
+   if (!el.disabled) {
+      if (on) {
+         el.defaultState = el.className = "down";
+      } else {
+         el.defaultState = el.className = null;
+      }
+   }
+}
+
+// getStyle(): called to obtain the class or type of formatting applied to an element,
+// This is used by reset() to set the state of the toolbar to indicate the class of
+// the current element.
+function getStyle() {
+   var style = document.queryCommandValue('FormatBlock');
+   if (style == "Normal") {
+      doc.focus();
+      var rng = document.selection.createRange();
+      if (typeof(rng.parentElement) != "undefined") {
+         var el = rng.parentElement();
+         var tag = el.nodeName.toUpperCase();
+         var str = el.className.toLowerCase();
+         if (!(tag == "DIV" && el.id == "doc" && str == "textedit")) {
+            if (tag == "SPAN") {
+               style = "." + str;
+            } else if (str == "") {
+               style = tag;
+            } else {
+               style = tag + "." + str;
+            }
+         }
+         return style;
+      }
+   }
+   return style;
+}
+
+// getfontface(): called to obtain the face attribute applied to a font tag,
+// This is used by reset() to set the state of the toolbar to indicate the class of
+// the current element.
+function getfontface()
+{
+var family = document.selection.createRange(); //create text range
+
+// don't get font face for image or table
+if (document.selection.type == 'Control') {
+   return;
+}
+
+var el = family.parentElement(); //get parent element
+var tag = el.nodeName.toUpperCase(); //convert tag element to upper case
+
+       if (typeof(el.parentElement) != "undefined" && tag == "FONT") { //only do function if tag is font - this is for greater execution speed
+               var elface = el.getAttribute('FACE'); //get the font tags FACE attribute
+               return elface; //return the value of the face attribute to the reset() function
+       }
+}
+
+// markSelectedElement(): called by onClick and onKeyup events
+// on the contectEditable area
+function markSelectedElement() {
+
+   RichEditor.selectedImage = null;
+
+   var r = document.selection.createRange();
+
+   if (document.selection.type != 'Text') {
+      if (r.length == 1) {
+         if (r.item(0).tagName == "IMG") {
+            RichEditor.selectedImage = r.item(0);
+         }
+      }
+   }
+}
+
+// reset(): called from all over the place to make the toolbar
+// represent the current text. If el specified, it was called from
+// hover(off)
+function reset(el)
+{
+   if (!RichEditor.txtView) return;      // Disabled in View Source mode
+   if (!el) color.style.display = 'none';
+   if (!el || el == ctlStyle)         selValue(ctlStyle, getStyle());
+   if (!el || el == ctlFont)         selValue(ctlFont, getfontface());
+   if (!el || el == ctlSize)         selValue(ctlSize, document.queryCommandValue('FontSize'));
+   if (!el || el == btnBold)         setState(btnBold, document.queryCommandValue('Bold'));
+   if (!el || el == btnItalic)         setState(btnItalic,   document.queryCommandValue('Italic'));
+   if (!el || el == btnUnderline)      setState(btnUnderline, document.queryCommandValue('Underline'));
+   if (!el || el == btnStrikethrough)   setState(btnStrikethrough, document.queryCommandValue('Strikethrough'));
+   if (!el || el == btnLeftJustify)   setState(btnLeftJustify, document.queryCommandValue('JustifyLeft'));
+   if (!el || el == btnCenter)         setState(btnCenter,   document.queryCommandValue('JustifyCenter'));
+   if (!el || el == btnRightJustify)   setState(btnRightJustify, document.queryCommandValue('JustifyRight'));
+   if (!el || el == btnFullJustify)   setState(btnFullJustify, document.queryCommandValue('JustifyFull'));
+   if (!el || el == btnNumList)      setState(btnNumList, document.queryCommandValue('InsertOrderedList'));
+   if (!el || el == btnBulList)      setState(btnBulList, document.queryCommandValue('InsertUnorderedList'));
+}
+
+// hover(): Handles mouse hovering over toolbar buttons
+function hover(on)
+{
+   if (!RichEditor.txtView) return;      // Disabled in View Source mode
+   var el = window.event.srcElement;
+   if (el && !el.disabled && el.nodeName == "IMG" && el.className != "spacer") {
+      if (on) {
+         el.className = "hover";
+      } else {
+         el.className = el.defaultState ? el.defaultState : null;
+      }
+   }
+}
+// hover(): Handles mouse clicks on toolbar buttons
+function press(on)
+{
+   if (!RichEditor.txtView) return;      // Disabled in View Source mode
+   var el = window.event.srcElement;
+   if (el && !el.disabled && el.nodeName == "IMG" && el.className != "spacer") {
+      if (on) {
+         el.className = "down";
+      } else {
+         el.className = el.className == "down" ? "hover" : el.defaultState ? el.defaultState : null;
+      }
+   }
+}
+
+// addTag(): This is the handler for the style dropdown.  This takes value
+// selected and interprates it and makes the necessary changes to the HTML to
+// apply this style.
+function addTag(obj) {
+
+   if (!RichEditor.txtView) return;      // Disabled in View Source mode
+
+   // Determine the type of element we are dealing with.
+   // TYPE 0 IS NORMAL-TAG, 1 IS CLASS, 2 IS SUBCLASS, 3 = Format Block command
+   var value = obj[obj.selectedIndex].value;
+   if (!value) {                        // Format Block
+      sel(obj);
+      return;
+   }
+
+   var type = 0;                        // TAG
+
+   if (value.indexOf(".") == 0) {            // .className
+      type = 1;
+   } else if (value.indexOf(".") != -1) {      // TAG.className
+      type = 2;
+   }
+
+   doc.focus();
+
+   // Pick up the highlighted text
+   var r = document.selection.createRange();
+   r.select();
+   var s = r.htmlText;
+
+   // If we have some selected text, then ignore silly selections
+   if (s == " " || s == "&nbsp;") {
+      return;
+   }
+
+   // How we apply formatting is based upon the type of formitting being
+   // done.
+   switch(type)
+   {
+   case 1:
+      // class: Wrap the selected text with a span of the specified
+      // class name
+      value = value.substring(1,value.length);
+      r.pasteHTML("<span class="+value+">" + r.htmlText + "</span>")
+      break;
+
+   case 2:
+      // subclass: split the value into tag + class
+      value = value.split(".");
+      r.pasteHTML('<' + value[0] + ' class="' + value[1] +'">'
+               + r.htmlText
+               + '</' + value[0] + '>'
+            );
+      break;
+
+   default:
+      // TAG: wrap up the highlighted text with the specified tag
+      r.pasteHTML("<"+value+">"+r.htmlText+"</"+value+">")
+      break;
+   }
+}
+
+// initStyleDropdown(): This takes the passed styleList and generates the style
+// dropdown list box from it.
+function initStyleDropdown(styleList) {
+
+   // Build the option list for the styles dropdown from the passed styles
+   for (var i = 0; i < styleList.length; i++) {
+      var oOption = document.createElement("OPTION");
+      if (styleList[i][0]) oOption.value = styleList[i][0];
+      oOption.text = styleList[i][1];
+      oOption.style.backgroundColor = 'white';
+      document.all.ctlStyle.add(oOption);
+   }
+}
+
+// applyOptions(): This takes the passed options string and actions them.
+// Called during the init process.
+function applyOptions(str)
+{
+   var options = str.split(";");
+   for (var i = 0; i < options.length; i++) {
+      var eq = options[i].indexOf('=');
+      var on = eq == -1 ? true : "yes;true;1".indexOf(options[i].substr(eq+1).toLowerCase()) != -1;
+      var name = eq == -1 ? options[i] : options[i].substr(0,eq);
+      var el = document.all("feature" + name);
+      if (el) {
+         el.runtimeStyle.display = (on ? 'inline' : 'none'); 
+      } else {
+         if (!RichEditor.aOptions) RichEditor.aOptions = new Array;
+         RichEditor.aOptions[name] = on;
+      }
+   }
+}
+
+// getOption(): Get the value for a previously set option or return undefined if
+// the option is not set.
+function getOption(name)
+{
+   if (RichEditor.aOptions) return RichEditor.aOptions[name];
+   return;   // Undefined
+} 
+
+// Handle drag and drop events into the editor window.  Until we
+// work out how to handle these better (which requires co-operation
+// from the code being dragged from as far as I can tell) we simply
+// disable the functionality.
+function handleDrag(n)
+{
+   // if drag and drop is disabled, then cancel the dragdrop
+   // events
+   if (!getOption("dragdrop"))
+   {
+      switch(n) {
+      case 0:   // ondragenter
+         window.event.dataTransfer.dropEffect = "none";
+         break;
+      }
+      // Cancel the event
+      window.event.returnValue = false;
+   }
+}
+
index 1011fa395b3400d7f430b15ead28a0e473bec1da..4976b4cd73ccbb84fdebfd7e2ba4eb221fedc579 100644 (file)
@@ -1222,13 +1222,27 @@ function make_table($table) {
     return $output;
 }
 
-function print_textarea($richedit, $rows, $cols, $width, $height, $name, $value="") {
+function print_textarea($richedit, $rows, $cols, $width, $height, $name, $value="", $courseid=0) {
 /// Prints a richtext field or a normal textarea
-    global $CFG, $THEME;
+    global $CFG, $THEME, $course;
+
+    if (!$courseid) {
+        if (!empty($course->id)) {  // search for it in global context
+            $courseid = $course->id;
+        }
+    }
 
     if ($richedit) {
+        if ($courseid) {
+            if (isteacher($courseid)) {
+                $richediturl = "$CFG->wwwroot/lib/rte/richedit.php?id=$courseid&wwwroot=$CFG->wwwroot";
+            } else {
+                $richediturl = "$CFG->wwwroot/lib/rte/richedit.html";
+            }
+        }
+
         echo "<object id=\"richedit\" style=\"background-color: buttonface\"";
-        echo " data=\"$CFG->wwwroot/lib/rte/richedit.html\"";
+        echo " data=\"$richediturl\"";
         echo " width=\"$width\" height=\"$height\" ";
         echo " type=\"text/x-scriptlet\" VIEWASTEXT=\"true\"></object>\n";
         echo "<textarea style=\"display:none\" name=\"$name\" rows=\"1\" cols=\"1\">";