diff --git a/bolt_checkin_notes.txt b/bolt_checkin_notes.txt index 5dd4ad31c6..fea18b94fd 100644 --- a/bolt_checkin_notes.txt +++ b/bolt_checkin_notes.txt @@ -259,3 +259,15 @@ David Oct 24 2008 bolt.css bolt_admin.css bolt_sched.php + +David Oct 30 2008 + - added "fill in the blank" (FITB) exercise type + - added "has_answer_page()" option for exercises + + html/ + inc/ + bolt_ex.inc + bolt.inc + user/ + bolt.css + bolt_sched.php diff --git a/checkin_notes b/checkin_notes index b55ef17a73..b79322e0dc 100644 --- a/checkin_notes +++ b/checkin_notes @@ -8901,3 +8901,15 @@ Charlie 30 Oct 2008 clientgui/ BOINCBaseFrame.cpp, .h BOINCGUIApp.cpp + +David 30 Oct 2008 + - web: change style sheet so tables are bordered only if class is "bordered" + - web: fix error if translation string missing + + html/ + inc/ + util.inc + translation.inc + user/ + language_select.php + white.css diff --git a/doc/index.php b/doc/index.php index dd41bf4144..8c03ab6389 100644 --- a/doc/index.php +++ b/doc/index.php @@ -21,9 +21,8 @@ function show_participant() {
Computing power
- Top 100 - · Single-computer - · Other lists + Top 100 volunteers + · Statistics
diff --git a/html/inc/bolt.inc b/html/inc/bolt.inc index 51af2e2da6..5a19084078 100644 --- a/html/inc/bolt.inc +++ b/html/inc/bolt.inc @@ -80,10 +80,15 @@ class BoltExercise extends BoltItem { public $callback; // called as func($student, $score, $query_string) after scoring public $weight; - function __construct($filename, $title, $attrs, $callback, $weight) { + public $has_answer_page; + + function __construct( + $filename, $title, $attrs, $callback, $weight, $has_answer_page + ) { parent::__construct($filename, $title, $attrs); $this->callback = $callback; $this->weight = $weight; + $this->has_answer_page = $has_answer_page; } function is_exercise() { return true; @@ -257,6 +262,10 @@ function filename($n) { return array('filename', $n); } +function has_answer_page($n) { + return array('has_answer_page', $n); +} + function attrs($n) { return array('attrs', $n); } @@ -297,6 +306,7 @@ function exercise() { $title = ""; $attrs = null; $weight = 1; + $has_answer_page = true; $args = func_get_args(); $callback = null; @@ -308,6 +318,7 @@ function exercise() { case 'attrs': $attrs = $arg[1]; break; case 'callback': $callback = $arg[1]; break; case 'weight': $weight = $arg[1]; break; + case 'has_answer_page': $has_answer_page = $arg[1]; break; default: echo "Unrecognized exercise parameter: ", $arg[0], "\n"; break; } } @@ -318,7 +329,9 @@ function exercise() { if (!$filename) { error_page("Missing filename in lesson"); } - return new BoltExercise($filename, $title, $attrs, $callback, $weight); + return new BoltExercise( + $filename, $title, $attrs, $callback, $weight, $has_answer_page + ); } function item_attrs() { diff --git a/html/inc/bolt_ex.inc b/html/inc/bolt_ex.inc index 16ad15e414..78cd5622d5 100644 --- a/html/inc/bolt_ex.inc +++ b/html/inc/bolt_ex.inc @@ -27,15 +27,8 @@ $bolt_ex->score = 0; // input/output: cumulative score (if mode = SCORE) $bolt_ex->weight = 0; // input/output: cumulative weight $bolt_ex->query_string = ""; // user's response (if SCORE or ANSWER) -class BoltWeight { - public $weight; - function __construct($weight) { - $this->weight = $weight; - } -} - function weight($w) { - return new BoltWeight($w); + return array('weight', $w); } function exclusive_choice() { @@ -47,14 +40,13 @@ function exclusive_choice() { foreach ($args as $arg) { if (is_string($arg)) { $choices[] = $arg; - } else if (is_object($arg)) { - if (get_class($arg) == 'BoltWeight') { - $weight = $arg->weight; - } else { - "bad arg to exclusive_choice()"; + } else if (is_array($arg)) { + switch ($arg[0]) { + case 'weight': $weight = $arg[1]; break; + default: echo "bad arg to exclusive_choice()"; } } else { - "bad arg to exclusive_choice()"; + echo "bad arg to exclusive_choice()"; } } @@ -129,10 +121,10 @@ function inclusive_choice() { if (get_class($arg) == 'BoltWeight') { $weight = $arg->weight; } else { - "bad arg to inclusive_choice()"; + echo "bad arg to inclusive_choice()"; } } else { - "bad arg to inclusive_choice()"; + echo "bad arg to inclusive_choice()"; } } @@ -197,8 +189,7 @@ function image_rect($img, $rect) { switch ($bolt_ex->mode) { case BOLT_MODE_SHOW: - echo "
- index src=$img> + echo "index src=$img> "; break; case BOLT_MODE_SCORE: @@ -247,4 +238,110 @@ function image_rect($img, $rect) { $bolt_ex->index++; } +class BoltFitbField { + public $textarea, $nrows, $ncols; + function __construct($textarea, $nrows, $ncols) { + $this->textarea = $textarea; + $this->nrows = $nrows; + $this->ncols = $ncols; + } +} + +function field($n) { + return new BoltFitbField(false, 1, $n); +} + +function box($nr, $nc) { + return new BoltFitbField(true, $nr, $nc); +} + +class BoltFitbAnswer { + public $type; // 0=constant, 1=regexp, 2=func + public $ans; + function __construct($type, $ans) { + $this->type = $type; + $this->ans = $ans; + } +} + +function answer($ans) { + return new BoltFitbAnswer(0, $ans); +} + +function answer_regexp($ans) { + return new BoltFitbAnswer(1, $ans); +} + +function answer_func($ans) { + return new BoltFitbAnswer(2, $ans); +} + +function fitb() { + global $bolt_ex; + $args = func_get_args(); + $field = new BoltFitbField(false, 1, 20); + $answer = null; + foreach ($args as $arg) { + if (is_array($arg)) { + $choices[] = $arg; + } else if (is_object($arg)) { + if (get_class($arg) == 'BoltFitbField') { + $field = $arg; + } else if (get_class($arg) == 'BoltFitbAns') { + $answer = $arg; + } else { + echo "bad arg to fitb()"; + } + } else { + echo "bad arg to fitb()"; + } + } + + switch ($bolt_ex->mode) { + case BOLT_MODE_SHOW: + if ($field->textarea) { + echo " + "; + } else { + echo "index." length=$field->ncols>"; + } + break; + case BOLT_MODE_SCORE: + if (!$answer) break; + $bolt_ex->score = 0; + $key = "q_".$bolt_ex->index; + if (isset($$key)) { + $response = $$key; + } else { + $response = ""; + } + switch ($answer->type) { + case 0: + if ($response == $answer->ans) { + $bolt_ex->score = 1; + } + break; + case 1: + if (ereg($answer->ans, $response)) { + $bolt_ex->score = 1; + } + break; + case 2: + $bolt_ex->score = call_user_func($answer->ans, $response); + break; + } + break; + case BOLT_MODE_ANSWER: + $key = "q_".$bolt_ex->index; + if (isset($$key)) { + $response = $$key; + } else { + $response = ""; + } + break; + } + $bolt_ex->index++; +} + ?> diff --git a/html/inc/translation.inc b/html/inc/translation.inc index f26b77983d..6840c85481 100644 --- a/html/inc/translation.inc +++ b/html/inc/translation.inc @@ -156,7 +156,7 @@ function tra($text /* ...arglist... */){ // Find the string in the user's language foreach ($languages_in_use as $language){ - if ($language_lookup_array[$language][$text]){ + if (isset($language_lookup_array[$language][$text])) { $text = $language_lookup_array[$language][$text]; break; } diff --git a/html/inc/util.inc b/html/inc/util.inc index 80d58a696e..77006ca0ac 100644 --- a/html/inc/util.inc +++ b/html/inc/util.inc @@ -227,12 +227,13 @@ function time_str($x) { function pretty_time_str($x) { return time_str($x); } + function start_table($extra="width=\"100%\"") { - echo ""; + echo "
"; } function start_table_noborder($width="100%") { - echo "
"; + echo "
"; } function end_table() { @@ -565,10 +566,13 @@ function post_int($name, $optional=false) { } function get_str($name, $optional=false) { - $x = null; - if (isset($_GET[$name])) $x = $_GET[$name]; - if (!$x && !$optional) { - error_page("missing or bad parameter: $name"); + if (!isset($_GET[$name])) { + if (!$optional) { + error_page("missing or bad parameter: $name"); + } + $x = null; + } else { + $x = $_GET[$name]; } return undo_magic_quotes($x); } diff --git a/html/user/bolt.css b/html/user/bolt.css index d699a477fc..e5a0ac8ed6 100644 --- a/html/user/bolt.css +++ b/html/user/bolt.css @@ -36,15 +36,14 @@ hr { } table { - border: 2px solid #e8e8e8; padding: 4px; margin: 2px; - -moz-border-radius: 6px; - -webkit-border-radius: 6px; } -table.noborder { - border: none; +table.bordered { + border: 2px solid #e8e8e8; + -moz-border-radius: 6px; + -webkit-border-radius: 6px; } th { @@ -129,7 +128,7 @@ td.friend { tr.message { background-color: #e0e0e0; } -input, select, textarea, .button { +input[type="text"], select, textarea, .button { border: 1px solid #d8d8d8; -moz-border-radius: 5px; -webkit-border-radius: 5px; diff --git a/html/user/bolt_sched.php b/html/user/bolt_sched.php index 5545cbe63e..74965de10a 100644 --- a/html/user/bolt_sched.php +++ b/html/user/bolt_sched.php @@ -150,7 +150,7 @@ function show_nav($links, $up_link, $view_id) {
"; foreach ($links as $link) { - echo ""; + echo "\n"; } echo "
$link$link

@@ -159,7 +159,7 @@ function show_nav($links, $up_link, $view_id) { id> - +
@@ -186,7 +186,7 @@ function show_item($iter, $view_id, $prev_view_id, $mode, $repeat=null) { $links[] = ""; } - $next = ""; + $next = ""; if ($item->is_exercise()) { $bolt_ex->mode = $mode; @@ -314,6 +314,39 @@ function start_refresh() { show_item($iter, $view_id, 0, $mode); } +function show_next($iter, $view) { + global $refresh, $user, $course; + $iter->next(); + + if ($refresh) { + $iter->at(); + if (!$iter->xset) { + // if we're doing a refresh and are no longer in an xset, + // we must have finished the refresh + // + show_refresh_finished(); + $refresh->update('count=count+1'); + break; + } + } + + if ($iter->item) { + $state = $iter->encode_state(); + $mode = default_mode($iter->item); + $view_id = create_view($iter, $mode, $view->id); + show_item($iter, $view_id, $view->id, $mode); + } else { + // course finished + $iter->frac_done = 1; + $fin_view_id = create_view($iter, BOLT_MODE_FINISHED, $view->id); + $e = new BoltEnrollment(); + $e->user_id = $user->id; + $e->course_id = $course->id; + $e->update("last_view_id=$fin_view_id"); + show_finished_page($fin_view_id, $view->id); + } +} + $user = get_logged_in_user(); BoltUser::lookup($user); $course_id = get_int('course_id'); @@ -402,35 +435,7 @@ case 'next': // "next" button in lesson or exercise answer page $iter = new BoltIter($course_doc); $iter->decode_state($view->state); - $iter->next(); - - if ($refresh) { - $iter->at(); - if (!$iter->xset) { - // if we're doing a refresh and are no longer in an xset, - // we must have finished the refresh - // - show_refresh_finished(); - $refresh->update('count=count+1'); - break; - } - } - - if ($iter->item) { - $state = $iter->encode_state(); - $mode = default_mode($iter->item); - $view_id = create_view($iter, $mode, $view->id); - show_item($iter, $view_id, $view->id, $mode); - } else { - // course finished - $iter->frac_done = 1; - $fin_view_id = create_view($iter, BOLT_MODE_FINISHED, $view_id); - $e = new BoltEnrollment(); - $e->user_id = $user->id; - $e->course_id = $course->id; - $e->update("last_view_id=$fin_view_id"); - show_finished_page($fin_view_id, $view->id); - } + show_next($iter, $view); break; case 'answer': // submit answer in exercise $view = finalize_view($view_id, BOLT_ACTION_SUBMIT); @@ -521,9 +526,13 @@ case 'answer': // submit answer in exercise // show the answer page - srand($view_id); - $view_id = create_view($iter, BOLT_MODE_ANSWER, $view->id); - show_item($iter, $view_id, $view->id, BOLT_MODE_ANSWER, $repeat); + if ($item->has_answer_page) { + srand($view_id); + $view_id = create_view($iter, BOLT_MODE_ANSWER, $view->id); + show_item($iter, $view_id, $view->id, BOLT_MODE_ANSWER, $repeat); + } else { + show_next($iter, $view); + } break; case 'answer_page': $view = BoltView::lookup_id($view_id); diff --git a/html/user/language_select.php b/html/user/language_select.php index 1ee9198b4c..be64d831e1 100644 --- a/html/user/language_select.php +++ b/html/user/language_select.php @@ -62,10 +62,10 @@ row2("", "Use browser language setting" ); sort($languages); -for ($i=0; $i".$languages[$i]."", - "".tr_specific("LANG_NAME_INTERNATIONAL", $languages[$i])." (".tr_specific("LANG_NAME_NATIVE", $languages[$i]).")" + "$language", + "".tr_specific("LANG_NAME_INTERNATIONAL", $language)." (".tr_specific("LANG_NAME_NATIVE", $language).")" ); } end_table(); diff --git a/html/user/white.css b/html/user/white.css index d699a477fc..e5a0ac8ed6 100644 --- a/html/user/white.css +++ b/html/user/white.css @@ -36,15 +36,14 @@ hr { } table { - border: 2px solid #e8e8e8; padding: 4px; margin: 2px; - -moz-border-radius: 6px; - -webkit-border-radius: 6px; } -table.noborder { - border: none; +table.bordered { + border: 2px solid #e8e8e8; + -moz-border-radius: 6px; + -webkit-border-radius: 6px; } th { @@ -129,7 +128,7 @@ td.friend { tr.message { background-color: #e0e0e0; } -input, select, textarea, .button { +input[type="text"], select, textarea, .button { border: 1px solid #d8d8d8; -moz-border-radius: 5px; -webkit-border-radius: 5px;