Index: openacs-4/packages/xowf/xowf.info =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowf/xowf.info,v diff -u -r1.12.2.9 -r1.12.2.10 --- openacs-4/packages/xowf/xowf.info 14 Feb 2020 13:42:12 -0000 1.12.2.9 +++ openacs-4/packages/xowf/xowf.info 21 Feb 2020 13:45:15 -0000 1.12.2.10 @@ -10,15 +10,16 @@ t xowf - + Gustaf Neumann XoWiki Content Flow - an XoWiki based workflow system implementing state-based behavior of wiki pages and forms 2017-08-06 WU Vienna 2 - + + Index: openacs-4/packages/xowf/catalog/xowf.de_DE.ISO-8859-1.xml =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowf/catalog/xowf.de_DE.ISO-8859-1.xml,v diff -u -r1.2.2.11 -r1.2.2.12 --- openacs-4/packages/xowf/catalog/xowf.de_DE.ISO-8859-1.xml 15 Feb 2020 10:38:09 -0000 1.2.2.11 +++ openacs-4/packages/xowf/catalog/xowf.de_DE.ISO-8859-1.xml 21 Feb 2020 13:45:15 -0000 1.2.2.12 @@ -3,8 +3,17 @@ Beispiel Bewertungsschema - Bewertung + Bewertung + Zuf�llige Reihenfolge + Tage + Tag Minuten + Minute + Stunden + Stunde + Sekunden + Sekunde + verbleibend Alternative Richtig! Falsch. @@ -29,40 +38,46 @@ Pr�fung ist freigeschaltet Pr�fung ist geschlossen Frage - Fragen - Erste Frage + Fragen + Erste Frage N�chste Frage - Vorherige Frage + Vorherige Frage Zur�ck zum Start Finale Abgabe Antwort zwischenspeichern Pr�fung beginnen Zusammenfassung der Antworten - Pr�fung verlassen - Erstelle Pr�fung + Pr�fung verlassen + Erstelle Pr�fung Schalte Pr�fung frei Schlie�e Pr�fung Schalte Pr�fung nochmals frei Aktualisieren Drucken + Signatur + Erzeuge einen digitalen Fingerabdruck bei Pr�fungsabgabe als Beleg der unver�nderten Abgabe + Aktuelle Signatur - Abgegebene Signatur + Abgegebene Signatur Liste der Bearbeitungen Wollen Sie einen Probelauf durchf�hren? - Studierende k�nnen die Fragen mit folgendem Link beantworten + Studierende k�nnen die Fragen mit folgendem Link beantworten Probelauf Die Pr�fung ist von der Aufsicht nicht freigegeben! Die Pr�fungszeit ist beendet Pr�fungsprotokoll Ergebnisse Abgegebene Pr�fungen Studierende haben eine Pr�fung abgegeben - Teilnehmer + Bezeichung der Pr�fung + Pr�fung aus ... + + Teilnehmer Teilnehmer haben diese Frage beantwortet Bitte beantworten Sie Ergebnisse - Zeige Antwortstatisktik + Zeige Antwortstatisktik Ergebnisse von Quiz beenden Antwort speichern @@ -73,10 +88,21 @@ Warte auf n�chste Frage ... Der Quiz kann derzeit nicht beantwortet werden Sie haben Frage %number% beantwortet - Zufallsauswahl + Bezeichung des Quiz + Quiz ... + + Abgabe def Pr�fung + Pr�fung ist abgegeben + + W�hlen Sie Fragen mittels Drag&Drop aus + + Randomisierte Fragenfolge + Zeige die Fragen der Pr�fung f�r jeden Studierenden in einer anderen Reihenfolge + + Zufallsauswahl Nie Pro Benutzer - Immer + Immer Kurztextfrage Single-Choice-Frage @@ -89,7 +115,11 @@ Textfrage Kurztextfrage MC-Frage - SC-Frage - Dateiabgabefrage + SC-Frage + Dateiabgabefrage + + Entwurf des Inclass-Exams (nicht freigegeben) + Inclass-Exam ge�ffnet (Zur Bearbeitung freigegeben) + Inclass-Exam geschlossen Index: openacs-4/packages/xowf/catalog/xowf.en_US.ISO-8859-1.xml =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowf/catalog/xowf.en_US.ISO-8859-1.xml,v diff -u -r1.2.2.10 -r1.2.2.11 --- openacs-4/packages/xowf/catalog/xowf.en_US.ISO-8859-1.xml 15 Feb 2020 10:38:09 -0000 1.2.2.10 +++ openacs-4/packages/xowf/catalog/xowf.en_US.ISO-8859-1.xml 21 Feb 2020 13:45:15 -0000 1.2.2.11 @@ -3,9 +3,17 @@ Exercise Grading Scheme - Score - Shuffle + Score + Shuffle + Days + Day Minutes + Minute + Hours + Hour + Seconds + Second + remaining Alternative That is correct! Sorry, incorrect! @@ -31,49 +39,55 @@ Exam closed Answer Question - Questions - First Question + Questions + First Question Next Question - Previous Question + Previous Question Restart Refresh Print Testrun Please answer - Participant + Participant participants answered this question Results - Show Results + Show Results Results of Actual Signature - Submission Signature - + Submission Signature + + Signature + Provide a digital finger print of submitted answers as proof of submitted content + Create Exam Review Exam Final submission Save Answer Start Exam - Leave Exam + Leave Exam Publish Exam Close Exam - Publish Exam again - Publish exam again, existing answers are NOT deleted. - Publish exam (already existing answers will be deleted) - Go back to start where questions can be selected (existing anwers will be deleted). + Open Exam again + Publish exam again, existing answers are NOT deleted. + Publish exam (already existing answers will be deleted) + Go back to start where questions can be selected (existing anwers will be deleted). Create a fresh Exam (will delete all answers to this exam) Listing of Filled-out Exams Do you want to try out the exam? - Students can now answer via - + Students can now answer via + The Exam has not been published The Exam is finished Exam Protocol Results Submitted exams - Persons have submitted exam + Persons have submitted exam + Name of Exam + Exam ... + The quiz has not been published The quiz is open The quiz is closed @@ -89,13 +103,23 @@ The quiz is currently not available for answering You have already answered question %number% Listing of Submitted Quizzes + Name of Quiz + Quiz ... + Drag and Drop Questions ... + + Randomized Item Order + Present question of exam to every student in different order + + Submit and Finish Exam + You have finished this exam. + Short Text Question Single Choice Question Multiple Choice Question Text Question File Upload Question - Sub-Question + Sub-Question Show Max None @@ -106,10 +130,16 @@ Short Text Interaction MC Interaction SC Interaction - Upload Interaction + Upload Interaction Online Exam Inclass Quiz - Inclass Exam + Inclass Exam + Draft Inclass Exam (not published) + Inclass Exam open (published) + Inclass Exam closed + + Created Questions + Created Assessments Fisheye: Tag 1.1 refers to a dead (removed) revision in file `openacs-4/packages/xowf/lib/inclass-exam-answer.wf'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `openacs-4/packages/xowf/lib/inclass-exam.wf'. Fisheye: No comparison available. Pass `N' to diff? Index: openacs-4/packages/xowf/lib/inclass-quiz-answer.wf =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowf/lib/inclass-quiz-answer.wf,v diff -u -r1.1.2.5 -r1.1.2.6 --- openacs-4/packages/xowf/lib/inclass-quiz-answer.wf 5 Dec 2019 21:09:53 -0000 1.1.2.5 +++ openacs-4/packages/xowf/lib/inclass-quiz-answer.wf 21 Feb 2020 13:45:15 -0000 1.1.2.6 @@ -88,11 +88,6 @@ set more_ahead 1 set quiz_available 1 - #if {$parent_state eq "created" && [$obj property try_out_mode]} { - # ns_log notice "FAKE state as published" - # set parent_state "published" - #} - switch $parent_state { "published" { # @@ -105,7 +100,7 @@ set form_answer [xowf::test_item::renaming_form_loader answer_for_form \ $form_name \ [$obj instance_attributes]] - ns_log notice "CURRENT answer '$form_answer' form_name $form_name" + #ns_log notice "CURRENT answer '$form_answer' form_name $form_name" if {$form_answer eq ""} { # # It was not answered yet, show the question as 'waiting_form' Index: openacs-4/packages/xowf/lib/inclass-quiz.wf =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowf/lib/inclass-quiz.wf,v diff -u -r1.1.2.10 -r1.1.2.11 --- openacs-4/packages/xowf/lib/inclass-quiz.wf 5 Feb 2020 20:48:42 -0000 1.1.2.10 +++ openacs-4/packages/xowf/lib/inclass-quiz.wf 21 Feb 2020 13:45:15 -0000 1.1.2.11 @@ -138,10 +138,11 @@ :proc load_form {ctx title} { set obj [$ctx object] set state [$obj property _state] + set wf [xowf::test_item::answer_manager get_answer_wf $obj] switch $state { "created" { - set current_form_info [::xowf::test_item::question_manager combined_question_form \ + set combined_form_info [::xowf::test_item::question_manager combined_question_form \ -with_numbers $obj] } default { @@ -151,13 +152,12 @@ "results" {set title "#xowf.results_of#: $title"} } set current_question [xowf::test_item::question_manager current_question_obj $obj] - set current_form_info [::xowf::test_item::question_manager current_question_form $obj] + set combined_form_info [::xowf::test_item::question_manager current_question_form $obj] } } - set fullQuestionForm [dict get $current_form_info form] - set full_fc [dict get $current_form_info disabled_form_constraints] - set wf [xowf::test_item::answer_manager get_answer_wf $obj] + set fullQuestionForm [dict get $combined_form_info form] + set full_fc [dict get $combined_form_info disabled_form_constraints] set qrCode "" set answerStatus "" @@ -174,7 +174,7 @@ "published" { set src [$obj pretty_link -query m=qrcode] - set qrCode [subst {
}] + set qrCode [subst {
}] set answerStatus [xowf::test_item::answer_manager answers_panel \ -polling=${:live_updates} \ -manager_ob $obj \ @@ -185,12 +185,13 @@ "done" - "results" { [$ctx object] setCSSDefaults - set marked [xowf::test_item::answer_manager marked_results $wf $current_form_info] + set marked [xowf::test_item::answer_manager marked_results -obj $obj -wf $wf $combined_form_info] set answerStatus [xowf::test_item::answer_manager answers_panel \ -manager_ob $obj \ -wf $wf \ -current_question $current_question] } + default { :msg "not handled: state=$state" } Index: openacs-4/packages/xowf/lib/online-exam-answer.wf =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowf/lib/online-exam-answer.wf,v diff -u -r1.2.2.21 -r1.2.2.22 --- openacs-4/packages/xowf/lib/online-exam-answer.wf 3 Feb 2020 22:55:55 -0000 1.2.2.21 +++ openacs-4/packages/xowf/lib/online-exam-answer.wf 21 Feb 2020 13:45:15 -0000 1.2.2.22 @@ -56,18 +56,17 @@ # or closed it already). Only allow usage in the try-out-mode. # if {$parent_state ne "published" && [$obj property try_out_mode 0] == 0} { - #:msg "LOCKED" set current_state [$obj property _state] - set lockin_state [expr {$current_state eq "initial" ? "initial" : "done"}] - set lockin_msg(initial) "#xowf.online-exam-not-published#" - set lockin_msg(done) "#xowf.online-exam-finished#" + set locking_state [expr {$current_state eq "initial" ? "initial" : "done"}] + set locking_msg(initial) "#xowf.online-exam-not-published#" + set locking_msg(done) "#xowf.online-exam-finished#" - util_user_message -message $lockin_msg($lockin_state) + util_user_message -message $locking_msg($locking_state) # # Force the user in the done state. Alternatively, we could # handle this in the provide a different form or push the user to some other state. # - [:wf_context] set_current_state $lockin_state + [:wf_context] set_current_state $locking_state } else { #:msg "not LOCKED" @@ -114,7 +113,6 @@ -label #xowf.online-exam-submit# \ -proc activate {obj} { [[$obj wf_context ] wf_container] addSignature $obj - set pid [$obj package_id] set try_out_mode [$obj property try_out_mode 0] set return_url [$obj property return_url .] #:msg "tryout $try_out_mode return_url $return_url" @@ -214,7 +212,9 @@ } # -# Set "title" with question/user/IP information. +# Set "title" with question/user/IP information. Note that the +# "set_title" method is as well responsible for calling the rename +# function via question_manager. # :proc set_title { obj @@ -232,7 +232,8 @@ -position $position \ -item_nr $item_nr \ $parent_obj] - set titleString [dict get $form_info title_infos full_title] + set title_info [lindex [dict get $form_info title_infos] 0] + set titleString [dict get $title_info full_title] set title [list [string trim $titleString]] } lappend title \ Index: openacs-4/packages/xowf/lib/online-exam.wf =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowf/lib/online-exam.wf,v diff -u -r1.6.2.21 -r1.6.2.22 --- openacs-4/packages/xowf/lib/online-exam.wf 15 Feb 2020 10:37:53 -0000 1.6.2.21 +++ openacs-4/packages/xowf/lib/online-exam.wf 21 Feb 2020 13:45:15 -0000 1.6.2.22 @@ -148,23 +148,32 @@ set pLink "." set menu "" } else { + # + # Always compute the testrun and answer link. + # set wf_pretty_link [$wf pretty_link] set tLink [export_vars -base $wf_pretty_link { {m create-new} {p.return_url "[::xo::cc url]"} {p.try_out_mode 1} {title "[$obj title]"} }] - set lLink "$wf_pretty_link?m=list" set aLink [$obj pretty_link -query m=answer] - set pLink1 [$obj pretty_link -query m=print-answers] - set pLink2 [$obj pretty_link -query m=print-answer-table] - #util_user_message -html -message "$survey is available as $pLink" - # [#xowf.refresh#, - set menu "\[" - if {[acs_user::site_wide_admin_p -user_id [::xo::cc user_id]]} { - append menu "#xowf.online-exam-exam_instances#, " + # + # If there are answers, include the full menu. + # + set answers [xowf::test_item::answer_manager get_answers $wf] + if {[llength $answers] > 0} { + + set lLink "$wf_pretty_link?m=list" + set pLink1 [$obj pretty_link -query m=print-answers] + set pLink2 [$obj pretty_link -query m=print-answer-table] + + set menu "\[" + if {[acs_user::site_wide_admin_p -user_id [::xo::cc user_id]]} { + append menu "#xowf.online-exam-exam_instances#, " + } + append menu \ + "#xowf.online-exam-protocol#, " \ + "#xowf.online-exam-results-table#\]" } - append menu \ - "#xowf.online-exam-protocol#, " \ - "#xowf.online-exam-results-table#\]" } set extraAction "" @@ -184,7 +193,7 @@ if {$state in {published done}} { if {$state eq "done"} { [$ctx object] setCSSDefaults - set marked [xowf::test_item::answer_manager marked_results $wf $combined_form_info] + set marked [xowf::test_item::answer_manager marked_results -obj $obj -wf $wf $combined_form_info] } set answerStats [xowf::test_item::answer_manager answers_panel \ -heading "#xowf.online-exam-submitted_exams_heading#" \ Index: openacs-4/packages/xowf/tcl/test-item-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowf/tcl/test-item-procs.tcl,v diff -u -r1.7.2.25 -r1.7.2.26 --- openacs-4/packages/xowf/tcl/test-item-procs.tcl 12 Feb 2020 12:43:26 -0000 1.7.2.25 +++ openacs-4/packages/xowf/tcl/test-item-procs.tcl 21 Feb 2020 13:45:15 -0000 1.7.2.26 @@ -149,7 +149,7 @@ set auto_correct ${:auto_correct} set can_shuffle true } - ul { # + ul { # set interaction_class upload_interaction set options "" set auto_correct false @@ -854,11 +854,55 @@ #:msg "fc=$fc" } } +############################################################################ +# Generic Assement interface +############################################################################ namespace eval ::xowf::test_item { - nx::Object create renaming_form_loader { + nx::Class create AssessmentInterface { # + # Abstract class for common functionality + # + :method assert_assessment_container {o:object} { + set ok [expr {[$o is_wf_instance] == 0 && [$o is_wf] == 1}] + if {!$ok} { + ns_log notice "NO ASSESSMENT CONTAINER [$o title]" + ns_log notice "NO ASSESSMENT CONTAINER page_template [[$o page_template] title]" + ns_log notice "NO ASSESSMENT CONTAINER iswfi [$o is_wf_instance] iswf [$o is_wf]" + ns_log notice "[$o serialize]" + error "'[lindex [info level -1] 0]': not an assessment container" + } + } + + :method assert_assessment {o:object} { + if {[llength [$o property question]] == 0} { + ns_log notice "NO ASSESSMENT [$o title]" + ns_log notice "NO ASSESSMENT page_template [[$o page_template] title]" + ns_log notice "NO ASSESSMENT iswfi [$o is_wf_instance] iswf [$o is_wf]" + ns_log notice "[$o serialize]" + error "'[lindex [info level -1] 0]': object has no questions" + } + } + + :method assert_answer_instance {o:object} { + # we could include as well {[$o property answer] ne ""} in case we initialize it + set ok [expr {[$o is_wf_instance] == 1 && [$o is_wf] == 0}] + if {!$ok} { + ns_log notice "NO ANSWER [$o title]" + ns_log notice "NO ANSWER page_template [[$o page_template] title]" + ns_log notice "NO ANSWER iswfi [$o is_wf_instance] iswf [$o is_wf]" + ns_log notice "[$o serialize]" + error "'[lindex [info level -1] 0]': not an answer instance" + } + } + + } +} +namespace eval ::xowf::test_item { + + nx::Class create Renaming_form_loader -superclass AssessmentInterface { + # # Form loader that renames "generic" form-field-names as provided # by the test-item form-field classes (@answer@) into names based # on the form name, such that multiple of these form names can be @@ -873,7 +917,7 @@ # - rename_attributes # - :object method map_form_constraints {form_constraints oldName newName} { + :method map_form_constraints {form_constraints oldName newName} { # # Rename form constraints starting with $oldName into $newName. # Handle as well "answer=$oldName" form constraint properties. @@ -891,7 +935,7 @@ }] } - :public object method form_name_based_attribute_stem {formName} { + :public method form_name_based_attribute_stem {formName} { # # Produce from the provided 'formName' an attribute stem for the # input fields of this form. @@ -902,7 +946,7 @@ } - :public object method answer_attributes {instance_attributes} { + :public method answer_attributes {instance_attributes} { # # Return all form-loader specific attributes from # instance_attributes. @@ -916,7 +960,7 @@ return $result } - :public object method answer_for_form {formName instance_attributes} { + :public method answer_for_form {formName instance_attributes} { # # Return answer for the provided formName from # instance_attributes of a single object. @@ -934,7 +978,7 @@ return $result } - :public object method answers_for_form {formName answers} { + :public method answers_for_form {formName answers} { # # Return a list of dicts for the provided formName from the # answers (as returned from [answer_manager get_answers ...]). @@ -954,7 +998,7 @@ return $result } - :public object method rename_attributes {form_obj:object} { + :public method rename_attributes {form_obj:object} { set form [$form_obj get_property -name form] set fc [$form_obj get_property -name form_constraints] @@ -984,20 +1028,22 @@ return $form_obj } - :public object method get_form_object {{-set_title:boolean true} ctx:object form_name} { - #ns_log notice "renaming_form_loader get_form_object for form_name <$form_name>" + :public method get_form_object {{-set_title:boolean true} ctx:object form_name} { set form_id [$ctx default_load_form_id $form_name] set obj [$ctx object] set form_obj [::xo::db::CrClass get_instance_from_db -item_id $form_id] return [:rename_attributes $form_obj] } } + + Renaming_form_loader create renaming_form_loader } + namespace eval ::xowf::test_item { - nx::Object create answer_manager { + nx::Class create Answer_manager -superclass AssessmentInterface { # # Public API: @@ -1010,10 +1056,10 @@ # # - marked_results # - answers_panel - # - participant_result # - result_table # - :public object method create_workflow { + + :public method create_workflow { {-answer_workflow /packages/xowf/lib/online-exam-answer.wf} {-master_workflow en:Workflow.form} parentObj:object @@ -1090,7 +1136,7 @@ ######################################################################## - :public object method delete_all_answer_data {obj:object} { + :public method delete_all_answer_data {obj:object} { # # Delete all instances of the answer workflow # @@ -1105,7 +1151,7 @@ ######################################################################## - :public object method get_answer_wf {obj:object} { + :public method get_answer_wf {obj:object} { # # return the workflow denoted by the property wfName in obj # @@ -1118,12 +1164,14 @@ ######################################################################## - :public object method get_wf_instances { + :public method get_wf_instances { {-initialize false} {-orderby ""} wf:object } { # get_wf_instances: return the workflow instances + :assert_assessment_container $wf + return [::xowiki::FormPage get_form_entries \ -base_item_ids [$wf item_id] \ -form_fields "" \ @@ -1136,7 +1184,7 @@ ######################################################################## - :public object method get_answers {{-state ""} wf:object} { + :public method get_answers {{-state ""} wf:object} { set results {} set items [:get_wf_instances $wf] foreach i [$items children] { @@ -1152,24 +1200,26 @@ ######################################################################## - :object method participant_result {obj:object form_info} { - # - # In case, the passed-in obj modifies during rendering the - # perconnection parameters, save and restore these. - # - set form_fields [:answer_form_field_objs -wf $obj] - $obj form_field_index $form_fields + :method participant_result { + -obj:object + answerObj:object + form_info + form_field_objs + } { - set instance_attributes [$obj instance_attributes] - set answer [list item $obj] + :assert_answer_instance $answerObj + :assert_assessment $obj - foreach f $form_fields { + set instance_attributes [$answerObj instance_attributes] + set answer [list item $answerObj] + + foreach f $form_field_objs { set att [$f name] if {[dict exists $instance_attributes $att]} { set value [dict get $instance_attributes $att] #ns_log notice "### '$att' value '$value'" - $obj combine_data_and_form_field_default 1 $f $value + $answerObj combine_data_and_form_field_default 1 $f $value $f set_feedback 1 $f add_statistics -options {word_statistics word_cloud} # @@ -1189,7 +1239,7 @@ return $answer } - :object method answer_form_field_objs {-clear:switch -wf:object} { + :method answer_form_field_objs {-clear:switch -wf:object form_info} { set key ::__test_item_answer_form_fields if {$clear} { # @@ -1199,25 +1249,32 @@ # unset $key } else { + #ns_log notice "### key exists [info exists $key]" if {![info exists $key]} { - set form_info [::xowf::test_item::question_manager combined_question_form -with_numbers $wf] + #ns_log notice "form_info: $form_info" + set fc [dict get $form_info disabled_form_constraints] set pc_params [::xo::cc perconnection_parameter_get_all] + #ns_log notice "### create_form_fields_from_form_constraints <$fc>" set $key [$wf create_form_fields_from_form_constraints \ -lookup \ - [dict get $form_info disabled_form_constraints]] + [lsort -unique $fc]] ::xo::cc perconnection_parameter_set_all $pc_params + $wf form_field_index [set $key] } return [set $key] } } - :public object method result_table { + + :public method result_table { -package_id:integer -items:object,required {-view_all_method print-answers} wf:object } { - set answer_form_field_objs [:answer_form_field_objs -wf $wf] + #set form_info [:combined_question_form -with_numbers $wf] + set form_info [::xowf::test_item::question_manager combined_question_form $wf] + set answer_form_field_objs [:answer_form_field_objs -wf $wf $form_info] set form_field_objs [$wf create_raw_form_field \ -name _online-exam-userName \ @@ -1302,17 +1359,21 @@ return $HTML } - :public object method marked_results {wf:object form_info} { + :public method marked_results {-obj:object -wf:object form_info} { + set form_field_objs [:answer_form_field_objs -wf $wf $form_info] + set items [:get_wf_instances $wf] set results "" foreach i [$items children] { - set participantResult [:participant_result $i $form_info] + set participantResult [:participant_result -obj $obj $i $form_info $form_field_objs] append results $participantResult \n } + + #ns_log notice "=== marked_results of [llength [$items children]] items => $results" return $results } - :public object method answers_panel { + :public method answers_panel { {-polling:switch false} {-heading #xowf.submitted_answers#} {-submission_msg #xowf.participants_answered_question#} @@ -1372,28 +1433,60 @@ return $answerStatus } - } -} -namespace eval ::xowf::test_item { - ::xotcl::Class create ::xowf::test_item::td_pretty_value \ - -superclass ::xowiki::formfield::FormField + :public method countdown_timer { + {-target_time:required} + {-id:required} + } { + # new Date('1995-12-17T03:24:00') + template::add_body_script -script [subst { + var countdown_target_date = new Date('$target_time').getTime(); + var countdown_days, countdown_hours, countdown_minutes, countdown_seconds; + var countdown = document.getElementById('$id'); - ::xowf::test_item::td_pretty_value instproc pretty_value {value} { - #ns_log notice "${:name} pretty_value [:info precedence]" - if {"::xowiki::formfield::checkbox" in [:info precedence]} { - set v ${value} - } else { - set v [next] + setInterval(function () { + var current_date = new Date().getTime(); + var seconds_left = (countdown_target_date - current_date) / 1000; + var HTML = ''; + + countdown_days = parseInt(seconds_left / 86400); + seconds_left = seconds_left % 86400; + countdown_hours = parseInt(seconds_left / 3600); + seconds_left = seconds_left % 3600; + countdown_minutes = parseInt(seconds_left / 60); + countdown_seconds = parseInt(seconds_left % 60); + + if (countdown_days != 0) { + HTML += '' + countdown_days + ' ' + + (countdown_days != 1 ? '[_ xowf.Days]' : '[_ xowf.Day]') + + ' '; + } + if (countdown_hours != 0 || countdown_days != 0) { + HTML += '' + countdown_hours + ' ' + + (countdown_hours != 1 ? '[_ xowf.Hours]' : '[_ xowf.Hour]') + + ' '; + } + HTML += '' + countdown_minutes + ' ' + + (countdown_minutes != 1 ? '[_ xowf.Minutes]' : '[_ xowf.Minute]') + + ' ' + + '' + countdown_seconds + ' ' + + (countdown_seconds != 1 ? '[_ xowf.Seconds]' : '[_ xowf.Second]') + + ' [_ xowf.remaining]' ; + + countdown.innerHTML = HTML; + }, 1000); + }] + return "
" } - return $v } + + Answer_manager create answer_manager } + namespace eval ::xowf::test_item { - - nx::Object create question_manager { + nx::Class create Question_manager -superclass AssessmentInterface { # # This code manages questions and the information related to a # current (selected) question via qthe "position" instance @@ -1413,20 +1506,21 @@ # - question_objs # - question_names # - question_property + # - total_minutes # - :public object method goto_page {obj:object position} { + :public method goto_page {obj:object position} { $obj set_property position $position } - :public object method more_ahead {{-position ""} obj:object} { + :public method more_ahead {{-position ""} obj:object} { if {$position eq ""} { set position [$obj property position] } set questions [dict get [$obj instance_attributes] question] return [expr {$position + 1 < [llength $questions]}] } - :object method load_question_objs {obj names} { + :method load_question_objs {obj:object names} { set questions [lmap ref $names { if {![string match "*/*" $ref]} { set ref [[$obj parent_id] name]/$ref @@ -1438,21 +1532,22 @@ -package_id [$obj package_id] \ -default_lang [$obj lang] \ -forms $questionNames] + #ns_log notice "load_question_objs called with $obj $names -> $questionForms" return $questionForms } - :public object method current_question_name {obj:object} { + :public method current_question_name {obj:object} { set questions [dict get [$obj instance_attributes] question] return [lindex [dict get [$obj instance_attributes] question] [$obj property position]] } - :public object method current_question_obj {obj:object} { + :public method current_question_obj {obj:object} { return [:load_question_objs $obj [:current_question_name $obj]] } - :public object method shuffled_question_objs {obj:object shuffle_id} { + :public method shuffled_question_objs {obj:object shuffle_id} { set form_objs [:question_objs $obj] set result {} foreach i [::xowiki::randomized_indices -seed $shuffle_id [llength $form_objs]] { @@ -1461,7 +1556,7 @@ return $result } - :public object method shuffled_index {{-shuffle_id:integer -1} obj:object position} { + :public method shuffled_index {{-shuffle_id:integer -1} obj:object position} { if {$shuffle_id > -1} { set form_objs [:question_objs $obj] set shuffled [::xowiki::randomized_indices -seed $shuffle_id [llength $form_objs]] @@ -1470,7 +1565,8 @@ return $position } - :public object method question_objs {{-shuffle_id:integer -1} obj:object} { + :public method question_objs {{-shuffle_id:integer -1} obj:object} { + :assert_assessment $obj set form_objs [:load_question_objs $obj [$obj property question]] if {$shuffle_id > -1} { set result {} @@ -1482,18 +1578,18 @@ return $form_objs } - :public object method question_names {obj:object} { + :public method question_names {obj:object} { return [$obj property question] } - :public object method nth_question_obj {obj:object position:integer} { + :public method nth_question_obj {obj:object position:integer} { + :assert_assessment $obj set questions [dict get [$obj instance_attributes] question] set result [:load_question_objs $obj [lindex $questions $position]] - #ns_log notice "nth_question_obj called with $position -> $result" return $result } - :object method question_info { + :method question_info { {-numbers ""} {-with_title:switch false} {-with_minutes:switch false} @@ -1503,6 +1599,7 @@ set full_fc {} set full_disabled_fc {} set title_infos {} + foreach form_obj $form_objs number $numbers { set form_obj [::xowf::test_item::renaming_form_loader rename_attributes $form_obj] set form_title [$form_obj title] @@ -1520,11 +1617,10 @@ append full_form "

$title

\n" append full_form [$form_obj property form] \n - lappend title_infos \ - full_title $title \ - title $form_title \ - minutes $minutes \ - number $number + lappend title_infos [list full_title $title \ + title $form_title \ + minutes $minutes \ + number $number] lappend full_fc [$form_obj property form_constraints] lappend full_disabled_fc [$form_obj property disabled_form_constraints] } @@ -1536,7 +1632,7 @@ } - :public object method question_property {form_obj:object attribute {default ""}} { + :public method question_property {form_obj:object attribute {default ""}} { # # Get an attribute of the original question # @@ -1550,7 +1646,7 @@ return $value } - :public object method minutes_string {form_obj:object} { + :public method minutes_string {form_obj:object} { # # Get an attribute of the original question # @@ -1561,7 +1657,7 @@ } } - :public object method combined_question_form { + :public method combined_question_form { {-with_numbers:switch false} {-with_title:switch false} {-with_minutes:switch false} @@ -1585,15 +1681,25 @@ $form_objs] } - :public object method current_question_form { + :public method total_minutes {form_info} { + set minutes 0 + foreach title_info [dict get $form_info title_infos] { + if {[dict exists $title_info minutes]} { + set minutes [expr {$minutes + [dict get $title_info minutes]}] + } + } + return $minutes + } + + :public method current_question_form { {-with_numbers:switch false} {-with_title:switch false} obj:object } { return [:nth_question_form -with_numbers=$with_numbers -with_title=$with_title $obj] } - :public object method nth_question_form { + :public method nth_question_form { {-position:integer} {-item_nr:integer} {-with_numbers:switch false} @@ -1621,33 +1727,40 @@ $form_objs] } - :public object method current_question_number {obj:object} { + :public method current_question_number {obj:object} { return [expr {[$obj property position] + 1}] } - :public object method current_question_title {{-with_numbers:switch false} obj:object} { + :public method current_question_title {{-with_numbers:switch false} obj:object} { if {$with_numbers} { return "#xowf.question# [:current_question_number $obj]" } } + } + Question_manager create question_manager - # :public object method set_page {obj increment} { - # #set pages [$obj property pages] - # set position [$obj property position 0] - # incr position $increment - # if {$position < 0} { - # set position 0 - # } elseif {$position >= [llength $pages]} { - # set position [expr {[llength $pages] - 1}] - # } - # $obj set_property position $position - # #$obj set_property -new 1 current_form [lindex $pages $position] - # } - } } namespace eval ::xowf::test_item { + # + # Define handling of form-field "td_pretty_value" + # + ::xotcl::Class create ::xowf::test_item::td_pretty_value \ + -superclass ::xowiki::formfield::FormField + ::xowf::test_item::td_pretty_value instproc pretty_value {value} { + #ns_log notice "${:name} pretty_value [:info precedence]" + if {"::xowiki::formfield::checkbox" in [:info precedence]} { + set v ${value} + } else { + set v [next] + } + return $v + } +} + + +namespace eval ::xowf::test_item { # # Copy the default policy (policy1) from xowiki and add elements for # FormPages as needed by the demo workflows: Index: openacs-4/packages/xowf/tcl/xowf-init.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowf/tcl/xowf-init.tcl,v diff -u -r1.3.2.3 -r1.3.2.4 --- openacs-4/packages/xowf/tcl/xowf-init.tcl 14 Feb 2020 13:42:12 -0000 1.3.2.3 +++ openacs-4/packages/xowf/tcl/xowf-init.tcl 21 Feb 2020 13:45:15 -0000 1.3.2.4 @@ -4,6 +4,11 @@ ::xowf::dav-todo register # +# Make sure, the site-wide pages are loaded +# +::xowf::Package require_site_wide_pages + +# # Run the checker for the scheduled at-jobs. # # As we are trying to run as close as possible to the minute change, Index: openacs-4/packages/xowf/tcl/xowf-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowf/tcl/xowf-procs.tcl,v diff -u -r1.28.2.25 -r1.28.2.26 --- openacs-4/packages/xowf/tcl/xowf-procs.tcl 14 Feb 2020 13:42:12 -0000 1.28.2.25 +++ openacs-4/packages/xowf/tcl/xowf-procs.tcl 21 Feb 2020 13:45:15 -0000 1.28.2.26 @@ -16,6 +16,7 @@ ::xo::db::require package xowiki ::xo::library require -package xowiki xowiki-procs +::xo::library require -package xotcl-core 06-package-procs namespace eval ::xowf { # @@ -44,6 +45,23 @@ parameter_page en:xowf-site-wide-parameter } + Package site_wide_pages { + Workflow.form + + TestItemText.form + TestItemShortText.form + TestItemMC.form + TestItemSC.form + TestItemUpload.form + + online-exam.wf + inclass-quiz.wf + inclass-exam.wf + + quiz-select_question.form + select_question.form + } + Package default_package_parameters { parameter_page en:xowf-default-parameter } @@ -54,11 +72,46 @@ instance_attributes { MenuBar t top_includelet none production_mode t with_user_tracking t with_general_comments f with_digg f with_tags f - ExtraMenuEntries {{entry -name New.Extra.Workflow -form /en:Workflow.form}} + ExtraMenuEntries {{entry -name New.Extra.Workflow -form en:Workflow.form}} with_delicious f with_notifications f security_policy ::xowiki::policy1 } } + Package ad_proc create_new_workflow_page { + -package_id:required + -parent_id:required + -name:required + -title:required + {-instance_attributes ""} + } { + Helper proc for loading workflow prototype page with less effort. + } { + # + # Load Workflow.form + # + xo::Package require $package_id + set item_ref_info [$package_id item_ref -use_site_wide_pages true -default_lang en \ + -parent_id $parent_id \ + en:Workflow.form] + set page_template [dict get $item_ref_info item_id] + if {$page_template != 0} { + # + # Create FormPage + # + set p [::xowiki::FormPage new \ + -name $name \ + -title $title \ + -set text {} \ + -instance_attributes $instance_attributes \ + -page_template $page_template] + } else { + ns_log error "could not load Workflow form, therefore creation of workflow $name failed as well" + set p "" + } + return $p + } + + Package ad_instproc initialize {} { Add mixin ::xowf::WorkflowPage to every FormPage. } { @@ -99,6 +152,8 @@ next } + + # Package instproc delete {-item_id -name} { # # Provide a method to delete the foreign key references, when # # an item for an atjob is deleted. We do here the same magic Fisheye: Tag 1.1 refers to a dead (removed) revision in file `openacs-4/packages/xowf/www/prototypes/TestItemMC.form.page'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `openacs-4/packages/xowf/www/prototypes/TestItemSC.form.page'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `openacs-4/packages/xowf/www/prototypes/TestItemShortText.form.page'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `openacs-4/packages/xowf/www/prototypes/TestItemText.form.page'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `openacs-4/packages/xowf/www/prototypes/TestItemUpload.form.page'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `openacs-4/packages/xowf/www/prototypes/assessment-index.page'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `openacs-4/packages/xowf/www/prototypes/inclass-exam.wf.page'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `openacs-4/packages/xowf/www/prototypes/inclass-quiz.wf.page'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `openacs-4/packages/xowf/www/prototypes/online-exam.wf.page'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `openacs-4/packages/xowf/www/prototypes/quiz-select_question.form.page'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag 1.1 refers to a dead (removed) revision in file `openacs-4/packages/xowf/www/prototypes/select_question.form.page'. Fisheye: No comparison available. Pass `N' to diff? Index: openacs-4/packages/xowf/www/resources/test-item.css =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/xowf/www/resources/test-item.css,v diff -u -r1.1.2.12 -r1.1.2.13 --- openacs-4/packages/xowf/www/resources/test-item.css 11 Feb 2020 21:26:04 -0000 1.1.2.12 +++ openacs-4/packages/xowf/www/resources/test-item.css 21 Feb 2020 13:45:15 -0000 1.1.2.13 @@ -192,3 +192,8 @@ height: auto; /* let the content decide it */ } + +div.xowiki-content h1 { + font-size: 24px; +} +