From: tjhunt
Date: Thu, 20 Nov 2008 06:59:11 +0000 (+0000)
Subject: quiz editing: MDL-17285 This is Olli Savolainen's new interface for editing quizzes.
X-Git-Url: http://git.mjollnir.org/gw?a=commitdiff_plain;h=fa583f5f6eb3b4c9f624e77df0cfb9f9e705e6c3;p=moodle.git
quiz editing: MDL-17285 This is Olli Savolainen's new interface for editing quizzes.
This was started and usability tested as a Finnish Summer of Code project, and then Olli did further work on it in his own time to get it in shape for inclusion in Moodle 2.0. I reviewed all the code. There are a number of minor outstanding issues that will be fixed soon. See the subtasks of MDL-17284 for a list.
The goal of these changes is to:
* help teachers new to Moodle, so when they first see the quiz editing page, they don't go "Huh! What on earth am I supposed to do here?"
* help novice Moodle users understand and learn to use some of the more advanced quiz feature;
* but, without slowing down more experienced quiz users.
Naturally, with ambitous goals like that, we won't have managed to satisy everybody, but I think this change is a big step in the right direction.
There is extensive documentation on this project at http://docs.moodle.org/en/Development:Quiz_UI_redesign.
---
diff --git a/lang/en_utf8/help/quiz/editconcepts.html b/lang/en_utf8/help/quiz/editconcepts.html
new file mode 100644
index 0000000000..e48d378738
--- /dev/null
+++ b/lang/en_utf8/help/quiz/editconcepts.html
@@ -0,0 +1,25 @@
+Basic ideas of making quizzes
+The main concepts while managing quiz content (questions) are:
+
+ Quiz and pages
+ Question bank and its categories
+ Random question
+
+You can think of a quiz , in essence, to be like a
+traditional pen&paper quiz (or an exam/test). It contains questions.
+You can divide the questions in a quiz on several pages
+or you can keep them all on one page.
+With Moodle Quiz, you can also give the grading beforehand for the
+questions in a quiz (as well as the total for the entire quiz).
+When you create questions, they are stored in the Question
+Bank . In the Question Bank you can create categories, which are similar
+to folders. You can use them to create a hierarchy for organizing
+questions, for example, by topic. When you create a question into
+an exam, a copy of it is stored in the Question Bank. If you decide to
+remove your question from an exam, it will still be intact in the
+question bank until you delete it from there, too.
+You can use Random Questions , if you want a question to
+vary between different attempts students make at the quiz (for example,
+to avoid cheating by means of students copying questions to each other).
+Just create a random question in the quiz and add questions in the
+category of the random question.
diff --git a/lang/en_utf8/quiz.php b/lang/en_utf8/quiz.php
index de2b29fb84..41748e573c 100644
--- a/lang/en_utf8/quiz.php
+++ b/lang/en_utf8/quiz.php
@@ -678,5 +678,44 @@ $string['youcannotwait'] = 'This quiz closes before you will be allowed to start
$string['youneedtoenrol'] = 'You need to enrol in this course before you can attempt this quiz';
$string['yourfinalgradeis'] = 'Your final grade for this quiz is $a.';
$string['zerosignificantfiguresnotallowed'] = 'The correct answer cannot have zero significant figures!';
-
+$string['totalquestionsinrandomqcategory'] = 'Total of $a questions in category.';
+$string['selectquestiontype'] = ' -- Select question type -- ';
+$string['adddescriptionlabel'] = 'Add description/label';
+$string['addrandomquestion'] = 'Add random question';
+$string['addrandomquestiontoquiz'] = 'Add random question to quiz $a';
+$string['parentcategory'] = 'Parent category';
+$string['selectcategory'] = 'Select category';
+$string['createcategoryfornewrandomquestion'] = 'Create a question category for the new random question';
+$string['qname'] = 'name';
+$string['qtypename'] = 'type, name';
+$string['age'] = 'age';
+$string['sortquestionsbyx'] = 'Sort questions by: $a';
+$string['addpagehere'] = 'Add page here';
+$string['questionbankmanagement'] = 'Question Bank management';
+$string['totalpoints'] = 'Total of grades';
+$string['quizwillopen'] = 'This quiz will open $a';
+$string['quizopenwillclose'] = 'This quiz is open, will close on $a at ';
+$string['basicideasofquiz'] = 'Basic ideas of making quizzes';
+$string['noquestionsinquiz'] = 'There are no questions in this quiz.';
+$string['addquestion'] = 'Add question';
+$string['questiontextisempty'] = '[Empty question text]';
+$string['addrandomfromcategory'] = 'Add random questions from category';
+$string['fromcategory'] = 'from category';
+$string['questionbankcontents'] = 'Question Bank contents';
+$string['quizorderrandom'] = '* Order of quiz is shuffled';
+$string['quizordernotrandom'] = 'Order of quiz not shuffled';
+$string['repaginatecommand'] = 'Repaginate';
+$string['orderandpaging'] = 'Order and paging';
+$string['noquestionsonpage'] = 'Empty page';
+$string['orderingquiz'] = 'Order and paging';
+$string['moveselectedonpage'] = 'Move selected questions to page';
+$string['addnewpagesafterselected'] = 'Add new pages after selected questions';
+$string['reorderquestions'] = 'Reorder questions';
+$string['noquestionsnotinuse'] = 'This random question is not in use, since its category is empty.';
+$string['addnewquestionsqbank'] = 'Add questions to the category $a in the \'Question bank contents\' tool >>';
+$string['empty'] = 'Empty';
+$string['quizopened'] = 'This quiz is open.';
+$string['areyousuredeleteselected'] = 'Are you sure you want to delete the selected questions?';
+$string['questionsperpageselected'] = 'Questions per page has been set so the paging is currently fixed. As a result, the paging controls have been disabled. You can change this in ';
+$string['shufflequestionsselected'] = '* Shuffle questions has been set so question order is random. As a result, the button Reorder questions has been disabled. You can change this in ';
?>
diff --git a/lib/weblib.php b/lib/weblib.php
index 050e79c0ca..d0f99e07b1 100644
--- a/lib/weblib.php
+++ b/lib/weblib.php
@@ -717,7 +717,7 @@ function close_window($delay=0) {
* @param mixed $listbox if false, display as a dropdown menu. If true, display as a list box.
* By default, the list box will have a number of rows equal to min(10, count($options)), but if
* $listbox is an integer, that number is used for size instead.
- * @param
+ * @param
*/
function choose_from_menu ($options, $name, $selected='', $nothing='choose', $script='',
$nothingvalue='0', $return=false, $disabled=false, $tabindex=0,
@@ -990,26 +990,30 @@ function print_textfield ($name, $value, $alt = '',$size=50,$maxlength=0, $retur
/**
- * Implements a complete little popup form
+ * Implements a complete little form with a dropdown menu. When JavaScript is on
+ * selecting an option from the dropdown automatically submits the form (while
+ * avoiding the usual acessibility problems with this appoach). With JavaScript
+ * off, a 'Go' button is printed.
*
- * @uses $CFG
- * @param string $common The URL up to the point of the variable that changes
- * @param array $options Alist of value-label pairs for the popup list
- * @param string $formid Id must be unique on the page (originaly $formname)
- * @param string $selected The option that is already selected
+ * @param string $baseurl The target URL up to the point of the variable that changes
+ * @param array $options A list of value-label pairs for the popup list
+ * @param string $formid id for the control. Must be unique on the page. Used in the HTML.
+ * @param string $selected The option that is initially selected
* @param string $nothing The label for the "no choice" option
* @param string $help The name of a help page if help is required
* @param string $helptext The name of the label for the help button
- * @param boolean $return Indicates whether the function should return the text
+ * @param boolean $return Indicates whether the function should return the HTML
* as a string or echo it directly to the page being rendered
* @param string $targetwindow The name of the target page to open the linked page in.
* @param string $selectlabel Text to place in a [label] element - preferred for accessibility.
- * @param array $optionsextra TODO, an array?
+ * @param array $optionsextra an array with the same keys as $options. The values are added within the corresponding tag.
+ * @param string $submitvalue Optional label for the 'Go' button. Defaults to get_string('go').
+ * @param boolean $disabled If true, the menu will be displayed disabled.
* @return string If $return is true then the entire form is returned as a string.
* @todo Finish documenting this function
*/
-function popup_form($common, $options, $formid, $selected='', $nothing='choose', $help='', $helptext='', $return=false,
-$targetwindow='self', $selectlabel='', $optionsextra=NULL) {
+function popup_form($baseurl, $options, $formid, $selected='', $nothing='choose', $help='', $helptext='', $return=false,
+$targetwindow='self', $selectlabel='', $optionsextra=NULL, $submitvalue='', $disabled=false) {
global $CFG, $SESSION;
static $go, $choose; /// Locally cached, in case there's lots on a page
@@ -1018,16 +1022,23 @@ $targetwindow='self', $selectlabel='', $optionsextra=NULL) {
return '';
}
- if (!isset($go)) {
- $go = get_string('go');
+ if (empty($submitvalue)){
+ if (!isset($go)) {
+ $go = get_string('go');
+ $submitvalue=$go;
+ }
}
-
if ($nothing == 'choose') {
if (!isset($choose)) {
$choose = get_string('choose');
}
$nothing = $choose.'...';
}
+ if ($disabled) {
+ $disabled = 'disabled="disabled"';
+ } else {
+ $disabled = '';
+ }
// changed reference to document.getElementById('id_abc') instead of document.abc
// MDL-7861
@@ -1046,16 +1057,16 @@ $targetwindow='self', $selectlabel='', $optionsextra=NULL) {
$selectlabel = ''.$selectlabel.' ';
}
- //IE and Opera fire the onchange when ever you move into a dropdwown list with the keyboard.
+ //IE and Opera fire the onchange when ever you move into a dropdown list with the keyboard.
//onfocus will call a function inside dropdown.js. It fixes this IE/Opera behavior.
//Note: There is a bug on Opera+Linux with the javascript code (first mouse selection is inactive),
//so we do not fix the Opera behavior on Linux
if (check_browser_version('MSIE') || (check_browser_version('Opera') && !check_browser_operating_system("Linux"))) {
- $output .= ''.$selectlabel.$button.'
'."\n";
+ $output .= ''.$selectlabel.$button.'
'."\n";
}
//Other browser
else {
- $output .= ''.$selectlabel.$button.'
'."\n";
+ $output .= '';
$output .= '
+
+';
+//apply CSS for when javascript is enabled
+require_js('mod/quiz/editcss.js',true);
+print_header_simple($pagetitle, '', $navigation, "", $localcss,true,
+ $questionbankmanagement.$strupdatemodule);
+echo $localjs;
+$mode = 'editq';
+$currenttab="edit";
+if($quiz_reordertool){
+ $mode="reorder";
+}
+include('tabs.php');
+
+if($quiz_qbanktool){
+ $showbank_inlinecss='display: none;';
+ $bank_inlinecss='display: block;';
+ $hidebank_inlinecss='display: inline;';
+ $quizcontents_inlinecss="";
+
+}else{
+ $showbank_inlinecss='display: inline;';
+ $bank_inlinecss='display: none;';
+ $hidebank_inlinecss='display: none;';
+ $quizcontents_inlinecss='width:100%;';
+}
+print_side_block_start(get_string('questionbankcontents','quiz').
+ ' ['.get_string("show").
+ ']
+ ['.get_string("hide").
+ ']
+ ', array("class"=>"questionbankwindow"));
+echo '';
+echo '
';
+echo '
';
+$cmoptions = new stdClass;
+$cmoptions->hasattempts=$quiz_has_attempts;
+quiz_question_showbank('editq', $contexts, $thispageurl, $cm,
+ $pagevars['qpage'],
+ $pagevars['qperpage'], $pagevars['qsortorder'],
+ $pagevars['qsortorderdecoded'],
+ $pagevars['cat'], $pagevars['recurse'], $pagevars['showhidden'],
+ $pagevars['showquestiontext'],$cmoptions);
+echo '
';
+echo '
';
+echo '
';
+print_side_block_end();
+
+if (!$quizname = $DB->get_field($cm->modname, 'name', array('id'=>$cm->instance))) {
+ print_error('cannotmodulename');
+}
+
+echo '';
+$questionsperpagebool = ($quiz->questionsperpage < 1) ? 0 : 1;
+if($questionsperpagebool){
+ $repaginatingdisabledhtml='disabled="disabled"';
+ $repaginatingdisabled=true;
+}else{
+ $repaginatingdisabledhtml='';
+ $repaginatingdisabled=false;
+}
+if($quiz_reordertool){
+ echo '
'.
+ get_string("repaginatecommand","quiz").'... ';
+ echo '
';
+}
+print_heading($pagetitle.": ".$quizname, 'left', 2);
+helpbutton("editconcepts", get_string("basicideasofquiz","quiz"), "quiz",
+ true,get_string("basicideasofquiz","quiz"));
+
+$notifystring="";
+if($quiz_has_attempts){
+ $string=get_string('cannoteditafterattempts', 'quiz');
+ $string.='
' .
+ quiz_num_attempt_summary($quiz, $cm) . ' ' ;
+ $notifystring.=notify($string,$style='notifyproblem', $align='center', $return=true);
+}
+if($questionsperpagebool && $quiz_reordertool){
+ $string=get_string('questionsperpageselected', 'quiz');
+ $updateurl=new moodle_url("$CFG->wwwroot/course/mod.php",
+ array("return"=>"true","update"=>$quiz->cmid, "sesskey"=>sesskey()));
+ $string.= '
';
+ $string.=get_string('updatethis', '', get_string('modulename', 'quiz'));
+ $string.=' .';
+ $notifystring.=notify($string,$style='notifyproblem', $align='center', $return=true);
+}
+if($quiz->shufflequestions && $quiz_reordertool){
+ $string=get_string('shufflequestionsselected', 'quiz');
+ $updateurl=new moodle_url("$CFG->wwwroot/course/mod.php",
+ array("return"=>"true","update"=>$quiz->cmid, "sesskey"=>sesskey()));
+ $string.= '
';
+ $string.=get_string('updatethis', '', get_string('modulename', 'quiz'));
+ $string.=' .';
+ $notifystring.=notify($string,$style='notifyproblem', $align='center', $return=true);
+}
+if(!empty($notifystring)){
+ //TODO: make the box closable so it is not in the way
+ print_box_start();
+ echo $notifystring;
+ print_box_end();
+}
+
+if($quiz_reordertool){
+ $perpage= array();
+ $perpage[0] = get_string('allinone', 'quiz');
+ for ($i=1; $i<=50; ++$i) {
+ $perpage[$i] = $i;
+ }
+ $gostring=get_string('go');
+ echo '
';
+ echo get_string("repaginatecommand","quiz");
+ echo '
';
+}
+ob_start();
+$sumgrades = quiz_print_question_list($quiz, $thispageurl, true,
+ null,
+ $quiz_reordertool, $quiz_qbanktool, $quiz_has_attempts);
+
+if (!$DB->set_field('quiz', 'sumgrades', $sumgrades, array('id' => $quiz->instance))) {
+ print_error('cannotsetsumgrades', 'quiz');
+}
+
+$question_list=ob_get_contents();
+ob_end_clean();
+$tabindex=0;
+
+if(!$quiz_reordertool){
+ quiz_print_grading_form($quiz,$thispageurl,$tabindex);
+}
+quiz_print_status_bar($quiz,$sumgrades);
?>
+
+
+
+:
+echo '
';
+
+if(!$quiz_reordertool){
+ // display category adding UI
+ ?>
+
+
+
+
+
+
display_randomquestion_user_interface();
+?>
+
+
\ No newline at end of file
diff --git a/mod/quiz/editcss.js b/mod/quiz/editcss.js
new file mode 100644
index 0000000000..92bc52fb2c
--- /dev/null
+++ b/mod/quiz/editcss.js
@@ -0,0 +1,7 @@
+/** JavaScript for /mod/quiz/edit.php to be loaded in the header
+ * Adds a CSS class to display edit.php for users with JavaScript.
+ */
+ YAHOO.util.Event.onDOMReady(
+ function(){
+ YAHOO.util.Dom.addClass('quizcontentsblock', 'usejs');
+ });
\ No newline at end of file
diff --git a/mod/quiz/editlib.php b/mod/quiz/editlib.php
index c969ff93d8..cf3c713f22 100644
--- a/mod/quiz/editlib.php
+++ b/mod/quiz/editlib.php
@@ -34,14 +34,7 @@ function quiz_delete_quiz_question($id, &$quiz) {
$question = $questions[$id];
unset($questions[$id]);
- // If we deleted the question at the top and it was followed by
- // a page break then delete page break as well
- if ($id == 0 && count($questions) > 1 && $questions[1] == 0) {
- unset($questions[1]);
- }
$quiz->questions = implode(",", $questions);
- // Avoid duplicate page breaks
- $quiz->questions = str_replace(',0,0', ',0', $quiz->questions);
// save new questionlist in database
if (!$DB->set_field('quiz', 'questions', $quiz->questions, array('id' => $quiz->instance))) {
print_error('cannotsavequestion', 'quiz');
@@ -62,10 +55,9 @@ function quiz_delete_quiz_question($id, &$quiz) {
* @param object $quiz The extended quiz object as used by edit.php
* This is updated by this function
*/
-function quiz_add_quiz_question($id, &$quiz) {
+function quiz_add_quiz_question($id, &$quiz, $page=0) {
global $DB;
$questions = explode(",", $quiz->questions);
-
if (in_array($id, $questions)) {
return false;
}
@@ -76,14 +68,42 @@ function quiz_add_quiz_question($id, &$quiz) {
$end = end($breaks);
$last = prev($breaks);
$last = $last ? $last : -1;
- if (!$quiz->questionsperpage or (($end - $last -1) < $quiz->questionsperpage)) {
+ if (!$quiz->questionsperpage or
+ (($end - $last -1) < $quiz->questionsperpage)) {
array_pop($questions);
}
}
- // add question
- $questions[] = $id;
- // add ending page break
- $questions[] = 0;
+ if(is_int($page) && $page >= 1){
+ $numofpages=quiz_number_of_pages($quiz->questions);
+ if ($numofpages<$page){
+ //the page specified does not exist in quiz
+ $page=0;
+ }else{
+ // add ending page break - the following logic requires doing
+ //this at this point
+ $questions[] = 0;
+ $currentpage=1;
+ $addnow=false;
+ foreach ($questions as $question){
+ if($question==0){
+ $currentpage++;
+ //The current page is the one after the one we want to add on,
+ //so we add the question before adding the current page.
+ if ($currentpage==$page+1){
+ $questions_new[]=$id;
+ }
+ }
+ $questions_new[]=$question;
+ }
+ $questions=$questions_new;
+ }
+ }
+ if ($page==0){
+ // add question
+ $questions[] = $id;
+ // add ending page break
+ $questions[] = 0;
+ }
// Save new questionslist in database
$quiz->questions = implode(",", $questions);
@@ -125,247 +145,1298 @@ function quiz_update_question_instance($grade, $questionid, $quizid) {
}
/**
-* Prints a list of quiz questions in a small layout form with knobs
+* Prints a list of quiz questions for the edit.php main view for edit
+* ($reordertool=false) and order and paging ($reordertool=true) tabs
*
* @return int sum of maximum grades
* @param object $quiz This is not the standard quiz object used elsewhere but
* it contains the quiz layout in $quiz->questions and the grades in
* $quiz->grades
* @param boolean $allowdelete Indicates whether the delete icons should be displayed
-* @param boolean $showbreaks Indicates whether the page breaks should be displayed
-* @param boolean $showbreaks Indicates whether the reorder tool should be displayed
+* @param boolean $reordertool Indicates whether the reorder tool should be displayed
+* @param boolean $quiz_qbanktool Indicates whether the question bank should be displayed
+* @param boolean $hasattempts Indicates whether the quiz has attempts
*/
-function quiz_print_question_list($quiz, moodle_url $pageurl, $allowdelete=true, $showbreaks=true, $reordertool=false) {
+//TODO: Tim? remove showbreaks since it is no longer used
+function quiz_print_question_list($quiz, $pageurl, $allowdelete=true,
+ $showbreaks=true,$reordertool=false, $quiz_qbanktool=false,
+ $hasattempts=false) {
global $USER, $CFG, $QTYPES, $DB;
$strorder = get_string("order");
$strquestionname = get_string("questionname", "quiz");
$strgrade = get_string("grade");
$strremove = get_string('remove', 'quiz');
+ $stredit = get_string("edit");
+ $strview = get_string("view");
$straction = get_string("action");
+ $strmove = get_string("move");
$strmoveup = get_string("moveup");
$strmovedown = get_string("movedown");
- $strsavegrades = get_string("savegrades", "quiz");
+ $strsave=get_string('save',"quiz");
+ $strreorderquestions=get_string("reorderquestions","quiz");
+
+ $strselectall = get_string("selectall", "quiz");
+ $strselectnone = get_string("selectnone", "quiz");
$strtype = get_string("type", "quiz");
$strpreview = get_string("preview", "quiz");
- if (!$quiz->questions) {
+ /*if (!$quiz->questions) {
echo "";
print_string("noquestions", "quiz");
echo "
";
return 0;
- }
-
- list($usql, $params) = $DB->get_in_or_equal(explode(',', $quiz->questions));
- if (!$questions = $DB->get_records_sql("SELECT q.*,c.contextid
+ }*/
+ if($quiz->questions){
+ list($usql, $params) = $DB->get_in_or_equal(explode(',', $quiz->questions));
+ $questions = $DB->get_records_sql("SELECT q.*,c.contextid
FROM {question} q,
{question_categories} c
WHERE q.id $usql
- AND q.category = c.id", $params)) {
- echo "";
- print_string("noquestions", "quiz");
- echo "
";
- return 0;
+ AND q.category = c.id", $params);
+ }
+ // if user only has empty pages we have to keep that: out with OR (!$questions)
+ if (!$quiz->questions) {
+ $pagecount=1;
+ echo 'Page '.
+ $pagecount.' ';
+ print_string("noquestionsinquiz", "quiz");
+ echo '
';
+ if(!$reordertool){
+ quiz_print_pagecontrols($quiz, $pageurl, $pagecount,$hasattempts);
+ }
+ echo "
";
+ //this is how it worked before summer 2008
+ //OR !$questions
+ if(!isset($questions)){
+ return 0;
+ }
}
- $count = 0;
- $qno = 1;
- $sumgrade = 0;
- $order = explode(',', $quiz->questions);
+
+ $layout=quiz_clean_layout($quiz->questions);
+ $order = explode(',', $layout);
$lastindex = count($order)-1;
- // If the list does not end with a pagebreak then add it on.
- if ($order[$lastindex] != 0) {
- $order[] = 0;
- $lastindex++;
+
+ if ($hasattempts){
+ $disabled='disabled="disabled"';
+ $movedisabled='';
+ $pagingdisabled='';
+ }else{
+ $disabled='';
+ $movedisabled='';
+ $pagingdisabled='';
+ }
+ if($quiz->shufflequestions){
+ $movedisabled='disabled="disabled"';
+ }
+ if($quiz->questionsperpage){
+ $pagingdisabled='disabled="disabled"';
}
- echo " ";
- echo '';
- echo "\n";
+}
- if (!$quiz->shufflequestions) {
- echo '';
+/**
+ * Print a given single question in quiz for the reordertool tab of edit.php.
+ * Meant to be used from quiz_print_question_list()
+ */
+function quiz_print_singlequestion_reordertool(&$question, &$questionurl, &$quiz){
+ $stredit = get_string("edit");
+ $strview = get_string("view");
- /// Button to show or hide pagebreaks.
- if ($showbreaks) {
- $newshowbreaks = 0;
- $caption = get_string('hidebreaks', 'quiz');
- } else {
- $newshowbreaks = 1;
- $caption = get_string('showbreaks', 'quiz');
+ global $COURSE,$QTYPES, $CFG;
+ $reordercheckboxlabel='
';
+ $reordercheckboxlabelclose=' ';
+
+ ?>
+
+ noclean = false;
+ $formatoptions->para = false;
+ $formatoptions->newlines = false;
+ echo $reordercheckboxlabel;
+ print_question_icon($question);
+ echo "$reordercheckboxlabelclose ";
+ $questiontext=strip_tags(format_text($question->questiontext,
+ FORMAT_MOODLE,$formatoptions, $COURSE->id));
+ $editstring="";
+ if (question_has_capability_on($question, 'edit', $question->category) || question_has_capability_on($question, 'move', $question->category)) {
+ echo "$reordercheckboxlabel ".
+ quiz_question_tostring($question,false).
+ $reordercheckboxlabelclose;
+ $editstring="
out(false, array('id'=>$question->id)).
+ "\"> pixpath/t/edit.gif\" alt=\"".
+ $stredit."\" /> ";
+ } elseif (question_has_capability_on($question, 'view',
+ $question->category)){
+ echo "$reordercheckboxlabel".
+ quiz_question_tostring($question,false).
+ "$reordercheckboxlabelclose";
+ $editstring="
out(false,
+ array('id'=>$question->id))."\">$questionstring pixpath/i/info.gif\" alt=\"$strview\" /> ";
+ }else{
+ echo "$reordercheckboxlabel".
+ quiz_question_tostring($question,false).
+ "$reordercheckboxlabelclose";
+ }
+ echo '
'.$editstring.
+ quiz_question_preview_button($quiz, $question, false).
+ ' ';
+ ?>
+
';
+
+ //TODO: Tim? I left this out from the below get_record call:, 'contextid', $contextid
+ if (!$category = $DB->get_record('question_categories', array('id' => $question->category))) {
+ notify('Random question category not found!');
+ return;
+ }
+ echo '
';
+ $url=$pageurl->out(false,array("qbanktool"=>1, "cat"=>$category->id.','.
+ $category->contextid));
+ $reordercheckboxlabel='
';
+ $reordercheckboxlabelclose=' ';
+
+ echo $reordercheckboxlabel;
+ print_question_icon($question);
+ $editstring= "
pixpath/t/edit.gif\" alt=\"".
+ get_string("edit")."\" /> ";
+ $questioncount=$DB->count_records_select('question',
+ "category IN ($category->id) AND parent = '0' ");
+ $randomquestionlistsize=3;
+
+ if(!$questioncount){
+ echo '
';
+ print_string("empty", "quiz");
+ echo ' ';
+ }
+
+ print_string('random','quiz');
+ echo ": $reordercheckboxlabelclose
";
+
+ echo '
';
+ echo ''.$reordercheckboxlabel.$category->name.
+ $reordercheckboxlabelclose.'';
+ echo ''.$editstring;
+ //TODO: URGENT fix question preview for random questions
+ /*echo
+ quiz_question_preview_button($quiz, $question);
+ */
+ echo ' ';
+ echo "
";
+
+
+ echo '
';
+ echo "
";
+
+ echo "
";
+
+}
+/**
+ * Creates a textual representation of a question for display.
+ */
+function quiz_question_tostring(&$question,$showicon=false,$showquestiontext=true, $return=true){
+ global $COURSE;
+ $result="";
+ $result.='';
+ if($showicon){
+ $result.=print_question_icon($question,true);
+ echo " ";
}
- print_single_button($pageurl->out(true),
- array('showbreaks' => $newshowbreaks) + $pageurl->params(), $caption);
+ $result.=shorten_text(format_string($question->name),200).' ';
+ if($showquestiontext){
+ $formatoptions = new stdClass;
+ $formatoptions->noclean = true;
+ $formatoptions->para = false;
+ $questiontext=strip_tags(format_text($question->questiontext,
+ $question->questiontextformat,
+ $formatoptions, $COURSE->id));
+ $questiontext=shorten_text($questiontext,200);
+ $result.='';
+ if(!empty($questiontext)){
+ $result.=$questiontext;
+ }else{
+ //TODO: if moodle used PHP exceptions, we would raise one here so that
+ //the main UI would know to display quis status "unfinished".
+ $result.='';
+ $result.= get_string("questiontextisempty","quiz");
+ $result.=' ';
+ }
+ $result.=' ';
+ }
+ if($return){
+ return $result;
+ }else{
+ echo $result;
+ }
+}
- echo ' ';
- /// Button to show or hide the reordering tool.
- if ($reordertool) {
- $newreordertool = 0;
- $caption = get_string('hidereordertool', 'quiz');
- } else {
- $newreordertool = 1;
- $caption = get_string('reordertool', 'quiz');
+
+
+
+/**
+ * Shows the question bank editing interface.
+ * A changed copy of the function at question/editlib.php; to be refactored.
+ *
+ * The function also processes a number of actions:
+ *
+ * Actions affecting the question pool:
+ * move Moves a question to a different category
+ * deleteselected Deletes the selected questions from the category
+ * Other actions:
+ * category Chooses the category
+ * displayoptions Sets display options
+ *
+ * @author Martin Dougiamas and many others. This has recently been extensively
+ * rewritten by Gustav Delius and other members of the Serving Mathematics project
+ * {@link http://maths.york.ac.uk/serving_maths}
+ * @param moodle_url $pageurl object representing this pages url.
+ */
+function quiz_question_showbank($tabname, $contexts, $pageurl, $cm,
+ $page, $perpage, $sortorder, $sortorderdecoded, $cat, $recurse,
+ $showhidden, $showquestiontext, $cmoptions){
+ global $COURSE,$DB;
+
+ if (optional_param('deleteselected', false, PARAM_BOOL)){ // teacher still has to confirm
+ // make a list of all the questions that are selected
+ $rawquestions = $_REQUEST; // This code is called by both POST forms and GET links, so cannot use data_submitted.
+ $questionlist = ''; // comma separated list of ids of questions to be deleted
+ $questionnames = ''; // string with names of questions separated by with
+ // an asterix in front of those that are in use
+ $inuse = false; // set to true if at least one of the questions is in use
+ foreach ($rawquestions as $key => $value) { // Parse input for question ids
+ if (preg_match('!^q([0-9]+)$!', $key, $matches)) {
+ $key = $matches[1];
+ $questionlist .= $key.',';
+ question_require_capability_on($key, 'edit');
+ if (record_exists('quiz_question_instances', 'question', $key)) {
+ $questionnames .= '* ';
+ $inuse = true;
+ }
+ $questionnames .= get_field('question', 'name', 'id', $key).
+ ' ';
+ }
+ }
+ if (!$questionlist) { // no questions were selected
+ redirect($pageurl->out());
}
- print_single_button($pageurl->out(true),
- array('reordertool' => $newreordertool) + $pageurl->params(), $caption);
- helpbutton('reorderingtool', get_string('reordertool', 'quiz'), 'quiz');
+ $questionlist = rtrim($questionlist, ',');
- echo ' ';
+ // Add an explanation about questions in use
+ if ($inuse) {
+ $questionnames .= ' '.get_string('questionsinuse', 'quiz');
+ }
+ notice_yesno(get_string("deletequestionscheck", "quiz", $questionnames),
+ $pageurl->out_action(array('deleteselected'=>$questionlist,
+ 'confirm'=>md5($questionlist))),
+ $pageurl->out_action());
+ }else{
+ //actual question bank
+ // starts with category selection form
+ list($categoryid, $contextid)= explode(',', $cat);
- /// Repaginate form.
- echo '';
- echo '';
- echo $pageurl->hidden_params_out();
- echo ' ';
- $perpage= array();
- $perpage[0] = get_string('allinone', 'quiz');
- for ($i=1; $i<=50; ++$i) {
- $perpage[$i] = $i;
- }
- print_string('repaginate', 'quiz', choose_from_menu($perpage, 'questionsperpage',
- $quiz->questionsperpage, '', '', '', true));
- echo ' ';
- echo '
';
- echo ' ';
+ if (!$categoryid) {
+ print_box_start('generalbox questionbank');
+ quiz_question_category_form($contexts->having_one_edit_tab_cap($tabname), $pageurl, $cat, $recurse, $showhidden, $showquestiontext);
+ echo "";
+ print_string("selectcategoryabove", "quiz");
+ echo "
";
+ print_box_end();
+ return;
+ }
+
+ if (!$category = $DB->get_record('question_categories',
+ array('id' => $categoryid, 'contextid' => $contextid))) {
+ print_box_start('generalbox questionbank');
+ notify('Category not found!');
+ print_box_end();
+ return;
+ }
+ $formatoptions = new stdClass;
+ $formatoptions->noclean = true;
+ $strcategory = get_string('category', 'quiz');
+ echo ''.
+ $strcategory;
+ echo ': ';
+ echo shorten_text(strip_tags(format_text($category->name, FORMAT_MOODLE,
+ $formatoptions, $COURSE->id)),60);
+ echo '
';
+ echo shorten_text(strip_tags(format_text($category->info, FORMAT_MOODLE,
+ $formatoptions, $COURSE->id)),200);
+ echo '
';
+
+ print_box_start('generalbox questionbank');
+
+ quiz_question_category_form($contexts->having_one_edit_tab_cap($tabname),
+ $pageurl, $cat, $recurse, $showhidden, $showquestiontext);
+ // continues with list of questions
+
+ quiz_question_list($contexts->having_one_edit_tab_cap($tabname),
+ $pageurl,
+ $cat,
+ isset($cm) ? $cm : null,
+ $recurse,
+ $page,
+ $perpage,
+ $showhidden,
+ $sortorder,
+ $sortorderdecoded,
+ $showquestiontext,
+ $contexts->having_cap('moodle/question:add'),
+ $cmoptions);
+
+ echo '';
+ echo "";
+ echo $pageurl->hidden_params_out(array('recurse', 'showhidden',
+ 'showquestiontext'));
+ question_category_form_checkbox('recurse', $recurse);
+ question_category_form_checkbox('showhidden', $showhidden);
+ echo ' ';
+ echo '
';
+
+ print_box_end();
}
- return $sumgrade;
}
+/**
+ * prints a form to choose categories
+ * A changed copy of the function at question/editlib.php; to be refactored.
+ *
+ */
+function quiz_question_category_form($contexts, $pageurl, $current, $recurse=1,
+ $showhidden=false, $showquestiontext=false) {
+ global $CFG;
-?>
+/// Get all the existing categories now
+ $catmenu = question_category_options($contexts, false, 0, true);
+
+ $strcategory = get_string('category', 'quiz');
+ $strselectcategory = get_string('selectcategory', 'quiz');
+ $strshow = get_string('show', 'quiz');
+ $streditcats = get_string('editcategories', 'quiz');
+
+ popup_form ('edit.php?'.$pageurl->get_query_string().'&category=',
+ $catmenu, 'catmenu', $current, '', '', '', false, 'self',
+ $strselectcategory.":");
+}
+
+
+
+/**
+* Prints the table of questions in a category with interactions
+* A changed copy of the function at question/editlib.php; to be refactored.
+*
+* @param object $course The course object
+* @param int $categoryid The id of the question category to be displayed
+* @param int $cm The course module record if we are in the context of a particular module, 0 otherwise
+* @param int $recurse This is 1 if subcategories should be included, 0 otherwise
+* @param int $page The number of the page to be displayed
+* @param int $perpage Number of questions to show per page
+* @param boolean $showhidden True if also hidden questions should be displayed
+* @param boolean $showquestiontext whether the text of each question should be shown in the list
+*/
+function quiz_question_list($contexts, $pageurl, $categoryandcontext,
+ $cm = null, $recurse=1, $page=0, $perpage=100, $showhidden=false,
+ $sortorder='typename', $sortorderdecoded='qtype, name ASC',
+ $showquestiontext = false, $addcontexts = array(), $cmoptions) {
+ global $USER, $CFG, $THEME, $COURSE, $DB;
+ list($categoryid, $contextid)= explode(',', $categoryandcontext);
+
+ $qtypemenu = question_type_menu();
+
+ $strcategory = get_string("category", "quiz");
+ $strquestion = get_string("question", "quiz");
+ $straddquestions = get_string("addquestions", "quiz");
+ $strimportquestions = get_string("importquestions", "quiz");
+ $strexportquestions = get_string("exportquestions", "quiz");
+ $strnoquestions = get_string("noquestions", "quiz");
+ $strselect = get_string("select", "quiz");
+ $strselectall = get_string("selectall", "quiz");
+ $strselectnone = get_string("selectnone", "quiz");
+ $strcreatenewquestion = get_string("createnewquestion", "quiz");
+ $strquestionname = get_string("questionname", "quiz");
+ $strdelete = get_string("delete");
+ $stredit = get_string("edit");
+ $strmove = get_string('moveqtoanothercontext', 'question');
+ $strview = get_string("view");
+ $straction = get_string("action");
+ $strrestore = get_string('restore');
+
+ $strtype = get_string("type", "quiz");
+ $strcreatemultiple = get_string("createmultiple", "quiz");
+ $strpreview = get_string("preview","quiz");
+
+ if (!$categoryid) {
+ echo "";
+ print_string("selectcategoryabove", "quiz");
+ echo "
";
+ return;
+ }
+
+ if (!$category = $DB->get_record('question_categories',
+ array('id' => $categoryid, 'contextid' => $contextid))) {
+ notify('Category not found!');
+ return;
+ }
+
+ $catcontext = get_context_instance_by_id($contextid);
+ $canadd = has_capability('moodle/question:add', $catcontext);
+ //check for capabilities on all questions in category, will also apply to sub cats.
+ $caneditall =has_capability('moodle/question:editall', $catcontext);
+ $canuseall =has_capability('moodle/question:useall', $catcontext);
+ $canmoveall =has_capability('moodle/question:moveall', $catcontext);
+
+ if ($cm AND $cm->modname == 'quiz') {
+ $quizid = $cm->instance;
+ } else {
+ $quizid = 0;
+ }
+ //create the url of the new question page to forward to. return url is given
+ //as a parameter and automatically urlencoded.
+
+
+
+ $returnurl = $pageurl->out();
+ $questionurl = new moodle_url("$CFG->wwwroot/question/question.php",
+ array('returnurl' => $returnurl));
+ if ($cm!==null){
+ $questionurl->param('cmid', $cm->id);
+ } else {
+ $questionurl->param('courseid', $COURSE->id);
+ }
+ $questionmoveurl = new moodle_url("$CFG->wwwroot/question/contextmoveq.php",
+ array('returnurl' => $returnurl));
+ if ($cm!==null){
+ $questionmoveurl->param('cmid', $cm->id);
+ } else {
+ $questionmoveurl->param('courseid', $COURSE->id);
+ }
+
+
+ $categorylist = ($recurse) ? question_categorylist($category->id) : $category->id;
+
+ // hide-feature
+ $showhidden = $showhidden ? '' : " AND hidden = '0'";
+ echo '';
+ if ($canadd) {
+ popup_form ($questionurl->out(false, array('category' => $category->id)).
+ '&qtype=', $qtypemenu, "addquestion_$page", "", "choose", "",
+ "", false, "self", "$strcreatenewquestion ");
+ helpbutton("questiontypes", $strcreatenewquestion, "quiz");
+ }
+ else {
+ print_string('nopermissionadd', 'question');
+ }
+ echo '
';
+
+
+ $categorylist_array = explode(',', $categorylist);
+
+ list($usql, $params) = $DB->get_in_or_equal($categorylist_array);
+ if (!$totalnumber = $DB->count_records_select('question',
+ "category $usql AND parent = '0' $showhidden", $params)) {
+ echo '';
+ print_string("noquestions", "quiz");
+ echo "
";
+ return;
+ }
+
+ if (!$questions = $DB->get_records_select('question',
+ "category $usql AND parent = '0' $showhidden", $params, $sortorderdecoded,
+ '*', $page*$perpage, $perpage)) {
+
+ // There are no questions on the requested page.
+ $page = 0;
+ if (!$questionsatall = $DB->get_records_select('question',
+ "category $usql AND parent = '0' $showhidden", $params, $sortorderdecoded,
+ '*', 0, $perpage)) {
+ // There are no questions at all
+ echo '';
+ print_string("noquestions", "quiz");
+ echo "
";
+ return;
+ }
+ }
+
+
+
+ echo '';
+ echo question_sort_options($pageurl, $sortorder);
+ echo '
';
+ echo '';
+ print_paging_bar($totalnumber, $page, $perpage, $pageurl, 'qpage');
+ echo '
';
+
+ echo '';
+ echo '';
+ echo ' ';
+ echo $pageurl->hidden_params_out();
+ echo '';
+ echo '
';
+ echo "";
+
+ echo "";
+ echo "";
+ echo " \n";
+ foreach ($questions as $question) {
+ $nameclass = '';
+ $textclass = '';
+ if ($question->hidden) {
+ $nameclass = 'dimmed_text';
+ $textclass = 'dimmed_text';
+ }
+ if ($showquestiontext) {
+ $nameclass .= ' header';
+ }
+ if ($nameclass) {
+ $nameclass = 'class="' . $nameclass . '"';
+ }
+ if ($textclass) {
+ $textclass = 'class="' . $textclass . '"';
+ }
+
+ echo "\n\n";
+
+ $canuseq = question_has_capability_on($question, 'use',
+ $question->category);
+ if (function_exists('module_specific_actions')) {
+ echo module_specific_actions($pageurl, $question->id, $cm->id,
+ $canuseq,$cmoptions);
+ }
+
+ if ($caneditall || $canmoveall || $canuseall){
+ echo " id\" id=\"checkq$question->id\" value=\"1\" />";
+ }
+ echo " \n";
+
+ echo "";
+ $questionstring=quiz_question_tostring($question,false,true,true);
+ echo "id\">";
+ print_question_icon($question);
+ echo " $questionstring ";
+
+
+
+ echo "
\n";
+ echo "";
+ // edit, hide, delete question, using question capabilities, not quiz capabilieies
+ if (question_has_capability_on($question, 'edit', $question->category) ||
+ question_has_capability_on($question, 'move',
+ $question->category)) {
+ echo "out(false,
+ array('id'=>$question->id))."\"> pixpath/t/edit.gif\" alt=\"$stredit\" /> ";
+ } elseif (question_has_capability_on($question, 'view',
+ $question->category)){
+
+ echo "out(false,
+ array('id'=>$question->id))."\"> pixpath/i/info.gif\" alt=\"$strview\" /> ";
+ }
+ // preview
+ if ($canuseq) {
+ $quizorcourseid = $quizid?('&quizid=' . $quizid):('&courseid=' .$COURSE->id);
+ link_to_popup_window('/question/preview.php?id=' . $question->id .
+ $quizorcourseid, 'questionpreview',
+ " pixpath/t/preview.gif\" class=\"iconsmall\" alt=\"$strpreview\" />",
+ 0, 0, $strpreview, QUESTION_PREVIEW_POPUP_OPTIONS);
+ }
+ echo " ";
+
+ echo " \n";
+ if($showquestiontext){
+ echo '';
+ $formatoptions = new stdClass;
+ $formatoptions->noclean = true;
+ $formatoptions->para = false;
+ echo format_text($question->questiontext,
+ $question->questiontextformat,
+ $formatoptions, $COURSE->id);
+ echo " \n";
+ }
+ }
+ echo "
\n";
+
+
+
+
+ echo '';
+ $paging = print_paging_bar($totalnumber, $page, $perpage,
+ $pageurl, 'qpage', false, true);
+ if ($totalnumber > DEFAULT_QUESTIONS_PER_PAGE) {
+ if ($perpage == DEFAULT_QUESTIONS_PER_PAGE) {
+ $showall = '
'.get_string('showall', 'moodle', $totalnumber).' ';
+ } else {
+ $showall = '
'.get_string('showperpage', 'moodle', DEFAULT_QUESTIONS_PER_PAGE).' ';
+ }
+ if ($paging) {
+ $paging = substr($paging, 0, strrpos($paging, '
'));
+ $paging .= " $showall";
+ } else {
+ $paging = "$showall
";
+ }
+ }
+ echo $paging;
+ echo '';
+ echo '\n";
+ echo '';
+ if ($caneditall || $canmoveall || $canuseall){
+ echo ' '.get_string('withselected', 'quiz').': ';
+ if (function_exists('module_specific_buttons')) {
+ echo module_specific_buttons($cm->id,$cmoptions);
+ }
+ // print delete and move selected question
+ if ($caneditall) {
+ echo ' \n";
+ }
+ if (function_exists('module_specific_controls') && $canuseall) {
+ $modulespecific=module_specific_controls($totalnumber, $recurse, $category,
+ $cm->id,$cmoptions);
+ if(!empty($modulespecific)){
+ echo "
$modulespecific";
+ }
+ }
+ }
+ echo "
\n";
+
+ echo '';
+ echo "\n";
+}
+
+?>
\ No newline at end of file
diff --git a/mod/quiz/locallib.php b/mod/quiz/locallib.php
index 68d5042f0d..29ec7d0232 100644
--- a/mod/quiz/locallib.php
+++ b/mod/quiz/locallib.php
@@ -81,9 +81,9 @@ function quiz_create_attempt($quiz, $attemptnumber, $lastattempt, $timenow, $isp
$attempt->userid = $USER->id;
$attempt->preview = 0;
if ($quiz->shufflequestions) {
- $attempt->layout = quiz_repaginate($quiz->questions, $quiz->questionsperpage, true);
+ $attempt->layout = quiz_clean_layout(quiz_repaginate($quiz->questions, $quiz->questionsperpage, true),true);
} else {
- $attempt->layout = $quiz->questions;
+ $attempt->layout = quiz_clean_layout($quiz->questions,true);
}
} else {
/// Build on last attempt.
@@ -229,7 +229,15 @@ function quiz_questions_on_page($layout, $page) {
* So 5,2,0,3,0 means questions 5 and 2 on page 1 and question 3 on page 2
*/
function quiz_questions_in_quiz($layout) {
- return str_replace(',0', '', $layout);
+ if($layout){
+ $layout=str_replace(',0', '', $layout);
+ //remove also the zero in the beginning, if any
+ if(isset($layout[0]) && $layout[0]=="0" &&
+ isset($layout[1]) && $layout[1]==","){
+ $layout=substr($layout,2);
+ }
+ }
+ return $layout;
}
/**
@@ -239,7 +247,31 @@ function quiz_questions_in_quiz($layout) {
* @param string $layout The string representing the quiz layout.
*/
function quiz_number_of_pages($layout) {
- return substr_count($layout, ',0');
+ $count=0;
+ if($layout){
+ //if the first page is empty, include it, too
+ if (strcmp($layout[0],"0")===0){
+ $count++;
+ }
+ $count+=substr_count($layout, ',0');
+ }
+ return $count;
+}
+/**
+ * Returns the number of questions in the quiz layout
+ *
+ * @return integer Comma separated list of question ids
+ * @param string $layout The string representing the quiz layout.
+ */
+function quiz_number_of_questions_in_quiz($layout) {
+ //TODO: clean layout before counting
+ //TODO: remove page breaks
+ $layout=quiz_questions_in_quiz($layout);
+ $count=substr_count($layout, ',');
+ if($count>0){
+ $count++;
+ }
+ return $count;
}
/**
@@ -275,6 +307,10 @@ function quiz_first_questionnumber($quizlayout, $pagelayout) {
function quiz_repaginate($layout, $perpage, $shuffle=false) {
$layout = str_replace(',0', '', $layout); // remove existing page breaks
$questions = explode(',', $layout);
+ //remove empty pages from beginning
+ while (reset($questions) == '0') {
+ array_shift($questions);
+ }
if ($shuffle) {
srand((float)microtime() * 1000000); // for php < 4.2
shuffle($questions);
@@ -705,7 +741,7 @@ function quiz_question_action_icons($quiz, $cmid, $question, $returnurl){
$stredit = get_string('edit');
$strview = get_string('view');
}
- $html ='';
+ $html ='';
if (($question->qtype != 'random')){
$html .= quiz_question_preview_button($quiz, $question);
}
@@ -727,15 +763,19 @@ function quiz_question_action_icons($quiz, $cmid, $question, $returnurl){
* @param object $question the question
* @return the HTML for a preview question icon.
*/
-function quiz_question_preview_button($quiz, $question) {
+function quiz_question_preview_button($quiz, $question, $label=true) {
global $CFG, $COURSE;
if (!question_has_capability_on($question, 'use', $question->category)){
return '';
}
$strpreview = get_string('previewquestion', 'quiz');
+ $strpreviewlabel="";
+ if($label){
+ $strpreviewlabel = " ".get_string('preview', 'quiz');
+ }
$quizorcourseid = $quiz->id?('&quizid=' . $quiz->id):('&courseid=' .$COURSE->id);
return link_to_popup_window('/question/preview.php?id=' . $question->id . $quizorcourseid, 'questionpreview',
- " pixpath/t/preview.gif\" class=\"iconsmall\" alt=\"$strpreview\" />",
+ " pixpath/t/preview.gif\" class=\"iconsmall\" alt=\"$strpreview\" />$strpreviewlabel",
0, 0, $strpreview, QUESTION_PREVIEW_POPUP_OPTIONS, true);
}
@@ -1085,7 +1125,78 @@ function quiz_send_notification_emails($course, $quiz, $attempt, $context, $cm)
// return the number of successfully sent emails
return $emailresult['good'];
}
+function print_timing_information($quiz,$showopenstatus=false){
+ $timenow = time();
+ $available = ($quiz->timeopen < $timenow and ($timenow < $quiz->timeclose or !$quiz->timeclose));
+ if ($available) {
+ if ($quiz->timelimit) {
+ echo get_string("quiztimelimit","quiz", format_time($quiz->timelimit * 60))."";
+ }
+ if ($quiz->timeopen) {
+ echo get_string('quizopens', 'quiz'), ': ', userdate($quiz->timeopen);
+ }
+ if ($quiz->timeclose) {
+ echo get_string('quizcloses', 'quiz'), ': ', userdate($quiz->timeclose);
+ }
+ if($showopenstatus){
+ if(!$quiz->timelimit && !$quiz->timeopen && !$quiz->timeclose){
+ echo get_string('quizopened', 'quiz');
+ }
+ }
+ } else if ($timenow < $quiz->timeopen) {
+ echo get_string("quiznotavailable", "quiz", userdate($quiz->timeopen));
+ } else {
+ echo get_string("quizclosed", "quiz", userdate($quiz->timeclose));
+ }
+ return $available;
+
+}
+function quiz_clean_layout($layout,$removeemptypages=false){
+ //remove duplicate "," (or triple, or...)
+ while(strstr($layout,",,")){
+ $layout = str_replace(',,', ',', $layout);
+ }
+ //remove duplicate question ids
+ $layout_arr=explode(",",$layout);
+ $new_arr=array();
+ $seen=array();
+ //remove duplicate questions
+ foreach($layout_arr as $key=>$value){
+ if(!in_array($value,$seen) && $value!=0){
+ $new_arr[]=$value;
+ $seen[]=$value;
+ }else if($value==0){
+ $new_arr[]=0;
+ }
+ }
+ if($removeemptypages){
+ // Avoid duplicate page breaks
+ // Go through all the array keys
+ for($i=0;$i1 AND
+ !($layout[$last-1] == ',' AND $layout[$last] == '0')){
+ $layout .= ',0';
+ }
+
+ return $layout;
+}
/**
* Print a quiz error message. This is a thin wrapper around print_error, for convinience.
*
diff --git a/mod/quiz/tabs.php b/mod/quiz/tabs.php
index aa6b1b961e..1f49a514d9 100644
--- a/mod/quiz/tabs.php
+++ b/mod/quiz/tabs.php
@@ -31,7 +31,7 @@ $tabs = array();
$row = array();
$inactive = array();
$activated = array();
-
+$stredit=get_string('edit');
if (has_capability('mod/quiz:view', $context)) {
$row[] = new tabobject('info', "$CFG->wwwroot/mod/quiz/view.php?id=$cm->id", get_string('info', 'quiz'));
}
@@ -39,10 +39,11 @@ if (has_capability('mod/quiz:viewreports', $context)) {
$row[] = new tabobject('reports', "$CFG->wwwroot/mod/quiz/report.php?q=$quiz->id", get_string('results', 'quiz'));
}
if (has_capability('mod/quiz:preview', $context)) {
- $row[] = new tabobject('preview', "$CFG->wwwroot/mod/quiz/startattempt.php?cmid=$cm->id&sesskey=" . sesskey(), get_string('preview', 'quiz'));
+ $strpreview = get_string('preview', 'quiz');
+ $row[] = new tabobject('preview', "$CFG->wwwroot/mod/quiz/startattempt.php?cmid=$cm->id&sesskey=" . sesskey(), " pixpath/t/preview.gif\" class=\"iconsmall\" alt=\"$strpreview\" /> $strpreview", $strpreview);
}
if (has_capability('mod/quiz:manage', $context)) {
- $row[] = new tabobject('edit', "$CFG->wwwroot/mod/quiz/edit.php?cmid=$cm->id", get_string('edit'));
+ $row[] = new tabobject('edit', "$CFG->wwwroot/mod/quiz/edit.php?cmid=$cm->id", " pixpath/t/edit.gif\" class=\"iconsmall\" alt=\"$stredit\" /> $stredit",$stredit);
}
if ($currenttab == 'info' && count($row) == 1) {
@@ -101,9 +102,11 @@ if ($currenttab == 'edit' and isset($mode)) {
$streditingquiz = get_string("editinga", "moodle", $strquiz);
if (has_capability('mod/quiz:manage', $context) && $contexts->have_one_edit_tab_cap('editq')) {
- $row[] = new tabobject('editq', "$CFG->wwwroot/mod/quiz/edit.php?".$thispageurl->get_query_string(), $strquiz, $streditingquiz);
+ //TODO: ensure that removing get_query_string here won't hurt
+ $row[] = new tabobject('editq', "$CFG->wwwroot/mod/quiz/edit.php?cmid=$cm->id", $stredit, $streditingquiz);
+ $row[] = new tabobject('reorder', "$CFG->wwwroot/mod/quiz/edit.php?reordertool=1&cmid=$cm->id", get_string('orderandpaging','quiz'), $streditingquiz);
}
- questionbank_navigation_tabs($row, $contexts, $thispageurl->get_query_string());
+ //questionbank_navigation_tabs($row, $contexts, $thispageurl->get_query_string());
$tabs[] = $row;
}
diff --git a/question/category_class.php b/question/category_class.php
index c6ef91ddbf..f927702463 100644
--- a/question/category_class.php
+++ b/question/category_class.php
@@ -12,6 +12,7 @@ define("QUESTION_PAGE_LENGTH", 25);
require_once("$CFG->libdir/listlib.php");
require_once("$CFG->dirroot/question/category_form.php");
+require_once("$CFG->dirroot/question/category_form_randomquestion.php");
require_once('move_form.php');
class question_category_list extends moodle_list {
@@ -135,6 +136,10 @@ class question_category_object {
* @var question_category_edit_form Object representing form for adding / editing categories.
*/
var $catform;
+ /**
+ * @var question_category_edit_form_randomquestion Object representing simplified form for adding a category in order to add it into a quiz as a random question.
+ */
+ var $catform_rand;
/**
* Constructor
@@ -197,8 +202,10 @@ class question_category_object {
list($paged, $count) = $this->editlists[$key]->list_from_records($paged, $count);
}
$this->catform = new question_category_edit_form($this->pageurl, compact('contexts', 'currentcat'));
+ $this->catform_rand = new question_category_edit_form_randomquestion($this->pageurl, compact('contexts', 'currentcat'));
if (!$currentcat){
$this->catform->set_data(array('parent'=>$defaultcategory));
+ $this->catform_rand->set_data(array('parent'=>$defaultcategory));
}
}
/**
@@ -216,6 +223,16 @@ class question_category_object {
$this->output_new_table();
echo ' ';
+ }
+ /**
+ * Displays the user interface
+ *
+ */
+ function display_randomquestion_user_interface() {
+
+ /// Interface for adding a new category:
+ $this->output_new_randomquestion_table();
+
}
/**
@@ -225,6 +242,13 @@ class question_category_object {
$this->catform->display();
}
+ /**
+ * Outputs a table to allow entry of a new category
+ */
+ function output_new_randomquestion_table() {
+ $this->catform_rand->display();
+ }
+
/**
* Outputs a list to allow editing/rearranging of existing categories
@@ -278,6 +302,8 @@ class question_category_object {
$category->categoryheader = $this->str->edit;
$this->catform->set_data($category);
$this->catform->display();
+ $this->catform_rand->set_data($category);
+ $this->catform_rand->display();
} else {
print_error('invalidcategory', '', '', $categoryid);
}
@@ -369,7 +395,7 @@ class question_category_object {
/**
* Creates a new category with given params
*/
- public function add_category($newparent, $newcategory, $newinfo) {
+ public function add_category($newparent, $newcategory, $newinfo, $return=false) {
global $DB;
if (empty($newcategory)) {
print_error('categorynamecantbeblank', 'quiz');
@@ -391,10 +417,14 @@ class question_category_object {
$cat->info = $newinfo;
$cat->sortorder = 999;
$cat->stamp = make_unique_id_code();
- if (!$DB->insert_record("question_categories", $cat)) {
+ if (!$categoryid=$DB->insert_record("question_categories", $cat)) {
print_error('cannotinsertquestioncate', 'question', '', $newcategory);
} else {
- redirect($this->pageurl->out());//always redirect after successful action
+ if($return){
+ return $categoryid;
+ }else{
+ redirect($this->pageurl->out());//always redirect after successful action
+ }
}
}
diff --git a/question/category_form_randomquestion.php b/question/category_form_randomquestion.php
new file mode 100644
index 0000000000..cde516caa2
--- /dev/null
+++ b/question/category_form_randomquestion.php
@@ -0,0 +1,49 @@
+libdir.'/formslib.php');
+
+class question_category_edit_form_randomquestion extends moodleform {
+
+ function definition() {
+ global $CFG, $DB;
+ $mform =& $this->_form;
+
+ $contexts = $this->_customdata['contexts'];
+ $currentcat = $this->_customdata['currentcat'];
+//--------------------------------------------------------------------------------
+ $mform->addElement('header', 'categoryheader', get_string('createcategoryfornewrandomquestion', 'quiz'));
+
+ $questioncategoryel = $mform->addElement('questioncategory', 'parent', get_string('parentcategory', 'quiz'),
+ array('contexts'=>$contexts, 'top'=>true, 'currentcat'=>$currentcat, 'nochildrenof'=>$currentcat));
+ $mform->setType('parent', PARAM_SEQUENCE);
+ if (1 == $DB->count_records_sql("SELECT count(*)
+ FROM {question_categories} c1,
+ {question_categories} c2
+ WHERE c2.id = ?
+ AND c1.contextid = c2.contextid", array($currentcat))){
+ //TODO: Tim? why does the above evaluate true, breaking the form?
+ // and more importantly, if this is a valid situation, how should we react,
+ // that is, what does this mean?
+ //$mform->hardFreeze('parent');
+ }
+ $mform->setHelpButton('parent', array('categoryparent', get_string('parent', 'quiz'), 'question'));
+
+ $mform->addElement('text','name', get_string('name'),'maxlength="254" size="50"');
+ $mform->setDefault('name', '');
+ $mform->addRule('name', get_string('categorynamecantbeblank', 'quiz'), 'required', null, 'client');
+ $mform->setType('name', PARAM_MULTILANG);
+
+ $mform->addElement('hidden', 'info', '');
+ $mform->setType('info', PARAM_MULTILANG);
+
+//--------------------------------------------------------------------------------
+ $this->add_action_buttons(false, get_string('addrandomquestion', 'quiz'));
+//--------------------------------------------------------------------------------
+ $mform->addElement('hidden', 'id', 0);
+ $mform->setType('id', PARAM_INT);
+ //TODO: Tim: is this questionable? to add a hidden field right from a get parameter?
+ $mform->addElement('hidden', 'addonpage', optional_param("addonpage_form", 0, PARAM_SEQUENCE), 'id="rform_qpage"');
+ $mform->setType('addonpage', PARAM_SEQUENCE);
+ }
+}
+?>
diff --git a/question/editlib.php b/question/editlib.php
index 14d5907df7..50b58d551c 100644
--- a/question/editlib.php
+++ b/question/editlib.php
@@ -158,7 +158,7 @@ function question_list($contexts, $pageurl, $categoryandcontext, $cm = null,
$straddquestions = get_string("addquestions", "quiz");
$strimportquestions = get_string("importquestions", "quiz");
$strexportquestions = get_string("exportquestions", "quiz");
- $strnoquestions = get_string("noquestions", "quiz");
+ $strnoquestions = get_string("noquestionsincategory", "quiz");
$strselect = get_string("select", "quiz");
$strselectall = get_string("selectall", "quiz");
$strselectnone = get_string("selectnone", "quiz");
@@ -244,7 +244,7 @@ function question_list($contexts, $pageurl, $categoryandcontext, $cm = null,
list($usql, $params) = $DB->get_in_or_equal($categorylist_array);
if (!$totalnumber = $DB->count_records_select('question', "category $usql AND parent = '0' $showhidden", $params)) {
echo "";
- print_string("noquestions", "quiz");
+ echo $strnoquestions;
echo "
";
return;
}
@@ -255,14 +255,13 @@ function question_list($contexts, $pageurl, $categoryandcontext, $cm = null,
if (!$questions = $DB->get_records_select('question', "category $usql AND parent = '0' $showhidden", $params, $sortorderdecoded, '*', 0, $perpage)) {
// There are no questions at all
echo "";
- print_string("noquestions", "quiz");
+ echo $strnoquestions;
echo "
";
return;
}
}
print_paging_bar($totalnumber, $page, $perpage, $pageurl, 'qpage');
-
echo question_sort_options($pageurl, $sortorder);
@@ -397,15 +396,21 @@ function question_list($contexts, $pageurl, $categoryandcontext, $cm = null,
function question_sort_options($pageurl, $sortorder){
global $USER;
//sort options
- $html = "";
- $html .= '
';
+ $html = "";
+ // POST method should only be used for parameters that change data
+ // or if POST method has to be used, the user must be redirected immediately to
+ // non-POSTed page to not break the back button
+ $html .= '
';
$html .= '';
$html .= ' ';
$html .= $pageurl->hidden_params_out(array('qsortorder'));
- $sortoptions = array('alpha' => get_string("sortalpha", "quiz"),
- 'typealpha' => get_string("sorttypealpha", "quiz"),
- 'age' => get_string("sortage", "quiz"));
- $html .= choose_from_menu ($sortoptions, 'qsortorder', $sortorder, false, 'this.form.submit();', '0', true);
+ //choose_from_menu concatenates the form name with
+ //"menu" so the label is for menuqsortorder
+ $sortoptions = array('alpha' => get_string("qname", "quiz"),
+ 'typealpha' => get_string("qtypename", "quiz"),
+ 'age' => get_string("age", "quiz"));
+ $a = choose_from_menu ($sortoptions, 'qsortorder', $sortorder, false, 'this.form.submit();', '0', true);
+ $html .= ''.get_string('sortquestionsbyx', 'quiz', $a).' ';
$html .= '
';
$html .= ' ';
$html .= " \n";
diff --git a/question/question.php b/question/question.php
index 65a60c1737..b763976d3e 100644
--- a/question/question.php
+++ b/question/question.php
@@ -24,6 +24,7 @@ $wizardnow = optional_param('wizardnow', '', PARAM_ALPHA);
$movecontext = optional_param('movecontext', 0, PARAM_BOOL);//switch to make question
//uneditable - form is displayed to edit category only
$returnurl = optional_param('returnurl', 0, PARAM_LOCALURL);
+$appendqnumstring = optional_param('appendqnumstring', '', PARAM_ALPHA);
$inpopup = optional_param('inpopup', 0, PARAM_BOOL);
@@ -132,6 +133,8 @@ $toform->category = "$category->id,$category->contextid";
if ($formeditable && $id){
$toform->categorymoveto = $toform->category;
}
+
+$toform->appendqnumstring = $appendqnumstring;
$toform->returnurl = $returnurl;
$toform->movecontext = $movecontext;
if ($cm !== null){
@@ -186,10 +189,14 @@ if ($mform->is_cancelled()){
notify(get_string('changessaved'), '');
close_window(3);
} else {
+ if($appendqnumstring){
+ $returnurl_object=new moodle_url($returnurl);
+ $returnurl=$returnurl_object->out(false,array($appendqnumstring=>($question->id), "sesskey"=>sesskey(), "cmid"=>$cmid));
+ }
redirect($returnurl);
}
} else {
- $nexturlparams = array('returnurl'=>$returnurl);
+ $nexturlparams = array('returnurl'=>$returnurl, 'appendqnumstring'=>$appendqnumstring);
if (isset($fromform->nextpageparam) && is_array($fromform->nextpageparam)){
$nexturlparams += $fromform->nextpageparam;//useful for passing data to the next page which is not saved in the database
}
diff --git a/question/type/edit_question_form.php b/question/type/edit_question_form.php
index da1a155d32..8a51868aaf 100644
--- a/question/type/edit_question_form.php
+++ b/question/type/edit_question_form.php
@@ -193,6 +193,10 @@ class question_edit_form extends moodleform {
$mform->setType('returnurl', PARAM_LOCALURL);
$mform->setDefault('returnurl', 0);
+ $mform->addElement('hidden', 'appendqnumstring');
+ $mform->setType('appendqnumstring', PARAM_ALPHA);
+ $mform->setDefault('appendqnumstring', 0);
+
$buttonarray = array();
if (!empty($this->question->id)){
//editing / moving question
@@ -219,17 +223,16 @@ class question_edit_form extends moodleform {
$mform->hardFreezeAllVisibleExcept(array('categorymoveto', 'buttonar', 'currentgrp'));
}
}
-
+
function validation($fromform, $files) {
$errors= parent::validation($fromform, $files);
- if (empty($fromform->makecopy) && isset($this->question->id)
- && ($this->question->formoptions->canedit || $this->question->formoptions->cansaveasnew)
+ if (empty($fromform->makecopy) && isset($this->question->id)
+ && ($this->question->formoptions->canedit || $this->question->formoptions->cansaveasnew)
&& empty($fromform->usecurrentcat) && !$this->question->formoptions->canmove){
$errors['currentgrp'] = get_string('nopermissionmove', 'question');
}
return $errors;
}
-
/**
* Add any question-type specific form fields.
diff --git a/theme/standard/styles_color.css b/theme/standard/styles_color.css
index 22f95b5a0d..b6c8ef5f17 100644
--- a/theme/standard/styles_color.css
+++ b/theme/standard/styles_color.css
@@ -1091,6 +1091,73 @@ table.quizreviewsummary td.cell {
#mod-quiz-report .negcovar{
border :medium solid pink;
}
+
+#mod-quiz-edit .questionbankwindow div.header{
+/*this color might need to be theme-specific,
+but in terms of usability, as testing showed,
+//TODO: add url
+it must be ensured that the question
+bank window's title is prominent enough*/
+ background-color:#009;
+ color:#fff;
+ background-image:none;
+}
+
+#mod-quiz-edit div.question div.content div.points,
+ #mod-quiz-edit div.question div.content div.qorder{
+ background-color:#ddf;
+}
+
+#mod-quiz-edit div.quizpage .pagecontent .pagestatus{
+ background-color:#eee;
+}
+#mod-quiz-edit .quizpagedelete img{
+ background-color:#d6d6d6;
+}
+#mod-quiz-edit div.quizpage .pagecontent form#addquestion{
+ background-color:#fff;
+}
+#mod-quiz-edit .questioncontentcontainer div.randomquestionqlist{
+ background-color:#eee;
+ color:#777;
+}
+#mod-quiz-edit .questioncontentcontainer div.randomquestionqlist .totalquestionsinrandomqcategory{
+ color:#000;
+}
+/*TODO: below applies to also question bank, so when
+question bank is adapted to the new UI, add the appropriate
+css id's of question bank*/
+#mod-quiz-edit .categoryinfo{
+ background-color:#eee;
+ border-bottom:1px solid #bbb;
+}
+#mod-quiz-edit .paging{
+ background-color:#ddd;
+}
+#mod-quiz-edit .questionsortoptions{
+ background-color:#ddd;
+}
+
+#mod-quiz-edit .paging a:hover{
+ background-color:#eef;
+}
+#mod-quiz-edit div.questionbank{
+ background-color:#e6e6ff;
+}
+#mod-quiz-edit .questionbank div.categoryquestionscontainer,.questionbank .categorysortopotionscontainer,.questionbank .categorypagingbarcontainer,.questionbank .categoryselectallcontainer{
+ background-color:#FFF;
+}
+#mod-quiz-edit div.question div.content div.questioncontrols{
+ background-color:#FFF;
+}
+#mod-quiz-edit div.editq div.question div.content{
+ background-color:#fff;
+}
+#mod-quiz-edit .questionbankwindow div.header a{
+ color:#FFF;
+}
+
+
/***
*** Modules: Resource
***/
@@ -1212,3 +1279,4 @@ form.mform .required .fgroup span label {
color:#000;
}
+
diff --git a/theme/standard/styles_fonts.css b/theme/standard/styles_fonts.css
index ea459dd254..b898103d7c 100644
--- a/theme/standard/styles_fonts.css
+++ b/theme/standard/styles_fonts.css
@@ -1006,7 +1006,60 @@ body#mod-forum-index .generalbox .cell {
text-decoration: underline;
}
-/***
+#mod-quiz-edit div.reorder .reordercontrols .moveselectedonpage{
+ text-align:right;
+}
+#mod-quiz-edit div.question div.qnum{
+ text-align:right;
+}
+#mod-quiz-edit div.reorder div.question div.qnum{
+ text-align:right;
+ font-size:1em;
+}
+#mod-quiz-edit div.editq div.question div.qnum{
+ font-size:1.5em;
+}
+#mod-quiz-edit .questionbankwindow div.header a{
+ text-decoration:underline;
+}
+#mod-quiz-edit div.questioncontentcontainer a{
+ text-decoration:underline;
+}
+
+#mod-quiz-edit div.questioncontentcontainer div.singlequestion a{
+ text-decoration:underline;
+}
+#mod-quiz-edit div.editq div.question div.content .singlequestion a .questionname,div.editq div.question div.content .singlequestion a .questiontext{
+ text-decoration:underline;
+}
+#mod-quiz-edit div.question div.content .questiontext,
+#categoryquestions .questiontext{
+ font-weight:bold;
+}
+#mod-quiz-edit div.question div.content div.questioncontrols{
+ text-align:right;
+}
+#mod-quiz-edit div.quizpage .pagecontent .pagestatus{
+ font-weight:bold;
+}
+#mod-quiz-edit div.question div.content .questiontype{
+ font-style:italic;
+}
+#mod-quiz-edit .questioncontentcontainer .randomquestioncategory{
+ font-weight:bold;
+}
+#mod-quiz-edit .categoryinfofield{
+ font-style:italic;
+}
+#mod-quiz-edit .categorynamefield{
+ font-weight:bold;
+}
+#mod-quiz-edit .questionbankwindow div.header{
+ font-weight:bold;
+}
+
+
+ /***
*** Modules: Resource
***/
diff --git a/theme/standard/styles_ie6.css b/theme/standard/styles_ie6.css
index 95a0de063d..b70aad7085 100755
--- a/theme/standard/styles_ie6.css
+++ b/theme/standard/styles_ie6.css
@@ -69,3 +69,22 @@ form.mform textarea {
#mod-quiz-review #middle-column {
height: 1%;
}
+#mod-quiz-edit div.question div.content .questionname,
+#categoryquestions .questionname{
+ /*ie6 shows this as an arrow if this is not specified*/
+ cursor: pointer;
+}
+#mod-quiz-edit #categoryquestions .questiontext{
+ /*ie6 shows this as an arrow if this is not specified*/
+ cursor: pointer;
+}
+#mod-quiz-edit div.tabtree a span img.iconsmall{
+ display:none;
+}
+
+#mod-quiz-edit div.question div.content .questiontext,#categoryquestions .questiontext{
+ width:50%;
+}
+#mod-quiz-edit div.question div.content .questionname,#categoryquestions .questionname{
+ width:20%;
+}
diff --git a/theme/standard/styles_layout.css b/theme/standard/styles_layout.css
index b7bfbaa398..4b45755d34 100644
--- a/theme/standard/styles_layout.css
+++ b/theme/standard/styles_layout.css
@@ -90,14 +90,6 @@ h6.main {
text-align: center;
}
-#redirect #message {
-
-}
-
-#redirect #continue {
-
-}
-
/* .clearfix {display: inline-table;} */
/* Hides from IE-mac \*/
@@ -4245,20 +4237,6 @@ table.quizreviewsummary td.cell {
margin-bottom: 0.5em;
}
-#mod-quiz-edit #page .controls,
-#mod-quiz-edit #page .quizattemptcounts
-{
- text-align: center;
-}
-#mod-quiz-edit .quizquestions h2 {
- margin-top: 0;
-}
-#mod-quiz-edit #showhidepagingcontrols {
- margin-top: 0.7em;
-}
-#mod-quiz-edit #showhidepagingcontrols .singlebutton {
- display: inline;
-}
.quizquestionlistcontrols {
text-align: center;
}
@@ -4421,6 +4399,545 @@ table.quizreviewsummary td.cell {
display: block;
margin: 0.5em 0;
}
+#mod-quiz-edit div.sideblock{
+ float:right;
+ width:30%;
+ right:0.3em;
+ padding-bottom:0.5em;
+ display:block;
+}
+
+#mod-quiz-edit div.quizcontents{
+ float:left;
+ width:70%;
+ display:block;
+}
+
+#mod-quiz-edit div.quizcontents,h2.main{
+ clear:left;
+}
+
+#mod-quiz-edit .addpage{
+ clear:both;
+ padding-top:0.3em;
+ float:right;
+ margin-right:2em;
+}
+
+#mod-quiz-edit h2.main{
+ display:inline;
+ padding-right:1em;
+}
+
+#mod-quiz-edit .statusdisplay{
+ clear:both;
+ display:block;
+ border:0.2em #FFF solid;
+ margin-bottom:0.3em;
+ margin-right:1em;
+ margin-top:0.3em;
+ padding:0.1em;
+}
+#mod-quiz-edit div.quizpage{
+ display:block;
+ clear:both;
+ width:100%;
+}
+
+#mod-quiz-edit div.quizpage span.pagetitle{
+ margin-top:0.3em;
+ float:left;
+ display:block;
+}
+
+#mod-quiz-edit div.reorder .reordercontrols .moveselectedonpage{
+ clear:right;
+ float:right;
+ padding:0.5em 0.3em;
+}
+
+#mod-quiz-edit div.reorder .reordercontrols .addnewpagesafterselected,#mod-quiz-edit .repaginatecommand{
+ float:right;
+ clear:right;
+ padding-right:1em;
+}
+
+#mod-quiz-edit div.reorder .reordercontrols .deleteselected{
+ float:right;
+ margin-right:1em;
+}
+
+#mod-quiz-edit div.reorder .reordercontrols{
+ clear:both;
+ padding-right:1em;
+ margin-top:0.5em;
+ padding-top:0.5em;
+ padding-bottom:0.5em;
+}
+
+#mod-quiz-edit div.quizpage .pagecontent{
+ margin-top:0.3em;
+ display:block;
+ float:left;
+ position:relative;
+ margin-left:0.3em;
+ border-left:solid #777 thin;
+ line-height:1.3em;
+ -webkit-border-radius:0.6em;
+ -webkit-border-radius-bottomleft:0;
+ -webkit-border-radius-topleft:0;
+ border-radius:0.6em;
+ border-radius-bottomleft:0;
+ border-radius-topleft:0;
+ width:88%;
+ padding:0 0 0.5em;
+}
+
+#mod-quiz-edit div.question{
+ clear:left;
+ width:100%;
+}
+
+#mod-quiz-edit div.question div.qnum{
+ display:block;
+ float:left;
+ width:1.4em;
+ padding-right:0.3em;
+ padding-left:0;
+ z-index:99;
+}
+
+#mod-quiz-edit div.reorder div.question div.qnum{
+ width:2.9em;
+ padding-top:0.1em;
+}
+/*edit tab*/
+#mod-quiz-edit div.editq div.question div.qnum{
+ padding-top:0.2em;
+}
+
+#mod-quiz-edit div.editq div.question{
+ padding-top:0.3em;
+}
+
+#mod-quiz-edit div.reorder div.question{
+ padding-top:0.2em;
+}
+
+#mod-quiz-edit div.question div.questioncontainer{
+ background-color:#ffc;
+}
+
+#mod-quiz-edit div.editq div.question div.content{
+ width:87%;
+ float:left;
+ position:relative;
+ -webkit-border-radius:0.6em;
+ -webkit-border-radius-bottomleft:0;
+ -webkit-border-radius-topleft:0;
+ border-radius:0.6em;
+ border-radius-bottomleft:0;
+ border-radius-topleft:0;
+ line-height:1.4em;
+ padding:0.5em;
+}
+
+#mod-quiz-edit .reorder div.question div.content{
+ width:87%;
+ float:left;
+ background-color:#fff;
+ position:relative;
+ -webkit-border-radius:0.3em;
+ -webkit-border-radius-bottomleft:0;
+ -webkit-border-radius-topleft:0;
+ border-radius:0.3em;
+ border-radius-bottomleft:0;
+ border-radius-topleft:0;
+ line-height:1.2em;
+ padding:0.1em;
+}
+
+#mod-quiz-edit div.question div.content div.points{
+ top:0.5em;
+ border-left:#FFF solid 0.4em;
+ width:7.5em;
+ padding:0.2em;
+}
+
+#mod-quiz-edit .questionbankwindow select#catmenu_jump{
+ /* In Opera9, IE6 the width of the
+ select obeys the width of its content
+ by default. This prevents that. */
+ width:100%;
+}
+
+#mod-quiz-edit .questionbankwindow div.header{
+ padding-top:0.2em;
+}
+
+#randomquestiondialog_c select{
+ width:100%;
+}
+
+
+#mod-quiz-edit div.question div.content div.points,
+ #mod-quiz-edit div.question div.content div.qorder{
+ line-height:1em;
+ float:right;
+ max-width:30%;
+ position:absolute;
+ right:50px;
+ -webkit-border-radius:0.2em;
+ -webkit-border-radius-bottomleft:0;
+ -webkit-border-radius-topleft:0;
+ border-radius:0.2em;
+ border-radius-bottomleft:0;
+ border-radius-topleft:0;
+ z-index:999;
+ display:block;
+ margin:0;
+}
+
+
+#mod-quiz-edit div.question div.content .editicon{
+ width:15px;
+}
+
+#mod-quiz-edit .editq div.questioncontentcontainer div.singlequestion img{
+ float:left;
+ padding-top:0.3em;
+ padding-right:0.3em;
+}
+
+
+#mod-quiz-edit div.question div.content .questionname,
+#categoryquestions .questionname{
+ white-space:nowrap;
+ text-overflow:ellipsis;
+ overflow:hidden;
+ zoom:1;
+ position:relative;
+ max-width:20%;
+ /*ie-only:*/
+ text-overflow:ellipsis;
+ /*opera-only*/
+ -o-text-overflow:ellipsis;
+}
+#mod-quiz-edit div.question div.content .singlequestion .questionname,
+#mod-quiz-edit div.question div.content .singlequestion .questiontext{
+ display:inline-block;
+}
+
+#mod-quiz-edit div.editq div.question div.content .singlequestion a .questionname,
+#mod-quiz-edit div.editq div.question div.content .singlequestion a .questiontext{
+ float:left;
+}
+
+#mod-quiz-edit .quizquestionlistcontrols{
+ display:inline;
+}
+
+#mod-quiz-edit div.question div.content .questiontext,
+#categoryquestions .questiontext{
+ -o-text-overflow:ellipsis;
+ text-overflow:ellipsis;
+ position:relative;
+ zoom:1;
+ padding-left:0.3em;
+ max-width:50%;
+ overflow:hidden;
+ white-space:nowrap;
+ text-overflow:ellipsis;
+}
+
+#mod-quiz-edit div.quizpage .pagecontent .pagestatus{
+ -webkit-border-radius-bottomright:0.3em;
+ -webkit-border-radius-topright:0.3em;
+ border-radius-bottomright:0.3em;
+ border-radius-topright:0.3em;
+ margin:0.3em;
+ padding:0.1em 0.1em 0.1em 0.3em;
+}
+
+#mod-quiz-edit div.question div.content .questiontype{
+ display:block;
+ clear:left;
+ float:left;
+}
+
+#mod-quiz-edit div.question div.content .questionpreview{
+ display:block;
+ float:left;
+ margin-left:0.3em;
+ padding-left:0.2em;
+ padding-right:0.2em;
+ background-color:#eee;
+}
+
+#mod-quiz-edit div.question div.content div.quiz_randomquestion .questionpreview{
+ display:inline;
+ float:none;
+}
+
+#mod-quiz-edit div.question div.content div.questioncontrols{
+ float:right;
+ width:45px;
+ position:absolute;
+ right:0.3em;
+ top:0;
+ z-index:999;
+ display:block;
+ padding:0.2em;
+}
+
+#mod-quiz-edit div.question div.content div.questioncontrols img.upwithoutdown{
+ padding-right:12px;
+ display:inline;
+}
+
+#mod-quiz-edit .quizpagedelete{
+ position:absolute;
+ top:0.2em;
+ right:0.2em;
+ display:inline;
+ z-index:999;
+}
+
+#mod-quiz-edit .quizpagedelete img{
+ background-color:#d6d6d6;
+ padding:0.5em;
+}
+
+#mod-quiz-edit .pagecontrols{
+ clear:both;
+ margin-left:0.5em;
+ padding-top:0.5em;
+}
+
+#mod-quiz-edit .pagecontrols .singlebutton{
+ float:left;
+}
+
+#mod-quiz-edit div.quizpage .pagecontent form#addquestion{
+ margin-right:1em;
+ -webkit-border-radius:0.2em;
+ border-radius:0.2em;
+ padding:0.3em;
+}
+
+#mod-quiz-edit div.quizpage .pagecontent form.randomquestionform{
+ padding-left:1em;
+}
+
+#mod-quiz-edit div.quizpage .pagecontent form.randomquestionform div{
+ /* it is a mystery why this has to be inline-table but
+ otherwise the layout gets screwed, even if
+ it is "inline" */
+ display:inline-table;
+}
+
+#mod-quiz-edit div.quizpage .pagecontent form.randomquestionform div input{
+ display:inline;
+}
+
+#mod-quiz-edit div.quizpage .pagecontent .adddescription{
+ clear:left;
+ margin-top:0.3em;
+}
+
+#mod-quiz-edit div.quizpage .pagecontent .addrandomquestion{
+ margin-top:0.3em;
+}
+
+/* a CSS class YUI container creates on the fly: */
+#mod-quiz-edit div#randomquestiondialog_c{
+ width:90%;
+}
+
+#mod-quiz-edit #repaginatedialog .hd{
+ display:none;
+}
+
+#mod-quiz-edit div#randomquestiondialog{
+ display:none;
+}
+
+#mod-quiz-edit div#randomquestiondialog_c .mform,
+#mod-quiz-edit div#repaginatedialog .mform{
+ margin-left:auto;
+ margin-right:auto;
+}
+
+#mod-quiz-edit div.container div.generalbox{
+ position:relative;
+ display:block;
+ border:0 none;
+ margin:0;
+ padding:0;
+}
+
+#mod-quiz-edit .questioncontentcontainer div.randomquestionqlist{
+ padding-left:0.2em;
+ padding-right:0.2em;
+ clear:both;
+ margin:0.5em;
+}
+
+
+#mod-quiz-edit .questioncontentcontainer div.randomquestionqlist ul{
+ list-style-type:none;
+ margin:0;
+ padding:0;
+}
+
+
+#mod-quiz-edit .reorder .questioncontentcontainer .randomquestioncategory,
+#mod-quiz-edit .reorder .questioncontentcontainer .randomquestionfromcategory,
+#mod-quiz-edit .reorder div.question div.content .questionpreview{
+ display:inline;
+ float:none;
+}
+
+#mod-quiz-edit .reorder .questioncontentcontainer{
+ position:relative;
+ overflow:hidden;
+ white-space:nowrap;
+}
+
+#mod-quiz-edit .reorder .questioncontentcontainer .randomquestioncategory{
+ overflow:hidden;
+ white-space:nowrap;
+}
+
+#mod-quiz-edit .reorder fieldset{
+ display:inline;
+}
+
+#mod-quiz-edit .questioncontentcontainer div.randomquestionqlist ul li{
+ clear:left;
+ width:100%;
+ overflow:hidden;
+ white-space:nowrap;
+}
+
+#mod-quiz-edit .questioncontentcontainer div.randomquestionqlist ul li span{
+ display:inline;
+}
+
+/*start question bank*/
+
+/*TODO: below applies to also question bank, so when
+question bank is adapted to the new UI, add the appropriate
+css id's of question bank*/
+#mod-quiz-edit .questionbankwindow .createnewquestion select,
+#mod-quiz-edit .questionbankwindow #catmenu select{
+ width:80%;
+}
+#mod-quiz-edit table#categoryquestions{
+ width:100%;
+ overflow:hidden;
+ table-layout:fixed;
+}
+
+#mod-quiz-edit table#categoryquestions td,#mod-quiz-edit table#categoryquestions th{
+ overflow:hidden;
+ white-space:nowrap;
+}
+
+#mod-quiz-edit table#categoryquestions col#qaction{
+ width:20%;
+}
+
+#mod-quiz-edit table#categoryquestions col#qextraactions{
+ width:40px;
+}
+
+#mod-quiz-edit table#categoryquestions .iconsmall{
+ padding-left:5px;
+}
+#mod-quiz-edit .categoryinfo{
+ padding:0.3em;
+}
+
+
+
+#mod-quiz-edit .paging{
+ margin-top:0;
+ margin-bottom:0;
+ display:block;
+}
+
+#mod-quiz-edit .questionsortoptions{
+ margin-top:0.3em;
+}
+
+#mod-quiz-edit .pagingbottom{
+ padding-bottom:0.3em;
+}
+
+#mod-quiz-edit div.questionbank form .invisiblefieldset{
+ clear:both;
+}
+
+#mod-quiz-edit div.createnewquestion{
+ padding-top:0.3em;
+ clear:left;
+}
+
+#mod-quiz-edit .sideblock .content{
+ padding:0;
+}
+
+#mod-quiz-edit .questionbank .categorysortopotionscontainer{
+ padding-top:0.5em;
+ margin-top:0.3em;
+}
+
+#mod-quiz-edit .questionbank .categoryselectallcontainer{
+ padding-bottom:0.5em;
+}
+
+#mod-quiz-edit .questionbank div.categoryquestionscontainer,
+#mod-quiz-edit .questionbank .categorysortopotionscontainer,
+#mod-quiz-edit .questionbank .categorypagingbarcontainer,
+#mod-quiz-edit .questionbank .categoryselectallcontainer{
+ padding-left:0.3em;
+ padding-right:0.3em;
+}
+
+#mod-quiz-edit .noquestionsincategory{
+ clear:both;
+ padding-top:1em;
+ padding-bottom:1em;
+}
+
+#mod-quiz-edit .modulespecificbuttonscontainer{
+ padding-left:0.3em;
+ padding-right:0.3em;
+}
+
+#mod-quiz-edit div#footer{
+ clear:both;
+ padding-top:1em;
+}
+
+#mod-quiz-edit #repaginatecommand{
+ display:none;
+}
+
+/*.usejs class is added via javascript so these will toggle if js is enabled*/
+#mod-quiz-edit .usejs #repaginatedialog{
+ display:none;
+}
+#mod-quiz-edit .usejs #repaginatedialog .hd{
+ display:block;
+}
+#mod-quiz-edit .usejs #repaginatedialog .bd{
+ padding:1em;
+}
+#mod-quiz-edit .usejs .repaginatecommand #repaginatecommand{
+ display:block;
+}
/***
*** Modules: Resource
diff --git a/theme/standard/styles_moz.css b/theme/standard/styles_moz.css
index 5b609f6ddb..a99f3c729f 100644
--- a/theme/standard/styles_moz.css
+++ b/theme/standard/styles_moz.css
@@ -1,6 +1,6 @@
/*******************************************************************
styles_moz.css
-
+
This CSS file uses the non-standard Mozilla CSS extensions
to add round corners to the current theme.
@@ -80,7 +80,7 @@
-moz-border-radius:3px;
}
-.categorybox, .categoryboxcontent,
+.categorybox, .categoryboxcontent,
.coursebox {
-moz-border-radius:10px;
}
@@ -347,3 +347,32 @@ body#course-user .section {
#quiznavigation .qnbutton {
-moz-box-sizing: content-box;
}
+#mod-quiz-edit div.quizpage .pagecontent{
+ -moz-border-radius:0.6em;
+ -moz-border-radius-bottomleft:0;
+ -moz-border-radius-topleft:0;
+}
+#mod-quiz-edit .reorder div.question div.content{
+
+ -moz-border-radius:0.3em;
+ -moz-border-radius-bottomleft:0;
+ -moz-border-radius-topleft:0;
+}
+#mod-quiz-edit div.editq div.question div.content{
+ -moz-border-radius:0.6em;
+ -moz-border-radius-bottomleft:0;
+ -moz-border-radius-topleft:0;
+}
+#mod-quiz-edit div.question div.content div.points,
+ #mod-quiz-edit div.question div.content div.qorder{
+ -moz-border-radius:0.2em;
+ -moz-border-radius-bottomleft:0;
+ -moz-border-radius-topleft:0;
+}
+#mod-quiz-edit div.quizpage .pagecontent .pagestatus{
+ -moz-border-radius-bottomright:0.3em;
+ -moz-border-radius-topright:0.3em;
+}
+#mod-quiz-edit div.quizpage .pagecontent form#addquestion{
+ -moz-border-radius:0.2em;
+}
\ No newline at end of file