diff --git a/.hgtags b/.hgtags index 3a5c914309bfe0839cf7a19ebc925e50958d4f78..327db5e6db67baa145f2cbfc5c4959db4e1b84ba 100644 --- a/.hgtags +++ b/.hgtags @@ -210,3 +210,5 @@ dc92e2661668e9867d401d8f929c02a6a3f92314 OpenOLAT 12.2.3 30e784886f4e1aa610acf5f850511adab8e3623e OpenOLAT 12.2.5 97e8d87f2416ba6dd43d47164100c2b4ec577ab7 OpenOLAT 12.2.6 4ceae571c62f6e2e2bc5711e7f445836c368bb71 OpenOLAT 12.2.7 +b600dc769f2f7b69b57bdea60591488d8e27ee7d OpenOLAT 12.2.8 +93154b0f3bb64433fde186ce8d8566f71cabc9ce OpenOLAT 12.3.0 diff --git a/pom.xml b/pom.xml index 196ef867364eedc36b5af3d4445df8037158394e..fd0f7cce32aee74b8ba491f5ef10e22a817be59a 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ <modelVersion>4.0.0</modelVersion> <groupId>org.openolat</groupId> <artifactId>openolat-lms</artifactId> - <version>12.3-SNAPSHOT</version> + <version>12.4-SNAPSHOT</version> <packaging>war</packaging> <name>OpenOLAT LMS</name> <url>http://www.openolat.org</url> diff --git a/src/main/java/de/bps/onyx/plugin/wsserver/ReturnWSService.java b/src/main/java/de/bps/onyx/plugin/wsserver/ReturnWSService.java index 136c8394fb38308ab22cb05a2ec5a9d6aaf1f5ad..e69b10220a36d6df1b51cd80e8ce97bad9454960 100644 --- a/src/main/java/de/bps/onyx/plugin/wsserver/ReturnWSService.java +++ b/src/main/java/de/bps/onyx/plugin/wsserver/ReturnWSService.java @@ -54,6 +54,7 @@ import org.olat.ims.qti.QTIResultSet; import org.olat.modules.assessment.Role; import org.olat.modules.assessment.model.AssessmentEntryStatus; +import de.bps.onyx.plugin.OnyxModule; import de.bps.onyx.plugin.OnyxResultManager; /** @@ -98,6 +99,11 @@ public class ReturnWSService { public void saveResult(@WebParam(name = "uniqueId") String uniqueId, @WebParam(name = "resultFile") byte[] resultFile, @WebParam(name = "params") MapWrapper params) throws Exception { + if(!CoreSpringFactory.getImpl(OnyxModule.class).isEnabled()) { + log.warn("ReturnWSService unauthorized attempt, service disabled"); + throw new RuntimeException("Onyx plugin disabled"); + } + File temp = null; try { @@ -292,6 +298,11 @@ public class ReturnWSService { @WebMethod public void saveResultLocal(@WebParam(name = "uniqueId") String uniqueId, @WebParam(name = "resultLocalFile") String resultLocalFile) { + if(!CoreSpringFactory.getImpl(OnyxModule.class).isEnabled()) { + log.warn("ReturnWSService unauthorized attempt, service disabled"); + throw new RuntimeException("Onyx plugin disabled"); + } + QTIResultSet qtiResultSet = OnyxResultManager.getResultSet(Long.parseLong(uniqueId)); if (resultLocalFile == null) { diff --git a/src/main/java/de/bps/onyx/plugin/wsserver/TraineeStatusService.java b/src/main/java/de/bps/onyx/plugin/wsserver/TraineeStatusService.java index d85c9cc72ae754be5fced393a0281a16b1db7c3a..0e5c30aadb584aaf7e619bdfb456d4d88c4873fe 100644 --- a/src/main/java/de/bps/onyx/plugin/wsserver/TraineeStatusService.java +++ b/src/main/java/de/bps/onyx/plugin/wsserver/TraineeStatusService.java @@ -27,10 +27,12 @@ import javax.jws.WebParam; import javax.jws.WebService; import javax.jws.soap.SOAPBinding; +import org.olat.core.CoreSpringFactory; import org.olat.core.id.Identity; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; +import de.bps.onyx.plugin.OnyxModule; import de.bps.onyx.util.ExamPoolManager; @WebService(name = "TraineeStatusService", serviceName = "TraineeStatusService", targetNamespace = "http://test.plugin.bps.de/") @@ -46,6 +48,11 @@ public class TraineeStatusService { @WebMethod(operationName = "updateStatus") public void updateStatus(@WebParam(name = "testSessionId") Long testSessionId, @WebParam(name = "studentIds") StudentIdsWrapper studentIds, @WebParam(name = "status") Integer status) { + if(!CoreSpringFactory.getImpl(OnyxModule.class).isEnabled()) { + log.warn("TraineeStatusService unauthorized attempt, service disabled"); + throw new RuntimeException("Onyx plugin disabled"); + } + TestState testState = TestState.getState(status); log.info("updateStatus: " + testSessionId + " # " + studentIds + " # " + testState); diff --git a/src/main/java/org/olat/admin/layout/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/admin/layout/_i18n/LocalStrings_fr.properties index f72a7c0c14841cef688416d6ed168a0b569ec151..13c4a3f8e2e29c05edca3a8b4d55d3c55ac5ff71 100644 --- a/src/main/java/org/olat/admin/layout/_i18n/LocalStrings_fr.properties +++ b/src/main/java/org/olat/admin/layout/_i18n/LocalStrings_fr.properties @@ -1,4 +1,4 @@ -#Sun Dec 14 17:23:30 CET 2014 +#Thu Feb 01 22:20:11 CET 2018 CustomizingAdminController.menu.title=Personnaliser la mise-en-page CustomizingAdminController.menu.title.alt=T\u00E9l\u00E9charger un logo et changer le pied de page. LayoutAdminControllerWithPersist.menu.title=Mise-en-page @@ -16,6 +16,8 @@ footerLine.description=Texte du pied de page (liens e-mail et adresses sont auto footerUrl.default=http\://www.frentix.com footerUrl.description=Entrer l'URL pour les clics sur le pied-de-page (en option) form.theme=Mise en page syst\u00E8me +form.theme.forceReload=Forcer le rechargement de toutes les ressources statiques +form.theme.forceReload.help=Le rechargement est uniquement n\u00E9cessaire si des modifications ont \u00E9t\u00E9 apport\u00E9es \u00E0 une mise en page qui a d\u00E9j\u00E0 \u00E9t\u00E9 t\u00E9l\u00E9charg\u00E9e. invitee=invit\u00E9(e) layout.intro=Par la suite, vous pouvez exp\u00E9rimenter avec les th\u00E8mes de mise en page mises \u00E0 disposition. Choisissez un sujet dans la liste pour l'utiliser. Pour activer les modifications d'affichage, vous devez vous d\u00E9connecter et vous reconnecter sur OLAT. layout.title=Mise en page diff --git a/src/main/java/org/olat/admin/security/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/admin/security/_i18n/LocalStrings_fr.properties index aca5c29802f377c43c0bec6bca9eea69a3e0c1a3..8f52021483d5d5b0c9660bc096572d3a6fadccf2 100644 --- a/src/main/java/org/olat/admin/security/_i18n/LocalStrings_fr.properties +++ b/src/main/java/org/olat/admin/security/_i18n/LocalStrings_fr.properties @@ -1,10 +1,10 @@ -#Tue Apr 15 21:59:54 CEST 2014 +#Thu Feb 01 22:21:50 CET 2018 admin.menu.title=S\u00E9curit\u00E9 admin.menu.title.alt=Modifier les param\u00E8tres de s\u00E9curit\u00E9 sec.description=S\u00E9curit\u00E9 sec.force.download=Forcer le t\u00E9l\u00E9chargement dans les dossiers sec.title=Param\u00E8tres de s\u00E9curit\u00E9 +sec.top.frame.explanation=En raison d'incompatibilit\u00E9s avec certains composants d'OpenOLAT (TinyMCE), il n'est pas possible d'int\u00E9grer OpenOLAT dans une frame. sec.topframe=Emp\u00EAcher l'int\u00E9gration dans les cadres/frames sec.wiki=Bloquer la resource de type wiki -sec.top.frame.explanation=En raison d'incompatibilit\u00E9s avec certains composants d'OpenOLAT (TinyMCE), il n'est pas possible d'int\u00E9grer OpenOLAT dans une frame. - +sec.xframe.sameorigin=Interdire l'encadrant dans une frame avec l'en-t\u00EAte "X-FRAME-OPTIONS\=SAMEDOMAIN" diff --git a/src/main/java/org/olat/admin/site/ui/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/admin/site/ui/_i18n/LocalStrings_fr.properties index 58589d008030092434bb136882092af0f5714373..fd13456fa05694a860fced8247cea49c3390a066 100644 --- a/src/main/java/org/olat/admin/site/ui/_i18n/LocalStrings_fr.properties +++ b/src/main/java/org/olat/admin/site/ui/_i18n/LocalStrings_fr.properties @@ -1,4 +1,4 @@ -#Thu Nov 16 20:28:37 CET 2017 +#Thu Feb 01 18:38:36 CET 2018 AdminSiteDef=Administration CatalogAdminSiteDef=Administration du catalogue CatalogSiteDef=Catalogue @@ -30,6 +30,7 @@ disabledSiteSecurityCallback=D\u00E9sactiv\u00E9 down=En bas managersSiteSecurityCallback=Tous les administrateurs poolPrivateMembersSiteSecurityCallback=Membres et administrateurs de pools de questions +poolTaxonomySiteSecurityCallback=Administrateurs banque de questions et comp\u00E9tences registredOrGuestSiteSecurityCallback=Utilisateurs enregistr\u00E9 et invit\u00E9s sans invitations portfolio registredSiteSecurityCallback=Utilisateurs enregistr\u00E9s sauf les invit\u00E9 / les invitations eP restrictToAuthorSiteSecurityCallback=Auteurs diff --git a/src/main/java/org/olat/core/commons/chiefcontrollers/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/core/commons/chiefcontrollers/_i18n/LocalStrings_fr.properties index e1b8f2d5ebbfe33f34f6d0b5efafd345bd4e3891..895ef1b5a48aa2a0a14cccbf9b6598b9ca809de1 100644 --- a/src/main/java/org/olat/core/commons/chiefcontrollers/_i18n/LocalStrings_fr.properties +++ b/src/main/java/org/olat/core/commons/chiefcontrollers/_i18n/LocalStrings_fr.properties @@ -1,4 +1,4 @@ -#Thu Nov 16 19:06:40 CET 2017 +#Thu Feb 01 18:31:22 CET 2018 AssessmentManager=Outil d'\u00E9valuation Binder=ePortfolio 2.0 BinderTemplate=Mod\u00E8le de portfolio 2.0 @@ -47,6 +47,7 @@ PFCourseNode=Dossier participant ReturnboxController=Dossier de restitution SolutionController=Solutions mod\u00E8les TaxonomyLibrary=Biblioth\u00E8que de taxonomie +Templates=Mod\u00E8le User=Utilisateur WikiPage=Wiki ajax.show.on=[Ajax-Beta-Mode] diff --git a/src/main/java/org/olat/core/commons/controllers/filechooser/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/core/commons/controllers/filechooser/_i18n/LocalStrings_fr.properties index 6dbdc37a5939e187965e09205f98724b7696895e..b2a93ebdff46a96a92a5d81be9059e4873945137 100644 --- a/src/main/java/org/olat/core/commons/controllers/filechooser/_i18n/LocalStrings_fr.properties +++ b/src/main/java/org/olat/core/commons/controllers/filechooser/_i18n/LocalStrings_fr.properties @@ -1,4 +1,4 @@ -#Thu Feb 26 21:09:16 CET 2015 +#Thu Feb 01 18:19:42 CET 2018 button.create=Cr\u00E9er calloutTrigerLink.select.site=Choisir une page calloutTriggerLink=Choisir, cr\u00E9er, t\u00E9l\u00E9charger un fichier @@ -7,6 +7,7 @@ chooseLink=Choisir un fichier command.create=Cr\u00E9er une page et l'ouvrir dans l'\u00E9diteur command.edit=Ouvrir la page dans l'\u00E9diteur command.preview.label=Choisir un fichier +command.remove=Enlever la page createLink=Cr\u00E9er un fichier error.deleted=Le fichier configur\u00E9 n'existe pas. Cr\u00E9er \u00E0 nouveau le fichier ou choisissez un autre fichier. error.name.empty=S'il vous pla\u00EEt entrez un nom de fichier diff --git a/src/main/java/org/olat/core/commons/services/analytics/ui/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/core/commons/services/analytics/ui/_i18n/LocalStrings_de.properties index 5224c875a21a1a8fd03af6029a3488e785712089..4a37012ef8f7bb4a057922d577a9eeb597f8f28f 100644 --- a/src/main/java/org/olat/core/commons/services/analytics/ui/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/core/commons/services/analytics/ui/_i18n/LocalStrings_de.properties @@ -7,6 +7,6 @@ analytics.privacy=Wir weisen Sie darauf hin, dass Sie als Betreiberin der Plattf analytics.disabled=Analytics Module nicht verwenden analytics.service=Analytics Service -analytics.google.title=Google Analytics Koniguration +analytics.google.title=Google Analytics Konfiguration analytics.google.desc=Wenn Sie ein Google Analytics Konto besitzen können Sie hier die Google Tracking ID eingeben um detaillierte statistische und real-time Auswertungen über die Nutzung Ihrer OpenOLAT Installation zu erhalten. analytics.google.tracking.id=Tracking ID diff --git a/src/main/java/org/olat/core/commons/services/analytics/ui/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/core/commons/services/analytics/ui/_i18n/LocalStrings_fr.properties new file mode 100644 index 0000000000000000000000000000000000000000..1d9492b58bc2ab2ee824eddf81b6c29208b4bbad --- /dev/null +++ b/src/main/java/org/olat/core/commons/services/analytics/ui/_i18n/LocalStrings_fr.properties @@ -0,0 +1,11 @@ +#Thu Feb 01 21:22:39 CET 2018 +admin.menu.title=Analyse d'audience +admin.menu.title.alt=Analyse du comportement des utilisateurs +analytics.desc=Choisissez un des services d'analyses optionnels pour confier l'\u00E9valuation du comportement des utilisateurs \u00E0 un service externe. +analytics.disabled=Le module d'analyse d'audience est d\u00E9sactiv\u00E9. +analytics.google.desc=Si vous poss\u00E9dez un compte Google Analytics, vous pouvez entrer ici votre Google Tracking ID pour g\u00E9n\u00E9rer et observer en temps r\u00E9el des statistiques d\u00E9taill\u00E9es sur la mani\u00E8re dont votre installation OpenOLAT est utilis\u00E9e. +analytics.google.title=Configuration Google Analytics +analytics.google.tracking.id=Tracking ID +analytics.privacy=Nous vous rendons attentif au fait qu'en tant qu'op\u00E9rateur de la plateforme vous devez vous engag\u00E9 \u00E0 informer vos utilisateurs de l'emploi de services d'analyse d'audience. +analytics.service=Service d'analyses +analytics.title=Module d'analyse d'audience diff --git a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/_i18n/LocalStrings_fr.properties index 80a582678cd31e2e1f0ffa1256f4063f9a5e2d0a..e9907cb59f605888ef0b94e8ad296c596acd67e5 100644 --- a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/_i18n/LocalStrings_fr.properties +++ b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/_i18n/LocalStrings_fr.properties @@ -1,4 +1,4 @@ -#Wed Sep 14 18:05:16 CEST 2016 +#Thu Feb 01 18:31:27 CET 2018 confirm.delete.file=Voulez-vous vraiment effacer ce fichier? confirm.delete.file.title=Effacer un fichier day.short.di=Mar @@ -27,6 +27,7 @@ month.long.mar=Mars month.long.nov=Novembre month.long.oct=Octobre month.long.sep=Septembre +selection.no.value=- text.element.error.maxvalue=valeur maximale autoris\u00E9e\: {0}. text.element.error.minvalue=valeur minimale autoris\u00E9e\: {0}. text.element.error.notlongerthan=max. {0} signes autoris\u00E9s. diff --git a/src/main/java/org/olat/core/util/i18n/ui/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/core/util/i18n/ui/_i18n/LocalStrings_fr.properties index 8bb1f8b2c6bae191824ff6f9dd1fcfe09cec61b6..358a94faebc35870b6cc855e9218bc616153b261 100644 --- a/src/main/java/org/olat/core/util/i18n/ui/_i18n/LocalStrings_fr.properties +++ b/src/main/java/org/olat/core/util/i18n/ui/_i18n/LocalStrings_fr.properties @@ -1,4 +1,4 @@ -#Sat Oct 26 20:39:05 CEST 2013 +#Thu Feb 01 18:32:11 CET 2018 cache.disabled=La m\u00E9moire cache de traduction n'est pas activ\u00E9. Ce r\u00E9glage doit \u00EAtre effectu\u00E9 dans le fichier olat.properties . Nous recommandons d'activer la m\u00E9moire cache. cache.flush=Effacer m\u00E9moire cache cache.flush.ok=La m\u00E9moire cache a \u00E9t\u00E9 vid\u00E9e. @@ -83,6 +83,7 @@ edit.crumb.link=Cl\u00E9 de traduction edit.customize.crumb.hoover=Formulaire pour la traduction d'une cl\u00E9 de traduction edit.customize.intro=Copiez ce terme depuis la langue vers l'adaptation et modifiez le terme selon vos souhaits. Vous pouvez \u00E9galement sauter le terme et l'adapter plus t\u00E2rd. Affichez la langue de comparaison, pour v\u00E9rifier vos modifications dans une autre langue. edit.customize.target.hover=Cliquez dans le champ d'entr\u00E9e pour adapter cette cl\u00E9. +edit.error.invalid.item=La traduction n'est pas valide\: {0} edit.error.noitem=Aucune cl\u00E9 de traduction n'a \u00E9t\u00E9 trouv\u00E9e. Retournez \u00E0 l'aper\u00E7u et r\u00E9essayez. edit.intro=Traduisez le terme depuis la langue de r\u00E9f\u00E9rence dans la langue cible. Vous pouvez aussi sauter le terme et traduire plus tard. Afficher la langue de comparaison pour v\u00E9rifier votre traduction dans une autre langue. edit.progressBar.unitLabel=Cl\u00E9 de traduction diff --git a/src/main/java/org/olat/core/util/mail/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/core/util/mail/_i18n/LocalStrings_fr.properties index fe159d3a2ef9ad104283153804b86226d25f4371..16133e4503f5b8896d0d2632d8539a136021751f 100644 --- a/src/main/java/org/olat/core/util/mail/_i18n/LocalStrings_fr.properties +++ b/src/main/java/org/olat/core/util/mail/_i18n/LocalStrings_fr.properties @@ -1,6 +1,7 @@ -#Thu Nov 16 16:54:08 CET 2017 +#Thu Feb 01 18:31:51 CET 2018 add.email=Ajouter contact.cp.from=Copie \u00E0 l'exp\u00E9diteur +error.too.long=Le mod\u00E8le est trop grand. La taille maximale est {0}\! footer.no.userdata=<p>Ce message a \u00E9t\u00E9 envoy\u00E9 automatiquement via la plateforme d'apprentissage OpenOLAT\: {0}</p> footer.with.userdata=<p>Exp\u00E9diteur\: {2} {3} ({0}), {4} {5}</p><p>Ce message a \u00E9t\u00E9 envoy\u00E9 via la plateforme d'apprentissage OpenOLAT\: {1}</p> mail.action.emtpy=S\u00E9lectionnez au moins une adresse e-mail pour d\u00E9clencher un effet. diff --git a/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_fr.properties index ba0d9054ac59ac49b44eb2616d11c4be9f74778e..606435ac57e548d578c8b92ca34d51466e6bd58e 100644 --- a/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_fr.properties +++ b/src/main/java/org/olat/course/archiver/_i18n/LocalStrings_fr.properties @@ -1,4 +1,4 @@ -#Thu Jun 08 21:24:36 CEST 2017 +#Thu Feb 01 18:33:31 CET 2018 checklist=Listes de contr\u00F4le cl=Listes de contr\u00F4le cmd.download=T\u00E9l\u00E9charger @@ -81,6 +81,7 @@ menu.scorm.alt=R\u00E9sultats SCORM menu.wikis=Wikis menu.wikis.alt=Archiver Wikis nodechoose.config.error=Choisissez s'il vous pla\u00EEt au moins une option. +nodechoose.intro.checklist=S\u00E9lectionner un \u00E9l\u00E9ment de cours pour archiver les r\u00E9sultats des listes de contr\u00F4les. nodechoose.intro.cl=S\u00E9lectionnez avec le dialogue suivant l'\u00E9l\u00E9ment de cours liste de contr\u00F4le que vous souhaitez \u00E9valuer. nodechoose.intro.config=L'archive contient\: tous les utilisateurs et toutes les questions. Modifier les options de t\u00E9l\u00E9chargement avec le bouton ci-dessus. nodechoose.intro.dialog=S\u00E9lectionnez un \u00E9l\u00E9ment de cours pour archiver ses discussions de fichiers. diff --git a/src/main/java/org/olat/course/assessment/ui/tool/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/course/assessment/ui/tool/_i18n/LocalStrings_fr.properties index f5a95e73dd7337121b992f848600cf560fa468ea..3af226a6afb6bf67de966391e85df56e9f90b999 100644 --- a/src/main/java/org/olat/course/assessment/ui/tool/_i18n/LocalStrings_fr.properties +++ b/src/main/java/org/olat/course/assessment/ui/tool/_i18n/LocalStrings_fr.properties @@ -1,4 +1,6 @@ -#Thu Jun 08 21:28:13 CEST 2017 +#Fri Feb 02 08:43:36 CET 2018 +assessment.mode.now=Le mode d'\u00E9valuation est actif. +assessment.modes.overview=Mode d'\u00E9valuation assessment.status.done=$org.olat.modules.assessment.ui\:assessment.status.done assessment.status.inProgress=$org.olat.modules.assessment.ui\:assessment.status.inProgress assessment.status.inReview=$org.olat.modules.assessment.ui\:assessment.status.inReview @@ -41,11 +43,14 @@ overview=Aper\u00E7u participantgroups.title=Participant des groupes previous=Retour reopen=$org.olat.modules.assessment.ui\:reopen +reset.attempts=R\u00E9initialiser le nombre de tentatives +reset.attempts.explanation=Ce test a \u00E9t\u00E9 termin\u00E9. Vous pouvez r\u00E9initialiser le nombre de tentatives. Le participant au test recommencera le test depuis le d\u00E9but. Exception faite si vous avez r\u00E9ouvert le test avec la fonction "R\u00E9ouvrir un test d\u00E9j\u00E0 termin\u00E9". Dans ce cas, l'utilisateur pourra reprendre l\u00E0 o\u00F9 il s'est arr\u00EAt\u00E9.<br>Le nombre de tentatives sera mis \u00E0 z\u00E9ro. Les donn\u00E9es de tentatives pr\u00E9c\u00E9dentes resteront sauv\u00E9es de mani\u00E8re ind\u00E9pendantes des nouvelles tentatives. save.done=$org.olat.modules.assessment.ui\:save.done statistics.small.overview=$org.olat.modules.assessment.ui\:statistics.small.overview sub.details=D\u00E9tails table.entries=Entr\u00E9es table.header.assessmentStatus=$org.olat.modules.assessment.ui\:table.header.assessmentStatus +table.header.completion=$org.olat.modules.assessment.ui\:table.header.completion table.header.description=Description table.header.elements.toReview=El\u00E9ment table.header.group.name=Noms @@ -63,6 +68,12 @@ table.header.tools=$org.olat.modules.assessment.ui\:table.header.tools table.header.userVisibility=<i class\='o_icon o_icon-fw o_icon_results_hidden'> </i> title.infocoach=Informations sur l'\u00E9valuation tool.correction=Corriger +tool.details=Montrer les d\u00E9tails / \u00E9valuer +tool.reopen=R\u00E9ouvrir l'\u00E9valuation +tool.reset.attempts=R\u00E9initialiser le nombre de tentatives +tool.set.done=Mettre le status "clos" +tool.set.not.visible=Rendre les r\u00E9sultats non visibles +tool.set.visible=Rendre les r\u00E9sultats visibles tooltip.of={0} \u00E0 {1} user.visibility=R\u00E9sultats user.visibility.hidden=pas encore visible pour les utilisateurs diff --git a/src/main/java/org/olat/course/editor/CourseAccessAndProperties.java b/src/main/java/org/olat/course/editor/CourseAccessAndProperties.java index 748088e412c573a7a332ab6ca0ccc227efc16652..39f4d5c76bbb07a3f563ba7d5b0bce38a7b6baf7 100644 --- a/src/main/java/org/olat/course/editor/CourseAccessAndProperties.java +++ b/src/main/java/org/olat/course/editor/CourseAccessAndProperties.java @@ -37,6 +37,7 @@ public class CourseAccessAndProperties { private boolean canCopy; private boolean canReference; private boolean canDownload; + private Boolean confirmationEmail; private List<OfferAccess> offerAccess; private List<OfferAccess> deletedOfferAccess; @@ -127,4 +128,12 @@ public class CourseAccessAndProperties { public void setCanDownload(boolean canDownload) { this.canDownload = canDownload; } + + public Boolean getConfirmationEmail() { + return confirmationEmail; + } + + public void setConfirmationEmail(Boolean confirmationEmail) { + this.confirmationEmail = confirmationEmail; + } } \ No newline at end of file diff --git a/src/main/java/org/olat/course/editor/PublishProcess.java b/src/main/java/org/olat/course/editor/PublishProcess.java index 0b59b5c73ec586317f8e6f6853630fac2068feb1..6446b40e37c282a3c81e95273330403b32560331 100644 --- a/src/main/java/org/olat/course/editor/PublishProcess.java +++ b/src/main/java/org/olat/course/editor/PublishProcess.java @@ -80,6 +80,7 @@ import org.olat.repository.controllers.EntryChangedEvent; import org.olat.repository.controllers.EntryChangedEvent.Change; import org.olat.repository.manager.CatalogManager; import org.olat.resource.accesscontrol.ACService; +import org.olat.resource.accesscontrol.Offer; import org.olat.resource.accesscontrol.OfferAccess; import org.olat.resource.references.Reference; import org.olat.resource.references.ReferenceManager; @@ -700,7 +701,7 @@ public class PublishProcess { return publishTreeModel; } - public void changeGeneralAccess(Identity author, int access, boolean membersOnly){ + public void changeGeneralAccess(Identity author, int access, boolean membersOnly) { RepositoryManager.getInstance().setAccess(repositoryEntry, access, membersOnly); MultiUserEvent modifiedEvent = new EntryChangedEvent(repositoryEntry, author, Change.modifiedAtPublish, "publish"); CoordinatorManager.getInstance().getCoordinator().getEventBus().fireEventToListenersOf(modifiedEvent, repositoryEntry); @@ -718,6 +719,16 @@ public class PublishProcess { // 1: add new and update existing offerings ACService acService = CoreSpringFactory.getImpl(ACService.class); for (OfferAccess newLink : offerAccess) { + if(accessAndProps.getConfirmationEmail() != null) { + Offer offer = newLink.getOffer(); + boolean confirmation = accessAndProps.getConfirmationEmail().booleanValue(); + if(offer.isConfirmationEmail() != confirmation) { + offer.setConfirmationEmail(confirmation); + if(offer.getKey() != null) { + offer = acService.save(offer); + } + } + } acService.saveOfferAccess(newLink); } // 2: remove offerings not available anymore @@ -777,6 +788,7 @@ public class PublishProcess { this.skippableNodes = new ArrayList<CourseEditorTreeNode>(); } + @Override public void visit(INode node) { /* * DO NOT add or delete nodes via editorTreeModel, ..................... @@ -787,10 +799,10 @@ public class PublishProcess { // root node changed and published CourseNode clone = (CourseNode)XStreamHelper.xstreamClone(cetn.getCourseNode()); resultingCourseRun.setRootNode(clone); - editorModelModifiedNodes.add(cetn);// TODO:pb: Review Change to fic OLAT-1644 + editorModelModifiedNodes.add(cetn); return; } - if (cetn == root) { // TODO:pb: Review Change to fix OLAT-1644 + if (cetn == root) { // root node CourseNode clone = (CourseNode)XStreamHelper.xstreamClone(cetn.getCourseNode()); resultingCourseRun.setRootNode(clone); @@ -818,7 +830,6 @@ public class PublishProcess { // already published, add it as it is. Silent "re-publish" addNodeTo(resultingCourseRun, cetn); } else { - // TODO:pb:REVIEW Change to fix OLAT-1644 // changed in edit but not published => take old from existingRun addNodeTo(resultingCourseRun, existingRun.getNode(cetn.getIdent()), cetn); } @@ -908,7 +919,6 @@ public class PublishProcess { parentClone.addChild(clone); } - // TODO:pb:REVIEW Change to fix OLAT-1644 /** * @param newRunStruct * @param cetn @@ -926,19 +936,15 @@ public class PublishProcess { /** * flat list of all CourseEditorTreeNodes starting from root * - * @param root + * @param treeNode * @param rootNodeWithSubtree */ - private void collectSubTreeNodesStartingFrom(CourseEditorTreeNode root, List<CourseEditorTreeNode> rootNodeWithSubtree) { - for (int i = 0; i < root.getChildCount(); i++) { - CourseEditorTreeNode node = (CourseEditorTreeNode)root.getChildAt(i); + private void collectSubTreeNodesStartingFrom(CourseEditorTreeNode treeNode, List<CourseEditorTreeNode> rootNodeWithSubtree) { + for (int i = 0; i < treeNode.getChildCount(); i++) { + CourseEditorTreeNode node = (CourseEditorTreeNode)treeNode.getChildAt(i); rootNodeWithSubtree.add(node); collectSubTreeNodesStartingFrom(node, rootNodeWithSubtree); } } }// end nested class - - - - } diff --git a/src/main/java/org/olat/course/editor/PublishStep01AccessForm.java b/src/main/java/org/olat/course/editor/PublishStep01AccessForm.java index 5f92779af49c5e841f17edeea65cf98819bf1239..71014ca9b89b27cfb8c3bfba3ffca37950fc214d 100644 --- a/src/main/java/org/olat/course/editor/PublishStep01AccessForm.java +++ b/src/main/java/org/olat/course/editor/PublishStep01AccessForm.java @@ -28,6 +28,7 @@ import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.form.flexible.FormItem; import org.olat.core.gui.components.form.flexible.FormItemContainer; import org.olat.core.gui.components.form.flexible.elements.FormLink; +import org.olat.core.gui.components.form.flexible.elements.MultipleSelectionElement; import org.olat.core.gui.components.form.flexible.elements.SelectionElement; import org.olat.core.gui.components.form.flexible.elements.SingleSelection; import org.olat.core.gui.components.form.flexible.impl.Form; @@ -82,6 +83,8 @@ public class PublishStep01AccessForm extends StepFormBasicController { RepositoryEntryAllowToLeaveOptions.never.name() }; + private static final String[] onKeys = new String[] { "on" }; + private SingleSelection leaveEl; private RepositoryEntry entry; @@ -104,7 +107,7 @@ public class PublishStep01AccessForm extends StepFormBasicController { private static final String MEMBERSONLY_KEY = "m"; private String[] publishedKeys; - + private MultipleSelectionElement confirmationEmailEl; private List<FormLink> addMethods = new ArrayList<>(); private List<OfferAccess> offerAccess = new ArrayList<>(); private List<OfferAccess> deletedOfferAccess = new ArrayList<>(); @@ -171,6 +174,11 @@ public class PublishStep01AccessForm extends StepFormBasicController { accessProperties.setOfferAccess(offerAccess); accessProperties.setDeletedOfferAccess(deletedOfferAccess); + if(confirmationEmailEl.isVisible()) { + accessProperties.setConfirmationEmail(confirmationEmailEl.isAtLeastSelected(1)); + } else { + accessProperties.setConfirmationEmail(null); + } addToRunContext("accessAndProperties", accessProperties); @@ -310,12 +318,25 @@ public class PublishStep01AccessForm extends StepFormBasicController { accessLayout.contextPut("methods", addMethods); } + String[] onValues = new String[] { "" }; + confirmationEmailEl = uifactory.addCheckboxesHorizontal("confirmation.email", accessLayout, onKeys, onValues); + confirmationEmailEl.addActionListener(FormEvent.ONCHANGE); + confirmationEmailEl.setVisible(false); + String confPage = velocity_root + "/configuration_list.html"; confControllerContainer = FormLayoutContainer.createCustomFormLayout("conf-controllers", getTranslator(), confPage); accessLayout.add(confControllerContainer); loadConfigurations(); + boolean confirmationEmail = false; + for(AccessInfo info:confControllers) { + confirmationEmail |= info.getLink().getOffer().isConfirmationEmail(); + } + if(confirmationEmail) { + confirmationEmailEl.select(onKeys[0], true); + } + confControllerContainer.contextPut("confControllers", confControllers); confControllerContainer.contextPut("emptyConfigGrantsFullAccess", Boolean.valueOf(emptyConfigGrantsFullAccess)); @@ -351,6 +372,14 @@ public class PublishStep01AccessForm extends StepFormBasicController { delLink.setIconLeftCSS("o_icon o_icon-fw o_icon_delete_item"); confControllerContainer.add(delLink.getName(), delLink); } + updateConfirmationEmail(); + } + + private void updateConfirmationEmail() { + if(confirmationEmailEl.isVisible() != !confControllers.isEmpty()) { + confirmationEmailEl.setVisible(!confControllers.isEmpty()); + accessLayout.setDirty(true); + } } public class AccessInfo { @@ -504,6 +533,12 @@ public class PublishStep01AccessForm extends StepFormBasicController { } else if(addMethods.contains(source)) { AccessMethod method = (AccessMethod)source.getUserObject(); addMethod(ureq, method); + } else if(confirmationEmailEl == source) { + for(AccessInfo info:confControllers) { + if(!offerAccess.contains(info.getLink())) { + offerAccess.add(info.getLink()); + } + } } else if (source instanceof FormLink) { FormLink button = (FormLink)source; String cmd = button.getCmd(); @@ -515,6 +550,7 @@ public class PublishStep01AccessForm extends StepFormBasicController { deletedOfferAccess.add(deleteOffer); } confControllers.remove(infos); + updateConfirmationEmail(); fireEvent(ureq, Event.CHANGED_EVENT); } else if("edit".equals(cmd)) { AccessInfo infos = (AccessInfo)source.getUserObject(); diff --git a/src/main/java/org/olat/course/editor/_content/access_configuration.html b/src/main/java/org/olat/course/editor/_content/access_configuration.html index 0047566062bd6fad59505d6ed0513823ae76a52a..e530afecc3a5027d9e48c322bb1a87186aaa6bae 100644 --- a/src/main/java/org/olat/course/editor/_content/access_configuration.html +++ b/src/main/java/org/olat/course/editor/_content/access_configuration.html @@ -12,6 +12,12 @@ #if ($off_info) <div class="o_info">$off_info</div> #end </div></div> #end + #if($r.visible("confirmation.email")) + <div class="form-group"> + <label class="control-label col-sm-3">$r.translate("confirmation.email")</label> + <div class="col-sm-9">$r.render("confirmation.email")</div> + </div> + #end <div class="form-group"> <label class="control-label col-sm-3">$r.translate("ac.methods.label") $r.render("acMethodsLabelHelp")</label> <div class="col-sm-9">$r.render("conf-controllers")</div> diff --git a/src/main/java/org/olat/course/groupsandrights/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/course/groupsandrights/_i18n/LocalStrings_fr.properties index 18a213153129e25f0a8ea3c8216a254893b7ed81..98c2545654f9a0d6d45979c7f694565e3c42ce75 100644 --- a/src/main/java/org/olat/course/groupsandrights/_i18n/LocalStrings_fr.properties +++ b/src/main/java/org/olat/course/groupsandrights/_i18n/LocalStrings_fr.properties @@ -1,26 +1,20 @@ -#Sat Jun 06 12:03:17 CEST 2015 +#Thu Feb 01 18:35:11 CET 2018 add.all=Ajouter toutes les permissions bgr.archive=Archivage des donn\u00E9es bgr.assess=Outil d'\u00E9valuation +bgr.assessmode=Mode d'\u00E9valuation bgr.dbs=Base de donn\u00E9e du cours bgr.editor=Editeur de cours bgr.glossary=Outil glossaire bgr.groupmngt=Gestion de groupes bgr.membermngt=Gestion des membres bgr.statistics=Statistiques - - - - - - - - - menu.rights=Permissions noRestriction=Aucune restriction participant=Participants remove.all=Effacer toutes les permissions +repo.participant=Participant du cours +repo.tutor=Coach du cours table.header.groups=Groupe table.header.remove=Effacer table.header.role=R\u00F4les diff --git a/src/main/java/org/olat/course/nodes/cl/ui/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/course/nodes/cl/ui/_i18n/LocalStrings_en.properties index b4e906e64aa31ffab93792048bef03764b7bba37..8a61a79d76e83e3976e52889e8437dd42f441fba 100644 --- a/src/main/java/org/olat/course/nodes/cl/ui/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/course/nodes/cl/ui/_i18n/LocalStrings_en.properties @@ -1,4 +1,4 @@ -#Tue Dec 16 09:04:07 CET 2014 +#Tue Feb 06 08:33:13 CET 2018 add.checkbox=Add checkbox assessment=Assessment assessment.checkbox.description=Edit per Checkbox\: Apply the checkbox filter to edit the same checkbox across all participants. @@ -19,6 +19,7 @@ column.header.homepage=Home page column.header.node.passed=Passed course element column.header.node.points=Score course element column.header.points=$\:box.points +column.header.seqnum=Sequence number comment.nocomment=$org.olat.course.nodes.ms\:comment.nocomment comment.title=$org.olat.course.nodes.ms\:comment.title condition.accessibility.title=Access @@ -49,10 +50,10 @@ down=Down edit.checkbox=Edit checkbox file=File filter.all=Show all -form.individual.assessment.docs=$org.olat.course.nodes.ms\:form.individual.assessment.docs form.error.date=A date must be indicated. form.error.scoreOutOfRange=$org.olat.course.assessment\:form.error.scoreOutOfRange form.error.wrongFloat=$org.olat.course.nodes.ms\:form.error.wrongFloat +form.individual.assessment.docs=$org.olat.course.nodes.ms\:form.individual.assessment.docs info.title=$org.olat.course.nodes.ms\:info.title label=Label label.achieved=Achieved diff --git a/src/main/java/org/olat/course/nodes/cl/ui/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/course/nodes/cl/ui/_i18n/LocalStrings_fr.properties index ba3aeee3911c408f20526a78ce8165e6d9445973..ce13b9ffb40af650a7643cf3fcb43933eacd9dbe 100644 --- a/src/main/java/org/olat/course/nodes/cl/ui/_i18n/LocalStrings_fr.properties +++ b/src/main/java/org/olat/course/nodes/cl/ui/_i18n/LocalStrings_fr.properties @@ -1,4 +1,4 @@ -#Thu Jun 08 20:30:59 CEST 2017 +#Thu Feb 01 22:07:04 CET 2018 add.checkbox=Ajouter une case \u00E0 cocher assessment=Evaluation assessment.checkbox.description=Modifier en fonction de la case \u00E0 cocher\: modifier la case \u00E0 cocher s\u00E9lectionner gr\u00E2ce au filtre de tous les participants. @@ -19,6 +19,7 @@ column.header.homepage=Page d'accueil column.header.node.passed=Element de cours r\u00E9ussi column.header.node.points=Points \u00E9l\u00E9ment de cours column.header.points=$\:box.points +column.header.seqnum=Num\u00E9ro comment.nocomment=$org.olat.course.nodes.ms\:comment.nocomment comment.title=$org.olat.course.nodes.ms\:comment.title condition.accessibility.title=Acc\u00E8s diff --git a/src/main/java/org/olat/course/nodes/gta/ui/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/course/nodes/gta/ui/_i18n/LocalStrings_de.properties index b842bd7174c98a9339eb74096d7e76eeaf82c37f..076a5029320b00182806646f2a5eae48249f08c4 100644 --- a/src/main/java/org/olat/course/nodes/gta/ui/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/course/nodes/gta/ui/_i18n/LocalStrings_de.properties @@ -20,7 +20,7 @@ choosed.areas=Lernbereich choosed.groups=Gruppe coach.assessment=Bewerten coach.back.to.submission=Abgabe erneut \u00F6ffnen -coach.back.to.submission.confirm.text=Sind Sie sicher dass Sie die Abgabe f\u00FCr "{0}" nochmals \u00F6ffnen m\u00F6chten? +coach.back.to.submission.confirm.text=Sind Sie sicher dass Sie die Abgabe f\u00FCr "{0}" nochmals \u00F6ffnen m\u00F6chten? Es werden dabei <strong>alle bereits eingereichten Dokumente</strong> gelöscht. Trotzdem weiterfahren? coach.back.to.submission.confirm.title=Abgabe erneut \u00F6ffnen coach.back.to.submission.desc=Hat der Teilnehmer versehentlich die endg\u00FCltige Abgabe ausgel\u00F6st, so kann mit dieser Aktion der Status auf "nicht abgegeben" zur\u00FCckgesetzt werden. coach.close.revision.button=Revision akzeptieren diff --git a/src/main/java/org/olat/course/nodes/gta/ui/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/course/nodes/gta/ui/_i18n/LocalStrings_en.properties index deffbd7ccb857dad7f81fe0e1f89352896c88f99..8ae8cc57914fc80d73a417e4894e4d90758987da 100644 --- a/src/main/java/org/olat/course/nodes/gta/ui/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/course/nodes/gta/ui/_i18n/LocalStrings_en.properties @@ -20,7 +20,7 @@ choosed.areas=Areas choosed.groups=Groups coach.assessment=Grade coach.back.to.submission=Reopen submission -coach.back.to.submission.confirm.text=Are you sure you wish to re-open the task submission for "{0}"? +coach.back.to.submission.confirm.text=Are you sure you wish to re-open the task submission for "{0}"? It will <strong>delete all submitted documents</strong>. coach.back.to.submission.confirm.title=Reopen submission coach.back.to.submission.desc=This action allows you to reset the submission status if a participant has submitted by accident. coach.close.revision.button=Accept revision diff --git a/src/main/java/org/olat/course/nodes/gta/ui/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/course/nodes/gta/ui/_i18n/LocalStrings_fr.properties index 5e3a955559751b351c84117ed59dbd6c58d20bcd..2de55d638f9c177ada7b5af5cc62b3c47af070dd 100644 --- a/src/main/java/org/olat/course/nodes/gta/ui/_i18n/LocalStrings_fr.properties +++ b/src/main/java/org/olat/course/nodes/gta/ui/_i18n/LocalStrings_fr.properties @@ -20,7 +20,7 @@ choosed.areas=Domaines d'\u00E9tudes choosed.groups=Groupes coach.assessment=Evaluer coach.back.to.submission=R\u00E9ouvrir la soumission -coach.back.to.submission.confirm.text=Etes-vous s\u00FBr de rouvrirez la soumission du devoir pour "{0}"? +coach.back.to.submission.confirm.text=Etes-vous s\u00FBr de rouvrirez la soumission du devoir pour "{0}"? Tous les documents déjà téléchargés seront <strong>effacés</strong>. coach.back.to.submission.confirm.title=R\u00E9ouvrir le d\u00E9p\u00F4t coach.back.to.submission.desc=Cette action permet d'annuler le d\u00E9p\u00F4t d'un devoir qu'un participant aurait involontairement rendu. coach.close.revision.button=Terminer le processus de r\u00E9vision diff --git a/src/main/java/org/olat/course/nodes/iq/QTI21AssessmentRunController.java b/src/main/java/org/olat/course/nodes/iq/QTI21AssessmentRunController.java index d6b0534c3b1487ccb47f0e09f10662ba961d8485..b46cea2ceeb8a3e77d5ef347ef31e51dcfbbbd45 100644 --- a/src/main/java/org/olat/course/nodes/iq/QTI21AssessmentRunController.java +++ b/src/main/java/org/olat/course/nodes/iq/QTI21AssessmentRunController.java @@ -42,7 +42,9 @@ import org.olat.core.gui.control.generic.iframe.IFrameDisplayController; import org.olat.core.gui.media.MediaResource; import org.olat.core.gui.media.NotFoundMediaResource; import org.olat.core.gui.translator.Translator; +import org.olat.core.id.Identity; import org.olat.core.id.OLATResourceable; +import org.olat.core.id.UserConstants; import org.olat.core.logging.activity.ThreadLocalUserActivityLogger; import org.olat.core.util.Formatter; import org.olat.core.util.StringHelper; @@ -785,7 +787,8 @@ public class QTI21AssessmentRunController extends BasicController implements Gen CourseEnvironment courseEnv, CourseNode courseNode, RepositoryEntry testEntry, Date timestamp, Locale locale) { MailBundle bundle = new MailBundle(); bundle.setToId(candidateSession.getIdentity()); - String fullname = CoreSpringFactory.getImpl(UserManager.class).getUserDisplayName(candidateSession.getIdentity()); + Identity assessedIdentity = candidateSession.getIdentity(); + String fullname = CoreSpringFactory.getImpl(UserManager.class).getUserDisplayName(assessedIdentity); Date assessedDate = candidateSession.getFinishTime() == null ? timestamp : candidateSession.getFinishTime(); String[] args = new String[] { @@ -796,7 +799,12 @@ public class QTI21AssessmentRunController extends BasicController implements Gen testEntry.getDisplayname(), // {4} fullname, // {5} Formatter.getInstance(locale) - .formatDateAndTime(assessedDate) // {6} + .formatDateAndTime(assessedDate), // {6} + assessedIdentity.getName(), // {7} + assessedIdentity.getUser() + .getProperty(UserConstants.INSTITUTIONALUSERIDENTIFIER, locale), // {8} + assessedIdentity.getUser() + .getProperty(UserConstants.INSTITUTIONALNAME, locale), // {9} }; Translator translator = Util.createPackageTranslator(QTI21AssessmentRunController.class, locale); diff --git a/src/main/java/org/olat/course/nodes/iq/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/course/nodes/iq/_i18n/LocalStrings_en.properties index 0a8e8e7f86489c13239170d6b2803ea30766c634..74d209896ebe2d1b637360aaa47f755824b4833e 100644 --- a/src/main/java/org/olat/course/nodes/iq/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/course/nodes/iq/_i18n/LocalStrings_en.properties @@ -1,11 +1,13 @@ -#Thu Dec 07 19:14:06 CET 2017 -allowRelativeLinks=Allow links in the entire storage folder. +#Tue Feb 06 08:34:50 CET 2018 Intro.self=Press the start button to begin with your self-test. Intro.surv=Press the start button to begin with your questionnaire. Intro.test=Press the start button to begin with your test. +allowRelativeLinks=Allow links in the entire storage folder. assessment.documents.title=Assessment documents attempts.nomoreattempts=There are no more attempts at your disposal. attempts.yourattempts=Number of attempts +block.dates.start=You will be able to start the test at <strong>{0}</strong>. +block.dates.start.end=The test can be started between the <strong>{0}</strong> and the <strong>{1}</strong>. button.export=Export results button.stats=$org.olat.ims.qti.statistics.ui\:menu.title changelog.title=Resource change log @@ -181,10 +183,11 @@ table.header.extra.time=Extra table.header.lastModified=Last modified table.header.results=Results time.limit.max=Time limit +time.limit.test.explain=The test takes a maximum of <strong>{0}</strong>. tool.delete.data=Reset all data tool.extra.time=Extend test time tool.pull=Pull running test -warning.assessment.mode=Test in process: +warning.assessment.mode=Test in process\: warning.assessment.mode.date={0} from {1} til {2} warning.test.with.essay=$org.olat.ims.qti.editor\:warning.test.with.essay warning.users.extra.time=You need to select a least one user which test can be prolonged. diff --git a/src/main/java/org/olat/course/nodes/iq/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/course/nodes/iq/_i18n/LocalStrings_fr.properties index 8e1da36c37156d2fe36363a5f8da91ef7b06fc88..e0f18af4d5fef780c3bea83d8d943c8b22c0ad64 100644 --- a/src/main/java/org/olat/course/nodes/iq/_i18n/LocalStrings_fr.properties +++ b/src/main/java/org/olat/course/nodes/iq/_i18n/LocalStrings_fr.properties @@ -1,11 +1,15 @@ -#Thu Jul 06 20:47:43 CEST 2017 -allowRelativeLinks=Permettre la cr\u00E9ation de liens dans tout le dossier de stockage +#Fri Feb 02 08:45:52 CET 2018 Intro.self=Pressez sur D\u00E9marrer pour commencer l'auto-test. Intro.surv=Pressez sur D\u00E9marrer pour commencer avec le questionnaire. Intro.test=Pressez sur D\u00E9marrer pour commencer le test. +allowRelativeLinks=Permettre la cr\u00E9ation de liens dans tout le dossier de stockage assessment.documents.title=Documents d'\u00E9valuation attempts.nomoreattempts=Vous n'avez plus d'autres essais attempts.yourattempts=Nombre d'essais effectu\u00E9es +block.dates.start=Vous pourrez d\u00E9marrer le test le <strong>{0}</strong> +block.dates.start.end=Le test pourra \u00EAtre commencer entre le <strong>{0}</strong> et le <strong>{1}</strong>. +button.export=Exporter les r\u00E9sultats +button.stats=$org.olat.ims.qti.statistics.ui\:menu.title changelog.title=Historique des modifications de la ressource choosenfile.self=Auto-test choosenfile.surv=Questionnaire @@ -47,6 +51,7 @@ error.assessment.pulled=Le test a \u00E9t\u00E9 retir\u00E9 par votre coach. error.assessment.stopped=Le test est termin\u00E9. error.begin.after.end=La date de d\u00E9but doit se trouver avant la date de fin. error.entry.locked=La ressource d'\u00E9tude choisie est actuellement \u00E9dit\u00E9e par un utilisateur. Veuillez choisir une autre ressource d'\u00E9tude SVP. +error.reopean.failed=Le test n'a pas pu \u00EAtre r\u00E9ouvert. error.resource.corrupted=L'object didactique n'a pas pu \u00EAtre lu. Il semble soit corrompu soit au mauvais format. error.self.undefined.long=Aucun auto-test d\u00E9fini pour "{0}". Choisissez dans "Configuration auto-test". error.self.undefined.short=Aucun auto-test d\u00E9fini pour "{0}". @@ -54,6 +59,10 @@ error.surv.undefined.long=Aucun questionnaire d\u00E9fini pour "{0}". Choisissez error.surv.undefined.short=Aucun questionnaire d\u00E9fini pour "{0}". error.test.undefined.long=Aucun test d\u00E9fini pour "{0}". Choisissez dans "Configurez test". error.test.undefined.short=Aucun test d\u00E9fini pour "{0}". +extra.time=Prolonger +extra.time.explain.1=Prolonger le temps pour l'utilisateur "{0}" de +extra.time.explain.2=minutes. +extra.time.warning=<strong>Attention\:</strong> la p\u00E9riode du mode d'\u00E9valuation ne sera pas prolong\u00E9e. Le mode d'\u00E9valuation doit \u00EAtre prolonger dans le menu "Mode d'\u00E9valuation". fieldset.allowRelativeLinksForm=Param\u00E8tres de s\u00E9curit\u00E9 fieldset.chosecreateeditfile=Texte informatif (page html) file.name=Fichier choisi @@ -135,7 +144,13 @@ qti.form.summary.responses=R\u00E9ponse, soumise par le participant qti.form.summary.section=R\u00E9sum\u00E9 de section (sans solutions) qti.form.summary.sections=R\u00E9sum\u00E9 section qti.form.summary.solutions=Solution +qti.form.test.date=D\u00E9finir une p\u00E9riode de test +qti.form.test.date.confirm=Le test peut \u00EAtre commencer pendant la p\u00E9riode d\u00E9finie. D\u00E8s que la date de fin est atteinte, le test est automatiquement stopp\u00E9 quelque que soit la dur\u00E9e d\u00E9finie pour le test. +qti.form.test.date.help=$\:qti.form.test.date.confirm qti.form.test.title=Test +reopen=R\u00E9ouvrir +reopen.explanation=Ce test a \u00E9t\u00E9 termin\u00E9. Vous pouvez r\u00E9ouvrir le test \u00E0 de nouvelles tentatives. Le participant pourra reprendre le test l\u00E0 o\u00F9 il s'est arr\u00EAt\u00E9. Si le nombre de tentatives est limit\u00E9es, peut-\u00EAtre devrez-vous \u00E9galement r\u00E9initialis\u00E9e le nombre de tentatives pour qu'il puisse reprendre le test. +reopen.test=R\u00E9ouvrir un test d\u00E9j\u00E0 termin\u00E9 replace.wizard.information.empty.results=<b>Indication\: ce test/questionnaire a d\u00E9j\u00E0 \u00E9t\u00E9 lanc\u00E9 par {0} participant/s\!</b> Tous les r\u00E9sultats d\u00E9j\u00E0 existants seront effac\u00E9s si vous cliquez sur "Terminer"au prochain pas.<br></br><b>Publiez votre cours le plus t\u00F4t possible\!</b> Les participants pourront lancer le nouveau test/questionnaire et les r\u00E9sultats pourront \u00EAtre enregistr\u00E9s seulement apr\u00E8s la publication. replace.wizard.information.paragraph1=<b>Indication\: ce test/questionnaire a d\u00E9j\u00E0 \u00E9t\u00E9 lanc\u00E9 par {0} participant/s et partiellement termin\u00E9\!</b> Tous les r\u00E9sultats d\u00E9j\u00E0 existants seront archiv\u00E9s si vous cliquez sur "Terminer" au prochain pas.<br></br> Les r\u00E9sultats archiv\u00E9s peuvent \u00EAtre t\u00E9l\u00E9charg\u00E9s ici\:<br /> replace.wizard.information.paragraph2=Une copie de cette vue d'ensemble des r\u00E9sultats se trouve dans votre dossier personnel sous\:<br/><i>private/archive/{0}/{1}</i><br /><br /><b>Publiez votre cours le plus vite possible\!</b>Les participants pourront lancer le nouveau test/questionnaire et les r\u00E9sultats pourront \u00EAtre enregistr\u00E9s seulement apr\u00E8s la publication. @@ -146,7 +161,11 @@ replace.wizard.title=Remplacer test ou questionnaire replace.wizard.title.step1=S\u00E9lectionner une nouvelle ressource didactique replace.wizard.title.step2=Informations sur les r\u00E9sultats replace.wizard.title.step3=Informer utilisateur +report.config=Rapport reporter.unavailable=$de.bps.onyx.plugin.course.nodes.iq\:reporter.unavailable +reset.test.data.title=R\u00E9initialiser les donn\u00E9es du test +retrieve.tests.title=$org.olat.ims.qti.statistics.ui\:menu.pull.tests.title +retrievetest.confirm.text=$org.olat.ims.qti\:retrievetest.confirm.text score.cut=Points n\u00E9cessaires pour "R\u00E9ussi" score.max=Maximum de points score.min=Minimum de points @@ -159,7 +178,16 @@ showResults.title=R\u00E9sultats showResults.visibility=Les r\u00E9sultats seront affich\u00E9s de "{0}" \u00E0 "{1}". showResults.visibility.future=Vos r\u00E9sultats seront visibles ici d\u00E8s que la correction en sera termin\u00E9e. start=D\u00E9marrer +table.header.end.date=Date de fin +table.header.extra.time=Suppl\u00E9ment table.header.lastModified=Derni\u00E8re mise \u00E0 jour table.header.results=R\u00E9sultats time.limit.max=Limite de temps +time.limit.test.explain=Le test dure au plus <strong>{0}</strong>. +tool.delete.data=R\u00E9initialiser toutes les donn\u00E9es +tool.extra.time=Prolonger la dur\u00E9e du test +tool.pull=Reprendre un test en cours +warning.assessment.mode=La configuration d'examen suivante est active +warning.assessment.mode.date={0} de {1} \u00E0 {2} warning.test.with.essay=$org.olat.ims.qti.editor\:warning.test.with.essay +warning.users.extra.time=Vous devez s\u00E9lectionner un utilisateur dont vous pouvez prolonger le test. diff --git a/src/main/java/org/olat/group/manager/BusinessGroupMailing.java b/src/main/java/org/olat/group/manager/BusinessGroupMailing.java index 36d9c811f9fd4d78ed0e93c1e10323ad73ce5e95..4168d1e3a48f8560fb5747aeae3bc817bfd1ebbf 100644 --- a/src/main/java/org/olat/group/manager/BusinessGroupMailing.java +++ b/src/main/java/org/olat/group/manager/BusinessGroupMailing.java @@ -126,7 +126,12 @@ public class BusinessGroupMailing { MailTemplate template = mailing == null ? null : mailing.getTemplate(); if(mailing == null || mailing.getTemplate() == null) { - template = getDefaultTemplate(type, group, ureqIdentity); + //booking by myself + if(type != null && type == MailType.addParticipant && ureqIdentity != null && ureqIdentity.equals(identity)) { + template = BGMailHelper.createAddMyselfMailTemplate(group, ureqIdentity); + } else { + template = getDefaultTemplate(type, group, ureqIdentity); + } } else if(group != null && template.getContext() != null && needTemplateEnhancement(template)) { BusinessGroupService businessGroupService = CoreSpringFactory.getImpl(BusinessGroupService.class); List<RepositoryEntryShort> repoEntries = businessGroupService.findShortRepositoryEntries(Collections.singletonList(group), 0, -1); diff --git a/src/main/java/org/olat/group/ui/edit/BusinessGroupEditAccessController.java b/src/main/java/org/olat/group/ui/edit/BusinessGroupEditAccessController.java index 8c726fdf7b17349dd0d1ef8c6f17bd0dc85c9bce..2217d7905be61e614a7130e328a3a98c77810ebf 100644 --- a/src/main/java/org/olat/group/ui/edit/BusinessGroupEditAccessController.java +++ b/src/main/java/org/olat/group/ui/edit/BusinessGroupEditAccessController.java @@ -24,7 +24,6 @@ import org.olat.core.CoreSpringFactory; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.form.flexible.FormItemContainer; import org.olat.core.gui.components.form.flexible.impl.FormBasicController; -import org.olat.core.gui.components.form.flexible.impl.FormLayoutContainer; import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.Event; import org.olat.core.gui.control.WindowControl; @@ -38,7 +37,7 @@ import org.olat.resource.accesscontrol.ui.AccessConfigurationController; /** * * Description:<br> - * Add a check box to the standard access control controller + * Wrapper for the resource's access control. * * <P> * Initial Date: 26 avr. 2011 <br> @@ -75,22 +74,11 @@ public class BusinessGroupEditAccessController extends FormBasicController { setFormTitle("accesscontrol.title"); setFormDescription("accesscontrol_group.desc"); setFormContextHelp("Group Administration#gruppensystem_buchung_ag"); + formLayout.setElementCssClass("o_block_large_bottom"); if(configController != null) { formLayout.add(configController.getInitialFormItem()); } - - if(configController != null && !managed) { - uifactory.addSpacerElement("spacer1", formLayout, false); - } - - if(!managed) { - final FormLayoutContainer buttonGroupLayout = FormLayoutContainer.createButtonLayout("buttonLayout", getTranslator()); - buttonGroupLayout.setRootForm(mainForm); - formLayout.add(buttonGroupLayout); - - uifactory.addFormSubmitButton("save", formLayout); - } } public void updateBusinessGroup(BusinessGroup businessGroup) { @@ -109,10 +97,7 @@ public class BusinessGroupEditAccessController extends FormBasicController { @Override protected void formOK(UserRequest ureq) { - if(configController != null) { - configController.formOK(ureq); - } - fireEvent(ureq, Event.DONE_EVENT); + // } @Override diff --git a/src/main/java/org/olat/ims/qti21/QTI21Constants.java b/src/main/java/org/olat/ims/qti21/QTI21Constants.java index fea31daebedde21dc052b4fd6248bc55af5de1f2..644a91c5766bf6931624774cea89c75df7f6d797 100644 --- a/src/main/java/org/olat/ims/qti21/QTI21Constants.java +++ b/src/main/java/org/olat/ims/qti21/QTI21Constants.java @@ -149,6 +149,8 @@ public class QTI21Constants { public static final String CSS_MATCH_DRAG_AND_DROP = "match_dnd"; + public static final String CSS_MATCH_TRUE_FALSE = "match_true_false"; + public static final String CSS_MATCH_KPRIM = "match_krpim"; public static final String CSS_MATCH_SOURCE_TOP = "source-top"; diff --git a/src/main/java/org/olat/ims/qti21/QTI21DeliveryOptions.java b/src/main/java/org/olat/ims/qti21/QTI21DeliveryOptions.java index 745c9dde45c684c5b4be500da0a582659c5eb791..c7b5e0e969f3e34a38cc701da39b3bae6ea2ec63 100644 --- a/src/main/java/org/olat/ims/qti21/QTI21DeliveryOptions.java +++ b/src/main/java/org/olat/ims/qti21/QTI21DeliveryOptions.java @@ -227,7 +227,7 @@ public class QTI21DeliveryOptions { defaultSettings.displayScoreProgress = false; defaultSettings.displayQuestionProgress = false; defaultSettings.hideFeedbacks = false; - defaultSettings.hideLms = false; + defaultSettings.hideLms = true; defaultSettings.showMenu = true; defaultSettings.showTitles = true; defaultSettings.personalNotes = false; diff --git a/src/main/java/org/olat/ims/qti21/manager/openxml/QTI21WordExport.java b/src/main/java/org/olat/ims/qti21/manager/openxml/QTI21WordExport.java index ba5463fb300267ae8e29cda9aae7caa11b8bde48..5278a31c438d052cacbe7df7ea426adca9cc205f 100644 --- a/src/main/java/org/olat/ims/qti21/manager/openxml/QTI21WordExport.java +++ b/src/main/java/org/olat/ims/qti21/manager/openxml/QTI21WordExport.java @@ -680,6 +680,8 @@ public class QTI21WordExport implements MediaResource { } else { startMatchDragAndDropVertical(matchInteraction); } + } else if(cssClasses != null && cssClasses.contains(QTI21Constants.CSS_MATCH_TRUE_FALSE)) { + startMatchTrueFalse(matchInteraction); } else { startMatchMatrix(matchInteraction); } @@ -798,6 +800,58 @@ public class QTI21WordExport implements MediaResource { endTable(); } + private void startMatchTrueFalse(MatchInteraction matchInteraction) { + SimpleMatchSet questionMatchSetVertical = matchInteraction.getSimpleMatchSets().get(0); + SimpleMatchSet questionMatchSetHorizontal = matchInteraction.getSimpleMatchSets().get(1); + List<SimpleAssociableChoice> horizontalAssociableChoices = questionMatchSetHorizontal.getSimpleAssociableChoices(); + List<SimpleAssociableChoice> verticalAssociableChoices = questionMatchSetVertical.getSimpleAssociableChoices(); + + // calculate the width of the table () and of its columns + int tableWidthDxa = OpenXMLConstants.TABLE_FULL_WIDTH_DXA; + int tableWidthPct = OpenXMLConstants.TABLE_FULL_WIDTH_PCT; + int halfTableWidthDxa = tableWidthDxa / 2; + int halfTableWidthPct = tableWidthPct / 2; + + int numOfColumns = horizontalAssociableChoices.size(); + int columnWidthDxa = halfTableWidthDxa / numOfColumns; + int columnWidthPct = halfTableWidthPct / numOfColumns; + + Integer[] columnsWidth = new Integer[numOfColumns + 1]; + for(int i=numOfColumns; i-->0; ) { + columnsWidth[i] = columnWidthDxa; + } + columnsWidth[numOfColumns] = halfTableWidthDxa; + startTable(columnsWidth); + + currentTable.addRowEl(); + + // horizontal headers + for(SimpleAssociableChoice choice:horizontalAssociableChoices) { + Element answerCell = currentTable.addCellEl(factory.createTableCell("E9EAF2", columnWidthPct, Unit.pct), 1); + appendSimpleAssociableChoice(choice, answerCell); + } + // white corner + Node emptyCell = currentTable.addCellEl(factory.createTableCell(null, halfTableWidthDxa, Unit.dxa), 1); + emptyCell.appendChild(factory.createParagraphEl("")); + currentTable.closeRow(); + + for(SimpleAssociableChoice choice:verticalAssociableChoices) { + currentTable.addRowEl(); + //checkbox + for(SimpleAssociableChoice horizontalChoice:horizontalAssociableChoices) { + boolean correct = isCorrectMatchResponse(choice.getIdentifier(), horizontalChoice.getIdentifier(), matchInteraction); + appendMatchCheckBox(correct, columnWidthPct, factory); + } + //answer + Element answerCell = currentTable.addCellEl(factory.createTableCell("E9EAF2", halfTableWidthPct, Unit.pct), 1); + appendSimpleAssociableChoice(choice, answerCell) ; + + currentTable.closeRow(); + } + + endTable(); + } + /** * The sources are in one column, the targets are in the second. * @param matchInteraction diff --git a/src/main/java/org/olat/ims/qti21/model/QTI21QuestionType.java b/src/main/java/org/olat/ims/qti21/model/QTI21QuestionType.java index 219eb4b23a6a0ee72d60e76778f35fb2838027ab..4927ccf7340dbc1a797ebab41de4c1908ca9aeed 100644 --- a/src/main/java/org/olat/ims/qti21/model/QTI21QuestionType.java +++ b/src/main/java/org/olat/ims/qti21/model/QTI21QuestionType.java @@ -51,6 +51,7 @@ public enum QTI21QuestionType { kprim(true, "kprim", "o_mi_qtikprim", QuestionType.KPRIM), match(true, "match", "o_mi_qtimatch", QuestionType.MATCH), matchdraganddrop(true, "matchdraganddrop", "o_mi_qtimatch_draganddrop", QuestionType.MATCHDRAGANDDROP), + matchtruefalse(true, "matchtruefalse", "o_mi_qtimatch_truefalse", QuestionType.MATCHTRUEFALSE), fib(true, "fib", "o_mi_qtifib", QuestionType.FIB), numerical(true, "numerical", "o_mi_qtinumerical", QuestionType.NUMERICAL), hotspot(true, "hotspot", "o_mi_qtihotspot", QuestionType.HOTSPOT), @@ -212,6 +213,8 @@ public enum QTI21QuestionType { Cardinality cardinalty = responseDeclaration.getCardinality(); if(hasClass(interaction, QTI21Constants.CSS_MATCH_DRAG_AND_DROP)) { return QTI21QuestionType.matchdraganddrop; + } else if(hasClass(interaction, QTI21Constants.CSS_MATCH_TRUE_FALSE)) { + return QTI21QuestionType.matchtruefalse; } else if(cardinalty.isMultiple()) { if(hasClass(interaction, QTI21Constants.CSS_MATCH_KPRIM)) { return QTI21QuestionType.kprim; diff --git a/src/main/java/org/olat/ims/qti21/model/xml/AssessmentItemFactory.java b/src/main/java/org/olat/ims/qti21/model/xml/AssessmentItemFactory.java index af53e6b42a460d766a715c6847b4b504a028367c..04a7e798d421c03bfefcc5ff4b4bc0bb707a2065 100644 --- a/src/main/java/org/olat/ims/qti21/model/xml/AssessmentItemFactory.java +++ b/src/main/java/org/olat/ims/qti21/model/xml/AssessmentItemFactory.java @@ -591,13 +591,13 @@ public class AssessmentItemFactory { SimpleMatchSet sourceMatchSet = new SimpleMatchSet(matchInteraction); matchInteraction.getSimpleMatchSets().add(sourceMatchSet); - String[] classic = new String[]{ "A", "B" }; - for(int i=0; i<2; i++) { + String[] sources = new String[]{ "A", "B" }; + for(int i=0; i<sources.length; i++) { SimpleAssociableChoice sourceChoice = new SimpleAssociableChoice(sourceMatchSet); sourceChoice.setMatchMax(0); sourceChoice.setMatchMin(0); - sourceChoice.setIdentifier(IdentifierGenerator.newNumberAsIdentifier(classic[i])); - P question = getParagraph(sourceChoice, classic[i]); + sourceChoice.setIdentifier(IdentifierGenerator.newNumberAsIdentifier(sources[i])); + P question = getParagraph(sourceChoice, sources[i]); sourceChoice.getFlowStatics().add(question); sourceMatchSet.getSimpleAssociableChoices().add(sourceChoice); } @@ -605,13 +605,13 @@ public class AssessmentItemFactory { SimpleMatchSet targetMatchSet = new SimpleMatchSet(matchInteraction); matchInteraction.getSimpleMatchSets().add(targetMatchSet); - String[] target = new String[]{ "M", "N" }; - for(int i=0; i<2; i++) { + String[] targets = new String[]{ "M", "N" }; + for(int i=0; i<targets.length; i++) { SimpleAssociableChoice targetChoice = new SimpleAssociableChoice(sourceMatchSet); targetChoice.setMatchMax(0); targetChoice.setMatchMin(0); - targetChoice.setIdentifier(IdentifierGenerator.newNumberAsIdentifier(target[i])); - P question = getParagraph(targetChoice, target[i]); + targetChoice.setIdentifier(IdentifierGenerator.newNumberAsIdentifier(targets[i])); + P question = getParagraph(targetChoice, targets[i]); targetChoice.getFlowStatics().add(question); targetMatchSet.getSimpleAssociableChoices().add(targetChoice); } @@ -619,6 +619,45 @@ public class AssessmentItemFactory { return matchInteraction; } + public static MatchInteraction appendMatchInteractionTrueFalse(ItemBody itemBody, + String unanswered, String right, String wrong, Identifier responseDeclarationId) { + MatchInteraction matchInteraction = new MatchInteraction(itemBody); + matchInteraction.setResponseIdentifier(responseDeclarationId); + matchInteraction.setMaxAssociations(4); + matchInteraction.setShuffle(false); + itemBody.getBlocks().add(matchInteraction); + + PromptGroup prompts = new PromptGroup(matchInteraction); + matchInteraction.getNodeGroups().add(prompts); + + SimpleMatchSet sourceMatchSet = new SimpleMatchSet(matchInteraction); + matchInteraction.getSimpleMatchSets().add(sourceMatchSet); + + String[] sources = new String[]{ "A", "B" }; + for(int i=0; i<sources.length; i++) { + appendSimpleAssociableChoice(sourceMatchSet, sources[i], 1, 1); + } + + SimpleMatchSet targetMatchSet = new SimpleMatchSet(matchInteraction); + matchInteraction.getSimpleMatchSets().add(targetMatchSet); + String[] targets = new String[]{ unanswered, right, wrong }; + for(int i=0; i<targets.length; i++) { + appendSimpleAssociableChoice(targetMatchSet, targets[i], 0, 0); + } + + return matchInteraction; + } + + public static void appendSimpleAssociableChoice(SimpleMatchSet matchSet, String value, int matchMax, int matchMin) { + SimpleAssociableChoice choice = new SimpleAssociableChoice(matchSet); + choice.setMatchMax(matchMax); + choice.setMatchMin(matchMin); + choice.setIdentifier(IdentifierGenerator.newNumberAsIdentifier(value)); + P question = getParagraph(choice, value); + choice.getFlowStatics().add(question); + matchSet.getSimpleAssociableChoices().add(choice); + } + public static SimpleAssociableChoice createSimpleAssociableChoice(String text, SimpleMatchSet matchSet) { SimpleAssociableChoice targetChoice = new SimpleAssociableChoice(matchSet); targetChoice.setMatchMax(0); @@ -629,22 +668,29 @@ public class AssessmentItemFactory { return targetChoice; } + /** + * Add the response declaration with correct answers (but without score mapping) + * + * @param assessmentItem + * @param declarationId + * @param associations + * @return + */ public static ResponseDeclaration createMatchResponseDeclaration(AssessmentItem assessmentItem, Identifier declarationId, - Map<Identifier, List<Identifier>> associations, double maxScore) { + Map<Identifier, List<Identifier>> associations) { ResponseDeclaration responseDeclaration = new ResponseDeclaration(assessmentItem); responseDeclaration.setIdentifier(declarationId); responseDeclaration.setCardinality(Cardinality.MULTIPLE); responseDeclaration.setBaseType(BaseType.DIRECTED_PAIR); - return appendAssociationMatchResponseDeclaration(responseDeclaration, associations, maxScore); + return appendAssociationMatchResponseDeclaration(responseDeclaration, associations); } public static ResponseDeclaration appendAssociationMatchResponseDeclaration(ResponseDeclaration responseDeclaration, - Map<Identifier, List<Identifier>> associations, double maxScore) { + Map<Identifier, List<Identifier>> associations) { responseDeclaration.setCardinality(Cardinality.MULTIPLE); responseDeclaration.setBaseType(BaseType.DIRECTED_PAIR); //correct response - int numOfassociations = 0; CorrectResponse correctResponse = new CorrectResponse(responseDeclaration); responseDeclaration.setCorrectResponse(correctResponse); for(Map.Entry<Identifier,List<Identifier>> association:associations.entrySet()) { @@ -655,27 +701,6 @@ public class AssessmentItemFactory { DirectedPairValue dpValue = new DirectedPairValue(sourceChoiceId, targetChoiceId); FieldValue fValue = new FieldValue(correctResponse, dpValue); correctResponse.getFieldValues().add(fValue); - numOfassociations++; - } - } - - double mappedValue = maxScore; - if(numOfassociations > 0) { - mappedValue = maxScore / numOfassociations; - } - - // mapping - Mapping mapping = new Mapping(responseDeclaration); - mapping.setDefaultValue(-mappedValue); - responseDeclaration.setMapping(mapping); - for(Map.Entry<Identifier,List<Identifier>> association:associations.entrySet()) { - Identifier sourceChoiceId = association.getKey(); - List<Identifier> targetChoiceIds = association.getValue(); - for(Identifier targetChoiceId:targetChoiceIds) { - MapEntry mapEntry = new MapEntry(mapping); - mapEntry.setMapKey(new DirectedPairValue(sourceChoiceId, targetChoiceId)); - mapEntry.setMappedValue(mappedValue); - mapping.getMapEntries().add(mapEntry); } } diff --git a/src/main/java/org/olat/ims/qti21/model/xml/interactions/MatchAssessmentItemBuilder.java b/src/main/java/org/olat/ims/qti21/model/xml/interactions/MatchAssessmentItemBuilder.java index 4f74399f85147fb0120843ce532165c3f242daec..68929a6ee802feb3e1129f86f2081a30f0a9dcbc 100644 --- a/src/main/java/org/olat/ims/qti21/model/xml/interactions/MatchAssessmentItemBuilder.java +++ b/src/main/java/org/olat/ims/qti21/model/xml/interactions/MatchAssessmentItemBuilder.java @@ -23,6 +23,7 @@ import static org.olat.ims.qti21.model.xml.AssessmentItemFactory.appendAssociati import static org.olat.ims.qti21.model.xml.AssessmentItemFactory.appendDefaultItemBody; import static org.olat.ims.qti21.model.xml.AssessmentItemFactory.appendDefaultOutcomeDeclarations; import static org.olat.ims.qti21.model.xml.AssessmentItemFactory.appendMatchInteraction; +import static org.olat.ims.qti21.model.xml.AssessmentItemFactory.appendMatchInteractionTrueFalse; import static org.olat.ims.qti21.model.xml.AssessmentItemFactory.appendSetOutcomeFeedbackCorrect; import static org.olat.ims.qti21.model.xml.AssessmentItemFactory.appendSetOutcomeFeedbackIncorrect; import static org.olat.ims.qti21.model.xml.AssessmentItemFactory.appendSetOutcomeScoreMapResponse; @@ -30,6 +31,7 @@ import static org.olat.ims.qti21.model.xml.AssessmentItemFactory.appendSetOutcom import static org.olat.ims.qti21.model.xml.AssessmentItemFactory.createMatchResponseDeclaration; import static org.olat.ims.qti21.model.xml.AssessmentItemFactory.createResponseProcessing; +import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -38,6 +40,8 @@ import java.util.Map; import javax.xml.transform.stream.StreamResult; import org.olat.core.gui.render.StringOutput; +import org.olat.core.logging.OLog; +import org.olat.core.logging.Tracing; import org.olat.core.util.StringHelper; import org.olat.ims.qti21.QTI21Constants; import org.olat.ims.qti21.model.QTI21QuestionType; @@ -80,6 +84,8 @@ import uk.ac.ed.ph.jqtiplus.value.SingleValue; * */ public class MatchAssessmentItemBuilder extends AssessmentItemBuilder { + + private static final OLog log = Tracing.createLoggerFor(MatchAssessmentItemBuilder.class); private String question; private boolean shuffle; @@ -92,14 +98,19 @@ public class MatchAssessmentItemBuilder extends AssessmentItemBuilder { public MatchAssessmentItemBuilder(String title, String matchCssClass, QtiSerializer qtiSerializer) { - super(createAssessmentItem(title, matchCssClass), qtiSerializer); + super(createAssessmentItem(title, matchCssClass, null, null, null), qtiSerializer); + } + + public MatchAssessmentItemBuilder(String title, String matchCssClass, + String unanswered, String right, String wrong, QtiSerializer qtiSerializer) { + super(createAssessmentItem(title, matchCssClass, unanswered, right, wrong), qtiSerializer); } public MatchAssessmentItemBuilder(AssessmentItem assessmentItem, QtiSerializer qtiSerializer) { super(assessmentItem, qtiSerializer); } - private static AssessmentItem createAssessmentItem(String title, String matchCssClass) { + private static AssessmentItem createAssessmentItem(String title, String matchCssClass, String unanswered, String right, String wrong) { AssessmentItem assessmentItem = AssessmentItemFactory.createAssessmentItem(QTI21QuestionType.match, title); NodeGroupList nodeGroups = assessmentItem.getNodeGroups(); @@ -107,20 +118,33 @@ public class MatchAssessmentItemBuilder extends AssessmentItemBuilder { double maxScore = 1.0d; Identifier responseDeclarationId = Identifier.assumedLegal("RESPONSE_1"); //define correct answer - ResponseDeclaration responseDeclaration = createMatchResponseDeclaration(assessmentItem, responseDeclarationId, new HashMap<>(), maxScore); + ResponseDeclaration responseDeclaration = createMatchResponseDeclaration(assessmentItem, responseDeclarationId, new HashMap<>()); nodeGroups.getResponseDeclarationGroup().getResponseDeclarations().add(responseDeclaration); - appendDefaultOutcomeDeclarations(assessmentItem, maxScore); //the single choice interaction ItemBody itemBody = appendDefaultItemBody(assessmentItem); - MatchInteraction interaction = appendMatchInteraction(itemBody, responseDeclarationId); + Map<Identifier, List<Identifier>> associations = new HashMap<>(); + MatchInteraction interaction; + if(QTI21Constants.CSS_MATCH_TRUE_FALSE.equals(matchCssClass)) { + interaction = appendMatchInteractionTrueFalse(itemBody, unanswered, right, wrong, responseDeclarationId); + + //default correct answers set to "right" + SimpleAssociableChoice rightChoice = interaction.getSimpleMatchSets().get(1).getSimpleAssociableChoices().get(1); + List<SimpleAssociableChoice> sourceChoices = interaction.getSimpleMatchSets().get(0).getSimpleAssociableChoices(); + for(SimpleAssociableChoice sourceChoice:sourceChoices) { + List<Identifier> targetIdentifiers = new ArrayList<>(); + targetIdentifiers.add(rightChoice.getIdentifier()); + associations.put(sourceChoice.getIdentifier(), targetIdentifiers); + } + } else { + interaction = appendMatchInteraction(itemBody, responseDeclarationId); + } List<String> cssClasses = new ArrayList<>(); cssClasses.add(matchCssClass); interaction.setClassAttr(cssClasses); - Map<Identifier, List<Identifier>> associations = new HashMap<>(); - appendAssociationMatchResponseDeclaration(responseDeclaration, associations, 1.0); + appendAssociationMatchResponseDeclaration(responseDeclaration, associations); //response processing ResponseProcessing responseProcessing = createResponseProcessing(assessmentItem, responseDeclarationId); @@ -199,20 +223,22 @@ public class MatchAssessmentItemBuilder extends AssessmentItemBuilder { } private void extractMatchInteraction() { - StringOutput sb = new StringOutput(); - List<Block> blocks = assessmentItem.getItemBody().getBlocks(); - for(Block block:blocks) { - if(block instanceof MatchInteraction) { - matchInteraction = (MatchInteraction)block; - responseIdentifier = matchInteraction.getResponseIdentifier(); - shuffle = matchInteraction.getShuffle(); - break; - } else { - qtiSerializer.serializeJqtiObject(block, new StreamResult(sb)); + try(StringOutput sb = new StringOutput()) { + List<Block> blocks = assessmentItem.getItemBody().getBlocks(); + for(Block block:blocks) { + if(block instanceof MatchInteraction) { + matchInteraction = (MatchInteraction)block; + responseIdentifier = matchInteraction.getResponseIdentifier(); + shuffle = matchInteraction.getShuffle(); + break; + } else { + qtiSerializer.serializeJqtiObject(block, new StreamResult(sb)); + } } + question = sb.toString(); + } catch(IOException e) { + log.error("", e); } - - question = sb.toString(); } private void extractScoreEvaluationMode() { @@ -244,8 +270,12 @@ public class MatchAssessmentItemBuilder extends AssessmentItemBuilder { public QTI21QuestionType getQuestionType() { if(matchInteraction != null) { List<?> cssClassses = matchInteraction.getClassAttr(); - if(cssClassses != null && cssClassses.contains(QTI21Constants.CSS_MATCH_DRAG_AND_DROP)) { - return QTI21QuestionType.matchdraganddrop; + if(cssClassses != null) { + if(cssClassses.contains(QTI21Constants.CSS_MATCH_DRAG_AND_DROP)) { + return QTI21QuestionType.matchdraganddrop; + } else if(cssClassses.contains(QTI21Constants.CSS_MATCH_TRUE_FALSE)) { + return QTI21QuestionType.matchtruefalse; + } } } return QTI21QuestionType.match; @@ -410,17 +440,13 @@ public class MatchAssessmentItemBuilder extends AssessmentItemBuilder { @Override protected void buildResponseAndOutcomeDeclarations() { - //need min. and max. score - double maxScore = getMaxScoreBuilder().getScore(); - //refresh correct response ResponseDeclaration responseDeclaration; if(assessmentItem.getResponseDeclaration(responseIdentifier) != null) { responseDeclaration = assessmentItem.getResponseDeclaration(responseIdentifier); - appendAssociationMatchResponseDeclaration(responseDeclaration, associations, maxScore); + appendAssociationMatchResponseDeclaration(responseDeclaration, associations); } else { - responseDeclaration = - createMatchResponseDeclaration(assessmentItem, responseIdentifier, associations, maxScore); + responseDeclaration = createMatchResponseDeclaration(assessmentItem, responseIdentifier, associations); assessmentItem.getResponseDeclarations().add(responseDeclaration); } diff --git a/src/main/java/org/olat/ims/qti21/pool/QTI21AssessmentItemFactory.java b/src/main/java/org/olat/ims/qti21/pool/QTI21AssessmentItemFactory.java index 788594a9baf431121753f40bb5891594ad760529..ee2c61dac26679f8b7fdfc68b7f5d86a215b2748 100644 --- a/src/main/java/org/olat/ims/qti21/pool/QTI21AssessmentItemFactory.java +++ b/src/main/java/org/olat/ims/qti21/pool/QTI21AssessmentItemFactory.java @@ -53,6 +53,7 @@ public class QTI21AssessmentItemFactory implements QItemFactory { case kprim: return "QTI 2.1 " + trans.translate("new.kprim"); case match: return "QTI 2.1 " + trans.translate("new.match"); case matchdraganddrop: return "QTI 2.1 " + trans.translate("new.matchdraganddrop"); + case matchtruefalse: return "QTI 2.1 " + trans.translate("new.matchtruefalse"); case fib: return "QTI 2.1 " + trans.translate("new.fib"); case numerical: return "QTI 2.1 " + trans.translate("new.fib.numerical"); case essay: return "QTI 2.1 " + trans.translate("new.essay"); diff --git a/src/main/java/org/olat/ims/qti21/pool/QTI21QPoolServiceProvider.java b/src/main/java/org/olat/ims/qti21/pool/QTI21QPoolServiceProvider.java index 877380a91464a28a5ccedb50aa57a36986c95169..6e84ffd1ec6b9dd9c6c2c547b348cd6cd390ae7d 100644 --- a/src/main/java/org/olat/ims/qti21/pool/QTI21QPoolServiceProvider.java +++ b/src/main/java/org/olat/ims/qti21/pool/QTI21QPoolServiceProvider.java @@ -350,6 +350,8 @@ public class QTI21QPoolServiceProvider implements QPoolSPI { case kprim: itemBuilder = new KPrimAssessmentItemBuilder(translator.translate("new.kprim"), translator.translate("new.answer"), qtiService.qtiSerializer()); break; case match: itemBuilder = new MatchAssessmentItemBuilder(translator.translate("new.match"), QTI21Constants.CSS_MATCH_MATRIX, qtiService.qtiSerializer()); break; case matchdraganddrop: itemBuilder = new MatchAssessmentItemBuilder(translator.translate("new.match"), QTI21Constants.CSS_MATCH_DRAG_AND_DROP, qtiService.qtiSerializer()); break; + case matchtruefalse: itemBuilder = new MatchAssessmentItemBuilder(translator.translate("new.match"), QTI21Constants.CSS_MATCH_TRUE_FALSE, + translator.translate("match.unanswered"), translator.translate("match.true"), translator.translate("match.false"), qtiService.qtiSerializer()); break; case fib: itemBuilder = new FIBAssessmentItemBuilder(translator.translate("new.fib"), EntryType.text, qtiService.qtiSerializer()); break; case numerical: itemBuilder = new FIBAssessmentItemBuilder(translator.translate("new.fib.numerical"), EntryType.numerical, qtiService.qtiSerializer()); break; case essay: itemBuilder = new EssayAssessmentItemBuilder(translator.translate("new.essay"), qtiService.qtiSerializer()); break; diff --git a/src/main/java/org/olat/ims/qti21/questionimport/CSVToAssessmentItemConverter.java b/src/main/java/org/olat/ims/qti21/questionimport/CSVToAssessmentItemConverter.java index de330b3e0c657dcf78411028d4dc5e6b831dd698..6c85414970833aa3f646b17454860755d793a160 100644 --- a/src/main/java/org/olat/ims/qti21/questionimport/CSVToAssessmentItemConverter.java +++ b/src/main/java/org/olat/ims/qti21/questionimport/CSVToAssessmentItemConverter.java @@ -22,10 +22,13 @@ package org.olat.ims.qti21.questionimport; import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; +import java.util.Locale; +import org.olat.core.gui.translator.Translator; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; import org.olat.core.util.StringHelper; +import org.olat.core.util.Util; import org.olat.ims.qti21.QTI21Constants; import org.olat.ims.qti21.model.xml.AssessmentItemBuilder; import org.olat.ims.qti21.model.xml.AssessmentItemFactory; @@ -39,6 +42,7 @@ import org.olat.ims.qti21.model.xml.interactions.MultipleChoiceAssessmentItemBui import org.olat.ims.qti21.model.xml.interactions.SimpleChoiceAssessmentItemBuilder; import org.olat.ims.qti21.model.xml.interactions.SimpleChoiceAssessmentItemBuilder.ScoreEvaluation; import org.olat.ims.qti21.model.xml.interactions.SingleChoiceAssessmentItemBuilder; +import org.olat.ims.qti21.ui.editor.AssessmentItemEditorController; import uk.ac.ed.ph.jqtiplus.node.content.xhtml.text.P; import uk.ac.ed.ph.jqtiplus.node.item.interaction.ChoiceInteraction; @@ -61,11 +65,13 @@ public class CSVToAssessmentItemConverter { private int currentLine; private int kprimPosition = 0; private ImportOptions options; + private final Locale locale; private final QtiSerializer qtiSerializer; private AssessmentItemAndMetadata currentItem; private final List<AssessmentItemAndMetadata> items = new ArrayList<>(); - public CSVToAssessmentItemConverter(ImportOptions options, QtiSerializer qtiSerializer) { + public CSVToAssessmentItemConverter(ImportOptions options, Locale locale, QtiSerializer qtiSerializer) { + this.locale = locale; this.options = options; this.qtiSerializer = qtiSerializer; } @@ -376,6 +382,13 @@ public class CSVToAssessmentItemConverter { itemBuilder = initMatchAssessmentItemBuilder(matchBuilder); break; } + case "truefalse": { + Translator trans = Util.createPackageTranslator(AssessmentItemEditorController.class, locale); + MatchAssessmentItemBuilder matchBuilder = new MatchAssessmentItemBuilder("Matrix", QTI21Constants.CSS_MATCH_TRUE_FALSE, + trans.translate("match.unanswered"), trans.translate("match.true"), trans.translate("match.false"), qtiSerializer); + itemBuilder = initMatchAssessmentItemBuilderForTrueFalse(matchBuilder); + break; + } default: { itemBuilder = null; } @@ -428,6 +441,19 @@ public class CSVToAssessmentItemConverter { return matchBuilder; } + private MatchAssessmentItemBuilder initMatchAssessmentItemBuilderForTrueFalse(MatchAssessmentItemBuilder matchBuilder) { + //reset + matchBuilder.setQuestion(""); + matchBuilder.clearAssociations(); + matchBuilder.clearMapping(); + matchBuilder.getSourceChoices().clear(); + //set default options + matchBuilder.setShuffle(false); + matchBuilder.setMultipleChoice(false); + matchBuilder.setScoreEvaluationMode(ScoreEvaluation.perAnswer); + return matchBuilder; + } + private void build() { if(currentItem != null) { try { @@ -513,6 +539,9 @@ public class CSVToAssessmentItemConverter { } else if(itemBuilder instanceof KPrimAssessmentItemBuilder) { itemBuilder.setMinScore(0.0d); itemBuilder.setMaxScore(points); + } else if(itemBuilder instanceof MatchAssessmentItemBuilder) { + itemBuilder.setMinScore(0.0d); + itemBuilder.setMaxScore(points); } } @@ -567,18 +596,20 @@ public class CSVToAssessmentItemConverter { } } else { String answer = parts[0]; - SimpleAssociableChoice sourceChoice = AssessmentItemFactory - .createSimpleAssociableChoice(answer, matchBuilder.getSourceMatchSet()); - matchBuilder.getSourceChoices().add(sourceChoice); - - //correct answer and points - for(int i=1; i<parts.length && i<(targetChoices.size() + 1); i++) { - double point = parseFloat(parts[i], 0.0f); - SimpleAssociableChoice targetChoice = targetChoices.get(i - 1); - DirectedPairValue directedPair = new DirectedPairValue(sourceChoice.getIdentifier(), targetChoice.getIdentifier()); - matchBuilder.addScore(directedPair, Double.valueOf(point)); - if(point > 0.0) { - matchBuilder.addAssociation(sourceChoice.getIdentifier(), targetChoice.getIdentifier()); + if(StringHelper.containsNonWhitespace(answer)) { + SimpleAssociableChoice sourceChoice = AssessmentItemFactory + .createSimpleAssociableChoice(answer, matchBuilder.getSourceMatchSet()); + matchBuilder.getSourceChoices().add(sourceChoice); + + //correct answer and points + for(int i=1; i<parts.length && i<(targetChoices.size() + 1); i++) { + double point = parseFloat(parts[i], 0.0f); + SimpleAssociableChoice targetChoice = targetChoices.get(i - 1); + DirectedPairValue directedPair = new DirectedPairValue(sourceChoice.getIdentifier(), targetChoice.getIdentifier()); + matchBuilder.addScore(directedPair, Double.valueOf(point)); + if(point > 0.0) { + matchBuilder.addAssociation(sourceChoice.getIdentifier(), targetChoice.getIdentifier()); + } } } } diff --git a/src/main/java/org/olat/ims/qti21/questionimport/OverviewQuestionController.java b/src/main/java/org/olat/ims/qti21/questionimport/OverviewQuestionController.java index 31e777fddc3cd43ff00f974fa510a8ce658b9fc4..806f102bb936f00d90d7a2b09b53a12e5c29a748 100644 --- a/src/main/java/org/olat/ims/qti21/questionimport/OverviewQuestionController.java +++ b/src/main/java/org/olat/ims/qti21/questionimport/OverviewQuestionController.java @@ -127,6 +127,7 @@ public class OverviewQuestionController extends StepFormBasicController { case essay: return translate("item.type.essay"); case match: return translate("item.type.match"); case matchdraganddrop: return translate("item.type.matchdraganddrop"); + case matchtruefalse: return translate("item.type.matchtruefalse"); default: return "??"; } } diff --git a/src/main/java/org/olat/ims/qti21/questionimport/TextInputController.java b/src/main/java/org/olat/ims/qti21/questionimport/TextInputController.java index dacc1635e3c96e8e8d5b2c7ff0a09e4fb8339e87..cc8dde4c5766a0fc973d11c13fd564689107d189 100644 --- a/src/main/java/org/olat/ims/qti21/questionimport/TextInputController.java +++ b/src/main/java/org/olat/ims/qti21/questionimport/TextInputController.java @@ -91,7 +91,7 @@ public class TextInputController extends StepFormBasicController { String inp = inputElement.getValue(); if(validatedInp == null || !validatedInp.equals(inp)) { - CSVToAssessmentItemConverter converter = new CSVToAssessmentItemConverter(options, qtiService.qtiSerializer()); + CSVToAssessmentItemConverter converter = new CSVToAssessmentItemConverter(options, getLocale(), qtiService.qtiSerializer()); try { converter.parse(inputElement.getValue()); List<AssessmentItemAndMetadata> items = converter.getItems(); @@ -110,7 +110,7 @@ public class TextInputController extends StepFormBasicController { @Override protected void formOK(UserRequest ureq) { - CSVToAssessmentItemConverter converter = new CSVToAssessmentItemConverter(options, qtiService.qtiSerializer()); + CSVToAssessmentItemConverter converter = new CSVToAssessmentItemConverter(options, getLocale(), qtiService.qtiSerializer()); converter.parse(inputElement.getValue()); importedItems.setItems(converter.getItems()); fireEvent(ureq, StepsEvent.ACTIVATE_NEXT); diff --git a/src/main/java/org/olat/ims/qti21/questionimport/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/ims/qti21/questionimport/_i18n/LocalStrings_de.properties index a0e0ae54b23ccd7009d16d875bd24bb97dc920cf..253c520b2b27b905436cd504b67a8d43b057090c 100644 --- a/src/main/java/org/olat/ims/qti21/questionimport/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/ims/qti21/questionimport/_i18n/LocalStrings_de.properties @@ -17,4 +17,5 @@ item.type.sc=$org.olat.ims.qti.editor\:item.type.sc item.type.essay=$org.olat.ims.qti21.ui.editor\:new.essay item.type.match=$org.olat.ims.qti21.ui.editor\:new.match item.type.matchdraganddrop=$org.olat.ims.qti21.ui.editor\:new.matchdraganddrop +item.type.matchtruefalse=$org.olat.ims.qti21.ui.editor\:new.matchtruefalse error.at.line=Problem auf Zeile {0} diff --git a/src/main/java/org/olat/ims/qti21/questionimport/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/ims/qti21/questionimport/_i18n/LocalStrings_en.properties index 3368a089f36e01e8e670d77c0e1ab01489b0197c..e5a25ae8a1bbb276f8cb2e61bd21a1ef89e994a8 100644 --- a/src/main/java/org/olat/ims/qti21/questionimport/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/ims/qti21/questionimport/_i18n/LocalStrings_en.properties @@ -17,4 +17,5 @@ item.type.sc=$org.olat.ims.qti.editor\:item.type.sc item.type.essay=$org.olat.ims.qti21.ui.editor\:new.essay item.type.match=$org.olat.ims.qti21.ui.editor\:new.match item.type.matchdraganddrop=$org.olat.ims.qti21.ui.editor\:new.matchdraganddrop +item.type.matchtruefalse=$org.olat.ims.qti21.ui.editor\:new.matchtruefalse error.at.line=Issue with line {0} \ No newline at end of file diff --git a/src/main/java/org/olat/ims/qti21/questionimport/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/ims/qti21/questionimport/_i18n/LocalStrings_fr.properties index 7d7701b21f484eac3a91c0a98557238fbfad8309..da4ab8cbd1b446afc58c19c1c7b7d4852182bdcf 100644 --- a/src/main/java/org/olat/ims/qti21/questionimport/_i18n/LocalStrings_fr.properties +++ b/src/main/java/org/olat/ims/qti21/questionimport/_i18n/LocalStrings_fr.properties @@ -1,4 +1,4 @@ -#Tue Aug 15 17:19:04 CEST 2017 +#Thu Feb 01 18:22:50 CET 2018 download.example=$org.olat.ims.qti.questionimport\:download.example error.at.line=Erreur ligne {0} form.importdata=$org.olat.ims.qti.questionimport\:form.importdata @@ -6,6 +6,8 @@ input.title=$org.olat.ims.qti.questionimport\:input.title item.type.essay=$org.olat.ims.qti.editor\:item.type.essay item.type.fib=$org.olat.ims.qti.editor\:item.type.fib item.type.kprim=$org.olat.ims.qti.editor\:item.type.kprim +item.type.match=$org.olat.ims.qti21.ui.editor\:new.match +item.type.matchdraganddrop=$org.olat.ims.qti21.ui.editor\:new.matchdraganddrop item.type.mc=$org.olat.ims.qti.editor\:item.type.mc item.type.sc=$org.olat.ims.qti.editor\:item.type.sc table.header.points=$org.olat.ims.qti.questionimport\:table.header.points diff --git a/src/main/java/org/olat/ims/qti21/ui/AssessmentEntryOutcomesListener.java b/src/main/java/org/olat/ims/qti21/ui/AssessmentEntryOutcomesListener.java index a8077ea5be0e9d226c2500b1099159311c14914d..f9c3c3bfc4d2ff3b81f77cde717a17ff3c4bf1a4 100644 --- a/src/main/java/org/olat/ims/qti21/ui/AssessmentEntryOutcomesListener.java +++ b/src/main/java/org/olat/ims/qti21/ui/AssessmentEntryOutcomesListener.java @@ -26,6 +26,8 @@ import java.util.concurrent.atomic.AtomicBoolean; import org.olat.core.CoreSpringFactory; import org.olat.core.gui.translator.Translator; +import org.olat.core.id.Identity; +import org.olat.core.id.UserConstants; import org.olat.core.logging.activity.ThreadLocalUserActivityLogger; import org.olat.core.util.Formatter; import org.olat.core.util.Util; @@ -80,7 +82,8 @@ public class AssessmentEntryOutcomesListener implements OutcomesListener { DigitalSignatureOptions options, Date timestamp, Locale locale) { MailBundle bundle = new MailBundle(); bundle.setToId(candidateSession.getIdentity()); - String fullname = CoreSpringFactory.getImpl(UserManager.class).getUserDisplayName(candidateSession.getIdentity()); + Identity assessedIdentity = candidateSession.getIdentity(); + String fullname = CoreSpringFactory.getImpl(UserManager.class).getUserDisplayName(assessedIdentity); Date assessedDate = candidateSession.getFinishTime() == null ? timestamp : candidateSession.getFinishTime(); @@ -93,7 +96,12 @@ public class AssessmentEntryOutcomesListener implements OutcomesListener { testEntry.getDisplayname(), // {4} fullname, // {5} Formatter.getInstance(locale) - .formatDateAndTime(assessedDate) // {6} + .formatDateAndTime(assessedDate), // {6} + assessedIdentity.getName(), // {7} + assessedIdentity.getUser() + .getProperty(UserConstants.INSTITUTIONALUSERIDENTIFIER, locale), // {8} + assessedIdentity.getUser() + .getProperty(UserConstants.INSTITUTIONALNAME, locale), // {9} }; String subject = translator.translate("digital.signature.mail.subject", args); diff --git a/src/main/java/org/olat/ims/qti21/ui/AssessmentResultController.java b/src/main/java/org/olat/ims/qti21/ui/AssessmentResultController.java index 1239e173bd47b83d24acf5423b91ce88d95750ff..acd2dbfcf0106d216809042de7cab92ba05ca8ec 100644 --- a/src/main/java/org/olat/ims/qti21/ui/AssessmentResultController.java +++ b/src/main/java/org/olat/ims/qti21/ui/AssessmentResultController.java @@ -746,7 +746,9 @@ public class AssessmentResultController extends FormBasicController { } public String getScorePercent() { - if(maxScore == null) return null; + if(maxScore == null) { + return null; + } if(score == null) return "0"; double percent = (score / maxScore) * 100.0d; diff --git a/src/main/java/org/olat/ims/qti21/ui/_content/assessment_results.html b/src/main/java/org/olat/ims/qti21/ui/_content/assessment_results.html index 1b7dbb6a20458f62093176a2df5eff8a7f0d27e8..42163a3ec170c478633c9732e9b7bf0e33c9dfc4 100644 --- a/src/main/java/org/olat/ims/qti21/ui/_content/assessment_results.html +++ b/src/main/java/org/olat/ims/qti21/ui/_content/assessment_results.html @@ -80,16 +80,15 @@ <td> <div> #if ($testResults.hasMaxScore()) - #if ($testResults.maxScore == "-1.0") + #if ($testResults.maxScore == "-1.0") $testResults.score $r.translate("results.points") ($r.translate("question.progress.noMaxScore")) - #else + #else <span title="$r.translateInAttribute("results.score.yourscore")" class="o_sel_assessmenttest_score">$testResults.score</span> - $r.translate("results.of") <span title="$r.translateInAttribute("score.max")" class="o_sel_assessmenttest_maxscore">$testResults.maxScore</span> $r.translate("results.of.points") + $r.translate("results.of") <span title="$r.translateInAttribute("score.max")" class="o_sel_assessmenttest_maxscore">$testResults.maxScore</span> $r.translate("results.of.points") (${testResults.scorePercent}%) #end #else $testResults.score #end - (${testResults.scorePercent}%) </div> </td> </tr> @@ -153,7 +152,7 @@ </div> </div> ## END left column / o_qti_metainfo_listing - #if(${testResults.hasScore()}) + #if(${testResults.hasScore()} && ${testResults.hasMaxScore()}) <div class="o_qti_metainfo_visual col-xs-12 col-sm-5 col-md-4 col-lg-3"> ## START right column <div class="o_block_centered_wrapper"><div class="o_block_centered_content"> <div class="radial-progress radial-progress-lg #if(${testResults.hasPass()}) #if(${testResults.getPass().booleanValue()}) radial-progress-success #elseif(!${testResults.getPass().booleanValue()}) radial-progress-danger #end #end " id="o_performance_summary_visual" data-progress="0"> @@ -398,6 +397,7 @@ / <span title="$r.translateInAttribute("score.max")" class="o_sel_assessmentitem_maxscore">$itemResult.maxScore</span> #end </div> + #if(${itemResult.hasMaxScore()}) <div class="col-xs-6 col-md-8"> <div class="progress" style="width:100%;"> <div class="progress-bar" role="progressbar" aria-valuenow="$itemResult.score" aria-valuemin="0" aria-valuemax="$itemResult.maxScore" style="width:${itemResult.scorePercent}%;"> @@ -406,6 +406,7 @@ </div> </div> <div class="col-xs-1">${itemResult.scorePercent}%</div> + #end </td> </tr> #elseif(${itemResult.hasMaxScore()}) diff --git a/src/main/java/org/olat/ims/qti21/ui/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/ims/qti21/ui/_i18n/LocalStrings_fr.properties index bd7144f56e387f9d9019b6027356a3bda611264b..667b869142061934241807f861b99832be7e8023 100644 --- a/src/main/java/org/olat/ims/qti21/ui/_i18n/LocalStrings_fr.properties +++ b/src/main/java/org/olat/ims/qti21/ui/_i18n/LocalStrings_fr.properties @@ -1,4 +1,4 @@ -#Thu Nov 30 09:44:19 CET 2017 +#Thu Feb 01 18:23:01 CET 2018 actualPoints=$org.olat.modules.iq\:actualPoints admin.12.title=Configuration QTI 1.2 admin.menu.title=QTI 2.1 @@ -112,6 +112,7 @@ error.integer=Format de nombre inad\u00E9quat. Exemple\: 15, 5, 1 error.mimetype=$org.olat.core.commons.modules.bc\:WrongMimeType error.reload.question=Une erreur inattendue s'est produite. Veuillez v\u00E9rifiez la r\u00E9ponse que vous avez donn\u00E9 \u00E0 la question et sauvez-la \u00E0 nouveau. error.required.format=Votre entr\u00E9e ne correspond pas au format requis. +error.test.closed=Le test est termin\u00E9 error.textEntry.invalid=Votre entr\u00E9e doit \u00EAtre un {0} valide. error.textEntry.invalid.float=Votre entr\u00E9e doit \u00EAtre un nombre {0} valide avec une virgule ou un point comme s\u00E9parateur d\u00E9cimal. error.textEntry.invalid.record=Votre entr\u00E9e doit un nombre valide. diff --git a/src/main/java/org/olat/ims/qti21/ui/components/AssessmentObjectComponentRenderer.java b/src/main/java/org/olat/ims/qti21/ui/components/AssessmentObjectComponentRenderer.java index e5b8d647bd2b05dba5eb0775a77db4f42bd98bbe..15a9b960758dbbabc8b410563e5d2fa3280fe49b 100644 --- a/src/main/java/org/olat/ims/qti21/ui/components/AssessmentObjectComponentRenderer.java +++ b/src/main/java/org/olat/ims/qti21/ui/components/AssessmentObjectComponentRenderer.java @@ -51,6 +51,7 @@ import static org.olat.ims.qti21.ui.components.AssessmentRenderFunctions.renderR import static org.olat.ims.qti21.ui.components.AssessmentRenderFunctions.renderSingleCardinalityValue; import static org.olat.ims.qti21.ui.components.AssessmentRenderFunctions.valueContains; +import java.io.IOException; import java.io.Reader; import java.io.StringReader; import java.net.URI; @@ -1026,6 +1027,8 @@ public abstract class AssessmentObjectComponentRenderer extends DefaultComponent interactionName += "_kprim"; } else if(hasClass(matchInteraction, QTI21Constants.CSS_MATCH_DRAG_AND_DROP)) { interactionName += "_dnd"; + } else if(hasClass(matchInteraction, QTI21Constants.CSS_MATCH_TRUE_FALSE)) { + interactionName += "_truefalse"; } else if(hasClass(matchInteraction, QTI21Constants.CSS_MATCH_KPRIM)) { interactionName += "_kprim"; } @@ -1375,14 +1378,17 @@ public abstract class AssessmentObjectComponentRenderer extends DefaultComponent ResolvedAssessmentItem resolvedAssessmentItem, ItemSessionState itemSessionState, Math math) { renderer.setMathXsltDisabled(true); - StringOutput mathOutput = StringOutputPool.allocStringBuilder(2048); - mathOutput.append("<math xmlns=\"http://www.w3.org/1998/Math/MathML\">"); - math.getContent().forEach((foreignElement) - -> renderMath(renderer, mathOutput, component, resolvedAssessmentItem, itemSessionState, foreignElement)); - mathOutput.append("</math>"); - String enrichedMathML = StringOutputPool.freePop(mathOutput); - renderer.setMathXsltDisabled(false); - transformMathmlAsString(sb, enrichedMathML); + try(StringOutput mathOutput = StringOutputPool.allocStringBuilder(2048)) { + mathOutput.append("<math xmlns=\"http://www.w3.org/1998/Math/MathML\">"); + math.getContent().forEach((foreignElement) + -> renderMath(renderer, mathOutput, component, resolvedAssessmentItem, itemSessionState, foreignElement)); + mathOutput.append("</math>"); + String enrichedMathML = StringOutputPool.freePop(mathOutput); + renderer.setMathXsltDisabled(false); + transformMathmlAsString(sb, enrichedMathML); + } catch(IOException e) { + log.error("", e); + } } protected void renderMath(AssessmentRenderer renderer, StringOutput out, AssessmentObjectComponent component, diff --git a/src/main/java/org/olat/ims/qti21/ui/components/AssessmentObjectVelocityRenderDecorator.java b/src/main/java/org/olat/ims/qti21/ui/components/AssessmentObjectVelocityRenderDecorator.java index 15dc7a694e8bbd32bf44a8ee121ad11190c936ae..0883fb38f8137c62451187e2b92be0a4b9a85899 100644 --- a/src/main/java/org/olat/ims/qti21/ui/components/AssessmentObjectVelocityRenderDecorator.java +++ b/src/main/java/org/olat/ims/qti21/ui/components/AssessmentObjectVelocityRenderDecorator.java @@ -554,6 +554,10 @@ public class AssessmentObjectVelocityRenderDecorator extends VelocityRenderDecor return AssessmentRenderFunctions.valueContains(value, string); } + public boolean trueFalseDefault(Value response, String targetIdentifier, MatchInteraction interaction) { + return AssessmentRenderFunctions.trueFalseDefault(response, targetIdentifier, interaction); + } + public ResponseData getResponseInput(Identifier identifier) { return AssessmentRenderFunctions.getResponseInput(itemSessionState, identifier); } diff --git a/src/main/java/org/olat/ims/qti21/ui/components/AssessmentRenderFunctions.java b/src/main/java/org/olat/ims/qti21/ui/components/AssessmentRenderFunctions.java index 3199e9125f4724a47fdee75f31f8b38994036eb3..955cc299589a5c64caaaa81b96b64fe08c51e841 100644 --- a/src/main/java/org/olat/ims/qti21/ui/components/AssessmentRenderFunctions.java +++ b/src/main/java/org/olat/ims/qti21/ui/components/AssessmentRenderFunctions.java @@ -46,7 +46,9 @@ import uk.ac.ed.ph.jqtiplus.node.QtiNode; import uk.ac.ed.ph.jqtiplus.node.content.basic.TextRun; import uk.ac.ed.ph.jqtiplus.node.item.AssessmentItem; import uk.ac.ed.ph.jqtiplus.node.item.CorrectResponse; +import uk.ac.ed.ph.jqtiplus.node.item.interaction.MatchInteraction; import uk.ac.ed.ph.jqtiplus.node.item.interaction.choice.Choice; +import uk.ac.ed.ph.jqtiplus.node.item.interaction.choice.SimpleAssociableChoice; import uk.ac.ed.ph.jqtiplus.node.item.response.declaration.ResponseDeclaration; import uk.ac.ed.ph.jqtiplus.node.item.template.declaration.TemplateDeclaration; import uk.ac.ed.ph.jqtiplus.node.test.TestFeedback; @@ -525,14 +527,20 @@ public class AssessmentRenderFunctions { //value-contains public static final boolean valueContains(Value value, Identifier identifier) { if(value != null && !value.isNull()) { - //TODO mimic the XSLT - return value.toQtiString().contains(identifier.toString()); - /* if(value.hasBaseType(BaseType.IDENTIFIER)) { - IdentifierValue identifierValue = (IdentifierValue)value; - return identifierValue.identifierValue().equals(identifier); + if(value.getCardinality().isSingle()) { + IdentifierValue identifierValue = (IdentifierValue)value; + return identifierValue.identifierValue().equals(identifier); + } else if(value.getCardinality().isList()) { + boolean contains = false; + for(IdentifierValue identifierValue : ((ListValue) value).values(IdentifierValue.class)) { + if(identifierValue.identifierValue().equals(identifier)) { + contains = true; + } + } + return contains; + } } - */ } return false; } @@ -540,9 +548,21 @@ public class AssessmentRenderFunctions { public static boolean valueContains(Value value, String string) { if(value == null || value.isNull() || value instanceof NullValue) { return false; - } else { - return value.toQtiString().contains(string);//TODO qti perhaps must match closer for MultipleValue } + return value.toQtiString().contains(string);//TODO qti perhaps must match closer for MultipleValue + } + + /** + * Return true if the answer is not answered + * @param response + * @param string + * @return + */ + public static boolean trueFalseDefault(Value response, String targetIdentifier, MatchInteraction interaction) { + //first target is "unanswered" + SimpleAssociableChoice unansweredChoice = interaction.getSimpleMatchSets().get(1).getSimpleAssociableChoices().get(0); + return (targetIdentifier.equals(unansweredChoice.getIdentifier().toString()) + && (response == null || response.isNull() || response instanceof NullValue)); } /** diff --git a/src/main/java/org/olat/ims/qti21/ui/components/_content/associateInteraction.html b/src/main/java/org/olat/ims/qti21/ui/components/_content/associateInteraction.html index faca66cbce70bc5a85fbfa666e33c406d7c68635..dd546cb1210d9bfb76a111f0148e9965d9c65294 100644 --- a/src/main/java/org/olat/ims/qti21/ui/components/_content/associateInteraction.html +++ b/src/main/java/org/olat/ims/qti21/ui/components/_content/associateInteraction.html @@ -13,7 +13,7 @@ <div class="o_error badResponse">$r.translate("error.as.directed")</div> #end <div id="${containerId}"> - <div id="${containerId}_items" class="clearfix" style="padding:15px;"> + <div id="${containerId}_items" class="o_associate_items clearfix" style="padding:15px;"> #foreach($choice in $choices) <div data-qti-id="${choice.identifier}" data-qti-match-max="${choice.matchMax}" class="o_associate_item" style="width: 100px; float:left;"> $r.renderFlowStatics($choice.getFlowStatics()) diff --git a/src/main/java/org/olat/ims/qti21/ui/components/_content/matchInteraction_truefalse.html b/src/main/java/org/olat/ims/qti21/ui/components/_content/matchInteraction_truefalse.html new file mode 100644 index 0000000000000000000000000000000000000000..ab59a131b2bf3b19ec45f67bba7aede1e02d99a0 --- /dev/null +++ b/src/main/java/org/olat/ims/qti21/ui/components/_content/matchInteraction_truefalse.html @@ -0,0 +1,54 @@ +#set($responseIdentifier = $r.responseUniqueId($interaction)) +#set($orderedSet1 = $r.getVisibleOrderedChoices($interaction,0)) +#set($orderedSet2 = $r.getVisibleOrderedChoices($interaction,1)) + +<input name="qtiworks_presented_${responseIdentifier}" type="hidden" value="1"/> +<div class="$localName match_true_false"> + #if($interaction.getPrompt()) + <div class="prompt">$r.renderPrompt($interaction.getPrompt())</div> + #end + + #if($r.isInvalidResponse($interaction.responseIdentifier)) + <div class="o_error badResponse">$r.translate("error.as.directed")</div> + #end + <table id="qti_container_${responseIdentifier}" class="table"> + <thead> + <tr> + #foreach($choice2 in $orderedSet2) + <th class="#if($foreach.index == 0) o_match_true_false_unanswered #elseif($foreach.index == 1) o_match_true_false_right #else o_match_true_false_wrong #end">$r.renderFlowStatics($choice2.getFlowStatics())</th> + #end + <th class="o_match_true_false_answer"> </th> + </tr> + </thead> + <tbody> + #foreach($choice1 in $orderedSet1) + #set($set1Identifier = $r.toString($choice1.identifier)) + <tr> + #foreach($choice2 in $orderedSet2) + #set($set2Identifier = $r.toString($choice2.identifier)) + #set($responseValue = $set1Identifier + " " + $set2Identifier) + #set($responseChecked = $r.getResponseValue($interaction.responseIdentifier)) + <td class="#if($foreach.index == 0) o_match_true_false_unanswered #elseif($foreach.index == 1) o_match_true_false_right #else o_match_true_false_wrong #end"> + <input id="oo_${set1Identifier}_${set2Identifier}" type="checkbox" name="qtiworks_response_${responseIdentifier}" value="${responseValue}" #if($r.valueContains($responseChecked, $responseValue) || $r.trueFalseDefault($responseChecked, $set2Identifier, $interaction)) checked #end #if($r.isItemSessionEnded()) disabled #end/> + $r.appendFlexiFormDirtyForCheckbox("oo_${set1Identifier}_${set2Identifier}") + </td> + #end + <td class="o_match_true_false_answer">$r.renderFlowStatics($choice1.getFlowStatics())</td> + </tr> + #end + </tbody> + </table> + #if($r.isItemSessionOpen()) + <script type='text/javascript'> + jQuery(function() { + jQuery('#qti_container_${responseIdentifier}').matchInteraction({ + responseIdentifier: '$responseIdentifier', + formDispatchFieldId: '$r.formDispatchFieldId', + maxAssociations: $interaction.maxAssociations, + leftData: {#foreach($choice1 in $orderedSet1) #if($foreach.count > 1),#end $choice1.identifier:$choice1.matchMax #end}, + rightData: {#foreach($choice2 in $orderedSet2) #if($foreach.count > 1),#end $choice2.identifier:$choice2.matchMax #end} + }); + }); + </script> + #end +</div> diff --git a/src/main/java/org/olat/ims/qti21/ui/editor/AssessmentItemEditorController.java b/src/main/java/org/olat/ims/qti21/ui/editor/AssessmentItemEditorController.java index c416c02bc87f21efb03583547fe90c8ed7185834..37a6514d99a3916b87b66ecce1691c8602a65315 100644 --- a/src/main/java/org/olat/ims/qti21/ui/editor/AssessmentItemEditorController.java +++ b/src/main/java/org/olat/ims/qti21/ui/editor/AssessmentItemEditorController.java @@ -64,6 +64,7 @@ import org.olat.ims.qti21.ui.editor.interactions.MatchEditorController; import org.olat.ims.qti21.ui.editor.interactions.MatchScoreController; import org.olat.ims.qti21.ui.editor.interactions.MultipleChoiceEditorController; import org.olat.ims.qti21.ui.editor.interactions.SingleChoiceEditorController; +import org.olat.ims.qti21.ui.editor.interactions.TrueFalseEditorController; import org.olat.ims.qti21.ui.editor.interactions.UploadEditorController; import org.olat.modules.assessment.AssessmentEntry; import org.olat.modules.assessment.AssessmentService; @@ -258,6 +259,7 @@ public class AssessmentItemEditorController extends BasicController { case kprim: itemBuilder = initKPrimChoiceEditors(ureq, item); break; case match: itemBuilder = initMatchChoiceEditors(ureq, item); break; case matchdraganddrop: itemBuilder = initMatchDragAndDropEditors(ureq, item); break; + case matchtruefalse: itemBuilder = initMatchTrueFalseEditors(ureq, item); break; case hotspot: itemBuilder = initHotspotEditors(ureq, item); break; case essay: itemBuilder = initEssayEditors(ureq, item); break; case upload: itemBuilder = initUploadEditors(ureq, item); break; @@ -336,7 +338,7 @@ public class AssessmentItemEditorController extends BasicController { itemEditor = new MatchEditorController(ureq, getWindowControl(), matchItemBuilder, rootDirectory, rootContainer, itemFile, restrictedEdit, readOnly); listenTo(itemEditor); - scoreEditor = new MatchScoreController(ureq, getWindowControl(), matchItemBuilder, itemRef, itemFile, + scoreEditor = new MatchScoreController(ureq, getWindowControl(), matchItemBuilder, itemRef, itemFile, true, restrictedEdit, readOnly); listenTo(scoreEditor); feedbackEditor = new FeedbacksEditorController(ureq, getWindowControl(), matchItemBuilder, @@ -355,7 +357,26 @@ public class AssessmentItemEditorController extends BasicController { itemEditor = new MatchEditorController(ureq, getWindowControl(), matchItemBuilder, rootDirectory, rootContainer, itemFile, restrictedEdit, readOnly); listenTo(itemEditor); - scoreEditor = new MatchScoreController(ureq, getWindowControl(), matchItemBuilder, itemRef, itemFile, + scoreEditor = new MatchScoreController(ureq, getWindowControl(), matchItemBuilder, itemRef, itemFile, true, + restrictedEdit, readOnly); + listenTo(scoreEditor); + feedbackEditor = new FeedbacksEditorController(ureq, getWindowControl(), matchItemBuilder, + rootDirectory, rootContainer, itemFile, FeedbacksEnabler.standardFeedbacks(), + restrictedEdit, readOnly); + listenTo(feedbackEditor); + + tabbedPane.addTab(translate("form.match"), itemEditor); + tabbedPane.addTab(translate("form.score"), scoreEditor); + tabbedPane.addTab(translate("form.feedback"), feedbackEditor); + return matchItemBuilder; + } + + private AssessmentItemBuilder initMatchTrueFalseEditors(UserRequest ureq, AssessmentItem item) { + MatchAssessmentItemBuilder matchItemBuilder = new MatchAssessmentItemBuilder(item, qtiService.qtiSerializer()); + itemEditor = new TrueFalseEditorController(ureq, getWindowControl(), matchItemBuilder, + rootDirectory, rootContainer, itemFile, restrictedEdit, readOnly); + listenTo(itemEditor); + scoreEditor = new MatchScoreController(ureq, getWindowControl(), matchItemBuilder, itemRef, itemFile, false, restrictedEdit, readOnly); listenTo(scoreEditor); feedbackEditor = new FeedbacksEditorController(ureq, getWindowControl(), matchItemBuilder, diff --git a/src/main/java/org/olat/ims/qti21/ui/editor/AssessmentTestComposerController.java b/src/main/java/org/olat/ims/qti21/ui/editor/AssessmentTestComposerController.java index a96e2720a569a6973359aa90838f68d41ae16d8a..ec845e72046d7d15d296b903cb0f40c69335b2c4 100644 --- a/src/main/java/org/olat/ims/qti21/ui/editor/AssessmentTestComposerController.java +++ b/src/main/java/org/olat/ims/qti21/ui/editor/AssessmentTestComposerController.java @@ -154,7 +154,7 @@ public class AssessmentTestComposerController extends MainLayoutBasicController private MenuTree menuTree; private Dropdown exportItemTools, addItemTools, changeItemTools; private Link newTestPartLink, newSectionLink, newSingleChoiceLink, newMultipleChoiceLink, - newKPrimLink, newMatchLink, newMatchDragAndDropLink, + newKPrimLink, newMatchLink, newMatchDragAndDropLink, newMatchTrueFalseLink, newFIBLink, newNumericalLink, newHotspotLink, newHottextLink, newEssayLink, newUploadLink, newDrawingLink; private Link importFromPoolLink, importFromTableLink, exportToPoolLink, exportToDocxLink; @@ -278,7 +278,10 @@ public class AssessmentTestComposerController extends MainLayoutBasicController newMatchDragAndDropLink = LinkFactory.createToolLink("new.matchdraganddrop", translate("new.matchdraganddrop"), this, "o_mi_qtimatch_draganddrop"); newMatchDragAndDropLink.setDomReplacementWrapperRequired(false); addItemTools.addComponent(newMatchDragAndDropLink); - + newMatchTrueFalseLink = LinkFactory.createToolLink("new.matchtruefalse", translate("new.matchtruefalse"), this, "o_mi_qtimatch_truefalse"); + newMatchTrueFalseLink.setDomReplacementWrapperRequired(false); + addItemTools.addComponent(newMatchTrueFalseLink); + newFIBLink = LinkFactory.createToolLink("new.fib", translate("new.fib"), this, "o_mi_qtifib"); newFIBLink.setDomReplacementWrapperRequired(false); addItemTools.addComponent(newFIBLink); @@ -514,6 +517,9 @@ public class AssessmentTestComposerController extends MainLayoutBasicController doNewAssessmentItem(ureq, menuTree.getSelectedNode(), new MatchAssessmentItemBuilder(translate("new.match"), QTI21Constants.CSS_MATCH_MATRIX, qtiService.qtiSerializer())); } else if(newMatchDragAndDropLink == source) { doNewAssessmentItem(ureq, menuTree.getSelectedNode(), new MatchAssessmentItemBuilder(translate("new.matchdraganddrop"), QTI21Constants.CSS_MATCH_DRAG_AND_DROP, qtiService.qtiSerializer())); + } else if(newMatchTrueFalseLink == source) { + doNewAssessmentItem(ureq, menuTree.getSelectedNode(), new MatchAssessmentItemBuilder(translate("new.matchtruefalse"), QTI21Constants.CSS_MATCH_TRUE_FALSE, + translate("match.unanswered"), translate("match.true"), translate("match.false"), qtiService.qtiSerializer())); } else if(newFIBLink == source) { doNewAssessmentItem(ureq, menuTree.getSelectedNode(), new FIBAssessmentItemBuilder(translate("new.fib"), EntryType.text, qtiService.qtiSerializer())); } else if(newNumericalLink == source) { diff --git a/src/main/java/org/olat/ims/qti21/ui/editor/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/ims/qti21/ui/editor/_i18n/LocalStrings_de.properties index 0ec4d2493e67627be447cdd18121ea08b77c00c1..0d6ca44f4e226f3ce17d7962b24a55a33c29df91 100644 --- a/src/main/java/org/olat/ims/qti21/ui/editor/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/ims/qti21/ui/editor/_i18n/LocalStrings_de.properties @@ -181,6 +181,9 @@ item.session.control.attempts.hint=Diese Einschr\u00E4nkung der L\u00F6sungsvers item.session.control.show.solution=L\u00F6sung anzeigen item.session.control.show.solution.hint=Beim R\u00FCckblick werden auch L\u00F6sungen angezeigt. lifecycle.version=$org.olat.modules.qpool.ui\:lifecycle.version +match.unanswered=Unbeantwortet +match.true=Richtig +match.false=Falsch math.operator.bigger=> math.operator.biggerEquals=>\= math.operator.equals=\= @@ -208,6 +211,7 @@ new.hottext.text=Hottext new.kprim=Kprim new.match=Matrix new.matchdraganddrop=Drag and Drop +new.matchtruefalse=True/false new.mc=Multiple Choice new.rectangle=Viereck new.sc=Single Choice diff --git a/src/main/java/org/olat/ims/qti21/ui/editor/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/ims/qti21/ui/editor/_i18n/LocalStrings_en.properties index 2bd777a1782d5996bb80f50130d6053be14899a8..b468c8a82483a8f75570af4e70d9bc270a4f76ba 100644 --- a/src/main/java/org/olat/ims/qti21/ui/editor/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/ims/qti21/ui/editor/_i18n/LocalStrings_en.properties @@ -180,6 +180,9 @@ item.session.control.attempts.hint=This limitation of the attempts is only valid item.session.control.show.solution=Show solution item.session.control.show.solution.hint=Solution is shown in review as well. lifecycle.version=$org.olat.modules.qpool.ui\:lifecycle.version +match.unanswered=Unanswered +match.true=Right +match.false=Wrong math.operator.bigger=> math.operator.biggerEquals=>\= math.operator.equals=\= @@ -208,6 +211,7 @@ new.hottext.text=text new.kprim=Kprim new.match=Match new.matchdraganddrop=Drag and Drop +new.matchtruefalse=True/false new.mc=Multiple choice new.rectangle=Rectangle new.sc=Single choice diff --git a/src/main/java/org/olat/ims/qti21/ui/editor/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/ims/qti21/ui/editor/_i18n/LocalStrings_fr.properties index 0be95da7d656e79c917232bf68229a8427aec79b..47a723b540a062aaf477298c6e84507d370558c7 100644 --- a/src/main/java/org/olat/ims/qti21/ui/editor/_i18n/LocalStrings_fr.properties +++ b/src/main/java/org/olat/ims/qti21/ui/editor/_i18n/LocalStrings_fr.properties @@ -1,4 +1,4 @@ -#Thu Nov 16 19:02:40 CET 2017 +#Thu Feb 01 18:25:17 CET 2018 Diff\u00E9rentes=alternatives MULTIPLE=Choix multiple SINGLE=Choix simple @@ -18,6 +18,8 @@ change.elements=Edition convert=Convertir convert.alien=Convertir convert.to=Transformer en\: +copy.at=Copi\u00E9 le +copy.qpool.question=Faire une copie et l'\u00E9diter correct.answers=Correct cut.value=Nombre de points n\u00E9cessaire pour "r\u00E9ussi" delete=Effacer @@ -135,6 +137,7 @@ form.match=Match form.metadata=M\u00E9tadonn\u00E9es form.metadata.description=Description form.metadata.title=Titre +form.pool=Banque de questions form.score=Score form.score.answer.correct=Correct form.score.answer.points=Points @@ -157,6 +160,8 @@ form.testPart.navigationMode.linear=Lin\u00E9aire form.testPart.navigationMode.nonlinear=Non lin\u00E9aire form.unkown=Inconnu form.upload=T\u00E9l\u00E9verser un fichier +general.identifier=$org.olat.modules.qpool.ui\:general.identifier +general.master.identifier=$org.olat.modules.qpool.ui\:general.master.identifier hotspot.layout=Couleur des hotpsots hotspot.layout.green=Vert hotspot.layout.inverted=Invers\u00E9 @@ -176,6 +181,7 @@ item.session.control.attempts=Tentatives item.session.control.attempts.hint=Cette limitation du nombre d'essai est seulement valide pour les parties de test et non pour le test entier. Le nombre d'essai pour le test entier peut \u00EAtre limit\u00E9 dans "Options". item.session.control.show.solution=Afficher la solution item.session.control.show.solution.hint=Lors de la revue, les solutions sont \u00E9galement pr\u00E9sent\u00E9es. +lifecycle.version=$org.olat.modules.qpool.ui\:lifecycle.version math.operator.bigger=> math.operator.biggerEquals=>\= math.operator.equals=\= @@ -203,6 +209,7 @@ new.hottext.text=texte new.kprim=Kprim new.match=Match new.matchdraganddrop=Drag and Drop +new.matchtruefalse=True/false new.mc=Choix multiples new.rectangle=Rectangle new.sc=Choix simple @@ -212,6 +219,7 @@ new.testpart=Partie de test new.upload=T\u00E9l\u00E9verser un fichier preview=Aper\u00E7u preview.solution=Aper\u00E7u de la solution +rights.owners=$org.olat.modules.qpool.ui\:rights.owners time.limit.max=Limite de temps (minute) title.add=$org.olat.ims.qti.editor\:title.add tools.change.copy=$org.olat.ims.qti.editor\:tools.change.copy @@ -233,6 +241,7 @@ warning.atleastone=Choisir au moins un \u00E9l\u00E9ment s'il vous pla\u00EEt. warning.atleastonesection=La section ne peut pas \u00EAtre supprim\u00E9e. Un test ou un "test part" doit contenir au moins une section. warning.conversion.list=Des incompatibilit\u00E9s avec l'\u00E9diteur ont \u00E9t\u00E9 d\u00E9tect\u00E9es\: warning.conversion.standard=Il existe un risque que des donn\u00E9es soient perdues bien qu'aucune incompatibilit\u00E9 n'ait \u00E9t\u00E9 d\u00E9tect\u00E9e. +warning.copy.from.pool=La question a \u00E9t\u00E9 copi\u00E9e depuis la banque de questions. Vous pouvez retrouver l'originale avec l'ID master. warning.custom.operator=Une extension non-standard a \u00E9t\u00E9 trouv\u00E9e que cette \u00E9diteur ne la supporte pas. warning.feedback.cutvalue=Le feedback est bas\u00E9 sur la valeur "Points n\u00E9cessaire pour 'R\u00E9ussi'" et cell-ci doit \u00EAtre d'abord d\u00E9finie. warning.in.use=La ressource est d\u00E9j\u00E0 utilis\u00E9e pour au moins une \u00E9valuation. L'\u00E9dition en est limit\u00E9e. diff --git a/src/main/java/org/olat/ims/qti21/ui/editor/interactions/MatchScoreController.java b/src/main/java/org/olat/ims/qti21/ui/editor/interactions/MatchScoreController.java index 4c5385eda1170bc3a048642e3b8c8386e98deabd..c91e91438dae43843b9d12bd36dbed57ad3ab020 100644 --- a/src/main/java/org/olat/ims/qti21/ui/editor/interactions/MatchScoreController.java +++ b/src/main/java/org/olat/ims/qti21/ui/editor/interactions/MatchScoreController.java @@ -80,16 +80,18 @@ public class MatchScoreController extends AssessmentItemRefEditorController impl private int count = 0; private final String mapperUri; private final File itemFileRef; + private final boolean sourceLeft; private List<MatchWrapper> sourceWrappers = new ArrayList<>(); private List<MatchWrapper> targetWrappers = new ArrayList<>(); private Map<DirectedPairValue, MatchScoreWrapper> scoreWrappers = new HashMap<>(); public MatchScoreController(UserRequest ureq, WindowControl wControl, MatchAssessmentItemBuilder itemBuilder, - AssessmentItemRef itemRef, File itemFileRef, boolean restrictedEdit, boolean readOnly) { + AssessmentItemRef itemRef, File itemFileRef, boolean sourceLeft, boolean restrictedEdit, boolean readOnly) { super(ureq, wControl, itemRef, restrictedEdit, readOnly); setTranslator(Util.createPackageTranslator(AssessmentTestEditorController.class, getLocale())); this.itemBuilder = itemBuilder; this.itemFileRef = itemFileRef; + this.sourceLeft = sourceLeft; URI assessmentObjectUri = itemFileRef.toURI(); mapperUri = registerCacheableMapper(null, "MatchScoreController::" + CodeHelper.getRAMUniqueID(), @@ -133,6 +135,7 @@ public class MatchScoreController extends AssessmentItemRefEditorController impl formLayout.add(scoreCont); scoreCont.setLabel(null, null); scoreCont.setVisible(assessmentModeEl.isSelected(1)); + scoreCont.contextPut("sourceLeft", Boolean.valueOf(sourceLeft)); for(SimpleAssociableChoice choice:itemBuilder.getSourceMatchSet().getSimpleAssociableChoices()) { sourceWrappers.add(createMatchWrapper(choice)); diff --git a/src/main/java/org/olat/ims/qti21/ui/editor/interactions/TrueFalseEditorController.java b/src/main/java/org/olat/ims/qti21/ui/editor/interactions/TrueFalseEditorController.java new file mode 100644 index 0000000000000000000000000000000000000000..0dc283e50758d4c6b9c68a61b30e5921671317c1 --- /dev/null +++ b/src/main/java/org/olat/ims/qti21/ui/editor/interactions/TrueFalseEditorController.java @@ -0,0 +1,364 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.ims.qti21.ui.editor.interactions; + +import static org.olat.ims.qti21.model.xml.AssessmentItemFactory.createSimpleAssociableChoice; + +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import org.olat.core.gui.UserRequest; +import org.olat.core.gui.components.form.flexible.FormItem; +import org.olat.core.gui.components.form.flexible.FormItemContainer; +import org.olat.core.gui.components.form.flexible.elements.FormLink; +import org.olat.core.gui.components.form.flexible.elements.RichTextElement; +import org.olat.core.gui.components.form.flexible.elements.TextElement; +import org.olat.core.gui.components.form.flexible.impl.FormBasicController; +import org.olat.core.gui.components.form.flexible.impl.FormEvent; +import org.olat.core.gui.components.form.flexible.impl.FormLayoutContainer; +import org.olat.core.gui.components.htmlheader.jscss.JSAndCSSFormItem; +import org.olat.core.gui.components.link.Link; +import org.olat.core.gui.control.Controller; +import org.olat.core.gui.control.WindowControl; +import org.olat.core.util.Util; +import org.olat.core.util.vfs.VFSContainer; +import org.olat.ims.qti21.model.QTI21QuestionType; +import org.olat.ims.qti21.model.xml.interactions.MatchAssessmentItemBuilder; +import org.olat.ims.qti21.ui.editor.AssessmentTestEditorController; +import org.olat.ims.qti21.ui.editor.events.AssessmentItemEvent; + +import uk.ac.ed.ph.jqtiplus.node.item.interaction.MatchInteraction; +import uk.ac.ed.ph.jqtiplus.node.item.interaction.choice.SimpleAssociableChoice; +import uk.ac.ed.ph.jqtiplus.types.Identifier; + +/** + * + * Initial date: 31 janv. 2018<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class TrueFalseEditorController extends FormBasicController { + + private TextElement titleEl; + private FormLink addRowButton; + private RichTextElement textEl; + private FormLayoutContainer answersCont; + + private int count = 0; + private VFSContainer itemContainer; + + private final boolean restrictedEdit, readOnly; + private MatchAssessmentItemBuilder itemBuilder; + private final List<SourceWrapper> sourceWrappers = new ArrayList<>(); + private final Map<String,List<String>> temporaryAssociations = new HashMap<>(); + + /** + * + * @param ureq The user request + * @param wControl The parent window control + * @param itemBuilder The assessment item builder for match (matrix or drag and drop) + * @param rootDirectory The directory for images... + * @param rootContainer The directory for images... + * @param itemFile The assessment item file + * @param matrix + * @param restrictedEdit + */ + public TrueFalseEditorController(UserRequest ureq, WindowControl wControl, MatchAssessmentItemBuilder itemBuilder, + File rootDirectory, VFSContainer rootContainer, File itemFile, boolean restrictedEdit, boolean readOnly) { + super(ureq, wControl, "simple_choices_editor"); + setTranslator(Util.createPackageTranslator(AssessmentTestEditorController.class, getLocale())); + this.itemBuilder = itemBuilder; + this.readOnly = readOnly; + this.restrictedEdit = restrictedEdit; + + String relativePath = rootDirectory.toPath().relativize(itemFile.toPath().getParent()).toString(); + itemContainer = (VFSContainer)rootContainer.resolve(relativePath); + + initForm(ureq); + } + + @Override + protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { + FormLayoutContainer metadata = FormLayoutContainer.createDefaultFormLayout("metadata", getTranslator()); + if (itemBuilder.getQuestionType() == QTI21QuestionType.matchdraganddrop) { + metadata.setFormContextHelp("Test editor QTI 2.1 in detail#details_testeditor_fragetypen_draganddrop"); + } else { + metadata.setFormContextHelp("Test editor QTI 2.1 in detail#details_testeditor_fragetypen_match"); + } + metadata.setRootForm(mainForm); + formLayout.add(metadata); + formLayout.add("metadata", metadata); + + titleEl = uifactory.addTextElement("title", "form.imd.title", -1, itemBuilder.getTitle(), metadata); + titleEl.setElementCssClass("o_sel_assessment_item_title"); + titleEl.setMandatory(true); + titleEl.setEnabled(!readOnly); + + String description = itemBuilder.getQuestion(); + textEl = uifactory.addRichTextElementForQTI21("desc", "form.imd.descr", description, 8, -1, itemContainer, + metadata, ureq.getUserSession(), getWindowControl()); + textEl.setEnabled(!readOnly); + + //responses + String page = velocity_root + "/match_truefalse.html"; + answersCont = FormLayoutContainer.createCustomFormLayout("answers", getTranslator(), page); + answersCont.setRootForm(mainForm); + answersCont.contextPut("showHeaders", (itemBuilder.getQuestionType() == QTI21QuestionType.matchdraganddrop)); + formLayout.add(answersCont); + formLayout.add("answers", answersCont); + + MatchInteraction interaction = itemBuilder.getMatchInteraction(); + if(interaction != null) { + List<SimpleAssociableChoice> sourceChoices = itemBuilder.getSourceChoices(); + for(SimpleAssociableChoice sourceChoice:sourceChoices) { + wrapSource(ureq, sourceChoice, sourceWrappers); + } + List<TargetWrapper> targetChoices = itemBuilder.getTargetChoices() + .stream().map(c -> new TargetWrapper(c)).collect(Collectors.toList()); + answersCont.contextPut("targetChoices", targetChoices); + } + answersCont.contextPut("sourceChoices", sourceWrappers); + answersCont.contextPut("restrictedEdit", restrictedEdit || readOnly); + answersCont.contextPut("responseIdentifier", itemBuilder.getResponseIdentifier()); + int maxAssociations = itemBuilder.getMatchInteraction().getMaxAssociations(); + answersCont.contextPut("interactionMaxAssociations", maxAssociations); + + JSAndCSSFormItem js = new JSAndCSSFormItem("js", new String[] { "js/jquery/qti/jquery.match.js" }); + formLayout.add(js); + + if(!readOnly) { + uifactory.addFormSubmitButton("submit", answersCont); + } + if(!restrictedEdit && !readOnly) { + addRowButton = uifactory.addFormLink("add.match.row", answersCont, Link.BUTTON); + addRowButton.setElementCssClass("o_sel_match_add_row"); + addRowButton.setIconLeftCSS("o_icon o_icon_add"); + } + } + + private void wrapSource(UserRequest ureq, SimpleAssociableChoice choice, List<SourceWrapper> wrappers) { + String choiceContent = itemBuilder.getHtmlHelper().flowStaticString(choice.getFlowStatics()); + String choiceId = "answer" + count++; + RichTextElement choiceEl = uifactory.addRichTextElementForQTI21Match(choiceId, "form.imd.answer", choiceContent, 4, -1, itemContainer, + answersCont, ureq.getUserSession(), getWindowControl()); + choiceEl.setUserObject(choice); + choiceEl.setEnabled(!readOnly); + answersCont.add("choiceId", choiceEl); + + FormLink deleteButton = uifactory.addFormLink("del_" + (count++), "delete", "delete", null, answersCont, Link.NONTRANSLATED); + deleteButton.setIconLeftCSS("o_icon o_icon_delete_item"); + deleteButton.setVisible(!restrictedEdit && !readOnly); + deleteButton.setI18nKey(""); + + SourceWrapper wrapper = new SourceWrapper(choice, choiceEl, deleteButton); + deleteButton.setUserObject(wrapper); + wrappers.add(wrapper); + } + + @Override + protected void doDispose() { + // + } + + @Override + protected boolean validateFormLogic(UserRequest ureq) { + boolean allOk = super.validateFormLogic(ureq); + + commitTemporaryAssociations(ureq); + for(SourceWrapper sourceWrapper:sourceWrappers) { + sourceWrapper.setErrorSingleChoice(false); + List<String> answers = temporaryAssociations.get(sourceWrapper.getIdentifierString()); + sourceWrapper.setErrorSingleChoice(answers == null || answers.size() != 1); + } + + return allOk; + } + + @Override + protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) { + if(addRowButton == source) { + commitTemporaryAssociations(ureq); + doAddSourceRow(ureq); + } else if(source instanceof FormLink) { + FormLink button = (FormLink)source; + if("delete".equals(button.getCmd())) { + commitTemporaryAssociations(ureq); + SourceWrapper associationWrapper = (SourceWrapper)button.getUserObject(); + doDeleteAssociableChoice(associationWrapper); + } + } + super.formInnerEvent(ureq, source, event); + } + + @Override + protected void formOK(UserRequest ureq) { + if(readOnly) return; + //title + itemBuilder.setTitle(titleEl.getValue()); + //question + String questionText = textEl.getRawValue(); + itemBuilder.setQuestion(questionText); + + if(!restrictedEdit) { + itemBuilder.setMultipleChoice(false); + itemBuilder.setShuffle(false); + } + + //update + for(SourceWrapper sourceWrapper:sourceWrappers) { + SimpleAssociableChoice choice = sourceWrapper.getSimpleChoice(); + String answer = sourceWrapper.getText().getRawValue(); + itemBuilder.getHtmlHelper().appendHtml(choice, answer); + } + + //correct answers + commitAssociations(ureq); + + fireEvent(ureq, new AssessmentItemEvent(AssessmentItemEvent.ASSESSMENT_ITEM_CHANGED, itemBuilder.getAssessmentItem(), QTI21QuestionType.match)); + } + + private void commitTemporaryAssociations(UserRequest ureq) { + temporaryAssociations.clear(); + + for(SourceWrapper sourceWrapper:sourceWrappers) { + String[] targetParamIds = ureq.getHttpReq().getParameterValues(sourceWrapper.getIdentifierString()); + if(targetParamIds != null && targetParamIds.length == 1) { + String sourceId = sourceWrapper.getIdentifierString(); + String targetId = targetParamIds[0]; + + List<String> targetIds = temporaryAssociations.computeIfAbsent(sourceId, s -> new ArrayList<>()); + targetIds.add(targetId); + temporaryAssociations.put(sourceId, targetIds); + } + } + } + + private void commitAssociations(UserRequest ureq) { + if(restrictedEdit) return; + + temporaryAssociations.clear(); + itemBuilder.clearAssociations(); + for(SourceWrapper sourceWrapper:sourceWrappers) { + String[] targetParamIds = ureq.getHttpReq().getParameterValues(sourceWrapper.getIdentifierString()); + if(targetParamIds != null && targetParamIds.length == 1) { + Identifier sourceChoiceId = sourceWrapper.getIdentifier(); + Identifier targetChoiceId = Identifier.assumedLegal(targetParamIds[0]); + itemBuilder.addAssociation(sourceChoiceId, targetChoiceId); + } + } + } + + private void doAddSourceRow(UserRequest ureq) { + SimpleAssociableChoice newChoice = createSimpleAssociableChoice("Text", itemBuilder.getSourceMatchSet()); + itemBuilder.getSourceMatchSet().getSimpleAssociableChoices().add(newChoice); + wrapSource(ureq, newChoice, sourceWrappers); + answersCont.setDirty(true); + } + + private void doDeleteAssociableChoice(SourceWrapper associationWrapper) { + if(sourceWrappers.remove(associationWrapper)) { + itemBuilder.removeSimpleAssociableChoice(associationWrapper.getSimpleChoice()); + } + answersCont.setDirty(true); + } + + public class TargetWrapper { + + private final Identifier choiceIdentifier; + private final String choiceText; + + public TargetWrapper(SimpleAssociableChoice choice) { + choiceText = itemBuilder.getHtmlHelper().flowStaticString(choice.getFlowStatics()); + choiceIdentifier = choice.getIdentifier(); + } + + public Identifier getIdentifier() { + return choiceIdentifier; + } + + public String getIdentifierString() { + return choiceIdentifier.toString(); + } + + public String getChoiceText() { + return choiceText; + } + } + + public class SourceWrapper { + + private FormLink deleteButton; + private RichTextElement choiceTextEl; + private final Identifier choiceIdentifier; + private final SimpleAssociableChoice choice; + + private boolean errorSingleChoice; + + public SourceWrapper(SimpleAssociableChoice choice, RichTextElement choiceTextEl, FormLink deleteButton) { + this.choice = choice; + this.choiceTextEl = choiceTextEl; + this.choiceIdentifier = choice.getIdentifier(); + this.deleteButton = deleteButton; + } + + public Identifier getIdentifier() { + return choiceIdentifier; + } + + public String getIdentifierString() { + return choiceIdentifier.toString(); + } + + public SimpleAssociableChoice getSimpleChoice() { + return choice; + } + + public FormLink getDeleteButton() { + return deleteButton; + } + + public RichTextElement getText() { + return choiceTextEl; + } + + public boolean isCorrect(Identifier targetChoiceId) { + String sourceId = choice.getIdentifier().toString(); + String targetId = targetChoiceId.toString(); + if(temporaryAssociations.containsKey(sourceId)) { + if(temporaryAssociations.get(sourceId).contains(targetId)) { + return true; + } + } + return itemBuilder.isCorrect(choiceIdentifier, targetChoiceId); + } + + public boolean isErrorSingleChoice() { + return errorSingleChoice; + } + + public void setErrorSingleChoice(boolean errorSingleChoice) { + this.errorSingleChoice = errorSingleChoice; + } + } +} diff --git a/src/main/java/org/olat/ims/qti21/ui/editor/interactions/_content/match_score.html b/src/main/java/org/olat/ims/qti21/ui/editor/interactions/_content/match_score.html index 56689877bf6d96efe3a93fae9931356fe4db25be..04bfa726f3d8a6504599d61086247f4de8c1767a 100644 --- a/src/main/java/org/olat/ims/qti21/ui/editor/interactions/_content/match_score.html +++ b/src/main/java/org/olat/ims/qti21/ui/editor/interactions/_content/match_score.html @@ -1,16 +1,19 @@ <table class="table matchInteraction score"> <thead> <tr> - <th></th> + #if($r.isTrue($sourceLeft)) <th></th> #end #foreach($targetChoice in $targetChoices) <th>${r.render($targetChoice.getSummaryEl())} #end + #if($r.isFalse($sourceLeft)) <th></th> #end </tr> </thead> <tbody> #foreach($sourceChoice in $sourceChoices) <tr> - <th>${r.render($sourceChoice.getSummaryEl())}</th> + #if($r.isTrue($sourceLeft)) + <th>${r.render($sourceChoice.getSummaryEl())}</th> + #end #set($sourceIndex = ${foreach.index}) #foreach($targetChoice in $targetChoices) <td class="o_sel_match_${sourceIndex}_${foreach.index}"> @@ -24,6 +27,9 @@ #end </td> #end + #if($r.isFalse($sourceLeft)) + <td>${r.render($sourceChoice.getSummaryEl())}</td> + #end </tr> #end </tbody> diff --git a/src/main/java/org/olat/ims/qti21/ui/editor/interactions/_content/match_truefalse.html b/src/main/java/org/olat/ims/qti21/ui/editor/interactions/_content/match_truefalse.html new file mode 100644 index 0000000000000000000000000000000000000000..41e288c947447485f191f922707bb8f10acf2791 --- /dev/null +++ b/src/main/java/org/olat/ims/qti21/ui/editor/interactions/_content/match_truefalse.html @@ -0,0 +1,49 @@ +<fieldset class="o_form form-horizontal"> + +<table id="qti_container_${responseIdentifier}" class="table match_true_false o_match_true_false_edit"> + <thead> + <tr> + #foreach($targetChoice in $targetChoices) + <th class="o_sel_match_target_${foreach.index}" style="border-top: none;">${targetChoice.getChoiceText()}</th> + #end + <th style="border-top: none;"> </th> + </tr> + </thead> + <tbody> + #foreach($sourceChoice in $sourceChoices) + #set($set1Identifier = $sourceChoice.getIdentifierString()) + <tr> + #set($sourceIndex = ${foreach.index}) + #foreach($targetChoice in $targetChoices) + #set($set2Identifier = $targetChoice.getIdentifierString()) + #set($responseValue = $set1Identifier + " " + $set2Identifier) + <td class="o_sel_match_${sourceIndex}_${foreach.index}"> + <input id="oo_${set1Identifier}_${set2Identifier}" type="radio" name="${set1Identifier}" value="${set2Identifier}" #if(${sourceChoice.isCorrect(${targetChoice.getIdentifier()})}) checked #end #if($restrictedEdit) disabled #end/> + $f.appendFlexiFormDirtyForCheckbox("oo_${set1Identifier}_${set2Identifier}") + #if(${sourceChoice.isErrorSingleChoice()}) + <div class="o_error">$r.translate("error.singlechoice")</div> + #end + </td> + #end + <th class="o_sel_match_source_${foreach.index}">$r.render(${sourceChoice.getText()}) + #if($f.hasError($item)) + <span class="o_icon o_icon_error form-control-feedback"></span> + #end + #if(!$restrictedEdit) <div class="pull-right">$r.render(${sourceChoice.getDeleteButton()})</div> #end + </th> + </tr> + #end + </tbody> +</table> + +#if($r.available("add.match.row") || $r.available("submit")) +<div class="o_button_group o_sel_match_save"> + #if($r.available("submit")) + $r.render("submit") + #end + #if($r.available("add.match.row")) + $r.render("add.match.row") + #end +</div> +#end +</fieldset> \ No newline at end of file diff --git a/src/main/java/org/olat/login/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/login/_i18n/LocalStrings_fr.properties index 38cdabc634c102ca754601eb9395fa1371aef2bb..86857ece73128768d35b43ae4db17242a04f7494 100644 --- a/src/main/java/org/olat/login/_i18n/LocalStrings_fr.properties +++ b/src/main/java/org/olat/login/_i18n/LocalStrings_fr.properties @@ -1,4 +1,4 @@ -#Tue Aug 15 17:29:04 CEST 2017 +#Thu Feb 01 18:37:13 CET 2018 about.copyright=Copyright et participations about.custom= about.custom.title= @@ -116,6 +116,7 @@ timeout.message=Votre session a expir\u00E9 ou le serveur a \u00E9t\u00E9 red\u0 timeout.title=Expiration de la session topnav.help=Aide topnav.help.alt=D\u00E9marrer l'aide de OpenOLAT +warning.old.browser=La version de votre butineur n'est plus support\u00E9e. Veuillez mettre \u00E0 jour votre butineur pour qu'OpenOLAT fonctionne sans accroc. Vous trouverez plus d'information dans le manual\: <a href\="{0}" target\="_blank">Manuel d'utilisation</a>. wayf.homesite=Institution wayf.intro=Veuillez choisir votre institution.<br>Vous allez \u00EAtre redirig\u00E9(e) pour l'authentification. wayf.pleasechoose=Veuillez choisir votre institution... diff --git a/src/main/java/org/olat/modules/assessment/ui/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/modules/assessment/ui/_i18n/LocalStrings_fr.properties index 37a549f67104fb6026b0c5c01131f75143b4266e..5d8f134f0fa4b0d423ccd1d204cf9e824343f64f 100644 --- a/src/main/java/org/olat/modules/assessment/ui/_i18n/LocalStrings_fr.properties +++ b/src/main/java/org/olat/modules/assessment/ui/_i18n/LocalStrings_fr.properties @@ -1,4 +1,4 @@ -#Fri Sep 23 11:41:35 CEST 2016 +#Thu Feb 01 18:26:00 CET 2018 assessment.status.done=Evalu\u00E9 assessment.status.inProgress=D\u00E9marr\u00E9 assessment.status.inReview=A passer en revue @@ -24,9 +24,11 @@ filter.passed=R\u00E9ussi index.introduction=Evaluez les participants de ce test avec l'outil d'\u00E9valuation. Il vous permettra d'acc\u00E9der aux r\u00E9sultats des tests et de les modifier. reopen=R\u00E9ouvrir review=Passer en revue +run.ended=Termin\u00E9 save.done=Sauver comme compl\u00E9t\u00E9 statistics.small.overview=Aper\u00E7u statistiques table.header.assessmentStatus=Status +table.header.completion=Progression table.header.elements.toReview=Passer en revue table.header.name=Nom d'utilisateur table.header.numOfAssessedIdentities=\# participants diff --git a/src/main/java/org/olat/modules/docpool/ui/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/modules/docpool/ui/_i18n/LocalStrings_fr.properties index ec400f245119e08d37e8f233e871f32d0f4a9e6c..d9200144f9c125a764bbc80baff7a862127fdbad 100644 --- a/src/main/java/org/olat/modules/docpool/ui/_i18n/LocalStrings_fr.properties +++ b/src/main/java/org/olat/modules/docpool/ui/_i18n/LocalStrings_fr.properties @@ -1,4 +1,4 @@ -#Fri Nov 17 11:56:26 CET 2017 +#Thu Feb 01 18:27:02 CET 2018 admin.description=La banque de documents propose une biblioth\u00E8que de documents structur\u00E9 automatiquement sur la base d'une taxonomie et des comp\u00E9tences. admin.menu.title=Banque de documents admin.menu.title.alt=Banque de documents @@ -34,3 +34,4 @@ teach.can.read.parent.levels.explain.1=Autoriser l'acc\u00E8s en lecture des teach.can.read.parent.levels.explain.2=niveaux au-dessus teach.can.write=Autoriser l'acc\u00E8s en \u00E9criture teach.competence=Comp\u00E9tence enseignement +warning.taxonomy.index.emtpy=La page d'informations de la banque de documents n'a pas \u00E9t\u00E9 configur\u00E9e. Demandez, s'il-vous-pla\u00EEt, \u00E0 l'administrateur syst\u00E8me d'en mettre une \u00E0 disposition des utilisateurs. diff --git a/src/main/java/org/olat/modules/portfolio/ui/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/modules/portfolio/ui/_i18n/LocalStrings_en.properties index 42132939fed00610aec8f96bddc2433f81b0795d..ec5dab3a51662acf675106af88219f1fe05da27a 100644 --- a/src/main/java/org/olat/modules/portfolio/ui/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/modules/portfolio/ui/_i18n/LocalStrings_en.properties @@ -1,4 +1,4 @@ -#Fri Aug 18 10:31:35 CEST 2017 +#Tue Feb 06 08:30:51 CET 2018 access=Access access.binder=The people below have access to the portfolio binder\: access.rights=Add access rights @@ -92,6 +92,8 @@ comment.several={0} comments comment.title=Comments comment.zero=Still no comments compare.evaluations=Evaluation +confirm.close.page=Do you really want to close this entry? The entry will be marked as closed for the trainee. +confirm.close.page.other.coaches=The following persons also have access to this entry\: confirmation=Confirmation create.binder=Create binder create.empty.binder=New empty binder @@ -347,9 +349,9 @@ status.inRevision=$\:status.in.revision status.not.started=not started status.published=published status.submitted=submitted -status.user.incoming=New -status.user.inProcess=In process status.user.done=Done +status.user.inProcess=In process +status.user.incoming=New summary=Summary summary.close=Hide summary summary.open=Open summary @@ -358,7 +360,6 @@ table.grading.failed.points=<span class\="o_state o_failed"><i class\="o_icon o_ table.grading.no=no grading yet table.grading.passed.points=<span class\="o_state o_passed"><i class\="o_icon o_icon_passed"> </i> {0} Point(s), passed</span> table.grading.points={0} Point(s) -table.header.mark=<i class\="o_icon o_icon_bookmark_header o_icon-lg" title\="Bookmark"> </i> table.header.categories=Categories table.header.change.status=Status table.header.closed=Closed @@ -372,6 +373,7 @@ table.header.grading=Grading table.header.inRevision=$\:status.in.revision table.header.key=ID table.header.lastUpdate=Last update +table.header.mark=<i class\="o_icon o_icon_bookmark_header o_icon-lg" title\="Bookmark"> </i> table.header.new=New table.header.numpages=\# Entries table.header.open=Start diff --git a/src/main/java/org/olat/modules/portfolio/ui/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/modules/portfolio/ui/_i18n/LocalStrings_fr.properties index 392425b122ae5250c3c7293cfea6f3824eacfcc9..b37c747c8fa0420003e1f32f3de883c472d5da29 100644 --- a/src/main/java/org/olat/modules/portfolio/ui/_i18n/LocalStrings_fr.properties +++ b/src/main/java/org/olat/modules/portfolio/ui/_i18n/LocalStrings_fr.properties @@ -1,4 +1,4 @@ -#Thu Nov 16 16:51:38 CET 2017 +#Thu Feb 01 21:29:46 CET 2018 access=Acc\u00E8s access.binder=Les personnes suivantes ont acc\u00E8s au classeur\: access.rights=Ajouter un droit d'acc\u00E8s @@ -72,6 +72,7 @@ binder.num.sections.pages={0} sections avec un total de {1} entr\u00E9es binder.status=Status binder.title=Portfolio {0} binders=Classeurs +bookmark=Favori categories=Cat\u00E9gories categories.add=Ajouter des cat\u00E9gories categories.hint=Entrer le texte de la cat\u00E9gorie et passer "Entrez" pour cr\u00E9er la cat\u00E9gorie d\u00E9sir\u00E9e. @@ -91,6 +92,8 @@ comment.several={0} commentaires comment.title=Commentaires comment.zero=Pas encore de commentaires compare.evaluations=Evaluation +confirm.close.page=Voulez-vous clore cette contribution? Cette contribution sera clos pour l'apprenant. +confirm.close.page.other.coaches=Les personnes suivantes ont acc\u00E8s \u00E0 la contribution\: confirmation=Confirmation create.binder=Cr\u00E9er un classeur create.empty.binder=Nouveau classeur vide @@ -162,6 +165,7 @@ export.page=Exporter la page export.page.onepage=En une page export.page.pdf=Exporter la page au format PDF fileupload=Image du titre +filter.sections.empty=Pas de sections ouvertes filter.show.all=Tout affichez firstName=Pr\u00E9nom go.to.trash=Aller \u00E0 la poubelle @@ -189,6 +193,8 @@ invitation.mail.success=Les personnes invit\u00E9es ont \u00E9t\u00E9 inform\u00 issue=Edition language=Langue lastName=Nom de famille +leave=Enlever +leave.explain=Voulez-vous enlever le classeur? Vous n'y aurez plus acc\u00E8s. Pour obtenir \u00E0 nouveau un acc\u00E8s, le propri\u00E9taire du classeur devra vous en accorder l'acc\u00E8s \u00E0 nouveau. mail=Courriel mail.body=Message mail.subject=Sujet @@ -326,6 +332,9 @@ section.up=Vers le haut select.form=S\u00E9lectionner un questionnaire select.mymap=$org.olat.course.nodes.portfolio\:select.mymap series=S\u00E9ries +shared.binders=Classeurs +shared.bookmarks=Favoris +shared.entries=Contributions / \u00E0 faire shared.with.me=Partag\u00E9 avec moi shared.with.me.text=Une liste de classeurs que d'autres personnes partagent avec vous. show.help.binder=Aide @@ -339,6 +348,9 @@ status.inRevision=$\:status.in.revision status.not.started=pas commenc\u00E9 status.published=publi\u00E9 status.submitted=soumis +status.user.done=Fait +status.user.inProcess=En cours +status.user.incoming=Nouveau summary=R\u00E9sum\u00E9 summary.placeholder=Court r\u00E9sum\u00E9 du contenu de la contribution table.grading.failed.points=<span class\="o_state o_failed"><i class\="o_icon o_icon_failed"> </i> {0} Point(s)</span> @@ -347,14 +359,19 @@ table.grading.passed.points=<span class\="o_state o_passed"><i class\="o_icon o_ table.grading.points={0} point(s) table.header.categories=Cat\u00E9gories table.header.change.status=Status +table.header.closed=Clos table.header.collection.date=Collect\u00E9 le table.header.course=Cours table.header.course.node=El\u00E9ment de cours table.header.date=Date table.header.down=<i class\='o_icon o_icon o_icon-lg o_icon_move_down'> </i> +table.header.draft=$\:status.draft table.header.grading=Evaluation +table.header.inRevision=$\:status.in.revision table.header.key=ID table.header.lastUpdate=Derni\u00E8re mise-\u00E0-jour +table.header.mark=<i class\="o_icon o_icon_bookmark_header o_icon-lg" title\="Favori"> </i> +table.header.new=Nouveau table.header.numpages=\# Contributions table.header.open=D\u00E9marrer table.header.open.sections=Ouvrir diff --git a/src/main/java/org/olat/modules/qpool/QuestionType.java b/src/main/java/org/olat/modules/qpool/QuestionType.java index 24ed4ad3b84b160b31c287391b702a0face9e377..2116a82b3fe593a16d66ea7dfe78d8ef7b153753 100644 --- a/src/main/java/org/olat/modules/qpool/QuestionType.java +++ b/src/main/java/org/olat/modules/qpool/QuestionType.java @@ -38,6 +38,7 @@ public enum QuestionType { DRAWING, MATCH, MATCHDRAGANDDROP, + MATCHTRUEFALSE, HOTTEXT, UNKOWN diff --git a/src/main/java/org/olat/modules/qpool/ui/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/modules/qpool/ui/_i18n/LocalStrings_de.properties index a36cc397dc3c2589a22f8ac10c6c5a6dd392430a..687c3952b98f12752ab0c3462511275f80342e36 100644 --- a/src/main/java/org/olat/modules/qpool/ui/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/modules/qpool/ui/_i18n/LocalStrings_de.properties @@ -216,7 +216,7 @@ process.rating.description=Bewerten Sie bitte die Frage. Jede Frage kann genau e process.rating.title=Beurteilung process.rating=Bewertung process.start.review.button=$\:process.activate.start.review -process.start.review.description=Nach dem Start des Beurteilungsprozesses werden alle Bewertungen der Frage gel\u00F6scht und die Frage kann nicht mehr bearbeitet werden. Wollen Sie den Beurteilungsprozess f\u00FCr die Frage "{0}" wriklich starten? +process.start.review.description=Nach dem Start des Beurteilungsprozesses werden alle Bewertungen der Frage gel\u00F6scht und die Frage kann nicht mehr bearbeitet werden. Wollen Sie den Beurteilungsprozess f\u00FCr die Frage "{0}" wirklich starten? process.start.review.taxonomy.level=$\:general.taxonomy.level process.start.review.title=$\:process.activate.start.review question=Itemanalyse diff --git a/src/main/java/org/olat/modules/qpool/ui/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/modules/qpool/ui/_i18n/LocalStrings_en.properties index d5643ce491d4520c5c8e21b42a60da9f114cdd32..d10e9999b6c762a9d6a8a61e2754f1763a469bbb 100644 --- a/src/main/java/org/olat/modules/qpool/ui/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/modules/qpool/ui/_i18n/LocalStrings_en.properties @@ -1,4 +1,4 @@ -#Tue Apr 15 11:12:45 CEST 2014 +#Tue Feb 06 08:32:16 CET 2018 add=+ add.to.list=Add to list admin.menu.title=Question bank @@ -11,9 +11,9 @@ classification.taxonomic.path=Subject path classification.taxonomic.path.incl=Subjects classification.taxonomy.level=Subject classification.taxonomy.parents=Path +collection.add.to.source=Add questions to list "{0}" collection.creationDate=Created at collection.name=Name -collection.add.to.source=Add questions to list "{0}" commands=Question confirm.copy.button=Copy confirm.copy.editable=Allow other users to edit the question @@ -23,17 +23,18 @@ confirm.copy.title=Copy confirm.delete.button=Delete confirm.delete.confirmation=Delete all questions confirm.delete.confirmation.error=Please confirm +confirm.delete.message=Do you really want to permanently delete these questions? They can not be recovered. confirm.delete.questions=Questions +confirm.delete.source=Do you really want to delete this list? confirm.delete.title=Delete -confirm.delete.message=Do you really want to permanently delete these questions? They can not be recovered. confirm.unshare=Do your really want to remove this question "{0}"? convert.editable=Allow other users to edit the question +convert.format=Format convert.item=Convert -convert.item.not.possible=You haven't selected any question you can convert. convert.item.msg=Do you want to convert the {0} question(s) in the following format? +convert.item.not.possible=You haven't selected any question you can convert. convert.item.successful={0} question(s) successfully converted. convert.item.warning={0} was not converted. -convert.format=Format convert.qti21.hint=You will find information about the conversion from QTI 1.2 to QTI 2.1 in the manual convert.questions=Questions copy=Copy @@ -177,14 +178,16 @@ menu.pools.main=Catalog menu.pools.main.alt=Catalog menu.queries=Questions menu.queries.all=All questions -menu.queries.whithout.taxonomy.level=Without subject menu.queries.whithout.author=Without author +menu.queries.whithout.taxonomy.level=Without subject +menu.queries.without.author=Without author +menu.queries.without.taxonomy.level=Without subject menu.ratings=Ratings menu.review=Review menu.share=Public shares -metadatas=Metadata -metadata.show=Metadata metadata.hide=Metadata +metadata.show=Metadata +metadatas=Metadata my.competences=My subjects my.list=My lists my.share=My shares @@ -197,19 +200,23 @@ pool.name=Name pool.owners=Owners pool.public=Public presentation.title=Question bank -process.activate.not.reviewable.description=It is not possible to review questions in the format 'QTI 1.2'. Please previously convert the question to the format 'QTI 2.1'. +previous=Previous process.activate.locked=The question is opened by '{0}'. Therefore, you are not able to start the review process. +process.activate.not.reviewable.description=It is not possible to review questions in the format 'QTI 1.2'. Please previously convert the question to the format 'QTI 2.1'. process.activate.review=Review question process.activate.review.description=The question is in the status 'Review'. Please review the question carefully to technical correctness and with regards to content. Subsequently you have to push the button below to rate the question. process.activate.start.review=Start review process process.activate.start.review.description=You can now create and revise the question, until it has a sufficient quality. If the question is completely created, you have to start the review process by pushing the button below. Afterwards the question can not be edited anymore. process.comment=Comment process.confirm.endOfLife=If a question is end of life, the question can not be used anymore. Do you really want to set the end of life for the question "{0}"? -process.review=Review +process.endOfLife=End of life +process.final=Final +process.rating=Rating process.rating.button=Rate process.rating.description=Please rate the question. You are only once able to rate a question. After the rating the question is not in the list of the review questions anymore. process.rating.title=Review -process.rating=Rating +process.review=Review +process.revision=Revision process.start.review.button=$\:process.activate.start.review process.start.review.description=After the start of the review process all ratings are deleted and the question can not be edited anymore. Do you really want to start the review process for the question "{0}"? process.start.review.taxonomy.level=$\:general.taxonomy.level @@ -254,14 +261,14 @@ share.item.pools=Share with pools share.options=Do you want to allow other users to edit the imported question(s)? share.pool=Share with pool shared=Shared +sharing.pools.empty.table=This question is not shared in any pool. sharing.shares=Groups sharing.shares.empty.table=This question is not shared with any group. -sharing.pools.empty.table=This question is not shared in any pool. source.status.draft=$\:lifecycle.status.draft ({0}) +source.status.endOfLife=$\:lifecycle.status.endOfLife ({0}) +source.status.finalVersion=$\:lifecycle.status.finalVersion ({0}) source.status.review=$\:lifecycle.status.review ({0}) source.status.revised=$\:lifecycle.status.revised ({0}) -source.status.finalVersion=$\:lifecycle.status.finalVersion ({0}) -source.status.endOfLife=$\:lifecycle.status.endOfLife ({0}) technical=Technical technical.creation=Created technical.editor=Editor diff --git a/src/main/java/org/olat/modules/qpool/ui/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/modules/qpool/ui/_i18n/LocalStrings_fr.properties index a37ada097f268361a8b6c779a054f7f6a886706b..6d1ad037b5f96c8dd3d8e6ebec7e78012810ce20 100644 --- a/src/main/java/org/olat/modules/qpool/ui/_i18n/LocalStrings_fr.properties +++ b/src/main/java/org/olat/modules/qpool/ui/_i18n/LocalStrings_fr.properties @@ -1,4 +1,4 @@ -#Thu Nov 16 19:06:10 CET 2017 +#Fri Feb 02 08:26:04 CET 2018 add=+ add.to.list=Ajouter \u00E0 la liste admin.menu.title=Banque de questions @@ -11,10 +11,24 @@ classification.taxonomic.path=Sujet chemin classification.taxonomic.path.incl=Sujets classification.taxonomy.level=Sujet classification.taxonomy.parents=Chemin +collection.add.to.source=Ajouter des questions \u00E0 la liste "{0}" collection.creationDate=Cr\u00E9er le collection.name=Nom +commands=Questions +confirm.copy.button=Copier +confirm.copy.editable=D'autres utilisateurs ont le droit d'\u00E9diter la question. +confirm.copy.message=Voulez-vous copier la question? +confirm.copy.questions=Questions +confirm.copy.title=Copier +confirm.delete.button=Effacer +confirm.delete.confirmation=Effacer toutes les questions +confirm.delete.confirmation.error=Confirmez s'il-vous-pla\u00EEt. +confirm.delete.message=Voulez-vous vraiment effacer ces questions? Elles ne pourront plus \u00EAtre restaur\u00E9es. +confirm.delete.questions=Questions confirm.delete.source=Voulez-vous vraiment effacer cette liste? +confirm.delete.title=Effacer confirm.unshare=Voulez-vous vraiment enlever cette question de "{0}"? +convert.editable=D'autres utilisateurs peuvent \u00E9diter la question. convert.format=Format convert.item=Convertir convert.item.msg=D\u00E9sirez-vous convertir la ou les questions "{0}" au format suivant? @@ -22,12 +36,16 @@ convert.item.not.possible=Vous n'avez pas s\u00E9lectionn\u00E9 de questions qui convert.item.successful={0} question(s) ont \u00E9t\u00E9 converties avec succ\u00E8s. convert.item.warning={0} question(s) n'ont pas \u00E9t\u00E9 converties. convert.qti21.hint=Vous trouverez plus d'informations sur la conversion QTI 1.2 vers QTI 2.1 dans le manuel d'utilisation +convert.questions=Questions copy=Copier create.collection.description=Donnez le nom de votre liste. create.list=Cr\u00E9er une liste create.pool=Cr\u00E9er un pool create.success=1 question a \u00E9t\u00E9 cr\u00E9er avec succ\u00E8s. create.test=Cr\u00E9er un test +create.test.format.qti12=QTI 1.2 +create.test.format.qti21=QTI 2.1 +create.test.no.formats=Les questions s\u00E9lectionn\u00E9es sont dans un format qui ne permet pas de cr\u00E9er un test. delete.collection=Effacer la liste delete.item=Effacer delete.pool=Effacer un pool @@ -43,8 +61,41 @@ educational.learningTime.minute=m educational.learningTime.second=s error.input.toolong=Le texte que vous avez entr\u00E9 est trop long ({1} caract\u00E8res). Limitez-vous s'il vous pla\u00EEt \u00E0 {1} caract\u00E8res. error.select.one=Vous devez s\u00E9lectionner au moins une question. +error.select.one.author=Vous devez s\u00E9lectionner au moins une question qu'auteur peut \u00E9diter. +error.select.one.convert=Vous devez s\u00E9lectionner au moins une question qui puisse \u00EAtre convertie dans un autre format. +error.select.one.copy=Vous devez s\u00E9lectionner au moins une question que vous puissiez copier. +error.select.one.create.test=Vous devez s\u00E9lectionner au moins une question que vous puissiez utiliser dans un test. +error.select.one.delete=Vous devez s\u00E9lectionner au moins une question que vous puissiez effacer. +error.select.one.export=Vous devez s\u00E9lectionner au moins une question que vous puissiez exporter. +error.select.one.metadata=Vous devez s\u00E9lectionner au moins une question dont vous puissiez changer les m\u00E9ta-donn\u00E9es. +error.select.one.remove=Vous devez s\u00E9lectionner au moins une question \u00E0 enlever. error.wrongFloat=Format num\u00E9rique inad\u00E9quat. Exemple\: 1.0, 0.5, 0.2 export.item=Exporter +export.log=Fichier log +export.log.header.additional.informations=$\:general.additional.informations +export.log.header.assessment.type=$\:question.assessmentType +export.log.header.context=$\:educational.context +export.log.header.copyright=$\:rights.copyright +export.log.header.coverage=$\:general.coverage +export.log.header.creator=$\:rights.creator +export.log.header.differentiation=$\:question.differentiation +export.log.header.difficulty=$\:question.difficulty +export.log.header.item.type=$\:question.type +export.log.header.keywords=$\:general.keywords +export.log.header.language=$\:general.language +export.log.header.learningTime=$\:educational.learningTime +export.log.header.log.action=Action +export.log.header.log.author=Chang\u00E9 par +export.log.header.log.date=Date +export.log.header.numOfAnswerAlternatives=$\:question.numOfAnswerAlternatives +export.log.header.status=$\:lifecycle.status +export.log.header.stdevDifficulty=$\:question.stdevDifficulty +export.log.header.taxonomic.path=$\:classification.taxonomic.path +export.log.header.title=$\:general.title +export.log.header.topic=$\:general.topic +export.log.header.usage=$\:question.usage +export.log.header.version=$\:lifecycle.version +export.overview.accept=Pris en compte general=G\u00E9n\u00E9ral general.additional.informations=Informations additionnelles general.additional.informations.long=$\:general.additional.informations @@ -55,6 +106,9 @@ general.key=Cl\u00E9 DB general.keywords=Mots cl\u00E9s general.language=Langue general.master.identifier=ID master +general.taxonomy.level=Sujet +general.taxonomy.path={0} +general.title=Titre general.topic=Th\u00E8me import.excellike.12=Importer QTI 1.2 un fichier Excel par copier coller import.excellike.21=Importer QTI 2.1 un fichier Excel par copier coller @@ -69,6 +123,7 @@ item.collectioned=La question {0} a \u00E9t\u00E9 ajout\u00E9e \u00E0 la liste. item.copied={0} question(s) ont \u00E9t\u00E9 copi\u00E9es. item.deleted=La question a \u00E9t\u00E9 effac\u00E9e. item.level=Niveau +item.numbers.of={0} / {1} item.pooled=La question {0} a \u00E9t\u00E9 ajout\u00E9e au pool. item.shared=La question {0} a \u00E9t\u00E9 partag\u00E9e. item.type.drawing=Dessin @@ -86,13 +141,18 @@ item.type.unkown=Inconnu item.type.upload=T\u00E9l\u00E9verser un fichier lifecycle.status=Statut lifecycle.status.draft=Ebauche +lifecycle.status.endOfLife=End of life lifecycle.status.finalVersion=Final +lifecycle.status.last.modified=Dernier changement de statut lifecycle.status.review=En cours d'examen lifecycle.status.revised=R\u00E9vis\u00E9 lifecycle.status.unavailable=Indisponible lifecycle.version=Version list=Listes +locked.readonly=La question est momentan\u00E9ment ouverte par "{0}". C'est pourquoi vous ne pouvez pas l'\u00E9diter pour l'instant. +manage.owners=Editer mark=<i class\="o_icon o_icon_bookmark_header o_icon-lg" title\="Favoris"> </i> +mark.add.to.source=Ajouter les questions aux favoris. menu.admin=Administration menu.admin.alt=Administration menu.admin.levels=Niveau @@ -100,30 +160,65 @@ menu.admin.levels.alt=Niveau menu.admin.licenses=Licenses menu.admin.licenses.alt=Administrer les licenses menu.admin.pools=Gestion des pools +menu.admin.review.process=Processus d'\u00E9valuation menu.admin.studyfields=Sujet menu.admin.studyfields.alt=Sujet menu.admin.types=Type de questions menu.admin.types.alt=Administrer les types de questions +menu.database=Ma banque de questions +menu.database.alt=Ma banque de questions menu.database.favorit=Mes favoris menu.database.favorit.alt=Mes favoris menu.database.my=Mes questions menu.database.my.alt=Mes questions +menu.final=Final menu.pools=Pool menu.pools.alt=Pool menu.pools.main=Catalogue menu.pools.main.alt=Catalogue +menu.queries=Questions +menu.queries.all=Toutes les questions +menu.queries.without.author=Sans auteur +menu.queries.without.taxonomy.level=Sans sujet +menu.ratings=Evaluations +menu.review=Evaluation menu.share=Partag\u00E9 +metadata.hide=M\u00E9ta-donn\u00E9es +metadata.show=M\u00E9ta-donn\u00E9es metadatas=M\u00E9tadonn\u00E9es +my.competences=Mes sujets my.list=Mes listes my.share=Partag\u00E9s new.item=Cr\u00E9er une question next=Suivant +numberOfRatings=Nombre d'\u00E9valuations +pool.add.to.source=Ajouter les questions au pool "{0}". pool.key=ID pool.name=Nom pool.owners=Propri\u00E9taires pool.public=Public presentation.title=Banque de questions previous=Pr\u00E9c\u00E9dent +process.activate.locked=La question est momentan\u00E9ment ouverte par "{0}". Le processus d'\u00E9valuation ne peut par cons\u00E9quent pas \u00EAtre d\u00E9marrer pour l'instant. +process.activate.not.reviewable.description=Les questions au format QTI 1.2 ne peuvent pas \u00EAtre \u00E9valu\u00E9es. Convertissez-les d'abord au format QTI 2.1. +process.activate.review=Evaluer la question +process.activate.review.description=La question est pass\u00E9e en revue. V\u00E9rifier attentivement , s'il vous pla\u00EEt, l'exactitude technique et la justesse de la question avant de soumettre votre \u00E9valuation avec le bouton ci-dessous. +process.activate.start.review=D\u00E9marrer le processus d'\u00E9valuation +process.activate.start.review.description=Vous pouvez cr\u00E9er ici une question et l'am\u00E9liorer jusqu'\u00E0 ce qu'elle soit de qualit\u00E9 suffisante. Lorsque la question est termin\u00E9e, vous pouvez commencer le processus d'\u00E9valuation. La question ne peut plus \u00EAtre modifi\u00E9e par la suite. +process.comment=Commentaire +process.confirm.endOfLife=Une question avec le "$\:lifecycle.status.endOfLife" ne heut plus \u00EAtre utilis\u00E9e. Voulez-vous mettre le statut "$\:lifecycle.status.endOfLife" \u00E0 la question "{0}"? +process.endOfLife=End of life +process.final=Final +process.rating=Evaluation +process.rating.button=Evaluer +process.rating.description=Evaluez la question s'il-vous-pla\u00EEt. Chaque question peut \u00EAtre \u00E9valuer exactement une fois. Apr\u00E8s \u00E9valuation, la question n'appara\u00EEtra plus dans la liste des questions \u00E0 \u00E9valuer. +process.rating.title=Evaluation +process.review=Evaluation +process.revision=R\u00E9vision +process.start.review.button=$\:process.activate.start.review +process.start.review.description=Apr\u00E8s le d\u00E9but du processus d'\u00E9valuation, toutes les \u00E9valuations de la question seront effac\u00E9es et la question ne pourra plus \u00EAtre \u00E9dit\u00E9e. Voulez-vous commencer l'\u00E9valuation de la question "{0}"? +process.start.review.taxonomy.level=$\:general.taxonomy.level +process.start.review.title=$\:process.activate.start.review question=Analyse \u00E9l\u00E9ment question.assessmentType=Type de test question.assessmentType.both=Tous les deux @@ -140,31 +235,48 @@ question.type=Type question.usage=Utilisation dans des tests quickview=<i class\='o_icon o_icon_quickview'> </i> rating=Evaluation +rating.creation.date=Date +rating.empty.table=Cette question n'a pas encore \u00E9t\u00E9 \u00E9valu\u00E9e. remove=- rename.collection=Renommer la liste rights=Droits rights.copyright=Copyright rights.creator=Propri\u00E9taires rights.description=License +rights.owners=Auteurs root.taxonomyLevel=Sujets select.group=Partag\u00E9 select.item=$\:details select.pool=Partagez dans un pool +share.add.to.source=Ajouter les questions au groupe "{0}". share.editable=Editer share.group=Partagez avec un groupe share.item=Partagez +share.item.group=Partagez par le groupe "{0}" +share.item.groups=Partage par groupes +share.item.pool=Partage par le pool "{0}" +share.item.pools=Partage par pools share.options=Voulez-vous permettre \u00E0 une autre personne d'\u00E9diter cette/ces question(s)? share.pool=Partagez dans un pool shared=Partag\u00E9 +sharing.pools.empty.table=Cette question n'est partag\u00E9 par aucun pool. sharing.shares=Groupes +sharing.shares.empty.table=Cette question n'est partag\u00E9 par aucun groupe. +source.status.draft=$\:lifecycle.status.draft ({0}) +source.status.endOfLife=$\:lifecycle.status.endOfLife ({0}) +source.status.finalVersion=$\:lifecycle.status.finalVersion ({0}) +source.status.review=$\:lifecycle.status.review ({0}) +source.status.revised=$\:lifecycle.status.revised ({0}) technical=Technique technical.creation=Cr\u00E9ation technical.editor=Editeur technical.editorVersion=Version de l'\u00E9diteur technical.format=Format technical.lastModified=Modifi\u00E9 +technical.statusLastModified=Dernier changement de statut technics=Technique topnav.qpool=Banque de questions topnav.qpool.alt=Banque de questions et partage unshare.item=Enlever used=Utilis\u00E9 +warning.qpool.index.emtpy=La page d'informations de la banque de documents n'a pas \u00E9t\u00E9 configur\u00E9e. Demandez \u00E0 l'administrateur syst\u00E8me d'ajouter une page d'informations dans <strong>Administration de la banque de questions</strong>. diff --git a/src/main/java/org/olat/modules/qpool/ui/admin/QEducationalContextsAdminController.java b/src/main/java/org/olat/modules/qpool/ui/admin/QEducationalContextsAdminController.java index 0134f440b376542105d78631063340b296501ca0..92014e037b5bcbaf2a28ab992e92c28a4768bf75 100644 --- a/src/main/java/org/olat/modules/qpool/ui/admin/QEducationalContextsAdminController.java +++ b/src/main/java/org/olat/modules/qpool/ui/admin/QEducationalContextsAdminController.java @@ -52,7 +52,6 @@ import org.olat.core.util.Util; import org.olat.core.util.i18n.ui.SingleKeyTranslatorController; import org.olat.modules.qpool.QPoolService; import org.olat.modules.qpool.model.QEducationalContext; -import org.olat.modules.qpool.ui.QuestionPoolMainEditorController; import org.olat.modules.qpool.ui.QuestionsController; /** @@ -173,7 +172,7 @@ public class QEducationalContextsAdminController extends FormBasicController { String[] keys2Translate = { key2Translate }; singleKeyTrnsCtrl = new SingleKeyTranslatorController(ureq, getWindowControl(), keys2Translate, - QuestionPoolMainEditorController.class); + QuestionsController.class); listenTo(singleKeyTrnsCtrl); removeAsListenerAndDispose(cmc); @@ -293,8 +292,8 @@ public class QEducationalContextsAdminController extends FormBasicController { case levelI18n: { String i18nKey = "item.level." + level.getLevel().toLowerCase(); String translation = getTranslator().translate(i18nKey); - if(translation.length() > 256) { - return getTranslator().translate("translation.missing"); + if(i18nKey.equals(translation) || translation.length() > 256) { + return level.getLevel(); } return translation; } diff --git a/src/main/java/org/olat/modules/qpool/ui/admin/QItemTypesAdminController.java b/src/main/java/org/olat/modules/qpool/ui/admin/QItemTypesAdminController.java index eb056481e26b02c566acff7e23fa01bb3a0a6412..d24399a5699aa3ffcca3ea79a03b822642670373 100644 --- a/src/main/java/org/olat/modules/qpool/ui/admin/QItemTypesAdminController.java +++ b/src/main/java/org/olat/modules/qpool/ui/admin/QItemTypesAdminController.java @@ -52,7 +52,6 @@ import org.olat.core.util.Util; import org.olat.core.util.i18n.ui.SingleKeyTranslatorController; import org.olat.modules.qpool.QPoolService; import org.olat.modules.qpool.model.QItemType; -import org.olat.modules.qpool.ui.QuestionPoolMainEditorController; import org.olat.modules.qpool.ui.QuestionsController; /** @@ -173,7 +172,7 @@ public class QItemTypesAdminController extends FormBasicController { String[] keys2Translate = { key2Translate }; singleKeyTrnsCtrl = new SingleKeyTranslatorController(ureq, getWindowControl(), keys2Translate, - QuestionPoolMainEditorController.class); + QuestionsController.class); listenTo(singleKeyTrnsCtrl); removeAsListenerAndDispose(cmc); diff --git a/src/main/java/org/olat/modules/qpool/ui/admin/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/modules/qpool/ui/admin/_i18n/LocalStrings_de.properties index 5d5b06e917acb0fc6a2cccf58425e4694401fa06..d765bb2bf5618e9b88bfdb43b8f1692885df3e14 100644 --- a/src/main/java/org/olat/modules/qpool/ui/admin/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/modules/qpool/ui/admin/_i18n/LocalStrings_de.properties @@ -78,7 +78,6 @@ taxonomy.selectable=Ausw\u00E4lbare Fachbereiche taxonomyLevel.deleted=Fachbereich wurde erfolgreich gel\u00F6scht taxonomyLevel.notdeleted=Fachbereich konnte nicht gel\u00F6scht werden, eventuell wird er bereits verwendet. translation=\u00dcbersetzung -translation.missing=Keine \u00dcbersetzung type.key=ID type.translation=\u00DCbersetzung type.type=Typ diff --git a/src/main/java/org/olat/modules/qpool/ui/admin/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/modules/qpool/ui/admin/_i18n/LocalStrings_en.properties index bdd72fd6e98ee67a126d2e728b11582cdabfe187..103546671ff4ea8434c63041edc9cdd28eb0fa3f 100644 --- a/src/main/java/org/olat/modules/qpool/ui/admin/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/modules/qpool/ui/admin/_i18n/LocalStrings_en.properties @@ -1,4 +1,4 @@ -#Wed Aug 28 17:36:55 CEST 2013 +#Tue Feb 06 08:32:43 CET 2018 admin.configuration.title=Question bank admin.levels.intro=Create those levels that apply to your organisations educational level. Examples for levels in an academic context could be elementary school, middle school, high school, bachelor, master. Within a corporation context, levels could be the following\: without apprenticeship, with vocational training, administration, middle management, CO admin.licenses.intro=You can create more license types if the default license types are not sufficient. Please note that the default licenses cannot be deleted. @@ -8,6 +8,7 @@ admin.review.process.decision.type=Decision method admin.review.process.title=Review process admin.studyfields.intro=Subjects allow for technical indexing the question items. It's organized as a hierarchical structure for modelling the potential degree programs. Select the "$org.olat.modules.taxonomy.ui\:add.taxonomy.level" in order to create a new subject, or select an existing one for editing purposes. admin.types.intro=Create more question types if the existing default types aren't sufficient. Please note that the default question types can not be deleted. +average.rating.for.final=Average rating for status "final" collections.enabled=Lists create.infos.page=Create infos page create.level=Create level @@ -15,12 +16,12 @@ create.license=Create license create.type=Create type delete.level=Delete delete.level.confirm=Do you really want to delete this level? -delete.taxonomyLevel=Delete -delete.taxonomyLevel.confirm=Do you really want to delete this subject "{0}"? -delete.qustions.without.author=Delete questions when author deleted -delete.qustions.without.author.info=When a user is deleted, he is removed as author from his question items. If this option is enabled and the user is the only author of the question item, the question item is deleted as well. delete.license=Delete delete.license.confirm=Do you really want to delete this license? +delete.qustions.without.author=Delete questions when author deleted +delete.qustions.without.author.info=When a user is deleted, he is removed as author from his question items. If this option is enabled and the user is the only author of the question item, the question item is deleted as well. +delete.taxonomyLevel=Delete +delete.taxonomyLevel.confirm=Do you really want to delete this subject "{0}"? delete.type=Delete delete.type.confirm=Do you really want to delete this type? edit.info.page=Edit infos page @@ -32,36 +33,35 @@ error.item.type.unique=A question type with this name already exists. final.visibility=Visibility of final questions final.visibility.manager=Manager final.visibility.manager.teacher=Manager, Teacher +import.create.subject=Create subject when importing item.license.deleted=License has been successfully deleted. item.license.notdeleted=License cannot be deleted, it is probably in use. item.type.deleted=Type has been successfully deleted. item.type.notdeleted=Type cannot be deleted, it is probably in use. -import.create.subject=Create subject when importing level.key=ID level.level=Level level.translation=Translation license.id=ID license.key=License +lower.limit=Lower limit for positive decision lower.limit.desc=The decision method "Lower limit" changes the status of a question to "$org.olat.modules.qpool.ui\:lifecycle.status.finalVersion", if the minimum number of ratings is reached and if all ratings are equal or higher then the lower limit. If a rating is lower then the lower limit, the question status this immediately changed to "$org.olat.modules.qpool.ui\:lifecycle.status.revised", even if the minimum number of ratings is not reached yet. lower.limit.provider.name=Lower limit -lower.limit=Lower limit for positive decision number.of.ratings=Number of ratings per question pool.manager.allowed=The pool manager is allowed to pool.manager.edit.matadata=see all questions and edit the metadata pool.manager.edit.status=change the status of a question -pool.manager.educational.context=edit the settings "$:\segment.educational.context" -pool.manager.licenses=edit the settings "$:\segment.licenses" -pool.manager.item.types=edit the settings "$:\segment.item.types" -pool.manager.pools=edit the settings "$:\segment.pools" -pool.manager.review.process=edit the settings "$:\segment.review.process" -pool.manager.taxonomy=edit the settings "$:\segment.taxonomy" +pool.manager.educational.context=edit the settings "$\:segment.educational.context" +pool.manager.item.types=edit the settings "$\:segment.item.types" +pool.manager.licenses=edit the settings "$\:segment.licenses" +pool.manager.pools=edit the settings "$\:segment.pools" +pool.manager.review.process=edit the settings "$\:segment.review.process" +pool.manager.taxonomy=edit the settings "$\:segment.taxonomy" pools.enabled=Pools reset.status=Reset all questions to state "draft". review.process.confirm.enable.button=Enable -review.process.confirm.enable.description=It is recommended to reset all questions the the question bank to the status "draft" to create a clean starting position for the introduction of the review process.<br\><br\>The resetting of the question states can not be undone! +review.process.confirm.enable.description=It is recommended to reset all questions the the question bank to the status "draft" to create a clean starting position for the introduction of the review process.<br><br>The resetting of the question states can not be undone\! review.process.confirm.enable.title=Enable review process review.process.enabled=Review process -shares.enabled=Groups segment.configuration=Question bank segment.educational.context=Levels segment.info.page=Infos page @@ -71,13 +71,13 @@ segment.pools=Pools segment.review.process=Review process segment.taxonomy=Subjects selected.taxonomy.tree=Taxonomy +shares.enabled=Groups taxonomy.all=All subjects taxonomy.competences=Subjects with competence "teach" or "manage" taxonomy.selectable=Selectable subjects taxonomyLevel.deleted=Subject has been successfully deleted. taxonomyLevel.notdeleted=The subject cannot be deleted, it is probably in use. translation=Translation -translation.missing=Translation missing type.key=ID type.translation=Translation type.type=Type diff --git a/src/main/java/org/olat/modules/qpool/ui/admin/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/modules/qpool/ui/admin/_i18n/LocalStrings_fr.properties index bf7585fea641527d9921ac377ee4480cb12dff3e..80488125de013ecd44189a9bb0503127be59f158 100644 --- a/src/main/java/org/olat/modules/qpool/ui/admin/_i18n/LocalStrings_fr.properties +++ b/src/main/java/org/olat/modules/qpool/ui/admin/_i18n/LocalStrings_fr.properties @@ -1,27 +1,39 @@ -#Sat Nov 02 16:23:20 CET 2013 +#Fri Feb 02 08:33:46 CET 2018 admin.configuration.title=Banque de questions admin.levels.intro=Cr\u00E9er les niveaux qui s'appliquent aux niveaux d'\u00E9ducation de votre organisation. Exemples de niveaux dans un contexte acad\u00E9mique pourrait \u00EAtre l'\u00E9cole primaire, coll\u00E8ge, lyc\u00E9e, bachelor, master. Dans le contexte d'une soci\u00E9t\u00E9, les niveaux pourraient \u00EAtre les suivantes\: sans apprentissage, formation professionnelle, administration... admin.licenses.intro=Vous pouvez cr\u00E9er plusieurs types de licence si ceux par d\u00E9faut ne sont pas suffisants. Veuillez noter que les licences par d\u00E9faut ne peuvent pas \u00EAtre supprim\u00E9es. +admin.pool.manager.title=Permissions des administrateurs de la banque de questions admin.pools.intro=Cr\u00E9ez un ou plusieurs pools de questions. Un pool est une banque de questions qui permet \u00E0 tous les utilisateurs avec droits d'auteur d'\u00E9changer des \u00E9l\u00E9ments - questions (si en acc\u00E8s public). Vous pouvez \u00E9galement opter pour un pool partag\u00E9 par seulement quelques auteurs, par exemple le personnel d'un d\u00E9partement (en acc\u00E8s priv\u00E9). +admin.review.process.decision.type=M\u00E9thode d'\u00E9valuation +admin.review.process.title=Processus d'\u00E9valuation admin.studyfields.intro=Les sujets permettent une indexation technique des questions. Elle est organis\u00E9e comme une structure hi\u00E9rarchique pour mod\u00E9liser les \u00E9ventuels programmes d'\u00E9tudes. S\u00E9lectionner le r\u00E9pertoire "$org.olat.modules.taxonomy.ui\:add.taxonomy.level" afin de cr\u00E9er un nouveau sujet, ou s\u00E9lectionnez un existant pour l'\u00E9diter. admin.types.intro=Cr\u00E9er davantage de types de questions si les types par d\u00E9faut ne sont pas suffisants. Veuillez noter que les types de questions par d\u00E9faut ne peuvent pas \u00EAtre supprim\u00E9s. +average.rating.for.final=Evaluation moyenne pour obtenir le statut "final" +collections.enabled=Listes create.infos.page=Cr\u00E9er une page d'information create.level=Cr\u00E9er un niveau create.license=Cr\u00E9er une license create.type=Cr\u00E9er un type delete.level=Effacer delete.level.confirm=Voulez-vous vraiment effacer ce niveau? -delete.taxonomyLevel=Effacer -delete.taxonomyLevel.confirm=Voulez-vous vraiment effacer le sujet suivant "{0}"? delete.license=Effacer delete.license.confirm=Voulez-vous vraiment effacer cette license? +delete.qustions.without.author=Effacer les questions si l'auteur est effac\u00E9 +delete.qustions.without.author.info=Apr\u00E8s l'effacement d'un utilisateur, celui-ci sera enlever de la liste des auteurs de toutes les questions de la banque. Si l'option en a \u00E9t\u00E9 activ\u00E9e, et que cette personne est l'unique auteur d'une question, la question sera \u00E9galement effac\u00E9e. +delete.taxonomyLevel=Effacer +delete.taxonomyLevel.confirm=Voulez-vous vraiment effacer le sujet suivant "{0}"? delete.type=Effacer delete.type.confirm=Voulez-vous vraiment effacer ce type? edit.info.page=Editer la page d'informations edit.taxonomyLevel=Editer le sujet educational.context.deleted=Le sujet a \u00E9t\u00E9 effac\u00E9 avec succ\u00E8s. educational.context.notdeleted=Le sujet n'a pas pu \u00EAtre effac\u00E9, il est probablement utilis\u00E9. -error.item.type.unique=Un type de question avec ce nom existe d\u00e9j\u00e0. +error.integer.positive=L'entr\u00E9e doit \u00EAtre un nombre positif. +error.item.type.unique=Un type de question avec ce nom existe d\u00E9j\u00E0. +final.visibility=Visibilit\u00E9 des questions "final" +final.visibility.manager=Administrateur +final.visibility.manager.teacher=Administrateur, enseignant +import.create.subject=Cr\u00E9er les sujets \u00E0 l'importation item.license.deleted=Le license a \u00E9t\u00E9 effac\u00E9 avec succ\u00E8s. item.license.notdeleted=Le license n'a pas pu \u00EAtre effac\u00E9 avec succ\u00E8s, il est probablement encore utilis\u00E9. item.type.deleted=Le type a \u00E9t\u00E9 effac\u00E9 avec succ\u00E8s. @@ -31,10 +43,41 @@ level.level=Niveau level.translation=Traduction license.id=ID license.key=License +lower.limit=Limite inf\u00E9rieure des \u00E9valuations positives +lower.limit.desc=Avec la m\u00E9thode d'\u00E9valuation "Limite inf\u00E9rieure", une question obtiendra le status "$org.olat.modules.qpool.ui\:lifecycle.status.finalVersion" si le nombre minimum d'\u00E9valuation a \u00E9t\u00E9 atteint et que toutes les \u00E9valuations sont sup\u00E9rieures ou \u00E9gales \u00E0 cette limite. Si une \u00E9valuation se situe sous la limite, la question passe imm\u00E9diatement au status "$org.olat.modules.qpool.ui\:lifecycle.status.revised" avant m\u00EAme que le nombre minimal d'\u00E9valuations ne soit atteint. +lower.limit.provider.name=Limite inf\u00E9rieure +number.of.ratings=Nombre d'\u00E9valuation par question +pool.manager.allowed=L'administrateur de la banque de donn\u00E9es peut +pool.manager.edit.matadata=voir toutes les questions et \u00E9diter les m\u00E9ta-donn\u00E9es +pool.manager.edit.status=changer le status de toutes les questions +pool.manager.educational.context=\u00E9diter les param\u00E8tres "$\:segment.educational.context" +pool.manager.item.types=\u00E9diter les param\u00E8tres "$\:segment.item.types" +pool.manager.licenses=\u00E9diter les param\u00E8tres "$\:segment.licenses" +pool.manager.pools=\u00E9diter les param\u00E8tres "$\:segment.pools" +pool.manager.review.process=\u00E9diter les param\u00E8tres "$\:segment.review.process" +pool.manager.taxonomy=\u00E9diter les param\u00E8tres "$\:segment.taxonomy" +pools.enabled=Pools +reset.status=Remettre le status "Brouillon" \u00E0 toutes questions +review.process.confirm.enable.button=activ\u00E9 +review.process.confirm.enable.description=Il est recommand\u00E9 de r\u00E9initialis\u00E9 tous les status des questions de la banque pour avoir une base uniforme pour d\u00E9buter avec le nouveau processus d'\u00E9valuation.<br><br>Une fois les status r\u00E9initialis\u00E9s, les status pr\u00E9c\u00E9dents ne pourront pas \u00EAtre r\u00E9activ\u00E9s. +review.process.confirm.enable.title=Activer le processus d'\u00E9valuation +review.process.enabled=Processus d'\u00E9valuation +segment.configuration=Banque de questions +segment.educational.context=Niveaux segment.info.page=Page d'informations +segment.item.types=Type de questions +segment.licenses=Licenses +segment.pools=Administration pool +segment.review.process=Processus d'\u00E9valuation +segment.taxonomy=Sujets selected.taxonomy.tree=Taxonomie +shares.enabled=Groupes +taxonomy.all=Tous les sujets +taxonomy.competences=Sujets avec la comp\u00E9tence "Enseigner" ou "G\u00E9rer" +taxonomy.selectable=Sujets s\u00E9lectionnables taxonomyLevel.deleted=Le sujet a \u00E9t\u00E9 effac\u00E9 avec succ\u00E8s. taxonomyLevel.notdeleted=Le sujet n'a pas pu \u00EAtre effac\u00E9 avec succ\u00E8s, il est probablement encore utilis\u00E9. +translation=Traductions type.key=ID type.translation=Traduction type.type=Type diff --git a/src/main/java/org/olat/modules/qpool/ui/metadata/MetaUIFactory.java b/src/main/java/org/olat/modules/qpool/ui/metadata/MetaUIFactory.java index f9bf1726ed97ca682fc703f3ed4d6030c9e0c582..cff1d26f16ac0f21eb18af9ad8e0418fe19cab58 100644 --- a/src/main/java/org/olat/modules/qpool/ui/metadata/MetaUIFactory.java +++ b/src/main/java/org/olat/modules/qpool/ui/metadata/MetaUIFactory.java @@ -78,8 +78,9 @@ public class MetaUIFactory { int count = 0; for(QEducationalContext level:levels) { contextKeys[count] = level.getLevel(); - String translation = translator.translate("item.level." + level.getLevel().toLowerCase()); - if(translation.length() > 128) { + String i18nKey = "item.level." + level.getLevel().toLowerCase(); + String translation = translator.translate(i18nKey); + if(i18nKey.equals(translation) || translation.length() > 256) { translation = level.getLevel(); } contextValues[count++] = translation; diff --git a/src/main/java/org/olat/modules/taxonomy/manager/TaxonomyDAO.java b/src/main/java/org/olat/modules/taxonomy/manager/TaxonomyDAO.java index 8b53c14013cb58ff02fef0bb4208679fe7103b49..52c8e88be75762e6d0a15ecdc5927824e4b0e50e 100644 --- a/src/main/java/org/olat/modules/taxonomy/manager/TaxonomyDAO.java +++ b/src/main/java/org/olat/modules/taxonomy/manager/TaxonomyDAO.java @@ -136,8 +136,7 @@ public class TaxonomyDAO implements InitializingBean{ File directory = new File(storage, type); directory.mkdirs(); Path relativePath = rootDirectory.toPath().relativize(directory.toPath()); - String relativePathString = relativePath.toString(); - return relativePathString; + return relativePath.toString(); } public VFSContainer getDocumentsLibrary(Taxonomy taxonomy) { diff --git a/src/main/java/org/olat/modules/taxonomy/manager/TaxonomyServiceImpl.java b/src/main/java/org/olat/modules/taxonomy/manager/TaxonomyServiceImpl.java index 624cd9be6da723f14294c7e5ccfe9b1d81ba44e1..ec293aed0ac7ffbac2e882dbf374bb6ecbe60ae1 100644 --- a/src/main/java/org/olat/modules/taxonomy/manager/TaxonomyServiceImpl.java +++ b/src/main/java/org/olat/modules/taxonomy/manager/TaxonomyServiceImpl.java @@ -21,11 +21,13 @@ package org.olat.modules.taxonomy.manager; import java.util.Date; import java.util.List; +import java.util.UUID; import org.olat.basesecurity.IdentityRef; import org.olat.core.id.Identity; import org.olat.core.util.StringHelper; import org.olat.core.util.vfs.VFSContainer; +import org.olat.core.util.vfs.VFSItem; import org.olat.core.util.vfs.VFSManager; import org.olat.modules.taxonomy.Taxonomy; import org.olat.modules.taxonomy.TaxonomyCompetence; @@ -160,12 +162,23 @@ public class TaxonomyServiceImpl implements TaxonomyService { merge(reloadedTaxonomyLevel, reloadedMergeTo); } else { VFSContainer library = taxonomyLevelDao.getDocumentsLibrary(reloadedTaxonomyLevel); - Taxonomy taxonomy = reloadedTaxonomyLevel.getTaxonomy(); - VFSContainer lostAndFound = taxonomyDao.getLostAndFoundDirectoryLibrary(taxonomy); - String dir = StringHelper.transformDisplayNameToFileSystemName(reloadedTaxonomyLevel.getIdentifier()); - dir += "_" + taxonomyLevel.getKey(); - VFSContainer lastStorage = lostAndFound.createChildContainer(dir); - VFSManager.copyContent(library, lastStorage); + if(library != null) { + Taxonomy taxonomy = reloadedTaxonomyLevel.getTaxonomy(); + VFSContainer lostAndFound = taxonomyDao.getLostAndFoundDirectoryLibrary(taxonomy); + String dir = StringHelper.transformDisplayNameToFileSystemName(reloadedTaxonomyLevel.getIdentifier()); + dir += "_" + taxonomyLevel.getKey(); + VFSContainer lastStorage = lostAndFound.createChildContainer(dir); + if(lastStorage == null) { + VFSItem storageItem = lostAndFound.resolve(dir); + if(storageItem instanceof VFSContainer) { + lastStorage = (VFSContainer)storageItem; + } else { + lastStorage = lostAndFound.createChildContainer(UUID.randomUUID().toString()); + } + } + + VFSManager.copyContent(library, lastStorage); + } //delete the competences taxonomyCompetenceDao.deleteCompetences(taxonomyLevel); //questions diff --git a/src/main/java/org/olat/modules/taxonomy/ui/TaxonomyLevelOverviewController.java b/src/main/java/org/olat/modules/taxonomy/ui/TaxonomyLevelOverviewController.java index 2abbda811b173d599a3fd9b753c4109427958ebe..65b98b210d8c0abe8ec8555faecd983452887995 100644 --- a/src/main/java/org/olat/modules/taxonomy/ui/TaxonomyLevelOverviewController.java +++ b/src/main/java/org/olat/modules/taxonomy/ui/TaxonomyLevelOverviewController.java @@ -213,13 +213,15 @@ public class TaxonomyLevelOverviewController extends BasicController implements showWarning("warning.atleastone.level"); return; } - + + taxonomyLevel = taxonomyService.getTaxonomyLevel(taxonomyLevel); Taxonomy taxonomy = taxonomyLevel.getTaxonomy(); - confirmDeleteCtrl = new DeleteTaxonomyLevelController(ureq, getWindowControl(), null, taxonomy); + List<TaxonomyLevel> levelToDelete = Collections.singletonList(taxonomyLevel); + confirmDeleteCtrl = new DeleteTaxonomyLevelController(ureq, getWindowControl(), levelToDelete, taxonomy); listenTo(confirmDeleteCtrl); String title = translate("confirmation.delete.level.title"); - cmc = new CloseableModalController(getWindowControl(), "close", moveLevelCtrl.getInitialComponent(), true, title); + cmc = new CloseableModalController(getWindowControl(), "close", confirmDeleteCtrl.getInitialComponent(), true, title); listenTo(cmc); cmc.activate(); } diff --git a/src/main/java/org/olat/modules/taxonomy/ui/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/modules/taxonomy/ui/_i18n/LocalStrings_en.properties index e48fce6efaa5801c924d074d236b3e1317694b27..deb3aa8c70663f382ee6479de397328e59e4dd2d 100644 --- a/src/main/java/org/olat/modules/taxonomy/ui/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/modules/taxonomy/ui/_i18n/LocalStrings_en.properties @@ -1,4 +1,4 @@ -#Fri Dec 08 12:28:56 CET 2017 +#Tue Feb 06 08:32:56 CET 2018 QuestionItemImpl=Question actions=Actions add.competence.have=Add "$\:have" @@ -18,12 +18,12 @@ assign.type=Assign atleast.one.competence=You must select at least one competence you can edit. confirm.delete.level.type.sucessfull=The level type "{0}" was successfully deleted. confirm.deleted.level=The level "{0}" was successfully deleted. +confirm.merge.level=The level(s) "{0}" was sucessfully merged. confirm.removed.competence=The competence(s) was successfully removed. confirmation.delete.level=Do you really want to delete the level "{0}"? confirmation.delete.level.title=Delete level confirmation.delete.type=Do you really want to delete this level type "{0}"? confirmation.delete.type.title=Delete level type "{0}" -confirm.merge.level=The level(s) "{0}" was sucessfully merged. confirmation.remove.competence=Do you really want to remove the competence "{0}" for the level {1}? confirmation.remove.competence.title=Remove competence create.taxonomy=Create new taxonomy @@ -33,10 +33,10 @@ details.delete=Delete edit.competence.title=Edit competence "{1}" of "{0}" edit.competences=Edit competences edit.level.types=Edit types -error.delete.num=These taxonomy levels contains the following elements: -error.delete.num.relations=<strong>{0}</strong> references to learn objects -error.delete.num.competences=<strong>{0}</strong> competence relations +error.delete.num=These taxonomy levels contains the following elements\: error.delete.num.child.levels=<strong>{0}</strong> children taxonomy levels +error.delete.num.competences=<strong>{0}</strong> competence relations +error.delete.num.relations=<strong>{0}</strong> references to learn objects error.discontinuous.selection=Discontinous selection of taxonomy levels is not supported. error.found.no.allowed.sub.types=No level type was found which is compatible with the selection and the level types configuration. error.select.target.level=You must select a taxonomy level. @@ -101,6 +101,7 @@ table.taxonomy.level.type.empty=There isn't any level type available. If you wan target=Target target.can.read="$\:target" allowed to read taxonomy.admin.enabled=Enable taxonomy +taxonomy.competence.expiration=Expiration date taxonomy.competence.fullName=Name taxonomy.competence.type=Competence taxonomy.description=Description diff --git a/src/main/java/org/olat/modules/taxonomy/ui/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/modules/taxonomy/ui/_i18n/LocalStrings_fr.properties index 7ff112f86edd9f511a48c72222dbe354ab720917..c6034489631af23770bda176ae84e4adc5d38a75 100644 --- a/src/main/java/org/olat/modules/taxonomy/ui/_i18n/LocalStrings_fr.properties +++ b/src/main/java/org/olat/modules/taxonomy/ui/_i18n/LocalStrings_fr.properties @@ -1,4 +1,4 @@ -#Fri Nov 17 12:09:10 CET 2017 +#Fri Feb 02 08:47:45 CET 2018 QuestionItemImpl=Question actions=Actions add.competence.have=Ajouter "$\:have" @@ -14,9 +14,11 @@ admin.configuration.title=Configuration taxonomie admin.menu.title=Taxonomie admin.menu.title.alt=Taxonomie admin.taxonomy.trees=Taxonomie +assign.type=Attribuer atleast.one.competence=Vous devez choisir au moins une comp\u00E9tence que vous pouvez \u00E9diter. confirm.delete.level.type.sucessfull=Le type de niveau "{0}" a \u00E9t\u00E9 effac\u00E9. confirm.deleted.level=Le niveau "{0}" de la taxonomie a \u00E9t\u00E9 effac\u00E9. +confirm.merge.level=Les niveaux "{0}" ont \u00E9t\u00E9 fusionn\u00E9s avec succ\u00E8s. confirm.removed.competence=La ou les comp\u00E9tences ont \u00E9t\u00E9 effac\u00E9es. confirmation.delete.level=Voulez-vous vraiment effacer le niveau "{0}" de la taxonomie? confirmation.delete.level.title=Effacer un niveau de la taxonomie @@ -31,10 +33,20 @@ details.delete=Effacer edit.competence.title=Editer la comp\u00E9tence "{1}" de "{0}" edit.competences=Editer la comp\u00E9tence edit.level.types=Editer le type +error.delete.num=Les niveaux de la taxonomie contiennent les \u00E9l\u00E9ments suivants\: +error.delete.num.child.levels=<strong>{0}</strong> sous-niveaux +error.delete.num.competences=<strong>{0}</strong> relations vers des comp\u00E9tences +error.delete.num.relations=<strong>{0}</strong> r\u00E9f\u00E9rences \u00E0 des objets didactiques +error.discontinuous.selection=La s\u00E9lection discontinue de niveaux de la taxonomie n'est pas support\u00E9 pour l'instant. +error.found.no.allowed.sub.types=Il n'y a aucun type de niveaux dont la configuration est compatible avec la s\u00E9lection. +error.select.target.level=Vous devez s\u00E9lectionner au moins un niveau de la taxonomie. error.sort.order.integer=Num\u00E9ro de tri doit \u00EAtre un chiffre entier. +error.target.no.parent=Ce niveau de la taxonomie ne peut pas \u00EAtre d\u00E9placer l\u00E0. +error.target.not.allowed=Ce niveau de la taxonomie ne peut pas \u00EAtre d\u00E9plac\u00E9 l\u00E0 car le type du niveau parent est incompatible avec celui-ci. filter.no.level.type=Sans type de niveau have=Acquis info.copy.level.type.sucessfull=Le type de niveau "{0}" a \u00E9t\u00E9 copi\u00E9. +info.delete.merge.to=Ces \u00E9l\u00E9ments peuvent \u00EAtre fusionn\u00E9s avec un autre niveau de la taxonomie. insert.taxonomy.levels=Ajouter un type de niveau level.description=Description level.directory.path=Chemin technique @@ -46,9 +58,14 @@ level.type=Type level.type.allowed.sub.types=Sous-types level.type.cssClass=Class CSS level.type.docs.enabled=Activer le dossier documents +level.types.to.assign=Types de niveaux level.visible=Visible manage=G\u00E9rer +merge.taxonomy.level=Fusionner +merge.to=Fusionner move.taxonomy.level=D\u00E9placer +move.taxonomy.level.title=D\u00E9placer "{0}" +move.taxonomy.levels.title=D\u00E9placer my.taxonomies=Ma taxonomie not.configured=Pas encore configur\u00E9e\! Configurer d'abord une taxonomie dans la partie administration. not.implemented=Not implemented @@ -56,6 +73,7 @@ open.taxonomy=montrer / \u00E9diter remove=Enlever selected.taxonomy.qpool=Taxonomie pour la banque de questions selected.taxonomy.tree=Taxonomie pour la banque de documents +show.all=Tout montrer table.competence.empty=Il n'y a pas encore de comp\u00E9tences attribu\u00E9es pour ce niveau de la taxonomie table.header.actions=<i class\='o_icon o_icon_actions o_icon-lg'> </i> table.header.competence.achievement=Accomplissement @@ -72,15 +90,18 @@ table.header.taxonomy.level.displayName=Nom table.header.taxonomy.level.externalId=R\u00E9f. ext. niveau table.header.taxonomy.level.identifier=Identifiant table.header.taxonomy.level.num.children=Nombre +table.header.taxonomy.level.type=Type de niveau table.header.taxonomy.level.type.identifier=Type du niveau table.header.type.displayName=Nom table.header.type.identifier=Identifiant table.relations.empty=Il n'y a pas encore de relations \u00E0 ce niveau de la taxonomie. table.taxonomy.empty=Il n'existe pas encore de taxonomie. Pour utiliser la banque de documents, la banque de questions ou les comp\u00E9tences, vous devez d'abord cr\u00E9er une taxonomie. +table.taxonomy.level.empty=Il n'y a pas de niveau disponible. table.taxonomy.level.type.empty=Il n'y pas encore de type de niveaux de la taxonomie. Pour utiliser la banque de documents ou la banque de questions, vous devez d\u00E9finir des types \u00E0 attribuer aux niveaux de la taxonomie. target=A atteindre target.can.read="$\:target" autoriser en lecture taxonomy.admin.enabled=Activer taxonomie +taxonomy.competence.expiration=Expiration taxonomy.competence.fullName=Nom taxonomy.competence.type=Comp\u00E9tence taxonomy.description=Description @@ -107,5 +128,8 @@ taxonomy.metadata=M\u00E9tadonn\u00E9es taxonomy.types=Types de niveaux teach=Enseigner tools=$\:table.header.actions +type.taxonomy.level=Attribuer un type de niveau +warning.atleastone.level=Vous devez s\u00E9lectionner au moins un niveau que vous pouvez \u00E9diter. +warning.atleastone.level.competence=Vous devez s\u00E9lectionner au moins un niveau. warning.delete.level=Ce niveau de la taxonomie ne peut pas \u00EAtre effac\u00E9 car il est encore utilis\u00E9. warning.delete.level.type=Le niveau de la taxonomie n'a pas \u00E9t\u00E9 effac\u00E9 car il est encore utilis\u00E9. diff --git a/src/main/java/org/olat/modules/video/ui/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/modules/video/ui/_i18n/LocalStrings_fr.properties index 3e5abeb9b306c434a481fbcfaebb3e9555061873..7c740386991942bc2aabaf064fb24fcfcf4f0ebe 100644 --- a/src/main/java/org/olat/modules/video/ui/_i18n/LocalStrings_fr.properties +++ b/src/main/java/org/olat/modules/video/ui/_i18n/LocalStrings_fr.properties @@ -1,4 +1,4 @@ -#Thu Mar 09 17:09:13 CET 2017 +#Thu Feb 01 18:30:54 CET 2018 add.track=Ajouter sous-titre admin.config.enable=Activ\u00E9 la resource de type vid\u00E9o admin.config.hint=Voulez-vous vraiment d\u00E9sactiver le transcodage vid\u00E9o? @@ -76,9 +76,9 @@ track.table.header.file=Fichier track.table.header.language=Langue track.table.label=Sous-titres track.upload=T\u00E9l\u00E9charger +track.upload.error.filetype=Pour les sous-titres, seuls les fichiers au format WebVTT avec le suffixe .srt sont support\u00E9s. track.upload.error.nofile=Choisissez un fichier s'il vous pla\u00EEt. track.upload.error.nolang=Choisissez une langue de la liste -track.upload.error.filetype=Pour les sous-titres, seuls les fichiers au format WebVTT avec le suffixe .srt sont support\u00E9s. transcoding.error=Master endommag\u00E9 transcoding.inefficient=Qualit\u00E9 m\u00E9diocre transcoding.processing=En cours @@ -121,3 +121,4 @@ video.not.replaced=Le fichier vid\u00E9o n'a pas pu \u00EAtre remplac\u00E9. Cho video.replace.desc=Veuillez choisir un fichier vid\u00E9o sur votre ordinateur et cliquer le bouton "Remplacer la vid\u00E9o" pour remplacer l'ancien. video.replace.upload=Fichier vid\u00E9o video.replaced=Le fichier vid\u00E9o a \u00E9t\u00E9 remplac\u00E9 et il sera transcod\u00E9 pour obtenir les diff\u00E9rentes r\u00E9solutions configur\u00E9es. +warning.no.poster.proposals=Un aper\u00E7u n'a pas pu \u00EAtre g\u00E9n\u00E9r\u00E9. diff --git a/src/main/java/org/olat/portfolio/manager/EPStructureManager.java b/src/main/java/org/olat/portfolio/manager/EPStructureManager.java index 378cefc4063b2c12a3d2bd17f14a7fbda7e1dc68..ab014fb1defc4aa9c0ce92cc4e3bddd05014c2c7 100755 --- a/src/main/java/org/olat/portfolio/manager/EPStructureManager.java +++ b/src/main/java/org/olat/portfolio/manager/EPStructureManager.java @@ -175,7 +175,7 @@ public class EPStructureManager { protected List<PortfolioStructure> getStructureElements(int firstResult, int maxResults, ElementType... types){ StringBuilder sb = new StringBuilder(); sb.append("select stEl from ").append(EPStructureElement.class.getName()).append(" stEl"); - sb.append(" where stEl.class in ("); + sb.append(" where type(stEl) in ("); boolean first = true; for(ElementType type:types) { if(first) first = false; @@ -205,7 +205,7 @@ public class EPStructureManager { .append(" where baseGroup=membership.group and membership.identity.key=:identityKey and membership.role='").append(GroupRoles.owner.name()).append("'") .append(" )"); if(types != null && types.length > 0) { - sb.append(" and stEl.class in ("); + sb.append(" and type(stEl) in ("); boolean first = true; for(ElementType type:types) { if(first) first = false; @@ -336,7 +336,7 @@ public class EPStructureManager { .append(" )"); } if (types != null && types.length > 0) { - sb.append(" and stEl.class in ("); + sb.append(" and type(stEl) in ("); boolean first = true; for (final ElementType type : types) { if (first) { @@ -397,7 +397,7 @@ public class EPStructureManager { .append(" )"); } if(types != null && types.length > 0) { - sb.append(" and stEl.class in ("); + sb.append(" and type(stEl) in ("); boolean first = true; for(ElementType type:types) { if(first) first = false; diff --git a/src/main/java/org/olat/repository/RepositoryMailing.java b/src/main/java/org/olat/repository/RepositoryMailing.java index 559fca1b8a049004efdb9f8927cada8607017e70..7c73d2bf7216e102b789380fb40b2cc4ee0e7936 100644 --- a/src/main/java/org/olat/repository/RepositoryMailing.java +++ b/src/main/java/org/olat/repository/RepositoryMailing.java @@ -74,6 +74,19 @@ public class RepositoryMailing { return createMailTemplate(re, actor, subjectKey, bodyKey); } + /** + * The mail template when adding users to a course. + * + * @param re + * @param actor + * @return the generated MailTemplate + */ + public static MailTemplate createAddAutoParticipantMailTemplate(RepositoryEntry re, Identity actor) { + String subjectKey = "notification.mail.added.auto.subject"; + String bodyKey = "notification.mail.added.auto.body"; + return createMailTemplate(re, actor, subjectKey, bodyKey); + } + /** * The mail template when adding tutors to a course. * @@ -119,6 +132,8 @@ public class RepositoryMailing { switch(type) { case addParticipant: return createAddParticipantMailTemplate(re, ureqIdentity); + case addParticipantItself: + return createAddAutoParticipantMailTemplate(re, ureqIdentity); case addTutor: return createAddTutorMailTemplate(re, ureqIdentity); case addOwner: @@ -131,7 +146,7 @@ public class RepositoryMailing { return null; } - protected static void sendEmail(Identity ureqIdentity, Identity identity, RepositoryEntry re, + public static void sendEmail(Identity ureqIdentity, Identity identity, RepositoryEntry re, Type type, MailPackage mailing) { if(mailing != null && !mailing.isSendEmail()) { @@ -181,7 +196,8 @@ public class RepositoryMailing { addTutor, removeTutor, addOwner, - removeOwner + removeOwner, + addParticipantItself } private static MailTemplate createMailTemplate(RepositoryEntry re, Identity actor, String subjectKey, String bodyKey) { diff --git a/src/main/java/org/olat/repository/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/repository/_i18n/LocalStrings_de.properties index f25e518daa8cd227e249de38041cdbf777c21266..b1a602c46540480aa1acedf7d791c599d88b4598 100644 --- a/src/main/java/org/olat/repository/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/repository/_i18n/LocalStrings_de.properties @@ -384,6 +384,8 @@ no.lifecycle=Keine Einschr\u00E4nkung no.catalog.entries=Diese Resource wurde noch nicht im Katalog registriert. \r\n\r\n Verwenden Sie den "In Katalog einf\u00FCgen" Button in der Toolbar, um die Resource auf einer bestimmten Katalog-Ebenen hinzuzuf\u00FCgen. Der Katalog erlaubt es dem Benutzer je nach Zugriffskonfiguration nach bestimmten Eintr\u00E4gen zu suchen. Sie k\u00F6nnen die Resource auf mehreren Katalog-Ebenen hinzuf\u00FCgen. info.catalog.entries=Verwenden Sie den "In Katalog einf\u00FCgen" Button in der Toolbar, um die Resource auf einer bestimmten Katalog-Ebenen hinzuzuf\u00FCgen. Der Katalog erlaubt es dem Benutzer je nach Zugriffskonfiguration nach bestimmten Eintr\u00E4gen zu suchen. Sie k\u00F6nnen die Resource auf mehreren Katalog-Ebenen hinzuf\u00FCgen. nomembers=XXX No members +notification.mail.added.auto.body=*** Das ist eine automatisch generierte Nachricht. Bitte antworten Sie nicht auf diese Nachricht *** \n\nSie haben sich f\u00FCr den folgenden Kurs angemeldet\: \n\nKursname\: $coursename\nBeschreibung\: $coursedescription\nZugang\: $courseurl +notification.mail.added.auto.subject=$\:notification.mail.added.subject notification.mail.added.body=*** Das ist eine automatisch generierte Nachricht. Bitte antworten Sie nicht auf diese Nachricht *** \n\nSie wurden von {0} {1} ({2}) in einen Kurs eingeladen\: \n\nKursname\: $coursename\nBeschreibung\: $coursedescription\nZugang\: $courseurl\n\nBei Fragen kontaktieren Sie bitte {0} {1} ({2}). notification.mail.added.subject=Kurs $coursename notification.mail.removed.body=*** Das ist eine automatisch generierte Nachricht. Bitte antworten Sie nicht auf diese Nachricht *** \n\nSie wurden von {0} {1} ({2}) aus dem Kurs ausgetragen\: \n\nKursname\: $coursename\nBeschreibung\: $coursedescription\n\nBei Fragen kontaktieren Sie bitte {0} {1} ({2}). diff --git a/src/main/java/org/olat/repository/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/repository/_i18n/LocalStrings_en.properties index c2a87e54010a7bd99e288dc35f80d5ca08abefa4..19026de10963c68967c64893efb76b1de13bc14a 100644 --- a/src/main/java/org/olat/repository/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/repository/_i18n/LocalStrings_en.properties @@ -381,6 +381,8 @@ no.lifecycle=No limitation no.catalog.entries=This resource has not been added to the catalog yet. \r\n\r\n Use the "Add to catalog" button in the toolbar above to add the resource to a specific level in the catalog. The catalog allows users to browse for available resources depending on th resource access configuration. You can add the resource to multiple catalog levels. info.catalog.entries=Use the "Add to catalog" button in the toolbar above to add the resource to a specific level in the catalog. The catalog allows users to browse for available resources depending on th resource access configuration. You can add the resource to multiple catalog levels. nomembers=XXX No members +notification.mail.added.auto.body=*** This is an automatically generated message. Please do not answer to this message *** \r\n\r\nYou registered you to the following course\:\r\n\r\nCourse name\: $coursename\r\nDescription\: $coursedescription\nLink\: $courseurl +notification.mail.added.auto.subject=$\:notification.mail.added.subject notification.mail.added.body=*** This is an automatically generated message. Please do not answer to this message *** \r\n\r\nYou have been added by {0} {1} ({2}) to a course\:\r\n\r\nCourse name\: $coursename\r\nDescription\: $coursedescription\nLink\: $courseurl\n\nIf you have questions regarding this action, please contact {0} {1} ({2}). notification.mail.added.subject=Course $coursename notification.mail.removed.body=*** This is an automatically generated message. Please do not answer to this message *** \r\n\r\nYou have been removed by {0} {1} ({2}) from a course\:\r\n\r\nCourse name\: $coursename\r\nDescription\: $coursedescription\r\n\r\nIf you have questions regarding this action, please contact {0} {1} ({2}). diff --git a/src/main/java/org/olat/repository/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/repository/_i18n/LocalStrings_fr.properties index 1d9de9f97f10c51cc6c1539ff5eaccf9c6ec10f2..087cc752e309f62400c50a4c1dfc7b2db7da1254 100644 --- a/src/main/java/org/olat/repository/_i18n/LocalStrings_fr.properties +++ b/src/main/java/org/olat/repository/_i18n/LocalStrings_fr.properties @@ -1,4 +1,4 @@ -#Tue Aug 15 17:30:54 CEST 2017 +#Thu Feb 01 18:37:37 CET 2018 BinderTemplate=Mod\u00E8le de portfolio 2.0 CourseModule=Cours EPStructuredMapTemplate=Mod\u00E8le de portfolio @@ -140,6 +140,10 @@ cif.private.dates=Date cif.public.dates=Semestre cif.requirements=Exigences cif.resourcename=Nom de fichier +cif.resources.status=Cours +cif.resources.status.active=Actif +cif.resources.status.all=Tous +cif.resources.status.closed=Termin\u00E9 cif.softkey=OpenOLAT-Soft-ID cif.type=Type cif.type.na=pas d'indication diff --git a/src/main/java/org/olat/resource/accesscontrol/Offer.java b/src/main/java/org/olat/resource/accesscontrol/Offer.java index 8c59b0b518b1ea78a3d40915764830ed9e54d53b..368f67cc4cdb6113ed033a424a9293dd16772682 100644 --- a/src/main/java/org/olat/resource/accesscontrol/Offer.java +++ b/src/main/java/org/olat/resource/accesscontrol/Offer.java @@ -68,5 +68,9 @@ public interface Offer extends Persistable { public boolean isAutoBooking(); public void setAutoBooking(boolean autoBooking); + + public boolean isConfirmationEmail(); + + public void setConfirmationEmail(boolean confirmationEmail); } diff --git a/src/main/java/org/olat/resource/accesscontrol/manager/ACFrontendManager.java b/src/main/java/org/olat/resource/accesscontrol/manager/ACFrontendManager.java index a517ed0173b7f314ef63370b40f63b68eefa950e..d9a3a9e2393b3cc616ac99c95bdf40e84cdaa7d1 100644 --- a/src/main/java/org/olat/resource/accesscontrol/manager/ACFrontendManager.java +++ b/src/main/java/org/olat/resource/accesscontrol/manager/ACFrontendManager.java @@ -41,6 +41,7 @@ import org.olat.core.id.Roles; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; import org.olat.core.util.StringHelper; +import org.olat.core.util.mail.MailPackage; import org.olat.group.BusinessGroup; import org.olat.group.BusinessGroupService; import org.olat.group.manager.BusinessGroupDAO; @@ -49,6 +50,7 @@ import org.olat.group.model.EnrollState; import org.olat.repository.RepositoryEntry; import org.olat.repository.RepositoryEntryRef; import org.olat.repository.RepositoryEntryShort; +import org.olat.repository.RepositoryMailing; import org.olat.repository.RepositoryManager; import org.olat.repository.RepositoryService; import org.olat.repository.manager.RepositoryEntryRelationDAO; @@ -113,11 +115,11 @@ public class ACFrontendManager implements ACService { @Autowired private BusinessGroupDAO businessGroupDao; @Autowired + private BusinessGroupService businessGroupService; + @Autowired private BusinessGroupRelationDAO businessGroupRelationDao; @Autowired private RepositoryEntryRelationDAO repositoryEntryRelationDao; - @Autowired - private BusinessGroupService businessGroupService; /** * The rule to access the repository entry:<br/> @@ -479,14 +481,19 @@ public class ACFrontendManager implements ACService { if("BusinessGroup".equals(resourceType)) { BusinessGroup group = businessGroupService.loadBusinessGroup(resource); if(group != null) { - EnrollState result = businessGroupService.enroll(identity, null, identity, group, null); - return result.isFailed() ? Boolean.FALSE : Boolean.TRUE; + MailPackage mailing = new MailPackage(offer.isConfirmationEmail()); + EnrollState result = businessGroupService.enroll(identity, null, identity, group, mailing); + return !result.isFailed(); } } else { - RepositoryEntryRef entry = repositoryManager.lookupRepositoryEntry(resource, false); + RepositoryEntry entry = repositoryManager.lookupRepositoryEntry(resource, false); if(entry != null) { if(!repositoryEntryRelationDao.hasRole(identity, entry, GroupRoles.participant.name())) { repositoryEntryRelationDao.addRole(identity, entry, GroupRoles.participant.name()); + if(offer.isConfirmationEmail()) { + MailPackage mailing = new MailPackage(offer.isConfirmationEmail()); + RepositoryMailing.sendEmail(identity, identity, entry, RepositoryMailing.Type.addParticipantItself, mailing); + } } return true; } diff --git a/src/main/java/org/olat/resource/accesscontrol/manager/ACMethodDAO.java b/src/main/java/org/olat/resource/accesscontrol/manager/ACMethodDAO.java index 65e609bf5e9242da0a34d1584a2d3c631c531a05..dede289ce9f44f0128cbf5af9d5a853b85339a3b 100644 --- a/src/main/java/org/olat/resource/accesscontrol/manager/ACMethodDAO.java +++ b/src/main/java/org/olat/resource/accesscontrol/manager/ACMethodDAO.java @@ -188,7 +188,7 @@ public class ACMethodDAO implements InitializingBean { StringBuilder sb = new StringBuilder(); sb.append("select method from ").append(AbstractAccessMethod.class.getName()).append(" method") .append(" where method.valid=true") - .append(" and method.class=").append(type.getName()); + .append(" and type(method) =").append(type.getName()); TypedQuery<AccessMethod> query = dbInstance.getCurrentEntityManager().createQuery(sb.toString(), AccessMethod.class); List<AccessMethod> methods = query.getResultList(); @@ -378,7 +378,7 @@ public class ACMethodDAO implements InitializingBean { protected void activateFreeMethod(boolean enable) { StringBuilder sb = new StringBuilder(); sb.append("select method from ").append(AbstractAccessMethod.class.getName()) - .append(" method where method.class=").append(FreeAccessMethod.class.getName()); + .append(" method where type(method) =").append(FreeAccessMethod.class.getName()); TypedQuery<AccessMethod> query = dbInstance.getCurrentEntityManager().createQuery(sb.toString(), AccessMethod.class); List<AccessMethod> methods = query.getResultList(); diff --git a/src/main/java/org/olat/resource/accesscontrol/manager/ACOfferDAO.java b/src/main/java/org/olat/resource/accesscontrol/manager/ACOfferDAO.java index 398013d122564e92ec00f6a1b2f11fe7ac74c60e..53442c6b3cb050b7523ad78f6833ecc86a3bc73c 100644 --- a/src/main/java/org/olat/resource/accesscontrol/manager/ACOfferDAO.java +++ b/src/main/java/org/olat/resource/accesscontrol/manager/ACOfferDAO.java @@ -135,6 +135,7 @@ public class ACOfferDAO { offer.setLastModified(now); offer.setResource(resource); offer.setValid(true); + offer.setConfirmationEmail(false); if(resourceName != null && resourceName.length() > 255) { resourceName = resourceName.substring(0, 250); } diff --git a/src/main/java/org/olat/resource/accesscontrol/model/OfferImpl.java b/src/main/java/org/olat/resource/accesscontrol/model/OfferImpl.java index 5c4f6cb4223d33c17b82bd88aa7e2caad5be54d0..3aa9c4f7183d52ecea65b13f35409c82b14f0bbd 100644 --- a/src/main/java/org/olat/resource/accesscontrol/model/OfferImpl.java +++ b/src/main/java/org/olat/resource/accesscontrol/model/OfferImpl.java @@ -98,6 +98,8 @@ public class OfferImpl implements Persistable, Offer, ModifiedInfo { private String token; @Column(name="autobooking", nullable=true, insertable=true, updatable=true) private boolean autoBooking; + @Column(name="confirmation_email", nullable=true, insertable=true, updatable=true) + private boolean confirmationEmail; @Column(name="resourceid", nullable=true, insertable=true, updatable=true) private Long resourceId; @@ -182,6 +184,7 @@ public class OfferImpl implements Persistable, Offer, ModifiedInfo { this.validTo = validTo; } + @Override public Long getResourceId() { return resourceId; } @@ -190,6 +193,7 @@ public class OfferImpl implements Persistable, Offer, ModifiedInfo { this.resourceId = resourceId; } + @Override public String getResourceTypeName() { return resourceTypeName; } @@ -198,6 +202,7 @@ public class OfferImpl implements Persistable, Offer, ModifiedInfo { this.resourceTypeName = resourceTypeName; } + @Override public String getResourceDisplayName() { return resourceDisplayName; } @@ -215,15 +220,25 @@ public class OfferImpl implements Persistable, Offer, ModifiedInfo { public void setDescription(String description) { this.description = description; } - + + @Override public boolean isAutoBooking() { return autoBooking; } - + + @Override public void setAutoBooking(boolean autoBooking) { this.autoBooking = autoBooking; } + public boolean isConfirmationEmail() { + return confirmationEmail; + } + + public void setConfirmationEmail(boolean confirmationEmail) { + this.confirmationEmail = confirmationEmail; + } + public String getToken() { return token; } diff --git a/src/main/java/org/olat/resource/accesscontrol/ui/AbstractConfigurationMethodController.java b/src/main/java/org/olat/resource/accesscontrol/ui/AbstractConfigurationMethodController.java index 67cc9d65aac158c16646d195abd6c884b152feea..3b9462286db794b5837cb2642eb5335cf8592760 100644 --- a/src/main/java/org/olat/resource/accesscontrol/ui/AbstractConfigurationMethodController.java +++ b/src/main/java/org/olat/resource/accesscontrol/ui/AbstractConfigurationMethodController.java @@ -33,10 +33,6 @@ import org.olat.resource.accesscontrol.model.AccessMethod; /** * - * Description:<br> - * TODO: srosse Class Description for AbstractConfigurationMethodController - * - * <P> * Initial Date: 18 avr. 2011 <br> * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com */ @@ -73,6 +69,7 @@ public abstract class AbstractConfigurationMethodController extends FormBasicCon public abstract AccessMethod getMethod(); + @Override public FormItem getInitialFormItem() { return flc; } diff --git a/src/main/java/org/olat/resource/accesscontrol/ui/AccessConfigurationController.java b/src/main/java/org/olat/resource/accesscontrol/ui/AccessConfigurationController.java index 5f30e7fa5e75db21fa9bfb89c99f6bbee46b72dc..e95c3beeb16b3574b7af0c9bd30a7d729c909563 100644 --- a/src/main/java/org/olat/resource/accesscontrol/ui/AccessConfigurationController.java +++ b/src/main/java/org/olat/resource/accesscontrol/ui/AccessConfigurationController.java @@ -24,14 +24,13 @@ import java.math.BigDecimal; import java.util.ArrayList; import java.util.Date; import java.util.List; -import java.util.Map; +import org.olat.core.commons.persistence.DB; import org.olat.core.gui.UserRequest; -import org.olat.core.gui.components.Component; import org.olat.core.gui.components.form.flexible.FormItem; import org.olat.core.gui.components.form.flexible.FormItemContainer; -import org.olat.core.gui.components.form.flexible.elements.DateChooser; import org.olat.core.gui.components.form.flexible.elements.FormLink; +import org.olat.core.gui.components.form.flexible.elements.MultipleSelectionElement; import org.olat.core.gui.components.form.flexible.impl.Form; import org.olat.core.gui.components.form.flexible.impl.FormBasicController; import org.olat.core.gui.components.form.flexible.impl.FormEvent; @@ -64,8 +63,12 @@ import org.springframework.beans.factory.annotation.Autowired; * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com */ public class AccessConfigurationController extends FormBasicController { + + private static final String[] onKeys = new String[] { "on" }; - private List<FormLink> addMethods = new ArrayList<FormLink>(); + private MultipleSelectionElement confirmationEmailEl; + private final List<FormLink> addMethods = new ArrayList<>(); + private final String displayName; private final OLATResource resource; @@ -73,7 +76,7 @@ public class AccessConfigurationController extends FormBasicController { private FormLayoutContainer confControllerContainer; private AbstractConfigurationMethodController newMethodCtrl, editMethodCtrl; - private final List<AccessInfo> confControllers = new ArrayList<AccessInfo>(); + private final List<AccessInfo> confControllers = new ArrayList<>(); private final boolean embbed; private final boolean emptyConfigGrantsFullAccess; @@ -82,6 +85,8 @@ public class AccessConfigurationController extends FormBasicController { private final Formatter formatter; + @Autowired + private DB dbInstance; @Autowired private ACService acService; @Autowired @@ -144,6 +149,11 @@ public class AccessConfigurationController extends FormBasicController { } ((FormLayoutContainer)formLayout).contextPut("methods", addMethods); } + + String[] onValues = new String[] { "" }; + confirmationEmailEl = uifactory.addCheckboxesHorizontal("confirmation.email", formLayout, onKeys, onValues); + confirmationEmailEl.addActionListener(FormEvent.ONCHANGE); + confirmationEmailEl.setVisible(false); String confPage = velocity_root + "/configuration_list.html"; confControllerContainer = FormLayoutContainer.createCustomFormLayout("conf-controllers", getTranslator(), confPage); @@ -154,6 +164,15 @@ public class AccessConfigurationController extends FormBasicController { confControllerContainer.contextPut("confControllers", confControllers); + boolean confirmationEmail = false; + for(AccessInfo info:confControllers) { + Offer offer = info.getLink().getOffer(); + confirmationEmail |= offer.isConfirmationEmail(); + } + if(confirmationEmail) { + confirmationEmailEl.select(onKeys[0], true); + } + if(!embbed) { setFormTitle("accesscontrol.title"); @@ -187,16 +206,6 @@ public class AccessConfigurationController extends FormBasicController { // } - @Override - public void event(UserRequest ureq, Component source, Event event) { - if(addMethods.contains(source)) { - AccessMethod method = (AccessMethod)((Link)source).getUserObject(); - addMethod(ureq, method); - } else { - super.event(ureq, source, event); - } - } - @Override protected void event(UserRequest ureq, Controller source, Event event) { if(newMethodCtrl == source) { @@ -243,39 +252,21 @@ public class AccessConfigurationController extends FormBasicController { String cmd = button.getCmd(); if("delete".equals(cmd)) { AccessInfo infos = (AccessInfo)source.getUserObject(); - acService.deleteOffer(infos.getLink().getOffer()); - confControllers.remove(infos); + removeMethod(infos); fireEvent(ureq, Event.CHANGED_EVENT); } else if("edit".equals(cmd)) { AccessInfo infos = (AccessInfo)source.getUserObject(); editMethod(ureq, infos); } + } else if(confirmationEmailEl == source) { + setConfirmationEmail(confirmationEmailEl.isAtLeastSelected(1)); } super.formInnerEvent(ureq, source, event); } @Override public void formOK(UserRequest ureq) { - Map<String,FormItem> formItemMap = confControllerContainer.getFormComponents(); - - List<OfferAccess> links = new ArrayList<OfferAccess>(); - for(AccessInfo info:confControllers) { - FormItem dateFrom = formItemMap.get("from_" + info.getLink().getKey()); - if(dateFrom instanceof DateChooser) { - Date from = ((DateChooser)dateFrom).getDate(); - info.getLink().setValidFrom(from); - info.getLink().getOffer().setValidFrom(from); - } - - FormItem dateTo = formItemMap.get("to_" + info.getLink().getKey()); - if(dateTo instanceof DateChooser) { - Date to = ((DateChooser)dateTo).getDate(); - info.getLink().setValidTo(to); - info.getLink().getOffer().setValidTo(to); - } - - links.add(info.getLink()); - } + // } protected void loadConfigurations() { @@ -320,6 +311,15 @@ public class AccessConfigurationController extends FormBasicController { delLink.setIconLeftCSS("o_icon o_icon-fw o_icon_delete_item"); confControllerContainer.add(delLink.getName(), delLink); } + + updateConfirmationEmail(); + } + + private void updateConfirmationEmail() { + if(confirmationEmailEl.isVisible() != !confControllers.isEmpty()) { + confirmationEmailEl.setVisible(!confControllers.isEmpty()); + flc.setDirty(true); + } } private void editMethod(UserRequest ureq, AccessInfo infos) { @@ -342,7 +342,9 @@ public class AccessConfigurationController extends FormBasicController { } protected void addMethod(UserRequest ureq, AccessMethod method) { + boolean confirmationEmail = confirmationEmailEl.isVisible() && confirmationEmailEl.isAtLeastSelected(1); Offer offer = acService.createOffer(resource, displayName); + offer.setConfirmationEmail(confirmationEmail); OfferAccess link = acService.createOfferAccess(offer, method); removeAsListenerAndDispose(newMethodCtrl); @@ -362,6 +364,23 @@ public class AccessConfigurationController extends FormBasicController { addConfiguration(newLink); } } + + private void removeMethod(AccessInfo infos) { + acService.deleteOffer(infos.getLink().getOffer()); + confControllers.remove(infos); + updateConfirmationEmail(); + } + + private void setConfirmationEmail(boolean confirmationEmail) { + for(AccessInfo info:confControllers) { + Offer offer = info.getLink().getOffer(); + offer.setConfirmationEmail(confirmationEmail); + offer = acService.save(offer); + } + dbInstance.commit();//make sure all is on the dabatase + confControllers.clear(); + loadConfigurations(); + } public class AccessInfo { private String name; diff --git a/src/main/java/org/olat/resource/accesscontrol/ui/_content/access_configuration.html b/src/main/java/org/olat/resource/accesscontrol/ui/_content/access_configuration.html index 0047566062bd6fad59505d6ed0513823ae76a52a..e530afecc3a5027d9e48c322bb1a87186aaa6bae 100644 --- a/src/main/java/org/olat/resource/accesscontrol/ui/_content/access_configuration.html +++ b/src/main/java/org/olat/resource/accesscontrol/ui/_content/access_configuration.html @@ -12,6 +12,12 @@ #if ($off_info) <div class="o_info">$off_info</div> #end </div></div> #end + #if($r.visible("confirmation.email")) + <div class="form-group"> + <label class="control-label col-sm-3">$r.translate("confirmation.email")</label> + <div class="col-sm-9">$r.render("confirmation.email")</div> + </div> + #end <div class="form-group"> <label class="control-label col-sm-3">$r.translate("ac.methods.label") $r.render("acMethodsLabelHelp")</label> <div class="col-sm-9">$r.render("conf-controllers")</div> diff --git a/src/main/java/org/olat/resource/accesscontrol/ui/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/resource/accesscontrol/ui/_i18n/LocalStrings_de.properties index be5ad639800744c5ea0412081a581203497cc5c0..c7a441396c7f8356b0f6c62b076a9f2f370749fd 100644 --- a/src/main/java/org/olat/resource/accesscontrol/ui/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/resource/accesscontrol/ui/_i18n/LocalStrings_de.properties @@ -38,6 +38,7 @@ admin.menu.title.alt=$\:admin.title admin.title=Verwaltung der Zugangskontrolle und Buchungsmethoden cmd.close=Schliessen cmd.title=Zugangskontrolle +confirmation.email=Best\u00E4tigungsemail f\u00FCr selbst eingetragene Benutzer course.closed=$org.olat.course.run\:course.closed create=Erstellen from=Von\: diff --git a/src/main/java/org/olat/resource/accesscontrol/ui/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/resource/accesscontrol/ui/_i18n/LocalStrings_en.properties index 701fa5425c9c805a9a16402e168a5b166581a2c7..a47f66b45d118e7e662482cd069e723c093b40f8 100644 --- a/src/main/java/org/olat/resource/accesscontrol/ui/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/resource/accesscontrol/ui/_i18n/LocalStrings_en.properties @@ -61,6 +61,7 @@ admin.title=Access control and booking methods administration cmd.close=Close cmd.title=Access control +confirmation.email=Confirmation email for self-registered users course.closed=$org.olat.course.run\:course.closed create=Create from=From\: diff --git a/src/main/java/org/olat/search/ui/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/search/ui/_i18n/LocalStrings_fr.properties index 03386d72b123d275ba2d32268313469298f2d562..c288b25c7e2b728d4b892ded17015e7b7cf45450 100644 --- a/src/main/java/org/olat/search/ui/_i18n/LocalStrings_fr.properties +++ b/src/main/java/org/olat/search/ui/_i18n/LocalStrings_fr.properties @@ -1,4 +1,4 @@ -#Fri Nov 17 12:07:55 CET 2017 +#Thu Feb 01 18:38:42 CET 2018 DocumentPool=Banque de documents EPSite=Portfolio HomeSite=Home @@ -6,6 +6,7 @@ LibrarySite=Biblioth\u00E8que Portfolio=Portfolio Taxonomy=Taxonomie TaxonomyLevel=Niveau de la taxonomie +Templates=Mod\u00E8le all.search.result.title=tous les {0} r\u00E9sultats area.blogs=Blogue/podcast area.courses=Cours diff --git a/src/main/java/org/olat/upgrade/OLATUpgrade_12_3_0.java b/src/main/java/org/olat/upgrade/OLATUpgrade_12_3_0.java index 2db559824a3fbf7df0ccb61a7e9eeaa0a2582170..a7ba6d015cd10d02c89ddecbe3d217d2866fb424 100644 --- a/src/main/java/org/olat/upgrade/OLATUpgrade_12_3_0.java +++ b/src/main/java/org/olat/upgrade/OLATUpgrade_12_3_0.java @@ -176,9 +176,9 @@ public class OLATUpgrade_12_3_0 extends OLATUpgrade { log.error("Not able to migrate question title: " + item, e); } } - log.info(counter + " QPool items processed."); counter += items.size(); dbInstance.commitAndCloseSession(); + log.info(counter + " QPool items processed."); } while(items.size() == BATCH_SIZE); } @@ -197,7 +197,7 @@ public class OLATUpgrade_12_3_0 extends OLATUpgrade { item.setTitle(title); dbInstance.getCurrentEntityManager().merge(item); } else { - throw new RuntimeException("No title found for QPool item"); + log.warn("Not able to migrate question title of QPool item (no title found). dir: " + item.getDirectory() + ", " + item); } } @@ -211,26 +211,36 @@ public class OLATUpgrade_12_3_0 extends OLATUpgrade { title = getTitleQTI12(item); break; default: - log.error("Not able to migrate question title. QPool item has no valid format: " + item); + log.warn("QPool item has no valid format for title migration: " + item.getFormat() + ", " + item); } return title; } private String getTitleQTI21(QuestionItemImpl item) { - File resourceDirectory = qpoolService.getRootDirectory(item); - File resourceFile = qpoolService.getRootFile(item); - URI assessmentItemUri = resourceFile.toURI(); - - ResolvedAssessmentItem resolvedAssessmentItem = qtiService - .loadAndResolveAssessmentItem(assessmentItemUri, resourceDirectory); - - return resolvedAssessmentItem.getRootNodeLookup().getRootNodeHolder().getRootNode().getTitle(); + try { + File resourceDirectory = qpoolService.getRootDirectory(item); + File resourceFile = qpoolService.getRootFile(item); + URI assessmentItemUri = resourceFile.toURI(); + + ResolvedAssessmentItem resolvedAssessmentItem = qtiService + .loadAndResolveAssessmentItem(assessmentItemUri, resourceDirectory); + + return resolvedAssessmentItem.getRootNodeLookup().getRootNodeHolder().getRootNode().getTitle(); + } catch (NullPointerException e) { + log.warn("Cannot read files from dir: " + item.getDirectory()); + } + return null; } private String getTitleQTI12(QuestionItemImpl item) { - VFSLeaf leaf = qpoolService.getRootLeaf(item); - Item xmlItem = QTIEditHelper.readItemXml(leaf); - return xmlItem.getTitle(); + try { + VFSLeaf leaf = qpoolService.getRootLeaf(item); + Item xmlItem = QTIEditHelper.readItemXml(leaf); + return xmlItem.getTitle(); + } catch (NullPointerException e) { + log.warn("Cannot read files from dir: " + item.getDirectory()); + } + return null; } private boolean migrateDialogElements(UpgradeManager upgradeManager, UpgradeHistoryData uhd) { diff --git a/src/main/resources/database/mysql/alter_12_3_x_to_12_4_0.sql b/src/main/resources/database/mysql/alter_12_3_x_to_12_4_0.sql index 05bd7c7c22ed2c2201f62ee5e95fdc33d13e3f90..e9681a365487751c8371f7cfbae56a4b24490699 100644 --- a/src/main/resources/database/mysql/alter_12_3_x_to_12_4_0.sql +++ b/src/main/resources/database/mysql/alter_12_3_x_to_12_4_0.sql @@ -1,4 +1,7 @@ -- Evaluation forms alter table o_eva_form_response drop column e_responsedatatype; -alter table o_eva_form_response add column e_file_response_path varchar(4000); \ No newline at end of file +alter table o_eva_form_response add column e_file_response_path varchar(4000); + +-- access control +alter table o_ac_offer add column confirmation_email bit default 0; \ No newline at end of file diff --git a/src/main/resources/database/mysql/setupDatabase.sql b/src/main/resources/database/mysql/setupDatabase.sql index e0410fd1e005bd6804bcaa23f2d7a3cb3e0c6e15..90f5fcc7c152574f8d626a15413fed0ae2ea0bba 100644 --- a/src/main/resources/database/mysql/setupDatabase.sql +++ b/src/main/resources/database/mysql/setupDatabase.sql @@ -973,6 +973,7 @@ create table if not exists o_ac_offer ( resourcetypename varchar(255), resourcedisplayname varchar(255), autobooking boolean default 0, + confirmation_email bit default 0, token varchar(255), price_amount DECIMAL(12,4), price_currency_code VARCHAR(3), diff --git a/src/main/resources/database/oracle/alter_12_3_x_to_12_4_0.sql b/src/main/resources/database/oracle/alter_12_3_x_to_12_4_0.sql index 05bd7c7c22ed2c2201f62ee5e95fdc33d13e3f90..7a9d6391a40d6e8484f53f56b19a6872985ea6e6 100644 --- a/src/main/resources/database/oracle/alter_12_3_x_to_12_4_0.sql +++ b/src/main/resources/database/oracle/alter_12_3_x_to_12_4_0.sql @@ -1,4 +1,7 @@ -- Evaluation forms alter table o_eva_form_response drop column e_responsedatatype; -alter table o_eva_form_response add column e_file_response_path varchar(4000); \ No newline at end of file +alter table o_eva_form_response add column e_file_response_path varchar(4000); + +-- access control +alter table o_ac_offer add confirmation_email number default 0; \ No newline at end of file diff --git a/src/main/resources/database/oracle/setupDatabase.sql b/src/main/resources/database/oracle/setupDatabase.sql index e277aed0d3ddbc0704e04d338a58ee7e304bb2a9..9835c84a5b3bdf81ba2e6ad09534709d6ede0575 100644 --- a/src/main/resources/database/oracle/setupDatabase.sql +++ b/src/main/resources/database/oracle/setupDatabase.sql @@ -889,6 +889,7 @@ create table o_ac_offer ( resourcedisplayname varchar(255 char), token varchar(255 char), autobooking number default 0 not null, + confirmation_email number default 0, price_amount number(20,2), price_currency_code VARCHAR(3 char), offer_desc VARCHAR(2000 char), diff --git a/src/main/resources/database/postgresql/alter_12_3_x_to_12_4_0.sql b/src/main/resources/database/postgresql/alter_12_3_x_to_12_4_0.sql index 05bd7c7c22ed2c2201f62ee5e95fdc33d13e3f90..91679515c5d411fb52ab1a5032773215fb65f75e 100644 --- a/src/main/resources/database/postgresql/alter_12_3_x_to_12_4_0.sql +++ b/src/main/resources/database/postgresql/alter_12_3_x_to_12_4_0.sql @@ -1,4 +1,7 @@ -- Evaluation forms alter table o_eva_form_response drop column e_responsedatatype; -alter table o_eva_form_response add column e_file_response_path varchar(4000); \ No newline at end of file +alter table o_eva_form_response add column e_file_response_path varchar(4000); + +-- access control +alter table o_ac_offer add column confirmation_email bool default false; \ No newline at end of file diff --git a/src/main/resources/database/postgresql/setupDatabase.sql b/src/main/resources/database/postgresql/setupDatabase.sql index 4012d0db76b43a7b4de0e5d435444ab5d67df453..45b02621327f35b47c3efbbfce4c6b72e7abe580 100644 --- a/src/main/resources/database/postgresql/setupDatabase.sql +++ b/src/main/resources/database/postgresql/setupDatabase.sql @@ -837,6 +837,7 @@ create table o_ac_offer ( resourcetypename varchar(255), resourcedisplayname varchar(255), autobooking bool not null default false, + confirmation_email bool default false, token varchar(255), price_amount DECIMAL, price_currency_code VARCHAR(3), diff --git a/src/main/resources/org/olat/ims/qti21/questionimport/qti-import-metadata.xlsx b/src/main/resources/org/olat/ims/qti21/questionimport/qti-import-metadata.xlsx index f736582664caef023283487991abf40083432f63..337788a2369fb178b73ae6c206045fc0536fe2a8 100644 Binary files a/src/main/resources/org/olat/ims/qti21/questionimport/qti-import-metadata.xlsx and b/src/main/resources/org/olat/ims/qti21/questionimport/qti-import-metadata.xlsx differ diff --git a/src/main/resources/serviceconfig/olat.properties b/src/main/resources/serviceconfig/olat.properties index fbd8788bc5f57485015847966d3f5063afdbe2c5..3348f67dd672ce10b3df510633824703d01e3430 100644 --- a/src/main/resources/serviceconfig/olat.properties +++ b/src/main/resources/serviceconfig/olat.properties @@ -1156,8 +1156,8 @@ ldap.learningResourceManagerRoleValue= # Build properties ##### application.name=OpenOLAT -build.version=12.3a -build.identifier=openolat123a-dev +build.version=12.4a +build.identifier=openolat124a-dev build.repo.revision=local-devel ##### diff --git a/src/main/webapp/static/js/jquery/qti/jquery.match.js b/src/main/webapp/static/js/jquery/qti/jquery.match.js index 4f46a3789ad8cd067def4e582d0beb3dcea78244..0ebe74c7eeacf09c40394e7e0a23499562301561 100644 --- a/src/main/webapp/static/js/jquery/qti/jquery.match.js +++ b/src/main/webapp/static/js/jquery/qti/jquery.match.js @@ -1,36 +1,36 @@ (function ($) { - $.fn.matchInteraction = function(options) { - var settings = $.extend({ - responseIdentifier: null, - formDispatchFieldId: null, - maxAssociations: 1, - leftData: {}, - rightData: {}, - leftMap: {}, - rightMap: {}, - matched: [] + $.fn.matchInteraction = function(options) { + var settings = $.extend({ + responseIdentifier: null, + formDispatchFieldId: null, + maxAssociations: 1, + leftData: {}, + rightData: {}, + leftMap: {}, + rightMap: {}, + matched: [] }, options ); - - for(var key in settings.leftData){ - settings.leftMap[key] = { - matchMax: settings.leftData[key], - matchCount: 0 - }; - } - for(var key in settings.rightData){ - settings.rightMap[key] = { - matchMax: settings.rightData[key], - matchCount: 0 - }; - } - - try { - match(this, settings); - } catch(e) { - if(window.console) console.log(e); - } - return this; - }; + + for(var key in settings.leftData){ + settings.leftMap[key] = { + matchMax: settings.leftData[key], + matchCount: 0 + }; + } + for(var key in settings.rightData){ + settings.rightMap[key] = { + matchMax: settings.rightData[key], + matchCount: 0 + }; + } + + try { + match(this, settings); + } catch(e) { + if(window.console) console.log(e); + } + return this; + }; function match($obj, settings) { queryInputElements(settings.responseIdentifier).on('click', function() { @@ -44,22 +44,26 @@ return jQuery('input[name=qtiworks_response_' + responseIdentifier + ']'); }; - function withCheckbox(settings, inputElement, callback) { - var directedPair = inputElement.value; - var splitPair = directedPair.split(" "); - var left = settings.leftMap[splitPair[0]]; - var right = settings.rightMap[splitPair[1]]; + function withCheckbox(settings, inputElement, callback) { + var directedPair = inputElement.value; + var splitPair = directedPair.split(" "); + var left = settings.leftMap[splitPair[0]]; + var right = settings.rightMap[splitPair[1]]; callback(inputElement, directedPair, left, right); }; - function recalculate(settings) { - settings.matchCount = 0; - settings.matched = {}; - for(var key in settings.leftMap) { - settings.leftMap[key].matchCount = 0; - } - for(var key in settings.rightMap) { - settings.rightMap[key].matchCount = 0; + /** + * Left -> source (set 0) + * Right -> target (set 1) + */ + function recalculate(settings) { + settings.matchCount = 0; + settings.matched = {}; + for(var key in settings.leftMap) { + settings.leftMap[key].matchCount = 0; + } + for(var key in settings.rightMap) { + settings.rightMap[key].matchCount = 0; } queryInputElements(settings.responseIdentifier).each(function() { @@ -74,48 +78,76 @@ }); }; - function updateDisabledStates(settings) { - queryInputElements(settings.responseIdentifier).each(function() { - withCheckbox(settings, this, function(inputElement, directedPair, left, right) { - if (inputElement.checked) { - inputElement.disabled = false; - } - else if ((settings.maxAssociations!=0 && settings.matchCount >= settings.maxAssociations) - || (left.matchMax!=0 && left.matchCount >= left.matchMax) - || (right.matchMax!=0 && right.matchCount >= right.matchMax)) { + /** + * Left -> source (set 0) + * Right -> target (set 1) + */ + function updateDisabledStates(settings) { + queryInputElements(settings.responseIdentifier).each(function() { + withCheckbox(settings, this, function(inputElement, directedPair, left, right) { + if (inputElement.checked) { + inputElement.disabled = false; + } else if (settings.maxAssociations != 0 && settings.matchCount >= settings.maxAssociations) { inputElement.disabled = true; - } - else { + } else if (left.matchMax != 0 && left.matchCount >= left.matchMax) { + if(left.matchMax != 1 && left.matchCount != 1) { + inputElement.disabled = true; + } else { + inputElement.disabled = false; + } + } else if (right.matchMax != 0 && right.matchCount >= right.matchMax) { + inputElement.disabled = true; + } else { inputElement.disabled = false; } }); }); }; - function checkMatch(settings, inputElement) { - withCheckbox(settings, inputElement, function(inputElement, directedPair, left, right) { - if (inputElement.checked){ - var incremented = false; - if (left.matchMax != 0 && left.matchMax <= left.matchCount) { + function checkMatch(settings, inputElement) { + withCheckbox(settings, inputElement, function(inputElement, directedPair, left, right) { + if(inputElement.checked){ + var incremented = false; + // left -> target + if(left.matchMax == 1) { + // deselect the other check + var jInputElement = jQuery(inputElement); + var inputId = jInputElement.attr('id'); + var inputRightId = jInputElement.attr('value').split(" ")[0]; + queryInputElements(settings.responseIdentifier).each(function() { + withCheckbox(settings, this, function(element, directedPair, left, right) { + var jElement = jQuery(element); + if(inputId !== jElement.attr('id') && element.checked) { + var elementRightId = jElement.attr('value').split(" ")[0]; + if(inputRightId === elementRightId) { + element.checked = false; + left.matchCount--; + settings.matchCount--; + } + } + }); + }); + + left.matchCount++; + settings.matchCount++; + incremented = true; + } else if (left.matchMax != 0 && left.matchMax <= left.matchCount) { inputElement.checked = false; - } - else { + } else { left.matchCount++; settings.matchCount++; incremented = true; } - + // right -> source if (right.matchMax != 0 && right.matchMax <= right.matchCount) { inputElement.checked = false; - } - else { + } else { right.matchCount++; if (!incremented) { settings.matchCount++; } } - } - else { + } else { settings.matchCount--; left.matchCount--; right.matchCount--; diff --git a/src/main/webapp/static/js/jquery/qti/jquery.order.js b/src/main/webapp/static/js/jquery/qti/jquery.order.js index 8001bc90508a43b24a64600aa55c3efadb919c23..7aa33724c6fd7abec8e77a428ca679a9d7a9cea2 100644 --- a/src/main/webapp/static/js/jquery/qti/jquery.order.js +++ b/src/main/webapp/static/js/jquery/qti/jquery.order.js @@ -10,7 +10,6 @@ }, options ); try { - console.log(settings.responseValue); if(typeof settings.responseValue != "undefined" && settings.responseValue.length > 0) { recalculate(settings); } diff --git a/src/main/webapp/static/js/jquery/qti/jquery.qti.min.js b/src/main/webapp/static/js/jquery/qti/jquery.qti.min.js index 8af3614bb3f30aa01604f1dbe2e59f9a7d48a3ca..45e0497c44285a2fda1bc002032f34ad1c6b740d 100644 --- a/src/main/webapp/static/js/jquery/qti/jquery.qti.min.js +++ b/src/main/webapp/static/js/jquery/qti/jquery.qti.min.js @@ -1 +1 @@ -(function(g){g.fn.associateInteraction=function(m){var n=g.extend({responseIdentifier:null,formDispatchFieldId:null,responseValue:null,opened:false,unrestricted:false},m);try{if(typeof n.responseValue!="undefined"&&n.responseValue.length>0){c(this,n)}if(n.opened){a(this,n)}}catch(o){if(window.console){console.log(o)}}return this};function c(m,q){var t=m.attr("id");var w=q.responseValue.split(",");var u=jQuery("#"+t+"_panel .association");for(var r=0;r<w.length;r++){var p=w[r].split(" ");var s=jQuery(u.get(r));if(s.size()==0){var v=d(t,q);s=jQuery("#"+v)}var o=jQuery("#"+t+"_items div[data-qti-id='"+p[0]+"']");if(e(o,t)){o=jQuery(o).clone()}var n=jQuery("#"+t+"_items div[data-qti-id='"+p[1]+"']");if(e(n,t)){n=jQuery(n).clone()}jQuery(o).addClass("oo-choosed");jQuery(n).addClass("oo-choosed");jQuery(s.find(".association_box.left")).addClass("oo-filled").append(o);jQuery(s.find(".association_box.right")).addClass("oo-filled").append(n)}l(t,q);if(q.unrestricted&&q.opened){i(t,q)}}function a(q,o){var m=q.attr("id");var n=jQuery("#"+m+" .o_associate_item");b(n,m,o);var p=jQuery("#"+m+"_panel .association_box");k(p,m,o)}function b(n,m,o){n.on("click",function(r,q){var p=jQuery(this);if(!p.hasClass("oo-choosed")&&!p.hasClass("oo-selected")){p.addClass("oo-selected")}}).draggable({containment:"#"+m,scroll:false,revert:"invalid",stop:function(p,q){jQuery(this).css({left:"0px",top:"0px"});jQuery(q.helper).removeClass("oo-drag")},helper:function(){var q=jQuery(this);var r=q.parent(".association_box").size()>0;if(!r&&e(this,m)){q.removeClass("oo-selected");var p=q.clone();jQuery(p).attr("id","n"+j()).data("qti-cloned","true").addClass("oo-drag");return p}q.addClass("oo-drag");return q}}).on("click",{formId:o.formDispatchFieldId},setFlexiFormDirtyByListener)}function e(r,n){var q=jQuery(r);var p=q.data("qti-match-max");var m=q.data("qti-id");var o=jQuery("#"+n+"_panel div[data-qti-id='"+m+"']").size();return(p==0||o+1<p)}function k(n,m,o){n.on("click",function(r,p){var q=jQuery(this);var s=jQuery(".o_associate_item",this).size();if(s==1){jQuery(".o_associate_item",this).each(function(t,u){h(u,q,m)})}else{jQuery("#"+m+"_items .o_associate_item.oo-selected").each(function(t,v){var u=jQuery(v);if(e(v,m)){u.removeClass("oo-selected");f(u.clone(),q,m)}else{f(u,q,m)}})}l(m,o);setFlexiFormDirty(o.formDispatchFieldId,false)}).droppable({drop:function(r,s){var q=jQuery(this);var t=jQuery(".o_associate_item",this).size();if(t>0){jQuery(".o_associate_item",this).each(function(u,v){h(v,q,m)})}var p;if(s.helper!=null&&jQuery(s.helper).data("qti-cloned")=="true"){var p=jQuery(s.draggable);p.removeClass("oo-selected").removeClass("oo-drag");p=p.clone();b(p,m,o);f(p,q,m)}else{var p=jQuery(s.draggable);p.removeClass("oo-selected").removeClass("oo-drag");f(p,q,m)}l(m,o);setFlexiFormDirty(o.formDispatchFieldId,false)}}).on("click",{formId:o.formDispatchFieldId},setFlexiFormDirtyByListener)}function f(o,n,m){o.removeClass("oo-selected").css({left:"0px",top:"0px"}).addClass("oo-choosed").appendTo(n);n.addClass("oo-filled")}function h(r,q,n){q.removeClass("oo-filled");var p=jQuery(r);p.removeClass("oo-choosed");var m=p.data("qti-id");var o=jQuery("#"+n+"_items div[data-qti-id='"+m+"']").size();if(o==0){p.appendTo(jQuery("#"+n+"_items"))}else{p.remove()}}function j(){function m(){return Math.floor((1+Math.random())*65536).toString(16).substring(1)}return m()+m()+m()+m()+m()+m()+m()}function l(m,o){var n=jQuery("#"+m+"_panel");n.find("input[type='hidden']").remove();jQuery("#"+m+"_panel .association").each(function(p,u){var r=jQuery(u).find(".o_associate_item");if(r.length==2){var s=jQuery(r.get(0)).data("qti-id");var q=jQuery(r.get(1)).data("qti-id");var t=jQuery('<input type="hidden"/>').attr("name","qtiworks_response_"+o.responseIdentifier).attr("value",s+" "+q);n.prepend(t)}else{if(r.length==0&&o.unrestricted){u.remove()}else{jQuery(u).find(".association_box").each(function(x,w){var v=jQuery(w).find(".o_associate_item").size();if(v==0&&jQuery(w).hasClass("oo-filled")){jQuery(w).removeClass("oo-filled")}})}}});i(m,o)}function i(m,p){if(!p.unrestricted||!p.opened){return}var n=jQuery("#"+m+"_panel");var o=true;jQuery("#"+m+"_panel .association").each(function(s,u){var t=jQuery(u).find(".o_associate_item");if(t.length!=2){o=false}});if(o){var r=d(m,p);var q=jQuery("#"+r+" .association_box");k(q,m,p)}}function d(m,n){var o=j();var p='<div id="'+o+'" class="association" style="">\n <div class="association_box left" style="width: 100px; height:50px; float:left;"></div>\n <div class="association_box right" style="width: 100px; height:50px; float:right;"></div>\n <div style="clear:both; "></div>\n</div>\n';jQuery("#"+m+"_panel").append(p);jQuery("#"+m+"_panel").append('<div style="clear:both; "></div>\n');return o}}(jQuery));(function(b){b.fn.choiceInteraction=function(d){var f=b.extend({responseIdentifier:null,formDispatchFieldId:null,maxChoices:0,},d);try{if(f.maxChoices>0){a(this,f);c(f)}}catch(g){if(window.console){console.log(g)}}return this};function a(f,d){var e=jQuery("#qti_container_"+d.responseIdentifier+" input[type=checkbox]");e.on("click",function(g,h){c(d)})}function c(d){var f=jQuery("#qti_container_"+d.responseIdentifier+" input[type=checkbox]");var e=0;f.each(function(g,h){if(h.checked){e++}});if(e>=d.maxChoices){f.each(function(g,h){if(h.checked){h.disabled=false}else{h.disabled=true}})}else{f.each(function(g,h){h.disabled=false})}}}(jQuery));(function(f){f.fn.gapMatchInteraction=function(h){var j=f.extend({responseIdentifier:null,formDispatchFieldId:null,gapChoiceData:{},gapData:{},opened:false,gapChoiceMap:{},gapMap:{},matched:{}},h);for(var i in j.gapChoiceData){var k=jQuery("#qtiworks_id_"+j.responseIdentifier+"_"+i);j.gapChoiceMap[i]={matchMax:j.gapChoiceData[i],matchCount:0,query:k,text:k.text()}}for(var i in j.gapData){var k=jQuery("#qtiworks_id_"+j.responseIdentifier+"_"+i);j.gapMap[i]={required:j.gapData[i],matched:false,matchedGapChoice:null,query:k,label:k.text()}}try{d(this,j)}catch(l){if(window.console){console.log(l)}}return this};function b(j,k,n){var m=k.value;var i=m.split(" ");var h=j.gapChoiceMap[i[0]];var l=j.gapMap[i[1]];n(j,k,m,h,l)}function d(i,h){if(h.opened){e(h.responseIdentifier).on("click",function(){a(h,this);setFlexiFormDirty(h.formDispatchFieldId)})}c(h);g(h)}function e(h){return jQuery("input[name=qtiworks_response_"+h+"]")}function c(j){j.matchCount=0;for(var i in j.gapChoiceMap){j.gapChoiceMap[i].matchCount=0}for(var i in j.gapMap){j.gapMap[i].matched=false;j.gapMap[i].matchedGapChoice=null}e(j.responseIdentifier).each(function(l,m){b(j,this,function(o,p,r,n,q){if(p.checked){n.matchCount++;q.matched=true;q.matchedGapChoice=n;o.matched[r]=true}})});for(var i in j.gapMap){var k=j.gapMap[i];var h;if(k.matched){h=k.matchedGapChoice.text}else{h=k.label}k.query.text(h)}}function g(h){e(h.responseIdentifier).each(function(){b(h,this,function(j,k,m,i,l){if(!j.opened){k.disabled=true}else{if(k.checked){k.disabled=false}else{if(l.matched||(i.matchMax!=0&&i.matchCount>=i.matchMax)){k.disabled=true}else{k.disabled=false}}}})})}function a(h,i){b(h,i,function(k,l,n,j,m){if(l.checked){if(m.matched||(j.matchMax!=0&&j.matchMax<=j.matchCount)){l.checked=false}else{j.matchCount++;m.matched=true;m.matchedGapChoice=j}m.query.text(j.text)}else{j.matchCount--;m.matched=false;m.matchedGapChoice=null;m.query.text(m.label)}g(k)})}}(jQuery));(function(d){d.fn.graphicAssociateInteraction=function(g){var h=d.extend({responseIdentifier:null,formDispatchFieldId:null,responseValue:null,maxAssociations:1,opened:false},g);try{if(!(typeof h.responseValue==="undefined")&&h.responseValue.length>0){e(this,h.responseValue,h.responseIdentifier)}if(h.opened){c(this,h.maxAssociations,h.responseIdentifier)}}catch(j){if(window.console){console.log(j)}}return this};function c(k,j,h){var g=k.attr("id");jQuery("#"+g+"_container area").on("click",function(t){var l=8;var q=jQuery("#"+g+"_container").data("openolat")||{};if(q.listOfPairs==undefined){q.currentSpot="";q.listOfPairs=[];jQuery("#"+g+"_container").data("openolat",q)}var w=jQuery(this).data("qti-id");if(q.currentSpot==""||q.currentSpot==w){q.currentSpot=w}else{var A=[q.currentSpot,w];q.listOfPairs.push(A);q.currentSpot=""}var m=document.getElementById(g+"_canvas");var u=m.getContext("2d");u.clearRect(0,0,jQuery(m).width(),jQuery(m).height());var B=jQuery("#"+g+"_container");B.find("input[type='hidden']").remove();var z=[];if(q.currentSpot!=""){b(u,"ac_"+h+"_"+q.currentSpot);z.push(q.currentSpot)}for(var p=q.listOfPairs.length;p-->0;){var o=q.listOfPairs[p];for(var n=o.length;n-->0;){if(0>z.indexOf(o[n])){b(u,"ac_"+h+"_"+o[n]);z.push(o[n])}}var s=jQuery("#ac_"+h+"_"+o[1]);var v=jQuery("#ac_"+h+"_"+o[0]);var C=f(s);var y=f(v);u.beginPath();u.moveTo(C[0],C[1]);u.lineTo(y[0],y[1]);u.lineWidth=3;u.stroke();var x=jQuery('<input type="hidden"/>').attr("name","qtiworks_response_"+h).attr("value",v.data("qti-id")+" "+s.data("qti-id"));B.prepend(x)}})}function e(g,v,t){var o=g.attr("id");var x=jQuery("#"+o+"_container");var k=document.getElementById(o+"_canvas");var q=k.getContext("2d");q.clearRect(0,0,jQuery(k).width(),jQuery(k).height());var w=[];var h=v.split(",");for(var n=h.length;n-->0;){var m=h[n].split(" ");for(var l=m.length;l-->0;){if(0>w.indexOf(m[l])){b(q,"ac_"+t+"_"+m[l]);w.push(m[l])}}if(m.length==2){var p=jQuery("#ac_"+t+"_"+m[1]);var r=jQuery("#ac_"+t+"_"+m[0]);var y=f(p);var u=f(r);q.beginPath();q.moveTo(y[0],y[1]);q.lineTo(u[0],u[1]);q.lineWidth=3;q.stroke();var s=jQuery('<input type="hidden"/>').attr("name","qtiworks_response_"+t).attr("value",r.data("qti-id")+" "+p.data("qti-id"));x.prepend(s)}}}function b(h,g){jQuery("#"+g).each(function(k,m){var l=jQuery(m);var n=f(l);var j=l.attr("shape");a(h,j,n,0,0)})}function a(j,g,k,h,l){h=h||0;l=l||0;j.beginPath();if(g=="rect"){j.rect(k[0]+h,k[1]+l,k[2]-k[0],k[3]-k[1])}else{if(g=="poly"){j.moveTo(k[0]+h,k[1]+l);for(i=2;i<k.length;i+=2){j.lineTo(k[i]+h,k[i+1]+l)}}else{if(g=="circ"||g=="circle"){j.arc(k[0]+h,k[1]+l,k[2]-2,0,Math.PI*2,false)}}}j.closePath();j.lineWidth=4;j.strokeStyle="#003300";j.stroke();j.fillStyle="green";j.fill()}function f(g){var h=g.attr("coords").split(",");for(i=h.length;i-->0;){h[i]=parseFloat(h[i])}return h}}(jQuery));(function(f){f.fn.graphicGapInteraction=function(j){var k=f.extend({maphilight:null,responseIdentifier:null,formDispatchFieldId:null,responseValue:null,opened:false},j);try{if(!(typeof k.responseValue==="undefined")&&k.responseValue.length>0){b(this,k)}if(k.opened){c(this,k)}}catch(l){if(window.console){console.log(l)}}return this};function b(j,m){var q=j.attr("id");var v=jQuery("#"+q);var l=m.responseValue.split(",");for(var n=l.length;n-->0;){var k=l[n].split(" ");var p=jQuery("#ac_"+m.responseIdentifier+"_"+k[0]);var o=jQuery("#ac_"+m.responseIdentifier+"_"+k[1]);var r,u;if(p.hasClass("gap_item")){r=p;u=o}else{r=o;u=p}var s=g(u);r.css("position","absolute");r.css("left",s[0]+"px");r.css("top",s[1]+"px");r.addClass("oo-choosed");var t=jQuery('<input type="hidden"/>').attr("name","qtiworks_response_"+m.responseIdentifier).attr("value",r.data("qti-id")+" "+u.data("qti-id"));v.prepend(t)}}function c(l,k){var j=l.attr("id");jQuery(".gap_item").on("click",function(q,p){var o=jQuery(this);if(o.hasClass("oo-choosed")){var n=o.data("drop-timestamp");if(!(typeof n==="undefined")&&n!=null){if((Date.now()-n)<1500){o.data("drop-timestamp",null);return}}o.removeClass("oo-choosed");var m=o.data("qti-id");jQuery("#"+j).find("input[type='hidden']").each(function(r,s){var t=jQuery(s).val();if(t.indexOf(m+" ")==0){jQuery(s).remove()}});o.css({position:"relative",left:"0px",top:"0px"})}else{o.addClass("oo-selected")}}).draggable({containment:"#"+j,scroll:false,revert:"invalid",stop:function(m,n){if(!jQuery(this).hasClass("oo-choosed")){jQuery(this).css({position:"relative",left:"0px",top:"0px"})}}}).mousemove(function(m,s){var u=jQuery(this);if(u.hasClass("ui-draggable-dragging")){var q=jQuery("#"+j+"_img");var p=q.offset();var o=u.offset();var n=o.left+(u.width()/2)-p.left;var t=o.top+(u.height()/2)-p.top;var r=h(n,t,j);if("invalid"!=r){jQuery("#"+j+" area").each(function(v,x){var w=jQuery(x);var y=w.attr("id");if(r==y){w.mouseover()}else{w.mouseout()}});jQuery("#"+r).mouseover()}else{jQuery("#"+j+" area").each(function(v,w){jQuery(w).mouseout()})}}});jQuery("#"+j).droppable({drop:function(m,t){var r=jQuery("#"+j+"_img");var p=r.offset();var u=jQuery(t.draggable);var o=u.offset();var n=o.left+(u.width()/2)-p.left;var w=o.top+(u.height()/2)-p.top;var s=h(n,w,j);if("invalid"!=s){var z=jQuery("#"+s);var v=g(z);var x=z.data("qti-id");var q=u.data("qti-id");u.css("position","absolute");u.css("left",v[0]+"px");u.css("top",v[1]+"px");u.css("border","none");u.removeClass("oo-selected");u.addClass("oo-choosed");var y=jQuery('<input type="hidden"/>').attr("name","qtiworks_response_"+k.responseIdentifier).attr("value",q+" "+x);jQuery(this).prepend(y);jQuery(z).mouseout();u.data("drop-timestamp",Date.now())}}});jQuery("#"+j+" area").on("click",function(o,n){var m=jQuery(this);jQuery(".gap_item.oo-selected").each(function(q,s){var r=jQuery(s);var t=g(m);var w=m.data("qti-id");var v=r.data("qti-id");r.css("position","absolute");r.css("left",t[0]+"px");r.css("top",t[1]+"px");r.css("border","none");r.removeClass("oo-selected");r.addClass("oo-choosed");var p=jQuery("#"+j);var u=jQuery('<input type="hidden"/>').attr("name","qtiworks_response_"+k.responseIdentifier).attr("value",v+" "+w);p.prepend(u)})})}function h(l,k,j){var m="invalid";jQuery("#"+j+" area").each(function(r,o){var v=jQuery(o);var u=v.attr("id");var t=v.attr("coords");var s=v.attr("shape");var w=g(v);if("circle"==s){if(a(l,k,w[0],w[1],w[2])){m=u}}else{if("rect"==s){if(d(l,k,w[0],w[1],w[2],w[3])){m=u}}else{if("poly"==s){var n={};n.x=[];n.y=[];var q=w.length/2;var p=0;for(ix=0;ix<q;ix++){n.x[ix]=w[p];n.y[ix]=w[p+1];p+=2}for(i=0;i<n.length;i++){if(e(n.x.length,n.x,n.y,l,k)){m=n.id;break}}}}}});return m}function a(k,o,m,l,j){var n=Math.pow(k-m,2)+Math.pow(o-l,2);return Math.pow(j,2)>=n}function d(j,o,n,l,k,m){if((n<=j)&&(j<=k)&&(l<=o)&&(o<=m)){return true}else{return false}}function e(l,p,o,k,r){var n,m,q=false;for(n=0,m=l-1;n<l;m=n++){if(((o[n]>r)!=(o[m]>r))&&(k<(p[m]-p[n])*(r-o[n])/(o[m]-o[n])+p[n])){q=!q}}return q}function g(j){var k=j.attr("coords").split(",");for(i=k.length;i-->0;){k[i]=parseFloat(k[i])}return k}}(jQuery));(function(c){c.fn.graphicOrderInteraction=function(d){var f=c.extend({responseIdentifier:null,formDispatchFieldId:null,responseValue:null,maxChoices:1,opened:false},d);try{if(!(typeof f.responseValue==="undefined")&&f.responseValue.length>0){b(this,f)}if(f.opened){a(this,f)}}catch(g){if(window.console){console.log(g)}}return this};function b(d,h){var m=d.attr("id");var r=jQuery("#"+m+"_container");var e=document.getElementById(m+"_canvas");var o=e.getContext("2d");o.clearRect(0,0,jQuery(e).width(),jQuery(e).height());var n=h.responseValue.split(",");for(var k=n.length;k-->0;){if(n[k].length==0){continue}var q=jQuery("#ac_"+h.responseIdentifier+"_"+n[k]);var f=q.data("qti-id");var l=q.attr("coords").split(",");var j=l[0];var g=l[1];o.font="16px Arial";o.fillText(""+(k+1),j,g);var p=jQuery('<input type="hidden"/>').attr("name","qtiworks_response_"+h.responseIdentifier).attr("value",f);r.prepend(p)}}function a(f,e){var d=f.attr("id");jQuery("#"+d+"_container area").on("click",function(v){var h=8;var x=jQuery(this).attr("id");var l=jQuery(this).data("qti-id");var u=jQuery(this).attr("coords").split(",");var o=u[0];var n=u[1];var t=jQuery("#"+d+"_container").data("openolat")||{};if(t.listOfPoints==undefined){t.listOfPoints=[];jQuery("#"+d+"_container").data("openolat",t)}var s=false;var m=[];for(var q=t.listOfPoints.length;q-->0;){var j=t.listOfPoints[q];var g=((j.x-o)*(j.x-o))+((j.y-n)*(j.y-n));if(h*h>g){s=true}else{m.push(j)}}if(s){t.listOfPoints=m}else{if(t.listOfPoints.length>=e.maxChoices){return false}else{t.listOfPoints.push({x:o,y:n,areaId:x,spotQtiId:l})}}var k=document.getElementById(d+"_canvas");var w=k.getContext("2d");w.clearRect(0,0,jQuery(k).width(),jQuery(k).height());var z=jQuery("#"+d+"_container");z.find("input[type='hidden']").remove();for(var q=t.listOfPoints.length;q-->0;){var j=t.listOfPoints[q];w.font="16px Arial";w.fillText(""+(q+1),j.x,j.y);var y=jQuery('<input type="hidden"/>').attr("name","qtiworks_response_"+e.responseIdentifier).attr("value",j.spotQtiId);z.prepend(y)}})}}(jQuery));(function(c){c.fn.hotspotInteraction=function(f){var g=c.extend({responseIdentifier:null,formDispatchFieldId:null,maxChoices:1,singleChoice:false,responseValue:null,opened:false,maphilightSettings:{}},f);try{if(!(typeof g.responseValue==="undefined")&&g.responseValue.length>0){a(this,g)}if(g.opened){e(this,g)}}catch(h){if(window.console){console.log(h)}}return this};function a(n,k){var f=n.attr("id");var g=jQuery("#"+f);var j=k.responseValue.split(",");for(i=j.length;i-->0;){var h=jQuery("#ac_"+k.responseIdentifier+"_"+j[i]);var l=h.data("maphilight")||{};l.selectedOn=true;b(l,k.maphilightSettings);h.data("maphilight",l).trigger("alwaysOn.maphilight");var m=jQuery('<input type="hidden"/>').attr("name","qtiworks_response_"+k.responseIdentifier).attr("value",h.data("qti-id"));g.append(m)}}function e(h,g){var f=h.attr("id");jQuery("#"+f+" map area").each(function(j,k){jQuery(k).on("click",function(){d(this,f,g.responseIdentifier,g.maxChoices,g.singleChoice,g.maphilightSettings)})})}function d(l,j,o,k,q,m){var n=jQuery(l);var h=n.data("maphilight")||{};if((typeof h.selectedOn==="undefined")||!h.selectedOn){if(q){jQuery("area","map[name='"+j+"_map']").each(function(r,t){var s=jQuery(t).data("maphilight")||{};if(s.selectedOn){s.selectedOn=false;b(s,m);jQuery(t).data("maphilight",s).trigger("alwaysOn.maphilight")}})}var f=k;if(f>0){var g=0;jQuery("area","map[name='"+j+"_map']").each(function(r,t){var s=jQuery(t).data("maphilight")||{};if(s.selectedOn){g++}});if(g>=f){return false}}}if(typeof h.selectedOn==="undefined"){h.selectedOn=true}else{h.selectedOn=!h.selectedOn}b(h,m);n.data("maphilight",h).trigger("alwaysOn.maphilight");var p=jQuery("#"+j);p.find("input[type='hidden']").remove();jQuery("area","map[name='"+j+"_map']").each(function(r,t){var u=jQuery(t);var s=u.data("maphilight")||{};if(s.selectedOn){var v=jQuery('<input type="hidden"/>').attr("name","qtiworks_response_"+o).attr("value",u.data("qti-id"));p.append(v)}})}function b(g,f){if(g.selectedOn){g.fillColor=f.selectedFillColor;g.fillOpacity=f.selectedFillOpacity;g.strokeColor=f.selectedStrokeColor;g.strokeOpacity=f.selectedStrokeOpacity;g.shadow=f.selectedShadow;g.shadowX=0;g.shadowY=0;g.shadowRadius=7;g.shadowColor="000000";g.shadowOpacity=0.8;g.shadowPosition="outside"}else{g.fillColor=f.fillColor;g.fillOpacity=f.fillOpacity;g.strokeColor=f.strokeColor;g.strokeOpacity=f.strokeOpacity;g.shadow=false}}}(jQuery));(function(a){a.fn.rwdImageMaps=function(c){var e=a.extend({fillColor:"bbbbbb",fillOpacity:0.5,strokeColor:"6E6E6E",strokeOpacity:1,},c);var d=this;var b=function(){d.each(function(){if(typeof(a(this).attr("usemap"))=="undefined"){return}var g=this,f=a(g);a("<img />").on("load",function(){var j="width",o="height",p=f.attr(j),l=f.attr(o);if(!p||!l){var q=new Image();q.src=f.attr("src");if(!p){p=q.width}if(!l){l=q.height}}var i=f.width()/100,m=f.height()/100,k=f.attr("usemap").replace("#",""),n="coords";a('map[name="'+k+'"]').find("area").each(function(){var t=a(this);if(!t.data(n)){t.data(n,t.attr(n))}var s=t.data(n).split(","),r=new Array(s.length);for(var h=0;h<r.length;++h){if(h%2===0){r[h]=parseInt(((s[h]/p)*100)*i)}else{r[h]=parseInt(((s[h]/l)*100)*m)}}t.attr(n,r.toString())});f.maphilight({fillColor:e.fillColor,fillOpacity:e.fillOpacity,strokeColor:e.strokeColor,strokeOpacity:e.strokeOpacity,strokeWidth:3,alwaysOn:true})}).attr("src",f.attr("src"))})};a(window).resize(b).trigger("resize");return this}})(jQuery);(function(f){f.fn.matchInteraction=function(h){var j=f.extend({responseIdentifier:null,formDispatchFieldId:null,maxAssociations:1,leftData:{},rightData:{},leftMap:{},rightMap:{},matched:[]},h);for(var i in j.leftData){j.leftMap[i]={matchMax:j.leftData[i],matchCount:0}}for(var i in j.rightData){j.rightMap[i]={matchMax:j.rightData[i],matchCount:0}}try{d(this,j)}catch(k){if(window.console){console.log(k)}}return this};function d(i,h){e(h.responseIdentifier).on("click",function(){a(h,this)});c(h);g(h)}function e(h){return jQuery("input[name=qtiworks_response_"+h+"]")}function b(j,l,n){var m=l.value;var h=m.split(" ");var k=j.leftMap[h[0]];var i=j.rightMap[h[1]];n(l,m,k,i)}function c(i){i.matchCount=0;i.matched={};for(var h in i.leftMap){i.leftMap[h].matchCount=0}for(var h in i.rightMap){i.rightMap[h].matchCount=0}e(i.responseIdentifier).each(function(){b(i,this,function(l,m,k,j){if(l.checked){i.matchCount++;k.matchCount++;j.matchCount++;i.matched[m]=true}})})}function g(h){e(h.responseIdentifier).each(function(){b(h,this,function(k,l,j,i){if(k.checked){k.disabled=false}else{if((h.maxAssociations!=0&&h.matchCount>=h.maxAssociations)||(j.matchMax!=0&&j.matchCount>=j.matchMax)||(i.matchMax!=0&&i.matchCount>=i.matchMax)){k.disabled=true}else{k.disabled=false}}})})}function a(h,i){b(h,i,function(m,n,l,k){if(m.checked){var j=false;if(l.matchMax!=0&&l.matchMax<=l.matchCount){m.checked=false}else{l.matchCount++;h.matchCount++;j=true}if(k.matchMax!=0&&k.matchMax<=k.matchCount){m.checked=false}else{k.matchCount++;if(!j){h.matchCount++}}}else{h.matchCount--;l.matchCount--;k.matchCount--}g(h)})}}(jQuery));(function(h){h.fn.matchInteractionDnd=function(m){var n=h.extend({responseIdentifier:null,formDispatchFieldId:null,maxAssociations:1,responseValue:null,opened:false},m);try{if(typeof n.responseValue!="undefined"&&n.responseValue.length>0){f(this,n)}if(n.opened){i(this,n)}}catch(o){if(window.console){console.log(o)}}return this};function f(m,o){var q=m.attr("id");var w=o.responseValue.split(",");var r=jQuery("#"+q);for(var p=0;p<w.length;p++){var n=w[p].split(" ");var t=n[0];var s=n[1];var v=jQuery("#"+q+" .o_match_dnd_sources li[data-qti-id='"+t+"']");if(g(v,q)){v=jQuery(v).clone()}var u=jQuery("#"+q+" .o_match_dnd_targets ul[data-qti-id='"+s+"']");jQuery(v).addClass("oo-choosed");jQuery(u).addClass("oo-choosed");jQuery(u).addClass("oo-filled").append(v)}l(q,o);if(o.unrestricted&&o.opened){addNewAssociationBoxAndEvents(q,o)}}function i(q,p){var n=q.attr("id");a(n,p);var o=jQuery("#"+n+" .o_match_dnd_source");e(o,n,p);var m=jQuery("#"+n+" .o_match_dnd_target");k(m,n,p)}function a(m,n){jQuery("#"+m+" .o_match_dnd_sources").droppable({tolerance:"pointer",over:function(o,p){jQuery(this).addClass("oo-accepted")},out:function(o,p){jQuery(this).removeClass("oo-accepted")},drop:function(s,t){var r=jQuery(this);r.removeClass("oo-accepted");var q=jQuery(t.draggable);var o=q.data("qti-id");var p=r.find("li[data-qti-id='"+o+"']");if(p.size()>0){if(q.parents(".o_match_dnd_sources").size()==0){q.remove()}}else{q.appendTo(r)}l(m,n);setFlexiFormDirty(n.formDispatchFieldId,false)}}).on("click",{formId:n.formDispatchFieldId},setFlexiFormDirtyByListener)}function e(n,m,o){n.on("click",function(r,q){var p=jQuery(this);if(!p.hasClass("oo-choosed")&&!p.hasClass("oo-selected")){jQuery("#"+m+" .o_match_dnd_sources .o_match_dnd_source").each(function(s,t){jQuery(t).removeClass("oo-selected")});p.addClass("oo-selected")}else{if(p.parents(".o_match_dnd_targets").size()>0&&!p.hasClass("oo-dropped-mrk")){d(p,m);l(m,o);setFlexiFormDirty(o.formDispatchFieldId,false)}}}).draggable({containment:"#"+m,scroll:false,revert:"invalid",cursorAt:{left:5,top:5},start:function(p,q){jQuery(q.helper).removeClass("oo-dropped-mrk")},stop:function(p,q){jQuery(this).css({left:"0px",top:"0px","z-index":""});jQuery(q.helper).removeClass("oo-drag")},helper:function(){var q=jQuery(this);var r=q.parent(".o_match_dnd_target").size()>0;if(!r&&g(this,m)){q.removeClass("oo-selected");var p=q.clone();jQuery(p).attr("id","n"+j()).data("qti-cloned","true").addClass("oo-drag").addClass("oo-drag-mrk").css("z-index",10).css("width",q.width()).css("height",q.height());return p}q.addClass("oo-drag").addClass("oo-drag-mrk").css("z-index",10);return q}}).on("click",{formId:o.formDispatchFieldId},setFlexiFormDirtyByListener)}function j(){function m(){return Math.floor((1+Math.random())*65536).toString(16).substring(1)}return m()+m()+m()+m()+m()+m()+m()}function g(r,n){var q=jQuery(r);if(q.parents(".o_match_dnd_target").size()>0){return false}var o=q.data("qti-match-max");var m=q.data("qti-id");var p=jQuery("#"+n+" .o_match_dnd_targets li[data-qti-id='"+m+"']").size();return(o==0||p+1<o)}function k(n,m,o){n.on("click",function(r,p){var q=jQuery(this);var s=jQuery(".o_associate_item",this).size();if(s==0){jQuery("#"+m+" .o_match_dnd_sources .oo-selected").each(function(t,v){var u=jQuery(v);if(g(v,m)){u.removeClass("oo-selected");u=u.clone();b(u,q,m);e(u,m,o)}else{b(u,q,m)}})}l(m,o);setFlexiFormDirty(o.formDispatchFieldId,false)}).droppable({tolerance:"pointer",accept:function(q){var p=jQuery(q).data("qti-id");var r=jQuery(".o_match_dnd_source[data-qti-id='"+p+"']",this).size()==0;if(r){var t=jQuery(this).data("qti-match-max");if(t>0){var s=jQuery(".o_match_dnd_source",this).size();if(s>=t){r=false}}}return r},over:function(p,q){jQuery(this).addClass("oo-accepted")},out:function(p,q){jQuery(this).removeClass("oo-accepted")},drop:function(t,u){var s=jQuery(this);s.removeClass("oo-accepted");var r=jQuery(u.draggable);var q=r.data("qti-id");var p=jQuery(".o_match_dnd_source[data-qti-id='"+q+"']",this).size();if(p>0){return}if(u.helper!=null&&jQuery(u.helper).data("qti-cloned")=="true"){r.removeClass("oo-selected").removeClass("oo-drag");r=r.clone();e(r,m,o);b(r,s,m)}else{r.removeClass("oo-selected").removeClass("oo-drag");b(r,s,m)}r.addClass("oo-dropped-mrk");setTimeout(function(){r.removeClass("oo-dropped-mrk")},100);l(m,o);setFlexiFormDirty(o.formDispatchFieldId,false)}}).on("click",{formId:o.formDispatchFieldId},setFlexiFormDirtyByListener)}function b(o,p,n){var m=p.find("ul.o_match_dnd_target_drop_zone");o.removeClass("oo-selected").css({width:"auto",left:"0px",top:"0px","z-index":""}).addClass("oo-choosed").appendTo(m);p.addClass("oo-filled")}function d(q,n){var p=jQuery(q);p.removeClass("oo-choosed");var m=p.data("qti-id");var o=jQuery("#"+n+" .o_match_dnd_sources li[data-qti-id='"+m+"']").size();if(o==0){p.css({width:"auto",left:"0px",top:"0px","z-index":""}).appendTo(jQuery("#"+n+" .o_match_dnd_sources"))}else{p.remove()}}function l(m,p){p.matchCount=0;p.matched={};for(var o in p.leftMap){p.leftMap[o].matchCount=0}for(var o in p.rightMap){p.rightMap[o].matchCount=0}var n=jQuery("#"+m);n.find("input[type='hidden']").remove();jQuery("#"+m+" .o_match_dnd_target_drop_zone").each(function(r,q){jQuery(q).find(".o_match_dnd_source").each(function(w,s){var u=jQuery(s).data("qti-id");var t=jQuery(q).data("qti-id");var v=jQuery('<input type="hidden"/>').attr("name","qtiworks_response_"+p.responseIdentifier).attr("value",u+" "+t);n.prepend(v)})})}function c(m,n){withCheckbox(m,n,function(r,s,q,p){if(r.checked){var o=false;if(q.matchMax!=0&&q.matchMax<=q.matchCount){r.checked=false}else{q.matchCount++;m.matchCount++;o=true}if(p.matchMax!=0&&p.matchMax<=p.matchCount){r.checked=false}else{p.matchCount++;if(!o){m.matchCount++}}}else{m.matchCount--;q.matchCount--;p.matchCount--}updateDisabledStates(m)})}}(jQuery));(function(c){c.fn.orderInteraction=function(d){var f=c.extend({responseIdentifier:null,formDispatchFieldId:null,minChoices:null,maxChoices:null,responseValue:null,opened:false},d);try{console.log(f.responseValue);if(typeof f.responseValue!="undefined"&&f.responseValue.length>0){b(f)}if(f.opened){a(this,f)}}catch(g){if(window.console){console.log(g)}}return this};function a(k,g){var d="#qtiworks_response_"+g.responseIdentifier;var i=jQuery(d+" div.source ul");var j=jQuery(d+" div.target ul");var h=jQuery(d+" div.source ul").get(0);var f=jQuery(d+" div.target ul").get(0);var e=dragula([h,f],{copy:function(l,m){return false},accepts:function(l,m){return m!==h}});e.on("drag",function(m,l){}).on("over",function(m,l,n){if(l===f){jQuery(l).addClass("oo-accepted")}}).on("drop",function(m,o,n,l){b(g);setFlexiFormDirty(g.formDispatchFieldId)}).on("dragend",function(l){jQuery(f).removeClass("oo-accepted")}).on("out",function(l){jQuery(f).removeClass("oo-accepted")})}function b(h){var d="#qtiworks_response_"+h.responseIdentifier;var i=jQuery(d+" div.source ul");var j=jQuery(d+" div.target ul");var e=jQuery(d+" div.target");var g=jQuery(d+" div.hiddenInputContainer");var f=j.children("li").size();if(h.minChoices!=null&&h.maxChoices!=null){if(f<h.minChoices||f>h.maxChoices){if(h.minChoices!=h.maxChoices){alert("You must select and order between "+h.minChoices+" and "+h.maxChoices+" items")}else{alert("You must select and order exactly "+h.minChoices+" item"+(minChoices>1?"s":""))}e.toggleClass("highlight",true);return false}else{e.toggleClass("highlight",false)}}var g=jQuery(d+" div.hiddenInputContainer");g.empty();j.children("li").each(function(l){var k=this.id.substring("qtiworks_response_".length);var m=jQuery('<input type="hidden">');m.attr("name","qtiworks_response_"+h.responseIdentifier);m.attr("value",k);g.append(m)})}}(jQuery));(function(b){b.fn.positionObjectStage=function(f){var g=b.extend({responseIdentifier:null,formDispatchFieldId:null,responseValue:null,maxChoices:1,opened:false},f);try{var d=this.attr("id");jQuery("#"+d+" .items_container .o_item.o_"+g.responseIdentifier).each(function(e,i){jQuery(i).attr("id","object-item-"+e)});if(!(typeof g.responseValue==="undefined")&&g.responseValue.length>0){c(this,g)}if(g.opened){a(this,g)}}catch(h){if(window.console){console.log(h)}}return this};function c(d,f){var k=d.attr("id");var r=jQuery("#"+k);var j=f.responseValue.split(":");var l=jQuery("#"+k+" .items_container .o_item.o_"+f.responseIdentifier);for(var h=j.length;h-->0;){var n=j[h].split(" ");var g=n[0];var e=n[1];var q=jQuery(l.get(h));q.css("position","absolute");q.css("top",e+"px");q.css("left",g+"px");var m=q.attr("id");var o="in-"+m+"-"+f.responseIdentifier;var p=jQuery('<input type="hidden"/>').attr("id",o).attr("name","qtiworks_response_"+f.responseIdentifier).attr("value",g+" "+e);r.prepend(p)}}function a(g,f){var d=g.attr("id");var e=jQuery("#"+d);jQuery("#"+d+" .items_container .o_item.o_"+f.responseIdentifier).draggable({containment:"#"+d,scroll:false,stop:function(h,p){var i=jQuery("#"+d+"_img");var k=jQuery(i).offset().top-jQuery(window).scrollTop();var n=jQuery(i).offset().left-jQuery(window).scrollLeft();var m=jQuery(this).offset().top-jQuery(window).scrollTop();var q=jQuery(this).offset().left-jQuery(window).scrollLeft();var l=Math.round((q-n));var j=Math.round((m-k));var o=jQuery(this).attr("id");var r="in-"+o+"-"+f.responseIdentifier;var s=e.find("#"+r);if(s.length==0){var t=jQuery('<input type="hidden"/>').attr("id",r).attr("name","qtiworks_response_"+f.responseIdentifier).attr("value",l+" "+j);e.prepend(t)}else{s.val(l+" "+j)}setFlexiFormDirty(f.formDispatchFieldId)}})}}(jQuery));(function(a){a.fn.selectPointInteraction=function(d){var f=a.extend({responseIdentifier:null,formDispatchFieldId:null,responseValue:null,maxChoices:1,opened:false},d);try{if(!(typeof f.responseValue==="undefined")&&f.responseValue.length>0){b(this,f)}if(f.opened){c(this,f)}}catch(g){if(window.console){console.log(g)}}return this};function b(d,h){var e=8;var j=d.attr("id");var q=jQuery("#"+j);var n=h.responseValue.split(":");var g=document.getElementById(j+"_canvas");var k=g.getContext("2d");k.clearRect(0,0,jQuery(g).width(),jQuery(g).height());for(i=n.length;i-->0;){if(n[i].length==0){continue}var f=n[i].split(" ");var m=f[0];var l=f[1];k.beginPath();k.arc(m,l,e,0,Math.PI*2,false);k.stroke();k.closePath();var o=jQuery('<input type="hidden"/>').attr("name","qtiworks_response_"+h.responseIdentifier).attr("value",m+" "+l);q.append(o)}}function c(f,e){var d=f.attr("id");jQuery("#"+d+"_canvas").on("click",function(u,z){var h=8;var q=jQuery(this).offset().top-jQuery(window).scrollTop();var w=jQuery(this).offset().left-jQuery(window).scrollLeft();var n=Math.round((u.clientX-w));var m=Math.round((u.clientY-q));var s=jQuery("#"+d).data("openolat")||{};if(s.listOfPoints==undefined){s.listOfPoints=[];jQuery("#"+d).data("openolat",s)}var o=false;var l=[];for(i=s.listOfPoints.length;i-->0;){var j=s.listOfPoints[i];var g=((j.x-n)*(j.x-n))+((j.y-m)*(j.y-m));if(Math.pow(h,2)>g){o=true}else{l.push(j)}}if(o){s.listOfPoints=l}else{if(s.listOfPoints.length>=e.maxChoices){return false}else{s.listOfPoints.push({x:n,y:m})}}var k=document.getElementById(d+"_canvas");var v=k.getContext("2d");v.clearRect(0,0,jQuery(k).width(),jQuery(k).height());var y=jQuery("#"+d);y.find("input[type='hidden']").remove();for(i=s.listOfPoints.length;i-->0;){var j=s.listOfPoints[i];v.beginPath();v.arc(j.x,j.y,h,0,Math.PI*2,false);v.stroke();v.closePath();var x=jQuery('<input type="hidden"/>').attr("name","qtiworks_response_"+e.responseIdentifier).attr("value",j.x+" "+j.y);y.append(x)}setFlexiFormDirty(e.formDispatchFieldId)})}}(jQuery));(function(b){b.fn.sliderInteraction=function(c){var d=b.extend({responseIdentifier:null,formDispatchFieldId:null,responseValue:null,min:1,max:1,step:1,orientation:null,isReversed:false,isDiscrete:false,opened:false,initialValue:null},c);try{a(this,d)}catch(f){if(window.console){console.log(f)}}return this};function a(g,d){var e=jQuery("#qtiworks_id_slider_"+d.responseIdentifier);var f=jQuery('input[name="qtiworks_response_'+d.responseIdentifier+'"]');var c=f.get(0).value||d.min;e.slider({value:c,step:d.step,disabled:!d.opened,orientation:d.orientation,min:d.isReversed?-d.max:d.min,max:d.isReversed?-d.min:d.max,slide:function(h,j){var i=d.isReversed?-j.value:j.value;var l=jQuery("#qtiworks_id_slidervalue_"+d.responseIdentifier);var k=jQuery('input[name="qtiworks_response_'+d.responseIdentifier+'"]');k.get(0).value=i;l.text(i);e.slider("value",d.isReversed?-i:i);setFlexiFormDirty(d.formDispatchFieldId)}})}}(jQuery)); \ No newline at end of file +(function(g){g.fn.associateInteraction=function(m){var n=g.extend({responseIdentifier:null,formDispatchFieldId:null,responseValue:null,opened:false,unrestricted:false},m);try{if(typeof n.responseValue!="undefined"&&n.responseValue.length>0){c(this,n)}if(n.opened){a(this,n)}}catch(o){if(window.console){console.log(o)}}return this};function c(m,q){var t=m.attr("id");var w=q.responseValue.split(",");var u=jQuery("#"+t+"_panel .association");for(var r=0;r<w.length;r++){var p=w[r].split(" ");var s=jQuery(u.get(r));if(s.size()==0){var v=d(t,q);s=jQuery("#"+v)}var o=jQuery("#"+t+"_items div[data-qti-id='"+p[0]+"']");if(e(o,t)){o=jQuery(o).clone()}var n=jQuery("#"+t+"_items div[data-qti-id='"+p[1]+"']");if(e(n,t)){n=jQuery(n).clone()}jQuery(o).addClass("oo-choosed");jQuery(n).addClass("oo-choosed");jQuery(s.find(".association_box.left")).addClass("oo-filled").append(o);jQuery(s.find(".association_box.right")).addClass("oo-filled").append(n)}l(t,q);if(q.unrestricted&&q.opened){i(t,q)}}function a(q,o){var m=q.attr("id");var n=jQuery("#"+m+" .o_associate_item");b(n,m,o);var p=jQuery("#"+m+"_panel .association_box");k(p,m,o)}function b(n,m,o){n.on("click",function(r,q){var p=jQuery(this);if(!p.hasClass("oo-choosed")&&!p.hasClass("oo-selected")){p.addClass("oo-selected")}}).draggable({containment:"#"+m,scroll:false,revert:"invalid",stop:function(p,q){jQuery(this).css({left:"0px",top:"0px"});jQuery(q.helper).removeClass("oo-drag")},helper:function(){var q=jQuery(this);var r=q.parent(".association_box").size()>0;if(!r&&e(this,m)){q.removeClass("oo-selected");var p=q.clone();jQuery(p).attr("id","n"+j()).data("qti-cloned","true").addClass("oo-drag");return p}q.addClass("oo-drag");return q}}).on("click",{formId:o.formDispatchFieldId},setFlexiFormDirtyByListener)}function e(r,n){var q=jQuery(r);var p=q.data("qti-match-max");var m=q.data("qti-id");var o=jQuery("#"+n+"_panel div[data-qti-id='"+m+"']").size();return(p==0||o+1<p)}function k(n,m,o){n.on("click",function(r,p){var q=jQuery(this);var s=jQuery(".o_associate_item",this).size();if(s==1){jQuery(".o_associate_item",this).each(function(t,u){h(u,q,m)})}else{jQuery("#"+m+"_items .o_associate_item.oo-selected").each(function(t,v){var u=jQuery(v);if(e(v,m)){u.removeClass("oo-selected");f(u.clone(),q,m)}else{f(u,q,m)}})}l(m,o);setFlexiFormDirty(o.formDispatchFieldId,false)}).droppable({drop:function(r,s){var q=jQuery(this);var t=jQuery(".o_associate_item",this).size();if(t>0){jQuery(".o_associate_item",this).each(function(u,v){h(v,q,m)})}var p;if(s.helper!=null&&jQuery(s.helper).data("qti-cloned")=="true"){var p=jQuery(s.draggable);p.removeClass("oo-selected").removeClass("oo-drag");p=p.clone();b(p,m,o);f(p,q,m)}else{var p=jQuery(s.draggable);p.removeClass("oo-selected").removeClass("oo-drag");f(p,q,m)}l(m,o);setFlexiFormDirty(o.formDispatchFieldId,false)}}).on("click",{formId:o.formDispatchFieldId},setFlexiFormDirtyByListener)}function f(o,n,m){o.removeClass("oo-selected").css({left:"0px",top:"0px"}).addClass("oo-choosed").appendTo(n);n.addClass("oo-filled")}function h(r,q,n){q.removeClass("oo-filled");var p=jQuery(r);p.removeClass("oo-choosed");var m=p.data("qti-id");var o=jQuery("#"+n+"_items div[data-qti-id='"+m+"']").size();if(o==0){p.appendTo(jQuery("#"+n+"_items"))}else{p.remove()}}function j(){function m(){return Math.floor((1+Math.random())*65536).toString(16).substring(1)}return m()+m()+m()+m()+m()+m()+m()}function l(m,o){var n=jQuery("#"+m+"_panel");n.find("input[type='hidden']").remove();jQuery("#"+m+"_panel .association").each(function(p,u){var r=jQuery(u).find(".o_associate_item");if(r.length==2){var s=jQuery(r.get(0)).data("qti-id");var q=jQuery(r.get(1)).data("qti-id");var t=jQuery('<input type="hidden"/>').attr("name","qtiworks_response_"+o.responseIdentifier).attr("value",s+" "+q);n.prepend(t)}else{if(r.length==0&&o.unrestricted){u.remove()}else{jQuery(u).find(".association_box").each(function(x,w){var v=jQuery(w).find(".o_associate_item").size();if(v==0&&jQuery(w).hasClass("oo-filled")){jQuery(w).removeClass("oo-filled")}})}}});i(m,o)}function i(m,p){if(!p.unrestricted||!p.opened){return}var n=jQuery("#"+m+"_panel");var o=true;jQuery("#"+m+"_panel .association").each(function(s,u){var t=jQuery(u).find(".o_associate_item");if(t.length!=2){o=false}});if(o){var r=d(m,p);var q=jQuery("#"+r+" .association_box");k(q,m,p)}}function d(m,n){var o=j();var p='<div id="'+o+'" class="association" style="">\n <div class="association_box left" style="width: 100px; height:50px; float:left;"></div>\n <div class="association_box right" style="width: 100px; height:50px; float:right;"></div>\n <div style="clear:both; "></div>\n</div>\n';jQuery("#"+m+"_panel").append(p);jQuery("#"+m+"_panel").append('<div style="clear:both; "></div>\n');return o}}(jQuery));(function(b){b.fn.choiceInteraction=function(d){var f=b.extend({responseIdentifier:null,formDispatchFieldId:null,maxChoices:0,},d);try{if(f.maxChoices>0){a(this,f);c(f)}}catch(g){if(window.console){console.log(g)}}return this};function a(f,d){var e=jQuery("#qti_container_"+d.responseIdentifier+" input[type=checkbox]");e.on("click",function(g,h){c(d)})}function c(d){var f=jQuery("#qti_container_"+d.responseIdentifier+" input[type=checkbox]");var e=0;f.each(function(g,h){if(h.checked){e++}});if(e>=d.maxChoices){f.each(function(g,h){if(h.checked){h.disabled=false}else{h.disabled=true}})}else{f.each(function(g,h){h.disabled=false})}}}(jQuery));(function(f){f.fn.gapMatchInteraction=function(h){var j=f.extend({responseIdentifier:null,formDispatchFieldId:null,gapChoiceData:{},gapData:{},opened:false,gapChoiceMap:{},gapMap:{},matched:{}},h);for(var i in j.gapChoiceData){var k=jQuery("#qtiworks_id_"+j.responseIdentifier+"_"+i);j.gapChoiceMap[i]={matchMax:j.gapChoiceData[i],matchCount:0,query:k,text:k.text()}}for(var i in j.gapData){var k=jQuery("#qtiworks_id_"+j.responseIdentifier+"_"+i);j.gapMap[i]={required:j.gapData[i],matched:false,matchedGapChoice:null,query:k,label:k.text()}}try{d(this,j)}catch(l){if(window.console){console.log(l)}}return this};function b(j,k,n){var m=k.value;var i=m.split(" ");var h=j.gapChoiceMap[i[0]];var l=j.gapMap[i[1]];n(j,k,m,h,l)}function d(i,h){if(h.opened){e(h.responseIdentifier).on("click",function(){a(h,this);setFlexiFormDirty(h.formDispatchFieldId)})}c(h);g(h)}function e(h){return jQuery("input[name=qtiworks_response_"+h+"]")}function c(j){j.matchCount=0;for(var i in j.gapChoiceMap){j.gapChoiceMap[i].matchCount=0}for(var i in j.gapMap){j.gapMap[i].matched=false;j.gapMap[i].matchedGapChoice=null}e(j.responseIdentifier).each(function(l,m){b(j,this,function(o,p,r,n,q){if(p.checked){n.matchCount++;q.matched=true;q.matchedGapChoice=n;o.matched[r]=true}})});for(var i in j.gapMap){var k=j.gapMap[i];var h;if(k.matched){h=k.matchedGapChoice.text}else{h=k.label}k.query.text(h)}}function g(h){e(h.responseIdentifier).each(function(){b(h,this,function(j,k,m,i,l){if(!j.opened){k.disabled=true}else{if(k.checked){k.disabled=false}else{if(l.matched||(i.matchMax!=0&&i.matchCount>=i.matchMax)){k.disabled=true}else{k.disabled=false}}}})})}function a(h,i){b(h,i,function(k,l,n,j,m){if(l.checked){if(m.matched||(j.matchMax!=0&&j.matchMax<=j.matchCount)){l.checked=false}else{j.matchCount++;m.matched=true;m.matchedGapChoice=j}m.query.text(j.text)}else{j.matchCount--;m.matched=false;m.matchedGapChoice=null;m.query.text(m.label)}g(k)})}}(jQuery));(function(d){d.fn.graphicAssociateInteraction=function(g){var h=d.extend({responseIdentifier:null,formDispatchFieldId:null,responseValue:null,maxAssociations:1,opened:false},g);try{if(!(typeof h.responseValue==="undefined")&&h.responseValue.length>0){e(this,h.responseValue,h.responseIdentifier)}if(h.opened){c(this,h.maxAssociations,h.responseIdentifier)}}catch(j){if(window.console){console.log(j)}}return this};function c(k,j,h){var g=k.attr("id");jQuery("#"+g+"_container area").on("click",function(t){var l=8;var q=jQuery("#"+g+"_container").data("openolat")||{};if(q.listOfPairs==undefined){q.currentSpot="";q.listOfPairs=[];jQuery("#"+g+"_container").data("openolat",q)}var w=jQuery(this).data("qti-id");if(q.currentSpot==""||q.currentSpot==w){q.currentSpot=w}else{var A=[q.currentSpot,w];q.listOfPairs.push(A);q.currentSpot=""}var m=document.getElementById(g+"_canvas");var u=m.getContext("2d");u.clearRect(0,0,jQuery(m).width(),jQuery(m).height());var B=jQuery("#"+g+"_container");B.find("input[type='hidden']").remove();var z=[];if(q.currentSpot!=""){b(u,"ac_"+h+"_"+q.currentSpot);z.push(q.currentSpot)}for(var p=q.listOfPairs.length;p-->0;){var o=q.listOfPairs[p];for(var n=o.length;n-->0;){if(0>z.indexOf(o[n])){b(u,"ac_"+h+"_"+o[n]);z.push(o[n])}}var s=jQuery("#ac_"+h+"_"+o[1]);var v=jQuery("#ac_"+h+"_"+o[0]);var C=f(s);var y=f(v);u.beginPath();u.moveTo(C[0],C[1]);u.lineTo(y[0],y[1]);u.lineWidth=3;u.stroke();var x=jQuery('<input type="hidden"/>').attr("name","qtiworks_response_"+h).attr("value",v.data("qti-id")+" "+s.data("qti-id"));B.prepend(x)}})}function e(g,v,t){var o=g.attr("id");var x=jQuery("#"+o+"_container");var k=document.getElementById(o+"_canvas");var q=k.getContext("2d");q.clearRect(0,0,jQuery(k).width(),jQuery(k).height());var w=[];var h=v.split(",");for(var n=h.length;n-->0;){var m=h[n].split(" ");for(var l=m.length;l-->0;){if(0>w.indexOf(m[l])){b(q,"ac_"+t+"_"+m[l]);w.push(m[l])}}if(m.length==2){var p=jQuery("#ac_"+t+"_"+m[1]);var r=jQuery("#ac_"+t+"_"+m[0]);var y=f(p);var u=f(r);q.beginPath();q.moveTo(y[0],y[1]);q.lineTo(u[0],u[1]);q.lineWidth=3;q.stroke();var s=jQuery('<input type="hidden"/>').attr("name","qtiworks_response_"+t).attr("value",r.data("qti-id")+" "+p.data("qti-id"));x.prepend(s)}}}function b(h,g){jQuery("#"+g).each(function(k,m){var l=jQuery(m);var n=f(l);var j=l.attr("shape");a(h,j,n,0,0)})}function a(j,g,k,h,l){h=h||0;l=l||0;j.beginPath();if(g=="rect"){j.rect(k[0]+h,k[1]+l,k[2]-k[0],k[3]-k[1])}else{if(g=="poly"){j.moveTo(k[0]+h,k[1]+l);for(i=2;i<k.length;i+=2){j.lineTo(k[i]+h,k[i+1]+l)}}else{if(g=="circ"||g=="circle"){j.arc(k[0]+h,k[1]+l,k[2]-2,0,Math.PI*2,false)}}}j.closePath();j.lineWidth=4;j.strokeStyle="#003300";j.stroke();j.fillStyle="green";j.fill()}function f(g){var h=g.attr("coords").split(",");for(i=h.length;i-->0;){h[i]=parseFloat(h[i])}return h}}(jQuery));(function(f){f.fn.graphicGapInteraction=function(j){var k=f.extend({maphilight:null,responseIdentifier:null,formDispatchFieldId:null,responseValue:null,opened:false},j);try{if(!(typeof k.responseValue==="undefined")&&k.responseValue.length>0){b(this,k)}if(k.opened){c(this,k)}}catch(l){if(window.console){console.log(l)}}return this};function b(j,m){var q=j.attr("id");var v=jQuery("#"+q);var l=m.responseValue.split(",");for(var n=l.length;n-->0;){var k=l[n].split(" ");var p=jQuery("#ac_"+m.responseIdentifier+"_"+k[0]);var o=jQuery("#ac_"+m.responseIdentifier+"_"+k[1]);var r,u;if(p.hasClass("gap_item")){r=p;u=o}else{r=o;u=p}var s=g(u);r.css("position","absolute");r.css("left",s[0]+"px");r.css("top",s[1]+"px");r.addClass("oo-choosed");var t=jQuery('<input type="hidden"/>').attr("name","qtiworks_response_"+m.responseIdentifier).attr("value",r.data("qti-id")+" "+u.data("qti-id"));v.prepend(t)}}function c(l,k){var j=l.attr("id");jQuery(".gap_item").on("click",function(q,p){var o=jQuery(this);if(o.hasClass("oo-choosed")){var n=o.data("drop-timestamp");if(!(typeof n==="undefined")&&n!=null){if((Date.now()-n)<1500){o.data("drop-timestamp",null);return}}o.removeClass("oo-choosed");var m=o.data("qti-id");jQuery("#"+j).find("input[type='hidden']").each(function(r,s){var t=jQuery(s).val();if(t.indexOf(m+" ")==0){jQuery(s).remove()}});o.css({position:"relative",left:"0px",top:"0px"})}else{o.addClass("oo-selected")}}).draggable({containment:"#"+j,scroll:false,revert:"invalid",stop:function(m,n){if(!jQuery(this).hasClass("oo-choosed")){jQuery(this).css({position:"relative",left:"0px",top:"0px"})}}}).mousemove(function(m,s){var u=jQuery(this);if(u.hasClass("ui-draggable-dragging")){var q=jQuery("#"+j+"_img");var p=q.offset();var o=u.offset();var n=o.left+(u.width()/2)-p.left;var t=o.top+(u.height()/2)-p.top;var r=h(n,t,j);if("invalid"!=r){jQuery("#"+j+" area").each(function(v,x){var w=jQuery(x);var y=w.attr("id");if(r==y){w.mouseover()}else{w.mouseout()}});jQuery("#"+r).mouseover()}else{jQuery("#"+j+" area").each(function(v,w){jQuery(w).mouseout()})}}});jQuery("#"+j).droppable({drop:function(m,t){var r=jQuery("#"+j+"_img");var p=r.offset();var u=jQuery(t.draggable);var o=u.offset();var n=o.left+(u.width()/2)-p.left;var w=o.top+(u.height()/2)-p.top;var s=h(n,w,j);if("invalid"!=s){var z=jQuery("#"+s);var v=g(z);var x=z.data("qti-id");var q=u.data("qti-id");u.css("position","absolute");u.css("left",v[0]+"px");u.css("top",v[1]+"px");u.css("border","none");u.removeClass("oo-selected");u.addClass("oo-choosed");var y=jQuery('<input type="hidden"/>').attr("name","qtiworks_response_"+k.responseIdentifier).attr("value",q+" "+x);jQuery(this).prepend(y);jQuery(z).mouseout();u.data("drop-timestamp",Date.now())}}});jQuery("#"+j+" area").on("click",function(o,n){var m=jQuery(this);jQuery(".gap_item.oo-selected").each(function(q,s){var r=jQuery(s);var t=g(m);var w=m.data("qti-id");var v=r.data("qti-id");r.css("position","absolute");r.css("left",t[0]+"px");r.css("top",t[1]+"px");r.css("border","none");r.removeClass("oo-selected");r.addClass("oo-choosed");var p=jQuery("#"+j);var u=jQuery('<input type="hidden"/>').attr("name","qtiworks_response_"+k.responseIdentifier).attr("value",v+" "+w);p.prepend(u)})})}function h(l,k,j){var m="invalid";jQuery("#"+j+" area").each(function(r,o){var v=jQuery(o);var u=v.attr("id");var t=v.attr("coords");var s=v.attr("shape");var w=g(v);if("circle"==s){if(a(l,k,w[0],w[1],w[2])){m=u}}else{if("rect"==s){if(d(l,k,w[0],w[1],w[2],w[3])){m=u}}else{if("poly"==s){var n={};n.x=[];n.y=[];var q=w.length/2;var p=0;for(ix=0;ix<q;ix++){n.x[ix]=w[p];n.y[ix]=w[p+1];p+=2}for(i=0;i<n.length;i++){if(e(n.x.length,n.x,n.y,l,k)){m=n.id;break}}}}}});return m}function a(k,o,m,l,j){var n=Math.pow(k-m,2)+Math.pow(o-l,2);return Math.pow(j,2)>=n}function d(j,o,n,l,k,m){if((n<=j)&&(j<=k)&&(l<=o)&&(o<=m)){return true}else{return false}}function e(l,p,o,k,r){var n,m,q=false;for(n=0,m=l-1;n<l;m=n++){if(((o[n]>r)!=(o[m]>r))&&(k<(p[m]-p[n])*(r-o[n])/(o[m]-o[n])+p[n])){q=!q}}return q}function g(j){var k=j.attr("coords").split(",");for(i=k.length;i-->0;){k[i]=parseFloat(k[i])}return k}}(jQuery));(function(c){c.fn.graphicOrderInteraction=function(d){var f=c.extend({responseIdentifier:null,formDispatchFieldId:null,responseValue:null,maxChoices:1,opened:false},d);try{if(!(typeof f.responseValue==="undefined")&&f.responseValue.length>0){b(this,f)}if(f.opened){a(this,f)}}catch(g){if(window.console){console.log(g)}}return this};function b(d,h){var m=d.attr("id");var r=jQuery("#"+m+"_container");var e=document.getElementById(m+"_canvas");var o=e.getContext("2d");o.clearRect(0,0,jQuery(e).width(),jQuery(e).height());var n=h.responseValue.split(",");for(var k=n.length;k-->0;){if(n[k].length==0){continue}var q=jQuery("#ac_"+h.responseIdentifier+"_"+n[k]);var f=q.data("qti-id");var l=q.attr("coords").split(",");var j=l[0];var g=l[1];o.font="16px Arial";o.fillText(""+(k+1),j,g);var p=jQuery('<input type="hidden"/>').attr("name","qtiworks_response_"+h.responseIdentifier).attr("value",f);r.prepend(p)}}function a(f,e){var d=f.attr("id");jQuery("#"+d+"_container area").on("click",function(v){var h=8;var x=jQuery(this).attr("id");var l=jQuery(this).data("qti-id");var u=jQuery(this).attr("coords").split(",");var o=u[0];var n=u[1];var t=jQuery("#"+d+"_container").data("openolat")||{};if(t.listOfPoints==undefined){t.listOfPoints=[];jQuery("#"+d+"_container").data("openolat",t)}var s=false;var m=[];for(var q=t.listOfPoints.length;q-->0;){var j=t.listOfPoints[q];var g=((j.x-o)*(j.x-o))+((j.y-n)*(j.y-n));if(h*h>g){s=true}else{m.push(j)}}if(s){t.listOfPoints=m}else{if(t.listOfPoints.length>=e.maxChoices){return false}else{t.listOfPoints.push({x:o,y:n,areaId:x,spotQtiId:l})}}var k=document.getElementById(d+"_canvas");var w=k.getContext("2d");w.clearRect(0,0,jQuery(k).width(),jQuery(k).height());var z=jQuery("#"+d+"_container");z.find("input[type='hidden']").remove();for(var q=t.listOfPoints.length;q-->0;){var j=t.listOfPoints[q];w.font="16px Arial";w.fillText(""+(q+1),j.x,j.y);var y=jQuery('<input type="hidden"/>').attr("name","qtiworks_response_"+e.responseIdentifier).attr("value",j.spotQtiId);z.prepend(y)}})}}(jQuery));(function(c){c.fn.hotspotInteraction=function(f){var g=c.extend({responseIdentifier:null,formDispatchFieldId:null,maxChoices:1,singleChoice:false,responseValue:null,opened:false,maphilightSettings:{}},f);try{if(!(typeof g.responseValue==="undefined")&&g.responseValue.length>0){a(this,g)}if(g.opened){e(this,g)}}catch(h){if(window.console){console.log(h)}}return this};function a(n,k){var f=n.attr("id");var g=jQuery("#"+f);var j=k.responseValue.split(",");for(i=j.length;i-->0;){var h=jQuery("#ac_"+k.responseIdentifier+"_"+j[i]);var l=h.data("maphilight")||{};l.selectedOn=true;b(l,k.maphilightSettings);h.data("maphilight",l).trigger("alwaysOn.maphilight");var m=jQuery('<input type="hidden"/>').attr("name","qtiworks_response_"+k.responseIdentifier).attr("value",h.data("qti-id"));g.append(m)}}function e(h,g){var f=h.attr("id");jQuery("#"+f+" map area").each(function(j,k){jQuery(k).on("click",function(){d(this,f,g.responseIdentifier,g.maxChoices,g.singleChoice,g.maphilightSettings)})})}function d(l,j,o,k,q,m){var n=jQuery(l);var h=n.data("maphilight")||{};if((typeof h.selectedOn==="undefined")||!h.selectedOn){if(q){jQuery("area","map[name='"+j+"_map']").each(function(r,t){var s=jQuery(t).data("maphilight")||{};if(s.selectedOn){s.selectedOn=false;b(s,m);jQuery(t).data("maphilight",s).trigger("alwaysOn.maphilight")}})}var f=k;if(f>0){var g=0;jQuery("area","map[name='"+j+"_map']").each(function(r,t){var s=jQuery(t).data("maphilight")||{};if(s.selectedOn){g++}});if(g>=f){return false}}}if(typeof h.selectedOn==="undefined"){h.selectedOn=true}else{h.selectedOn=!h.selectedOn}b(h,m);n.data("maphilight",h).trigger("alwaysOn.maphilight");var p=jQuery("#"+j);p.find("input[type='hidden']").remove();jQuery("area","map[name='"+j+"_map']").each(function(r,t){var u=jQuery(t);var s=u.data("maphilight")||{};if(s.selectedOn){var v=jQuery('<input type="hidden"/>').attr("name","qtiworks_response_"+o).attr("value",u.data("qti-id"));p.append(v)}})}function b(g,f){if(g.selectedOn){g.fillColor=f.selectedFillColor;g.fillOpacity=f.selectedFillOpacity;g.strokeColor=f.selectedStrokeColor;g.strokeOpacity=f.selectedStrokeOpacity;g.shadow=f.selectedShadow;g.shadowX=0;g.shadowY=0;g.shadowRadius=7;g.shadowColor="000000";g.shadowOpacity=0.8;g.shadowPosition="outside"}else{g.fillColor=f.fillColor;g.fillOpacity=f.fillOpacity;g.strokeColor=f.strokeColor;g.strokeOpacity=f.strokeOpacity;g.shadow=false}}}(jQuery));(function(a){a.fn.rwdImageMaps=function(c){var e=a.extend({fillColor:"bbbbbb",fillOpacity:0.5,strokeColor:"6E6E6E",strokeOpacity:1,},c);var d=this;var b=function(){d.each(function(){if(typeof(a(this).attr("usemap"))=="undefined"){return}var g=this,f=a(g);a("<img />").on("load",function(){var j="width",o="height",p=f.attr(j),l=f.attr(o);if(!p||!l){var q=new Image();q.src=f.attr("src");if(!p){p=q.width}if(!l){l=q.height}}var i=f.width()/100,m=f.height()/100,k=f.attr("usemap").replace("#",""),n="coords";a('map[name="'+k+'"]').find("area").each(function(){var t=a(this);if(!t.data(n)){t.data(n,t.attr(n))}var s=t.data(n).split(","),r=new Array(s.length);for(var h=0;h<r.length;++h){if(h%2===0){r[h]=parseInt(((s[h]/p)*100)*i)}else{r[h]=parseInt(((s[h]/l)*100)*m)}}t.attr(n,r.toString())});f.maphilight({fillColor:e.fillColor,fillOpacity:e.fillOpacity,strokeColor:e.strokeColor,strokeOpacity:e.strokeOpacity,strokeWidth:3,alwaysOn:true})}).attr("src",f.attr("src"))})};a(window).resize(b).trigger("resize");return this}})(jQuery);(function(f){f.fn.matchInteraction=function(h){var j=f.extend({responseIdentifier:null,formDispatchFieldId:null,maxAssociations:1,leftData:{},rightData:{},leftMap:{},rightMap:{},matched:[]},h);for(var i in j.leftData){j.leftMap[i]={matchMax:j.leftData[i],matchCount:0}}for(var i in j.rightData){j.rightMap[i]={matchMax:j.rightData[i],matchCount:0}}try{d(this,j)}catch(k){if(window.console){console.log(k)}}return this};function d(i,h){e(h.responseIdentifier).on("click",function(){a(h,this)});c(h);g(h)}function e(h){return jQuery("input[name=qtiworks_response_"+h+"]")}function b(j,l,n){var m=l.value;var h=m.split(" ");var k=j.leftMap[h[0]];var i=j.rightMap[h[1]];n(l,m,k,i)}function c(i){i.matchCount=0;i.matched={};for(var h in i.leftMap){i.leftMap[h].matchCount=0}for(var h in i.rightMap){i.rightMap[h].matchCount=0}e(i.responseIdentifier).each(function(){b(i,this,function(l,m,k,j){if(l.checked){i.matchCount++;k.matchCount++;j.matchCount++;i.matched[m]=true}})})}function g(h){e(h.responseIdentifier).each(function(){b(h,this,function(k,l,j,i){if(k.checked){k.disabled=false}else{if(h.maxAssociations!=0&&h.matchCount>=h.maxAssociations){k.disabled=true}else{if(j.matchMax!=0&&j.matchCount>=j.matchMax){if(j.matchMax!=1&&j.matchCount!=1){k.disabled=true}else{k.disabled=false}}else{if(i.matchMax!=0&&i.matchCount>=i.matchMax){k.disabled=true}else{k.disabled=false}}}}})})}function a(h,i){b(h,i,function(p,q,o,m){if(p.checked){var l=false;if(o.matchMax==1){var n=jQuery(p);var k=n.attr("id");var j=n.attr("value").split(" ")[0];e(h.responseIdentifier).each(function(){b(h,this,function(s,w,v,r){var u=jQuery(s);if(k!==u.attr("id")&&s.checked){var t=u.attr("value").split(" ")[0];if(j===t){s.checked=false;v.matchCount--;h.matchCount--}}})});o.matchCount++;h.matchCount++;l=true}else{if(o.matchMax!=0&&o.matchMax<=o.matchCount){p.checked=false}else{o.matchCount++;h.matchCount++;l=true}}if(m.matchMax!=0&&m.matchMax<=m.matchCount){p.checked=false}else{m.matchCount++;if(!l){h.matchCount++}}}else{h.matchCount--;o.matchCount--;m.matchCount--}g(h)})}}(jQuery));(function(h){h.fn.matchInteractionDnd=function(m){var n=h.extend({responseIdentifier:null,formDispatchFieldId:null,maxAssociations:1,responseValue:null,opened:false},m);try{if(typeof n.responseValue!="undefined"&&n.responseValue.length>0){f(this,n)}if(n.opened){i(this,n)}}catch(o){if(window.console){console.log(o)}}return this};function f(m,o){var q=m.attr("id");var w=o.responseValue.split(",");var r=jQuery("#"+q);for(var p=0;p<w.length;p++){var n=w[p].split(" ");var t=n[0];var s=n[1];var v=jQuery("#"+q+" .o_match_dnd_sources li[data-qti-id='"+t+"']");if(g(v,q)){v=jQuery(v).clone()}var u=jQuery("#"+q+" .o_match_dnd_targets ul[data-qti-id='"+s+"']");jQuery(v).addClass("oo-choosed");jQuery(u).addClass("oo-choosed");jQuery(u).addClass("oo-filled").append(v)}l(q,o);if(o.unrestricted&&o.opened){addNewAssociationBoxAndEvents(q,o)}}function i(q,p){var n=q.attr("id");a(n,p);var o=jQuery("#"+n+" .o_match_dnd_source");e(o,n,p);var m=jQuery("#"+n+" .o_match_dnd_target");k(m,n,p)}function a(m,n){jQuery("#"+m+" .o_match_dnd_sources").droppable({tolerance:"pointer",over:function(o,p){jQuery(this).addClass("oo-accepted")},out:function(o,p){jQuery(this).removeClass("oo-accepted")},drop:function(s,t){var r=jQuery(this);r.removeClass("oo-accepted");var q=jQuery(t.draggable);var o=q.data("qti-id");var p=r.find("li[data-qti-id='"+o+"']");if(p.size()>0){if(q.parents(".o_match_dnd_sources").size()==0){q.remove()}}else{q.appendTo(r)}l(m,n);setFlexiFormDirty(n.formDispatchFieldId,false)}}).on("click",{formId:n.formDispatchFieldId},setFlexiFormDirtyByListener)}function e(n,m,o){n.on("click",function(r,q){var p=jQuery(this);if(!p.hasClass("oo-choosed")&&!p.hasClass("oo-selected")){jQuery("#"+m+" .o_match_dnd_sources .o_match_dnd_source").each(function(s,t){jQuery(t).removeClass("oo-selected")});p.addClass("oo-selected")}else{if(p.parents(".o_match_dnd_targets").size()>0&&!p.hasClass("oo-dropped-mrk")){d(p,m);l(m,o);setFlexiFormDirty(o.formDispatchFieldId,false)}}}).draggable({containment:"#"+m,scroll:false,revert:"invalid",cursorAt:{left:5,top:5},start:function(p,q){jQuery(q.helper).removeClass("oo-dropped-mrk")},stop:function(p,q){jQuery(this).css({left:"0px",top:"0px","z-index":""});jQuery(q.helper).removeClass("oo-drag")},helper:function(){var q=jQuery(this);var r=q.parent(".o_match_dnd_target").size()>0;if(!r&&g(this,m)){q.removeClass("oo-selected");var p=q.clone();jQuery(p).attr("id","n"+j()).data("qti-cloned","true").addClass("oo-drag").addClass("oo-drag-mrk").css("z-index",10).css("width",q.width()).css("height",q.height());return p}q.addClass("oo-drag").addClass("oo-drag-mrk").css("z-index",10);return q}}).on("click",{formId:o.formDispatchFieldId},setFlexiFormDirtyByListener)}function j(){function m(){return Math.floor((1+Math.random())*65536).toString(16).substring(1)}return m()+m()+m()+m()+m()+m()+m()}function g(r,n){var q=jQuery(r);if(q.parents(".o_match_dnd_target").size()>0){return false}var o=q.data("qti-match-max");var m=q.data("qti-id");var p=jQuery("#"+n+" .o_match_dnd_targets li[data-qti-id='"+m+"']").size();return(o==0||p+1<o)}function k(n,m,o){n.on("click",function(r,p){var q=jQuery(this);var s=jQuery(".o_associate_item",this).size();if(s==0){jQuery("#"+m+" .o_match_dnd_sources .oo-selected").each(function(t,v){var u=jQuery(v);if(g(v,m)){u.removeClass("oo-selected");u=u.clone();b(u,q,m);e(u,m,o)}else{b(u,q,m)}})}l(m,o);setFlexiFormDirty(o.formDispatchFieldId,false)}).droppable({tolerance:"pointer",accept:function(q){var p=jQuery(q).data("qti-id");var r=jQuery(".o_match_dnd_source[data-qti-id='"+p+"']",this).size()==0;if(r){var t=jQuery(this).data("qti-match-max");if(t>0){var s=jQuery(".o_match_dnd_source",this).size();if(s>=t){r=false}}}return r},over:function(p,q){jQuery(this).addClass("oo-accepted")},out:function(p,q){jQuery(this).removeClass("oo-accepted")},drop:function(t,u){var s=jQuery(this);s.removeClass("oo-accepted");var r=jQuery(u.draggable);var q=r.data("qti-id");var p=jQuery(".o_match_dnd_source[data-qti-id='"+q+"']",this).size();if(p>0){return}if(u.helper!=null&&jQuery(u.helper).data("qti-cloned")=="true"){r.removeClass("oo-selected").removeClass("oo-drag");r=r.clone();e(r,m,o);b(r,s,m)}else{r.removeClass("oo-selected").removeClass("oo-drag");b(r,s,m)}r.addClass("oo-dropped-mrk");setTimeout(function(){r.removeClass("oo-dropped-mrk")},100);l(m,o);setFlexiFormDirty(o.formDispatchFieldId,false)}}).on("click",{formId:o.formDispatchFieldId},setFlexiFormDirtyByListener)}function b(o,p,n){var m=p.find("ul.o_match_dnd_target_drop_zone");o.removeClass("oo-selected").css({width:"auto",left:"0px",top:"0px","z-index":""}).addClass("oo-choosed").appendTo(m);p.addClass("oo-filled")}function d(q,n){var p=jQuery(q);p.removeClass("oo-choosed");var m=p.data("qti-id");var o=jQuery("#"+n+" .o_match_dnd_sources li[data-qti-id='"+m+"']").size();if(o==0){p.css({width:"auto",left:"0px",top:"0px","z-index":""}).appendTo(jQuery("#"+n+" .o_match_dnd_sources"))}else{p.remove()}}function l(m,p){p.matchCount=0;p.matched={};for(var o in p.leftMap){p.leftMap[o].matchCount=0}for(var o in p.rightMap){p.rightMap[o].matchCount=0}var n=jQuery("#"+m);n.find("input[type='hidden']").remove();jQuery("#"+m+" .o_match_dnd_target_drop_zone").each(function(r,q){jQuery(q).find(".o_match_dnd_source").each(function(w,s){var u=jQuery(s).data("qti-id");var t=jQuery(q).data("qti-id");var v=jQuery('<input type="hidden"/>').attr("name","qtiworks_response_"+p.responseIdentifier).attr("value",u+" "+t);n.prepend(v)})})}function c(m,n){withCheckbox(m,n,function(r,s,q,p){if(r.checked){var o=false;if(q.matchMax!=0&&q.matchMax<=q.matchCount){r.checked=false}else{q.matchCount++;m.matchCount++;o=true}if(p.matchMax!=0&&p.matchMax<=p.matchCount){r.checked=false}else{p.matchCount++;if(!o){m.matchCount++}}}else{m.matchCount--;q.matchCount--;p.matchCount--}updateDisabledStates(m)})}}(jQuery));(function(c){c.fn.orderInteraction=function(d){var f=c.extend({responseIdentifier:null,formDispatchFieldId:null,minChoices:null,maxChoices:null,responseValue:null,opened:false},d);try{if(typeof f.responseValue!="undefined"&&f.responseValue.length>0){b(f)}if(f.opened){a(this,f)}}catch(g){if(window.console){console.log(g)}}return this};function a(k,g){var d="#qtiworks_response_"+g.responseIdentifier;var i=jQuery(d+" div.source ul");var j=jQuery(d+" div.target ul");var h=jQuery(d+" div.source ul").get(0);var f=jQuery(d+" div.target ul").get(0);var e=dragula([h,f],{copy:function(l,m){return false},accepts:function(l,m){return m!==h}});e.on("drag",function(m,l){}).on("over",function(m,l,n){if(l===f){jQuery(l).addClass("oo-accepted")}}).on("drop",function(m,o,n,l){b(g);setFlexiFormDirty(g.formDispatchFieldId)}).on("dragend",function(l){jQuery(f).removeClass("oo-accepted")}).on("out",function(l){jQuery(f).removeClass("oo-accepted")})}function b(h){var d="#qtiworks_response_"+h.responseIdentifier;var i=jQuery(d+" div.source ul");var j=jQuery(d+" div.target ul");var e=jQuery(d+" div.target");var g=jQuery(d+" div.hiddenInputContainer");var f=j.children("li").size();if(h.minChoices!=null&&h.maxChoices!=null){if(f<h.minChoices||f>h.maxChoices){if(h.minChoices!=h.maxChoices){alert("You must select and order between "+h.minChoices+" and "+h.maxChoices+" items")}else{alert("You must select and order exactly "+h.minChoices+" item"+(minChoices>1?"s":""))}e.toggleClass("highlight",true);return false}else{e.toggleClass("highlight",false)}}var g=jQuery(d+" div.hiddenInputContainer");g.empty();j.children("li").each(function(l){var k=this.id.substring("qtiworks_response_".length);var m=jQuery('<input type="hidden">');m.attr("name","qtiworks_response_"+h.responseIdentifier);m.attr("value",k);g.append(m)})}}(jQuery));(function(b){b.fn.positionObjectStage=function(f){var g=b.extend({responseIdentifier:null,formDispatchFieldId:null,responseValue:null,maxChoices:1,opened:false},f);try{var d=this.attr("id");jQuery("#"+d+" .items_container .o_item.o_"+g.responseIdentifier).each(function(e,i){jQuery(i).attr("id","object-item-"+e)});if(!(typeof g.responseValue==="undefined")&&g.responseValue.length>0){c(this,g)}if(g.opened){a(this,g)}}catch(h){if(window.console){console.log(h)}}return this};function c(d,f){var k=d.attr("id");var r=jQuery("#"+k);var j=f.responseValue.split(":");var l=jQuery("#"+k+" .items_container .o_item.o_"+f.responseIdentifier);for(var h=j.length;h-->0;){var n=j[h].split(" ");var g=n[0];var e=n[1];var q=jQuery(l.get(h));q.css("position","absolute");q.css("top",e+"px");q.css("left",g+"px");var m=q.attr("id");var o="in-"+m+"-"+f.responseIdentifier;var p=jQuery('<input type="hidden"/>').attr("id",o).attr("name","qtiworks_response_"+f.responseIdentifier).attr("value",g+" "+e);r.prepend(p)}}function a(g,f){var d=g.attr("id");var e=jQuery("#"+d);jQuery("#"+d+" .items_container .o_item.o_"+f.responseIdentifier).draggable({containment:"#"+d,scroll:false,stop:function(h,p){var i=jQuery("#"+d+"_img");var k=jQuery(i).offset().top-jQuery(window).scrollTop();var n=jQuery(i).offset().left-jQuery(window).scrollLeft();var m=jQuery(this).offset().top-jQuery(window).scrollTop();var q=jQuery(this).offset().left-jQuery(window).scrollLeft();var l=Math.round((q-n));var j=Math.round((m-k));var o=jQuery(this).attr("id");var r="in-"+o+"-"+f.responseIdentifier;var s=e.find("#"+r);if(s.length==0){var t=jQuery('<input type="hidden"/>').attr("id",r).attr("name","qtiworks_response_"+f.responseIdentifier).attr("value",l+" "+j);e.prepend(t)}else{s.val(l+" "+j)}setFlexiFormDirty(f.formDispatchFieldId)}})}}(jQuery));(function(a){a.fn.selectPointInteraction=function(d){var f=a.extend({responseIdentifier:null,formDispatchFieldId:null,responseValue:null,maxChoices:1,opened:false},d);try{if(!(typeof f.responseValue==="undefined")&&f.responseValue.length>0){b(this,f)}if(f.opened){c(this,f)}}catch(g){if(window.console){console.log(g)}}return this};function b(d,h){var e=8;var j=d.attr("id");var q=jQuery("#"+j);var n=h.responseValue.split(":");var g=document.getElementById(j+"_canvas");var k=g.getContext("2d");k.clearRect(0,0,jQuery(g).width(),jQuery(g).height());for(i=n.length;i-->0;){if(n[i].length==0){continue}var f=n[i].split(" ");var m=f[0];var l=f[1];k.beginPath();k.arc(m,l,e,0,Math.PI*2,false);k.stroke();k.closePath();var o=jQuery('<input type="hidden"/>').attr("name","qtiworks_response_"+h.responseIdentifier).attr("value",m+" "+l);q.append(o)}}function c(f,e){var d=f.attr("id");jQuery("#"+d+"_canvas").on("click",function(u,z){var h=8;var q=jQuery(this).offset().top-jQuery(window).scrollTop();var w=jQuery(this).offset().left-jQuery(window).scrollLeft();var n=Math.round((u.clientX-w));var m=Math.round((u.clientY-q));var s=jQuery("#"+d).data("openolat")||{};if(s.listOfPoints==undefined){s.listOfPoints=[];jQuery("#"+d).data("openolat",s)}var o=false;var l=[];for(i=s.listOfPoints.length;i-->0;){var j=s.listOfPoints[i];var g=((j.x-n)*(j.x-n))+((j.y-m)*(j.y-m));if(Math.pow(h,2)>g){o=true}else{l.push(j)}}if(o){s.listOfPoints=l}else{if(s.listOfPoints.length>=e.maxChoices){return false}else{s.listOfPoints.push({x:n,y:m})}}var k=document.getElementById(d+"_canvas");var v=k.getContext("2d");v.clearRect(0,0,jQuery(k).width(),jQuery(k).height());var y=jQuery("#"+d);y.find("input[type='hidden']").remove();for(i=s.listOfPoints.length;i-->0;){var j=s.listOfPoints[i];v.beginPath();v.arc(j.x,j.y,h,0,Math.PI*2,false);v.stroke();v.closePath();var x=jQuery('<input type="hidden"/>').attr("name","qtiworks_response_"+e.responseIdentifier).attr("value",j.x+" "+j.y);y.append(x)}setFlexiFormDirty(e.formDispatchFieldId)})}}(jQuery));(function(b){b.fn.sliderInteraction=function(c){var d=b.extend({responseIdentifier:null,formDispatchFieldId:null,responseValue:null,min:1,max:1,step:1,orientation:null,isReversed:false,isDiscrete:false,opened:false,initialValue:null},c);try{a(this,d)}catch(f){if(window.console){console.log(f)}}return this};function a(g,d){var e=jQuery("#qtiworks_id_slider_"+d.responseIdentifier);var f=jQuery('input[name="qtiworks_response_'+d.responseIdentifier+'"]');var c=f.get(0).value||d.min;e.slider({value:c,step:d.step,disabled:!d.opened,orientation:d.orientation,min:d.isReversed?-d.max:d.min,max:d.isReversed?-d.min:d.max,slide:function(h,j){var i=d.isReversed?-j.value:j.value;var l=jQuery("#qtiworks_id_slidervalue_"+d.responseIdentifier);var k=jQuery('input[name="qtiworks_response_'+d.responseIdentifier+'"]');k.get(0).value=i;l.text(i);e.slider("value",d.isReversed?-i:i);setFlexiFormDirty(d.formDispatchFieldId)}})}}(jQuery)); \ No newline at end of file diff --git a/src/main/webapp/static/themes/light/_config.scss b/src/main/webapp/static/themes/light/_config.scss index 0756478dabc02637899485ed7c3725fe641ce944..4bea91ac194b1da24473a2bfc43a340d437e719b 100644 --- a/src/main/webapp/static/themes/light/_config.scss +++ b/src/main/webapp/static/themes/light/_config.scss @@ -433,6 +433,9 @@ $o-qti-match-drop-accept-border-color : darken($brand-info, 25%) !default; $o-qti-match-target-border-color : $brand-info !default; $o-qti-match-target-bg : $state-info-bg !default; $o-qti-match-border-radius : $panel-border-radius !default; +$o-qti-match-true-false-unanswered-bg : lighten($gray-lighter, 5%) !default; +$o-qti-match-true-false-right-bg : lighten($brand-success, 40%) !default; +$o-qti-match-true-false-wrong-bg : lighten($brand-danger, 40%) !default; $o-qti-order-source-border-style : dashed !default; $o-qti-order-sources-border-color : $o-qti-run-infos-border-color !default; $o-qti-order-border-radius : $panel-border-radius !default; diff --git a/src/main/webapp/static/themes/light/content.css.map b/src/main/webapp/static/themes/light/content.css.map index e8dc4a71ecfc588b904e61074ff5bc7905548336..f5106438231becc6fea18bcebc823439cb6fdb15 100644 --- a/src/main/webapp/static/themes/light/content.css.map +++ b/src/main/webapp/static/themes/light/content.css.map @@ -1,6 +1,6 @@ { "version": 3, -"mappings": "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", +"mappings": "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", "sources": ["_license.scss","../../bootstrap/stylesheets/bootstrap/_normalize.scss","../../bootstrap/stylesheets/bootstrap/_print.scss","../../bootstrap/stylesheets/bootstrap/_scaffolding.scss","../../bootstrap/stylesheets/bootstrap/mixins/_vendor-prefixes.scss","_config.scss","../../bootstrap/stylesheets/bootstrap/_variables.scss","../../bootstrap/stylesheets/bootstrap/mixins/_tab-focus.scss","../../bootstrap/stylesheets/bootstrap/mixins/_image.scss","../../bootstrap/stylesheets/bootstrap/_type.scss","../../bootstrap/stylesheets/bootstrap/mixins/_text-emphasis.scss","../../bootstrap/stylesheets/bootstrap/mixins/_background-variant.scss","../../bootstrap/stylesheets/bootstrap/mixins/_clearfix.scss","../../bootstrap/stylesheets/bootstrap/mixins/_text-overflow.scss","../../font-awesome/scss/_path.scss","../../font-awesome/scss/_core.scss","modules/_helpers.scss","../../bootstrap/stylesheets/bootstrap/mixins/_opacity.scss","modules/_dialog.scss","modules/_mixins.scss","modules/_emoticons.scss","modules/_content.scss","modules/_content_embedded.scss","../../bootstrap/stylesheets/bootstrap/mixins/_border-radius.scss","../../font-awesome/scss/_variables.scss","modules/_tinymce.scss","modules/_print.scss"], "names": [], "file": "content.css" diff --git a/src/main/webapp/static/themes/light/modules/_icons.scss b/src/main/webapp/static/themes/light/modules/_icons.scss index 38512891dbd9dba5342e7140ccc03bcfadda3a1d..d76767176e8e2fdbc048904bfc2bddb911b80614 100644 --- a/src/main/webapp/static/themes/light/modules/_icons.scss +++ b/src/main/webapp/static/themes/light/modules/_icons.scss @@ -470,6 +470,7 @@ $fa-css-prefix: "o_icon" !default; .o_mi_qtisc:before { content: $fa-var-dot-circle-o; } .o_mi_qtimatch:before { content: $fa-var-table; } .o_mi_qtimatch_draganddrop:before { content: $fa-var-clone; } +.o_mi_qtimatch_truefalse:before { content: $fa-var-list-ol; } .o_mi_qtimc:before { content: $fa-var-check-square-o; } .o_mi_qtikprim:before { content: $fa-var-check-square; } .o_mi_qtifib:before { content: $fa-var-ellipsis-h; } diff --git a/src/main/webapp/static/themes/light/modules/_qti21.scss b/src/main/webapp/static/themes/light/modules/_qti21.scss index 746cee42ba4687bc1286d117b46a34cfbb39b2bc..acf88255f843db3d9922e4b1155cc912d07e31ae 100644 --- a/src/main/webapp/static/themes/light/modules/_qti21.scss +++ b/src/main/webapp/static/themes/light/modules/_qti21.scss @@ -866,6 +866,53 @@ tr.choiceinteraction { } } +/* Match true/false */ +.table.o_match_true_false_edit { + th.o_sel_match_target_0, th.o_sel_match_target_1, th.o_sel_match_target_2 { + width: 12%; + } +} + +.match_true_false { + + input[type="checkbox"] { + -webkit-appearance: radio; + -moz-appearance: radio; + -ms-appearance: radio; + appearance: radio; + } + + .table>tbody>tr>td.o_match_true_false_unanswered, + .table>tbody>tr>td.o_match_true_false_right, + .table>tbody>tr>td.o_match_true_false_wrong { + vertical-align: middle; + width: 11%; + } + + th.o_match_true_false_unanswered, + th.o_match_true_false_right, + th.o_match_true_false_wrong { + width: 11%; + } + + td.o_match_true_false_answer, + th.o_match_true_false_answer { + width: 67%; + } + + td.o_match_true_false_unanswered { + background-color: $o-qti-match-true-false-unanswered-bg; + } + + td.o_match_true_false_right { + background-color: $o-qti-match-true-false-right-bg; + } + + td.o_match_true_false_wrong { + background-color: $o-qti-match-true-false-wrong-bg; + } +} + /* MathEntryInteraction styling for MathAssess */ .o_assessmentitem .mathEntryInteraction { border: 1px solid #ddedfc; diff --git a/src/main/webapp/static/themes/openolat/content.css.map b/src/main/webapp/static/themes/openolat/content.css.map index ced71d8c4e1e1ec9be1733241d9a22f739fdfd58..3b26712a57c9247d51836102c73f0480e6080b9c 100644 --- a/src/main/webapp/static/themes/openolat/content.css.map +++ b/src/main/webapp/static/themes/openolat/content.css.map @@ -1,6 +1,6 @@ { "version": 3, -"mappings": "CAEA;;;;;;;;;;;;;;;;;;;;;;;;IAwBG,DC1BH,4DAA4D,AAQ5D,IAAK,CACH,WAAW,CAAE,UAAU,CACvB,oBAAoB,CAAE,IAAI,CAC1B,wBAAwB,CAAE,IAAI,CAOhC,IAAK,CACH,MAAM,CAAE,CAAC,CAaX,0FAYQ,CACN,OAAO,CAAE,KAAK,CAQhB,2BAGM,CACJ,OAAO,CAAE,YAAY,CACrB,cAAc,CAAE,QAAQ,CAQ1B,qBAAsB,CACpB,OAAO,CAAE,IAAI,CACb,MAAM,CAAE,CAAC,CAQX,iBACS,CACP,OAAO,CAAE,IAAI,CAUf,CAAE,CACA,gBAAgB,CAAE,WAAW,CAO/B,gBACQ,CACN,OAAO,CAAE,CAAC,CAUZ,WAAY,CACV,aAAa,CAAE,UAAU,CAO3B,QACO,CACL,WAAW,CAAE,IAAI,CAOnB,GAAI,CACF,UAAU,CAAE,MAAM,CAQpB,EAAG,CACD,SAAS,CAAE,GAAG,CACd,MAAM,CAAE,QAAQ,CAOlB,IAAK,CACH,UAAU,CAAE,IAAI,CAChB,KAAK,CAAE,IAAI,CAOb,KAAM,CACJ,SAAS,CAAE,GAAG,CAOhB,OACI,CACF,SAAS,CAAE,GAAG,CACd,WAAW,CAAE,CAAC,CACd,QAAQ,CAAE,QAAQ,CAClB,cAAc,CAAE,QAAQ,CAG1B,GAAI,CACF,GAAG,CAAE,MAAM,CAGb,GAAI,CACF,MAAM,CAAE,OAAO,CAUjB,GAAI,CACF,MAAM,CAAE,CAAC,CAOX,cAAe,CACb,QAAQ,CAAE,MAAM,CAUlB,MAAO,CACL,MAAM,CAAE,QAAQ,CAOlB,EAAG,CACD,eAAe,CAAE,WAAW,CAC5B,UAAU,CAAE,WAAW,CACvB,MAAM,CAAE,CAAC,CAOX,GAAI,CACF,QAAQ,CAAE,IAAI,CAOhB,iBAGK,CACH,WAAW,CAAE,oBAAoB,CACjC,SAAS,CAAE,GAAG,CAkBhB,qCAIS,CACP,KAAK,CAAE,OAAO,CACd,IAAI,CAAE,OAAO,CACb,MAAM,CAAE,CAAC,CAOX,MAAO,CACL,QAAQ,CAAE,OAAO,CAUnB,aACO,CACL,cAAc,CAAE,IAAI,CAWtB,yEAGqB,CACnB,kBAAkB,CAAE,MAAM,CAC1B,MAAM,CAAE,OAAO,CAOjB,qCACqB,CACnB,MAAM,CAAE,OAAO,CAOjB,gDACwB,CACtB,MAAM,CAAE,CAAC,CACT,OAAO,CAAE,CAAC,CAQZ,KAAM,CACJ,WAAW,CAAE,MAAM,CAWrB,0CACoB,CAClB,UAAU,CAAE,UAAU,CACtB,OAAO,CAAE,CAAC,CASZ,+FACgD,CAC9C,MAAM,CAAE,IAAI,CASd,oBAAqB,CACnB,kBAAkB,CAAE,SAAS,CAC7B,eAAe,CAAE,WAAW,CAC5B,kBAAkB,CAAE,WAAW,CAC/B,UAAU,CAAE,WAAW,CASzB,kGACgD,CAC9C,kBAAkB,CAAE,IAAI,CAO1B,QAAS,CACP,MAAM,CAAE,iBAAiB,CACzB,MAAM,CAAE,KAAK,CACb,OAAO,CAAE,qBAAqB,CAQhC,MAAO,CACL,MAAM,CAAE,CAAC,CACT,OAAO,CAAE,CAAC,CAOZ,QAAS,CACP,QAAQ,CAAE,IAAI,CAQhB,QAAS,CACP,WAAW,CAAE,IAAI,CAUnB,KAAM,CACJ,eAAe,CAAE,QAAQ,CACzB,cAAc,CAAE,CAAC,CAGnB,KACG,CACD,OAAO,CAAE,CAAC,CCzaZ,qFAAqF,AAOrF,YAAa,CACT,kBAEQ,CACJ,UAAU,CAAE,sBAAsB,CAClC,KAAK,CAAE,eAAe,CACtB,UAAU,CAAE,eAAe,CAC3B,WAAW,CAAE,eAAe,CAGhC,WACU,CACN,eAAe,CAAE,SAAS,CAG9B,aAAc,CACV,OAAO,CAAE,mBAAmB,CAGhC,iBAAkB,CACd,OAAO,CAAE,oBAAoB,CAKjC,+CAC6B,CACzB,OAAO,CAAE,EAAE,CAGf,cACW,CACP,MAAM,CAAE,cAAc,CACtB,iBAAiB,CAAE,KAAK,CAG5B,KAAM,CACF,OAAO,CAAE,kBAAkB,CAG/B,MACI,CACA,iBAAiB,CAAE,KAAK,CAG5B,GAAI,CACA,SAAS,CAAE,eAAe,CAG9B,OAEG,CACC,OAAO,CAAE,CAAC,CACV,MAAM,CAAE,CAAC,CAGb,KACG,CACC,gBAAgB,CAAE,KAAK,CAO3B,MAAO,CACH,UAAU,CAAE,eAAe,CAI/B,OAAQ,CACJ,OAAO,CAAE,IAAI,CAIb,+BAAS,CACL,gBAAgB,CAAE,eAAe,CAGzC,MAAO,CACH,MAAM,CAAE,cAAc,CAG1B,MAAO,CACH,eAAe,CAAE,mBAAmB,CAEpC,mBACG,CACC,gBAAgB,CAAE,eAAe,CAIrC,qCACG,CACC,MAAM,CAAE,yBAAyB,EC3F7C,CAAE,CCgEA,kBAAkB,CD/DE,UAAU,CCgE3B,eAAe,CDhEE,UAAU,CCiEtB,UAAU,CDjEE,UAAU,CAEhC,gBACQ,CC4DN,kBAAkB,CD3DE,UAAU,CC4D3B,eAAe,CD5DE,UAAU,CC6DtB,UAAU,CD7DE,UAAU,CAMhC,IAAK,CACH,SAAS,CAAE,IAAI,CACf,2BAA2B,CAAE,WAAa,CAG5C,IAAK,CACH,WAAW,CESkB,2CAAiB,CFR9C,SAAS,CG2Be,IAAI,CH1B5B,WAAW,CGsCa,WAAW,CHrCnC,KAAK,CE4gBmB,IAAW,CF3gBnC,gBAAgB,CE0gBM,IAAQ,CFtgBhC,4BAGS,CACP,WAAW,CAAE,OAAO,CACpB,SAAS,CAAE,OAAO,CAClB,WAAW,CAAE,OAAO,CAMtB,CAAE,CACA,KAAK,CEomB8B,OAAc,CFnmBjD,eAAe,CAAE,IAAI,CAErB,eACQ,CACN,KAAK,CEyawB,OAAiB,CFxa9C,eAAe,CGZK,SAAS,CHe/B,OAAQ,CIrDR,OAAO,CAAE,WAAW,CAEpB,OAAO,CAAE,iCAAiC,CAC1C,cAAc,CAAE,IAAI,CJ6DtB,MAAO,CACL,MAAM,CAAE,CAAC,CAMX,GAAI,CACF,cAAc,CAAE,MAAM,CAIxB,eAAgB,CKvEd,OAAO,CADuB,KAAK,CAEnC,SAAS,CAAE,IAAI,CACf,MAAM,CAAE,IAAI,CL0Ed,YAAa,CACX,aAAa,CG2Ba,GAAG,CHrB/B,cAAe,CACb,OAAO,CGwoBqB,GAAG,CHvoB/B,WAAW,CG3Ba,WAAW,CH4BnC,gBAAgB,CE0cM,IAAQ,CFzc9B,MAAM,CAAE,cAA2B,CACnC,aAAa,CEnCgB,GAAwB,CD2HrD,kBAAkB,CAAE,oBAAW,CAC1B,aAAa,CAAE,oBAAW,CACvB,UAAU,CAAE,oBAAW,CIlL/B,OAAO,CL4FiB,YAAY,CK3FpC,SAAS,CAAE,IAAI,CACf,MAAM,CAAE,IAAI,CL8Fd,WAAY,CACV,aAAa,CAAE,GAAG,CAMpB,EAAG,CACD,UAAU,CEqFgB,IAAqB,CFpF/C,aAAa,CEoFa,IAAqB,CFnF/C,MAAM,CAAE,CAAC,CACT,UAAU,CAAE,cAAoB,CAQlC,QAAS,CACP,QAAQ,CAAE,QAAQ,CAClB,KAAK,CAAE,GAAG,CACV,MAAM,CAAE,GAAG,CACX,MAAM,CAAE,IAAI,CACZ,OAAO,CAAE,CAAC,CACV,QAAQ,CAAE,MAAM,CAChB,IAAI,CAAE,gBAAa,CACnB,MAAM,CAAE,CAAC,CAQT,kDACQ,CACN,QAAQ,CAAE,MAAM,CAChB,KAAK,CAAE,IAAI,CACX,MAAM,CAAE,IAAI,CACZ,MAAM,CAAE,CAAC,CACT,QAAQ,CAAE,OAAO,CACjB,IAAI,CAAE,IAAI,CM3Id,yCAC6B,CAC3B,WAAW,CH8Da,OAAO,CG7D/B,WAAW,CH8Da,GAAG,CG7D3B,WAAW,CH8Da,GAAG,CG7D3B,KAAK,CH8DmB,OAAO,CG5D/B,+OACO,CACL,WAAW,CAAE,MAAM,CACnB,WAAW,CAAE,CAAC,CACd,KAAK,CJkmB0B,IAAW,CI9lB9C,oBAEQ,CACN,UAAU,CJ4KgB,IAAqB,CI3K/C,aAAa,CAAE,IAA2B,CAE1C,uHACO,CACL,SAAS,CAAE,GAAG,CAGlB,oBAEQ,CACN,UAAU,CAAE,IAA2B,CACvC,aAAa,CAAE,IAA2B,CAE1C,uHACO,CACL,SAAS,CAAE,GAAG,CAIlB,MAAQ,CAAE,SAAS,CHaO,IAA8B,CGZxD,MAAQ,CAAE,SAAS,CHaO,IAA+B,CGZzD,MAAQ,CAAE,SAAS,CHaO,IAA6B,CGZvD,MAAQ,CAAE,SAAS,CHaO,IAA8B,CGZxD,MAAQ,CAAE,SAAS,CHaO,IAAe,CGZzC,MAAQ,CAAE,SAAS,CHaO,IAA8B,CGPxD,CAAE,CACA,MAAM,CAAE,QAA+B,CAGzC,KAAM,CACJ,aAAa,CJwIa,IAAqB,CIvI/C,SAAS,CAAE,IAA+B,CAC1C,WAAW,CAAE,GAAG,CAChB,WAAW,CAAE,GAAG,CAEhB,yBAAmC,CANrC,KAAM,CAOF,SAAS,CAAE,IAAuB,EAStC,YACO,CACL,SAAS,CAAE,GAAkD,CAG/D,UACM,CACJ,gBAAgB,CJkcK,OAAiB,CIjctC,OAAO,CAAE,IAAI,CAIf,UAAqB,CAAE,UAAU,CAAE,IAAI,CACvC,WAAqB,CAAE,UAAU,CAAE,KAAK,CACxC,YAAqB,CAAE,UAAU,CAAE,MAAM,CACzC,aAAqB,CAAE,UAAU,CAAE,OAAO,CAC1C,YAAqB,CAAE,WAAW,CAAE,MAAM,CAG1C,eAAqB,CAAE,cAAc,CAAE,SAAS,CAChD,eAAqB,CAAE,cAAc,CAAE,SAAS,CAChD,gBAAqB,CAAE,cAAc,CAAE,UAAU,CAGjD,WAAY,CACV,KAAK,CJ+gB4B,IAAW,CKjnB5C,aAAW,CACT,KAAK,CL+oB4B,OAAc,CK7oBjD,oBAAkB,CAChB,KAAK,CAAE,OAAmB,CAJ5B,aAAW,CACT,KAAK,CLghBgB,OAAmB,CK9gB1C,oBAAkB,CAChB,KAAK,CAAE,OAAmB,CAJ5B,UAAW,CACT,KAAK,CL4gBc,OAAgB,CK1gBrC,iBAAkB,CAChB,KAAK,CAAE,OAAmB,CAJ5B,aAAW,CACT,KAAK,CLkhBgB,OAAmB,CKhhB1C,oBAAkB,CAChB,KAAK,CAAE,OAAmB,CAJ5B,YAAW,CACT,KAAK,CLohBe,OAAkB,CKlhBxC,mBAAkB,CAChB,KAAK,CAAE,OAAmB,CD8G9B,WAAY,CAGV,KAAK,CAAE,IAAI,CErHX,WAAW,CACT,gBAAgB,CN+oBiB,OAAc,CM7oBjD,kBAAkB,CAChB,gBAAgB,CAAE,OAAmB,CAJvC,WAAW,CACT,gBAAgB,CN+gBG,OAAiB,CM7gBtC,kBAAkB,CAChB,gBAAgB,CAAE,OAAmB,CAJvC,QAAW,CACT,gBAAgB,CN2gBC,OAAc,CMzgBjC,eAAkB,CAChB,gBAAgB,CAAE,OAAmB,CAJvC,WAAW,CACT,gBAAgB,CNihBG,OAAiB,CM/gBtC,kBAAkB,CAChB,gBAAgB,CAAE,OAAmB,CAJvC,UAAW,CACT,gBAAgB,CNmhBE,OAAgB,CMjhBpC,iBAAkB,CAChB,gBAAgB,CAAE,OAAmB,CFiIzC,YAAa,CACX,cAAc,CAAE,GAAiC,CACjD,MAAM,CAAE,WAAmD,CAC3D,aAAa,CAAE,cAAmC,CAQpD,KACG,CACD,UAAU,CAAE,CAAC,CACb,aAAa,CAAE,IAA2B,CAC1C,uBACG,CACD,aAAa,CAAE,CAAC,CAYpB,cAAe,CAJb,YAAY,CAAE,CAAC,CACf,UAAU,CAAE,IAAI,CASlB,YAAa,CAVX,YAAY,CAAE,CAAC,CACf,UAAU,CAAE,IAAI,CAWhB,WAAW,CAAE,IAAI,CAEjB,eAAK,CACH,OAAO,CAAE,YAAY,CACrB,YAAY,CAAE,GAAG,CACjB,aAAa,CAAE,GAAG,CAKtB,EAAG,CACD,UAAU,CAAE,CAAC,CACb,aAAa,CJYa,IAAqB,CIVjD,KACG,CACD,WAAW,CH3Ha,WAAW,CG6HrC,EAAG,CACD,WAAW,CAAE,IAAI,CAEnB,EAAG,CACD,WAAW,CAAE,CAAC,CGvLd,gDACQ,CACN,OAAO,CAAE,GAAG,CACZ,OAAO,CAAE,KAAK,CAEhB,uBAAQ,CACN,KAAK,CAAE,IAAI,CH8Lb,yBAA2C,CACzC,iBAAG,CACD,KAAK,CAAE,IAAI,CACX,KAAK,CAAE,KAA4B,CACnC,KAAK,CAAE,IAAI,CACX,UAAU,CAAE,KAAK,CIlNrB,QAAQ,CAAE,MAAM,CAChB,aAAa,CAAE,QAAQ,CACvB,WAAW,CAAE,MAAM,CJmNjB,iBAAG,CACD,WAAW,CHmoBa,KAA4B,EGznB1D,qCAE0B,CACxB,MAAM,CAAE,IAAI,CACZ,aAAa,CAAE,eAA6B,CAE9C,WAAY,CACV,SAAS,CAAE,GAAG,CACd,cAAc,CAAE,SAAS,CAI3B,UAAW,CACT,OAAO,CAAE,SAAiD,CAC1D,MAAM,CAAE,QAAyB,CACjC,SAAS,CHomBoB,MAAsB,CGnmBnD,WAAW,CAAE,cAAkC,CAK7C,yEAAa,CACX,aAAa,CAAE,CAAC,CAMpB,oDAEO,CACL,OAAO,CAAE,KAAK,CACd,SAAS,CAAE,GAAG,CACd,WAAW,CHlMW,WAAW,CGmMjC,KAAK,CJ+W0B,IAAW,CI7W1C,yEAAS,CACP,OAAO,CAAE,aAAa,CAQ5B,yCACsB,CACpB,aAAa,CAAE,IAAI,CACnB,YAAY,CAAE,CAAC,CACf,YAAY,CAAE,cAAkC,CAChD,WAAW,CAAE,CAAC,CACd,UAAU,CAAE,KAAK,CAMf,+MAAS,CAAE,OAAO,CAAE,EAAE,CACtB,yMAAQ,CACN,OAAO,CAAE,aAAa,CAM5B,OAAQ,CACN,aAAa,CJhGa,IAAqB,CIiG/C,UAAU,CAAE,MAAM,CAClB,WAAW,CHrOa,WAAW,CQhErC,UAWC,CAVC,WAAW,CAAE,aAAa,CAC1B,GAAG,CAAE,+DAAgE,CACrE,GAAG,CAAE,wbAI8F,CAEnG,WAAW,CAAE,MAAM,CACnB,UAAU,CAAE,MAAM,CCVpB,OAAmB,CACjB,OAAO,CAAE,YAAY,CACrB,IAAI,CAAE,uCAA8E,CACpF,SAAS,CAAE,OAAO,CAClB,cAAc,CAAE,IAAI,CACpB,sBAAsB,CAAE,WAAW,CACnC,uBAAuB,CAAE,SAAS,CCJpC,+DAAiC,CAChC,aAAa,CAAE,GAAG,CAEnB,qCAA2B,CAC1B,UAAU,CAAE,GAAG,CAMhB,oCAA6C,CAC5C,aAAa,CAAE,KAAK,CAErB,iCAAuC,CACtC,UAAU,CAAE,KAAK,CAMlB,oCAA6C,CAC5C,aAAa,CAAE,GAAG,CAEnB,iCAAuC,CACtC,UAAU,CAAE,GAAG,CAMhB,+EAAiC,CAChC,OAAO,CAAE,YAAY,CAEtB,yCAA2C,CAE1C,WAAW,CAAE,KAAK,CAGnB,0CAA6C,CAE5C,YAAY,CAAE,KAAK,CAQpB,yBAA0B,CACzB,OAAO,CAAE,KAAK,CACd,KAAK,CAAE,IAAI,CACX,MAAM,CAAE,IAAI,CAEb,yBAA0B,CACzB,OAAO,CAAE,UAAU,CACnB,cAAc,CAAE,MAAM,CACtB,UAAU,CAAE,MAAM,CAInB,gBAAiB,CAChB,iBAAiB,CAAC,SAAS,CAC3B,mBAAmB,CAAE,MAAM,CAC3B,eAAe,CAAE,KAAK,CACtB,qBAAK,CACJ,OAAO,CAAE,GAAG,CACZ,gBAAgB,CXwmBY,qBAAwB,CWrmBrD,sHACE,CACD,OAAO,CAAE,GAAG,CACZ,gBAAgB,CXkmBY,qBAAwB,CWjmBpD,OAAO,CAAE,YAAY,CACrB,0JAAQ,CACP,OAAO,CAAE,GAAG,CACZ,OAAO,CAAE,KAAK,CAOjB,gCAA+B,CAE9B,UAAU,CAAE,IAAI,CAChB,UAAU,CAAE,MAAM,CAEf,kBAAkB,CAAE,wBAAwB,CAC5C,0BAA0B,CAAE,KAAK,CAIrC,eAAgB,CAEf,UAAU,CAAE,MAAM,CAClB,yFAA6B,CAC5B,YAAY,CAAE,GAAG,CACjB,aAAa,CAAE,KAAK,CACpB,qIAAa,CACZ,YAAY,CAAE,CAAC,CAIhB,+FAAiB,CAChB,YAAY,CAAE,CAAC,CACf,aAAa,CAAE,CAAC,CAGlB,8BAAe,CACd,UAAU,CAAE,IAAI,CAIlB,oBAAqB,CACpB,UAAU,CAAE,IAAI,CAEjB,qBAAsB,CACrB,UAAU,CAAE,KAAK,CAElB,mBAAoB,CACnB,UAAU,CAAE,CAAC,CJjHZ,0DACQ,CACN,OAAO,CAAE,GAAG,CACZ,OAAO,CAAE,KAAK,CAEhB,4BAAQ,CACN,KAAK,CAAE,IAAI,CIiHd,2JAAuB,CACtB,OAAO,CAAE,YAAY,CAEtB,sCAAgB,CACf,aAAa,CAAE,CAAC,CAChB,KAAK,CAAE,KAAK,CAGb,yCAAoB,CAClB,UAAU,CAAE,IAA6B,CAE3C,yCAAoB,CAClB,UAAU,CAAE,IAA6B,CAE3C,yCAAoB,CAClB,UAAU,CXmDe,IAAqB,CWjDhD,yCAAoB,CAClB,UAAU,CAAE,IAA2B,CAEzC,yCAAoB,CAClB,UAAU,CAAE,cAA2B,CAEzC,yCAAoB,CAClB,UAAU,CAAE,GAA2B,CAI1C,wDAA0D,CACzD,UAAU,CAAE,CAAC,CAGd,oCAAqC,CACpC,aAAa,CAAE,CAAC,CAKhB,0BAAS,CAAC,OAAO,CAAC,GAAG,CACrB,yBAAQ,CAAC,OAAO,CAAC,GAAG,CAKrB,cAAe,CACd,iBAAiB,CAAC,SAAS,CAC3B,mBAAmB,CAAE,MAAM,CAC3B,eAAe,CAAE,KAAK,CAEtB,2CAA+B,CAC9B,gBAAgB,CXyfY,qBAAwB,CWxfpD,aAAa,CAAE,WAAW,CAE3B,+BAAiB,CAChB,OAAO,CAAE,GAAG,CACZ,gBAAgB,CXofY,qBAAwB,CW/etD,kBAAmB,CAClB,YAAY,CXocuB,GAAG,CWnctC,YAAY,CAAE,MAAM,CACpB,YAAY,CXscuB,OAAwC,CWrc3E,aAAa,CXkcuB,IAAI,CWhcxC,8BAAY,CACX,OAAO,CXmcuB,IAAI,CWlclC,6CAAiB,CAChB,UAAU,CAAE,IAAI,CAEjB,4IAEgB,CACf,UAAU,CAAE,CAAC,CAGd,8CAAgB,CACf,aAAa,CAAE,CAAC,CAGlB,iCAAe,CACd,uBAAuB,CAAE,GAAwE,CACjG,sBAAsB,CAAE,GAAwE,CAChG,YAAY,CX6asB,GAAG,CW5arC,YAAY,CAAE,MAAM,CACpB,YAAY,CX+asB,OAAwC,CW9a1E,UAAU,CAAE,IAAI,CAChB,WAAW,CAAE,IAAI,CACjB,YAAY,CAAE,IAAI,CAClB,KAAK,CXsb8B,OAAc,CWrbjD,WAAW,CXyasB,IAAI,CWvatC,gCAAc,CACb,0BAA0B,CAAE,GAAwE,CACpG,yBAAyB,CAAE,GAAwE,CACnG,YAAY,CXiasB,GAAG,CWharC,YAAY,CAAE,MAAM,CACpB,YAAY,CXmasB,OAAwC,CWla1E,aAAa,CAAE,IAAI,CACnB,WAAW,CAAE,IAAI,CACjB,YAAY,CAAE,IAAI,CASpB,2CAAqB,CACpB,SAAS,CXiXY,IAAgB,CW/WtC,uCAAmB,CAClB,SAAS,CX8WY,IAAgB,CW5WtC,uCAAmB,CAClB,SAAS,CXoZiB,IAAgB,CWlZ3C,2CAAqB,CACpB,SAAS,CXiZiB,IAAgB,CW7Y3C,mDAAyB,CACxB,KAAK,CAAE,eAAoC,CAK3C,MAAM,CAAE,OAAO,CAJf,mCAAO,CACN,KAAK,CAAE,eAAoC,CAM7C,2CAAqB,CCtQnB,OAAO,CDuQS,EAAE,CCpQlB,MAAM,CAAE,iBAA6B,CDuQvC,mDAAyB,CACxB,WAAW,CAAE,IAAI,CAGlB,+CAAuB,CACtB,eAAe,CAAE,YAAY,CAG9B,2BAA4B,CAC3B,gBAAgB,CXgO6B,OAAe,CW5N7D,YAA2B,CAC1B,MAAM,CAAE,OAAO,CAIhB,QAAS,CAAE,KAAK,CAAE,OAAO,CACzB,OAAQ,CAAE,KAAK,CAAE,OAAO,CAKvB,iHAAgB,CACf,eAAe,CAAE,IAAI,CAKvB,gEAA2B,CACxB,WAAW,CVxPY,6CAAiD,CUyPxE,OAAO,CAAE,OAAO,CAChB,SAAS,CAAE,GAAG,CACd,KAAK,CV6gBsB,OAAO,CU5gBnC,gBAAgB,CV6gBY,OAAO,CU5gBlC,aAAa,CVjMY,GAAG,CUmM5B,iIAAe,CACd,MAAM,CAAE,CAAC,CACT,KAAK,CAAE,GAAG,CACV,UAAU,CAAE,WAAW,CAK3B,yDAAqB,CACpB,WAAW,CAAE,MAAM,CACnB,QAAQ,CAAE,MAAM,CAChB,aAAa,CAAE,QAAQ,CAKvB,4BAAW,CACV,UAAU,CAAE,IAA2B,CAKzC,iDAAqD,CRhUnD,OAAO,CQiUgB,YAAY,CRhUnC,SAAS,CAAE,IAAI,CACf,MAAM,CAAE,IAAI,CQgUb,SAAS,CAAE,IAAI,CAEhB,kCAAiC,CRpU/B,OAAO,CQqUgB,YAAY,CRpUnC,SAAS,CAAE,IAAI,CACf,MAAM,CAAE,IAAI,CQoUb,SAAS,CAAE,IAAI,CAIhB,wBAAyB,CACxB,OAAO,CAAE,YAAY,CACrB,SAAS,CAAE,GAAG,CACd,+BAAO,CACN,OAAO,CAAE,KAAK,CAEf,mCAAW,CACV,OAAO,CAAE,aAAa,CACtB,YAAY,CAAE,MAAM,CACpB,SAAS,CAAE,GAAG,CACd,UAAU,CAAE,MAAM,CAClB,UAAU,CAAE,MAAM,CAMpB,+BAAgC,CAC/B,OAAO,CAAE,YAAY,CAClB,MAAM,CAAE,IAAI,CACZ,cAAc,CAAE,MAAM,CACtB,4CAAgB,CACf,cAAc,CAAE,MAAM,CAK3B,eAAiC,CAChC,eAAe,CAAE,IAAI,CACrB,YAAY,CAAE,IAAI,CAClB,WAAW,CAAE,IAAI,CACjB,OAAO,CAAE,IAAI,CEjXd,mCAAiB,CCChB,MAAM,CAAE,MAAe,CACvB,OAAO,CdygBa,IAAI,CcxgBxB,WAAW,CAAE,cAAyC,CACtD,gBAAgB,CdygBI,IAAa,CcxgBjC,uFAAe,CAAE,KAAK,Cd+mBY,IAAW,CajnB9C,mCAAiB,CCFhB,MAAM,CAAE,MAAe,CACvB,OAAO,CdygBa,IAAI,CcxgBxB,WAAW,CAAE,iBAAyC,CACtD,gBAAgB,Cd2gBI,OAAc,Cc1gBlC,uFAAe,CAAE,KAAK,Cd2gBA,OAAgB,Ca1gBvC,uDAA2B,CCL1B,MAAM,CAAE,MAAe,CACvB,OAAO,CdygBa,IAAI,CcxgBxB,WAAW,CAAE,iBAAyC,CACtD,gBAAgB,Cd6gBQ,OAAO,Cc5gB/B,+HAAe,CAAE,KAAK,Cd6gBI,OAAO,CazgBlC,+CAAuB,CCRtB,MAAM,CAAE,MAAe,CACvB,OAAO,CdygBa,IAAI,CcxgBxB,WAAW,CAAE,iBAAyC,CACtD,gBAAgB,Cd+gBM,OAAiB,Cc9gBvC,+GAAe,CAAE,KAAK,Cd+gBE,OAAmB,CaxgB5C,8DAAuB,CCXtB,MAAM,CAAE,MAAe,CACvB,OAAO,CdygBa,IAAI,CcxgBxB,WAAW,CAAE,iBAAyC,CACtD,gBAAgB,CdihBM,OAAiB,CchhBvC,uLAAe,CAAE,KAAK,CdihBE,OAAmB,CavgB5C,uCAAmB,CCdlB,MAAM,CAAE,MAAe,CACvB,OAAO,CdygBa,IAAI,CcxgBxB,WAAW,CAAE,iBAAyC,CACtD,gBAAgB,CdmhBK,OAAgB,CclhBrC,+FAAe,CAAE,KAAK,CdmhBC,OAAkB,CatgB1C,cAAe,CAEd,UAAU,CAAE,GAAG,CACf,WAAW,CAAE,IAAI,CACjB,WAAW,CAAE,IAAI,CACjB,cAAc,CAAE,IAAI,CAErB,8BAAiC,CAChC,aAAa,CAAE,GAAG,CAInB,qBAAsB,CACrB,QAAQ,CAAE,KAAK,CACf,GAAG,CAAE,CAAC,CAAE,IAAI,CAAE,CAAC,CACf,KAAK,CAAC,IAAI,CAAE,MAAM,CAAC,IAAI,CACvB,IAAI,CAAC,CAAC,CACN,UAAU,CAAE,IAAI,CDjCf,OAAO,CCkCS,CAAC,CD/BjB,MAAM,CAAE,gBAA6B,CCmCvC,aAAc,CACb,QAAQ,CAAE,KAAK,CACf,GAAG,CAAE,KAAK,CACV,IAAI,CAAE,CAAC,CACP,OAAO,CAAE,IAAI,CACZ,OAAO,CAAE,IAAI,CACb,KAAK,CAAE,IAAI,CACX,UAAU,CAAE,MAAM,CAElB,oBAAO,CACP,QAAQ,CAAE,QAAQ,CAClB,KAAK,CAAE,IAAI,CACX,MAAM,CAAC,MAAM,CACb,UAAU,CAAE,IAAI,CdchB,kBAAkB,CAAE,iCAAO,CACnB,UAAU,CAAE,iCAAO,CcZ3B,mCAAe,CACd,KAAK,CAAE,KAAK,CACZ,KAAK,Cb0jB2B,IAAW,CazjB3C,yCAAQ,CACP,KAAK,CbilBe,IAAoB,Ca9kB1C,yBAAmC,CAdnC,oBAAO,CAgBH,KAAK,CZiiBmB,KAAK,EY3hBnC,mCAAqC,CACpC,QAAQ,CAAE,QAAQ,CAClB,KAAK,Cb+ckB,OAAkB,Ca9czC,gBAAgB,Cb6cK,OAAgB,Ca5crC,MAAM,CAAE,iBAA8B,CACtC,OAAO,CAAE,mBAAmG,CAC5G,UAAU,CAAE,IAAyB,CAErC,MAAM,CAAE,cAAgD,CAExD,qEAAiB,CAChB,QAAQ,CAAE,QAAQ,CAClB,IAAI,CAAE,IAAgC,CACtC,GAAG,CAAE,GAAgC,CACrC,SAAS,CAAE,IAAyB,CAGrC,mFAA0B,CACzB,UAAU,CAAE,CAAC,CAOb,yBAAmC,CADpC,yBAAmB,CAEjB,KAAK,CAAE,GAAG,EAEX,yBAAmC,CAJpC,yBAAmB,CAKjB,KAAK,CAAE,GAAG,EAGZ,uBAAiB,CAChB,KAAK,Cb2iB8B,OAAc,Ca1iB/C,WAAW,CbiWgB,GAAqB,CahWlD,WAAW,CZnCa,OAAO,CYoC7B,WAAW,CZlCW,GAAG,CczE7B,qBAA0B,CAAC,UAAU,CAAG,+CAAgD,CAAE,KAAK,CAAE,IAAI,CAAE,MAAM,CAAE,IAAI,CACnH,qBAA0B,CAAC,UAAU,CAAG,6CAA8C,CAAE,KAAK,CAAE,IAAI,CAAE,MAAM,CAAE,IAAI,CACjH,wBAA0B,CAAC,UAAU,CAAG,6CAA8C,CAAE,KAAK,CAAE,IAAI,CAAE,MAAM,CAAE,IAAI,CACjH,wBAA0B,CAAC,UAAU,CAAG,iDAAkD,CAAE,KAAK,CAAE,IAAI,CAAE,MAAM,CAAE,IAAI,CACrH,oBAA0B,CAAC,UAAU,CAAG,8CAA+C,CAAE,KAAK,CAAE,IAAI,CAAE,MAAM,CAAE,IAAI,CAClH,mBAA0B,CAAC,UAAU,CAAG,6CAA8C,CAAE,KAAK,CAAE,IAAI,CAAE,MAAM,CAAE,IAAI,CACjH,qBAA0B,CAAC,UAAU,CAAG,8CAA+C,CAAE,KAAK,CAAE,IAAI,CAAE,MAAM,CAAE,IAAI,CAClH,oBAA0B,CAAC,UAAU,CAAG,8CAA+C,CAAE,KAAK,CAAE,IAAI,CAAE,MAAM,CAAE,IAAI,CAClH,oBAA0B,CAAC,UAAU,CAAG,8CAA+C,CAAE,KAAK,CAAE,IAAI,CAAE,MAAM,CAAE,IAAI,CAClH,oBAA0B,CAAC,UAAU,CAAG,6CAA8C,CAAE,KAAK,CAAE,IAAI,CAAE,MAAM,CAAE,IAAI,CACjH,mBAA0B,CAAC,UAAU,CAAG,6CAA8C,CAAE,KAAK,CAAE,IAAI,CAAE,MAAM,CAAE,IAAI,CACjH,oBAA0B,CAAC,UAAU,CAAG,kDAAmD,CAAE,KAAK,CAAE,IAAI,CAAE,MAAM,CAAE,IAAI,CACtH,qBAA0B,CAAC,UAAU,CAAG,yCAA0C,CAAE,KAAK,CAAE,IAAI,CAAE,MAAM,CAAE,IAAI,CAC7G,sBAA0B,CAAC,UAAU,CAAG,8CAA+C,CAAE,KAAK,CAAE,IAAI,CAAE,MAAM,CAAE,IAAI,CAClH,oBAA0B,CAAC,UAAU,CAAG,+CAAgD,CAAE,KAAK,CAAE,IAAI,CAAE,MAAM,CAAE,IAAI,CACnH,qBAA0B,CAAC,UAAU,CAAG,8CAA+C,CAAE,KAAK,CAAE,IAAI,CAAE,MAAM,CAAE,IAAI,CAClH,oBAA0B,CAAC,UAAU,CAAG,8CAA+C,CAAE,KAAK,CAAE,IAAI,CAAE,MAAM,CAAE,IAAI,CAClH,uBAA0B,CAAC,UAAU,CAAG,mDAAoD,CAAE,KAAK,CAAE,IAAI,CAAE,MAAM,CAAE,IAAI,CACvH,kBAAwB,CAAC,UAAU,CAAG,2CAA4C,CAAE,KAAK,CAAE,IAAI,CAAE,MAAM,CAAE,IAAI,CAC7G,oBAA0B,CAAC,UAAU,CAAG,wCAAyC,CAAE,KAAK,CAAE,IAAI,CAAE,MAAM,CAAE,IAAI,CCA5G,IAAK,CACH,WAAW,ChBekB,2CAAiB,CgBd9C,SAAS,ChBekB,IAAe,CgBd1C,WAAW,ChBekB,WAAiB,CgBd9C,KAAK,ChBkhBmB,IAAW,CgBjhBnC,gBAAgB,ChBghBM,IAAQ,CgB7gBhC,CAAE,CACA,KAAK,ChBunB8B,OAAc,CgBtnBjD,eAAe,CAAE,IAAI,CAErB,eACQ,CACN,KAAK,ChB4bwB,OAAiB,CgB3b9C,eAAe,ChBSW,SAAS,CgBNrC,OAAQ,CdlCR,OAAO,CAAE,WAAW,CAEpB,OAAO,CAAE,iCAAiC,CAC1C,cAAc,CAAE,IAAI,CcoCtB,EAAG,CACF,KAAK,ChBwmB+B,OAAc,CgBtmBnD,EAAG,CACF,KAAK,ChBqmB+B,OAAc,CgBnmBnD,EAAG,CACF,KAAK,ChBkmB+B,OAAc,CgBhmBnD,EAAG,CACF,KAAK,ChB+lB+B,OAAc,CgB7lBnD,EAAG,CACF,KAAK,ChB4lB+B,OAAc,CgB1lBnD,EAAG,CACF,KAAK,ChBylB+B,OAAc,CgBvlBnD,EAAG,CACF,UAAU,CAAE,cAA4C,CCtDxD,uBAAE,CACD,KAAK,CjB2oB8B,OAAc,CiB1oBjD,eAAe,CAAE,IAAI,CACrB,2DACQ,CACP,KAAK,CjBidyB,OAAiB,CiBhd/C,eAAe,CjB8BY,SAAS,CiBAvC,6CAAgD,CAC/C,MAAM,CAAE,cAAsC,CAC9C,OAAO,CjBcwB,GAAG,CkBzDjC,uBAAuB,ClBwDM,GAAoB,CkBvDhD,sBAAsB,ClBuDM,GAAoB,CkBhDjD,0BAA0B,ClBgDG,GAAoB,CkB/ChD,yBAAyB,ClB+CG,GAAoB,CiBoBlD,QAAG,CACF,cAAc,CAAE,GAAG,CAGpB,YAAS,CACR,KAAK,CAAE,KAAK,CACZ,UAAU,CAAE,WAAW,CACvB,eAAe,CAAE,QAAQ,CACzB,+BAAO,CACN,OAAO,CAAE,OAA2C,CACpD,MAAM,CAAE,cAAiC,CAE1C,qCAAa,CACZ,UAAU,CjBkbQ,IAAa,CiBjb/B,WAAW,CAAE,IAAI,CAGnB,cAAW,CACV,KAAK,CAAE,KAAK,CACZ,UAAU,CAAE,WAAW,CACvB,eAAe,CAAE,QAAQ,CACzB,mCAAO,CACN,OAAO,CAAE,OAA2C,CACpD,MAAM,CAAE,cAAiC,CAE1C,yCAAa,CACZ,UAAU,CjBqaQ,IAAa,CiBpa/B,WAAW,CAAE,IAAI,CAGnB,kBAAe,CACd,KAAK,CAAE,KAAK,CACZ,UAAU,CAAE,WAAW,CACvB,eAAe,CAAE,QAAQ,CACzB,2CAAO,CACN,OAAO,CAAE,OAA2C,CACpD,MAAM,CAAE,CAAC,CAEV,iDAAa,CACZ,WAAW,CAAE,IAAI,CAGnB,YAAS,CACR,KAAK,CAAE,KAAK,CAEb,cAAW,CACV,UAAU,CAAE,WAAW,CACvB,iBAAG,CACF,cAAc,CAAE,MAAM,CAGxB,YAAS,CAlET,eAAe,CAAE,QAAQ,CACzB,+BAAO,CACN,OAAO,CAAE,OAA2C,CACpD,UAAU,CjB2cS,IAAa,CiB1chC,MAAM,CAAE,cAA+B,CAExC,qCAAa,CACZ,UAAU,CAAE,OAAoB,CAChC,WAAW,CAAE,IAAI,CA6DlB,YAAS,CArET,eAAe,CAAE,QAAQ,CACzB,+BAAO,CACN,OAAO,CAAE,OAA2C,CACpD,UAAU,CjB6cS,OAAc,CiB5cjC,MAAM,CAAE,cAA+B,CAExC,qCAAa,CACZ,UAAU,CAAE,OAAoB,CAChC,WAAW,CAAE,IAAI,CAgElB,aAAU,CAxEV,eAAe,CAAE,QAAQ,CACzB,iCAAO,CACN,OAAO,CAAE,OAA2C,CACpD,UAAU,CjBidW,OAAiB,CiBhdtC,MAAM,CAAE,cAA+B,CAExC,uCAAa,CACZ,UAAU,CAAE,OAAoB,CAChC,WAAW,CAAE,IAAI,CAmElB,cAAW,CA3EX,eAAe,CAAE,QAAQ,CACzB,mCAAO,CACN,OAAO,CAAE,OAA2C,CACpD,UAAU,CjBmdW,OAAiB,CiBldtC,MAAM,CAAE,cAA+B,CAExC,yCAAa,CACZ,UAAU,CAAE,OAAoB,CAChC,WAAW,CAAE,IAAI,CAsElB,WAAQ,CA9ER,eAAe,CAAE,QAAQ,CACzB,6BAAO,CACN,OAAO,CAAE,OAA2C,CACpD,UAAU,CjBqdU,OAAgB,CiBpdpC,MAAM,CAAE,cAA+B,CAExC,mCAAa,CACZ,UAAU,CAAE,OAAoB,CAChC,WAAW,CAAE,IAAI,CAwGnB,eAAgB,CACf,UAAU,CAAE,IAAI,CAEjB,eAAgB,CACf,UAAU,CAAE,MAAM,CAEnB,gBAAiB,CAChB,UAAU,CAAE,KAAK,CAElB,kBAAmB,CAClB,UAAU,CAAC,OAAO,CAInB,eAAgB,CACf,KAAK,CjBqd+B,OAAc,CiBpdlD,sBAAS,CHpLR,OAAO,CAAE,YAAY,CACrB,WAAW,CAAE,WAAW,CACxB,UAAU,CAAE,MAAM,CAClB,WAAW,CAAE,MAAM,CACnB,WAAW,CAAE,CAAC,CACd,sBAAsB,CAAE,WAAW,CACnC,uBAAuB,CAAE,SAAS,CGgLlC,aAAa,CAAE,KAAK,CACpB,OAAO,CEwDc,GAAO,CFrD9B,eAAgB,CACf,KAAK,CjB6c+B,OAAc,CiB5clD,sBAAS,CH5LR,OAAO,CAAE,YAAY,CACrB,WAAW,CAAE,WAAW,CACxB,UAAU,CAAE,MAAM,CAClB,WAAW,CAAE,MAAM,CACnB,WAAW,CAAE,CAAC,CACd,sBAAsB,CAAE,WAAW,CACnC,uBAAuB,CAAE,SAAS,CGwLlC,aAAa,CAAE,KAAK,CACpB,OAAO,CEiCW,GAAO,CF7B3B,gBAAiB,CAChB,KAAK,CjBoc+B,OAAc,CiBnclD,uBAAS,CHrMR,OAAO,CAAE,YAAY,CACrB,WAAW,CAAE,WAAW,CACxB,UAAU,CAAE,MAAM,CAClB,WAAW,CAAE,MAAM,CACnB,WAAW,CAAE,CAAC,CACd,sBAAsB,CAAE,WAAW,CACnC,uBAAuB,CAAE,SAAS,CGiMlC,aAAa,CAAE,KAAK,CACpB,OAAO,CEkXM,GAAO,CFxWtB,gBAAiB,CAChB,KAAK,CAAE,IAAI,CACX,MAAM,CAAE,WAAW,CAEpB,sBAAuB,CACtB,KAAK,CAAE,IAAI,CACX,MAAM,CAAE,WAAW,CACnB,OAAO,CAAE,KAAK,CAEf,iBAAkB,CACjB,KAAK,CAAE,KAAK,CACZ,MAAM,CAAE,WAAW,CAEpB,uBAAwB,CACvB,KAAK,CAAE,IAAI,CACX,OAAO,CAAE,KAAK,CACd,MAAM,CAAE,YAAY,CAErB,+BAAgC,CAC/B,KAAK,CAAE,IAAI,CACX,OAAO,CAAE,KAAK,CACd,MAAM,CAAE,OAAO,CAEhB,cAAe,CACd,KAAK,CAAE,IAAI,CACX,OAAO,CAAE,KAAK,CACd,MAAM,CAAE,eAAe,CAExB,YAAa,CACZ,aAAa,CAAE,GAAG,CAEnB,iBAAkB,CACjB,MAAM,CAAE,cAAsC,CAC9C,OAAO,CjBhMwB,GAAG,CkB5DjC,uBAAuB,ClB2DM,GAAwB,CkB1DpD,sBAAsB,ClB0DM,GAAwB,CkBnDrD,0BAA0B,ClBmDG,GAAwB,CkBlDpD,yBAAyB,ClBkDG,GAAwB,CiB+MvD,gBAAiB,CAChB,MAAM,CAAE,YAAqD,CAC7D,SAAS,CAAE,GAAkD,CAC7D,WAAW,ChBxMc,OAAO,CgB0MjC,kBAAmB,CAClB,KAAK,CAAE,IAAI,CACX,MAAM,CAAE,YAAqD,CAC7D,SAAS,CAAE,GAAkD,CAC7D,WAAW,ChB9Mc,OAAO,CgBkNjC,gDAAmD,CAClD,KAAK,CAAE,IAAI,CGtRZ,iBAAkB,CACd,KAAK,CAAE,IAAI,CAGf,kBAAmB,CACf,KAAK,CAAE,KAAK,CAGhB,YAAa,CACT,OAAO,CAAE,YAAY,CACrB,MAAM,CAAE,cAAc,CACtB,MAAM,CAAE,WAAW,CACnB,UAAU,CAAE,OAAO,CAGvB,gBAAiB,CACb,MAAM,CAAE,aAAa,CAGzB,uBAAwB,CACpB,MAAM,CAAE,eAAe,CACvB,UAAU,CAAE,MAAM,CAOtB,cAAe,CACX,KAAK,CAAE,IAAI,CAGf,eAAgB,CACZ,KAAK,CAAE,KAAK,CAIhB,QAAS,CACL,MAAM,CAAE,cAAc,CAG1B,WAAY,CACR,MAAM,CAAE,GAAG,CAGf,WAAY,CACR,eAAe,CAAE,IAAI,CAQxB,yBAAe,CACd,OAAO,CAAE,KAAK,CACd,UAAU,CAAE,MAAM,CAEnB,uBAAa,CACZ,KAAK,CAAE,IAAI,CACX,OAAO,CAAE,KAAK,CACd,UAAU,CAAE,IAAI,CAChB,kCAAW,CACV,UAAU,CAAE,IAAI,CAGlB,wBAAc,CACb,KAAK,CAAE,IAAI,CACX,OAAO,CAAE,KAAK,CACd,UAAU,CAAE,KAAK,CACjB,mCAAW,CACV,UAAU,CAAE,KAAK,CAMpB,YAAa,CACZ,MAAM,CAAE,WAAW,CAChB,MAAM,CAAE,CAAC,CACT,UAAU,CAAE,IAAI,CAGlB,8MAKa,CACZ,KAAK,CAAE,IAAI,CACX,OAAO,CAAE,YAAY,CACrB,MAAM,CAAE,CAAC,CAGX,uBAAW,CACV,SAAS,CAAE,GAAG,CACd,UAAU,CAAE,MAAM,CCxFpB,YAAa,CAGZ,aAAc,CACV,OAAO,CAAE,EAAE,CAIf,wLAYW,CACV,OAAO,CAAE,eAAe,CAIzB,oBAAqB,CACpB,iBAAiB,CAAG,KAAK,CAE1B,qBAAsB,CACrB,iBAAiB,CAAE,MAAM,CAE1B,oBAAqB,CACpB,KAAK,CAAC,IAAI,CACV,gBAAgB,CAAC,MAAM,CAIxB,IAAK,CACJ,OAAO,CAAE,IAAI,CAIb,wDACgC,CAC/B,0BAA0B,CAAE,KAAK,CACjC,YAAY,CAAE,KAAK,CACnB,UAAU,CAAE,eAAe,CAC3B,MAAM,CAAE,eAAe,CACvB,KAAK,CAAE,eAAe,CACtB,MAAM,CAAE,IAAI,CAKd,qCACiB,CACf,OAAO,CAAE,eAAe,CAI1B,SAAU,CACT,OAAO,CAAE,IAAI,CAId,UAAW,CACV,UAAU,CAAE,gBAAgB,CAC5B,0BAA0B,CAAE,KAAK,CACjC,YAAY,CAAE,KAAK,CAIpB,aAAc,CACb,MAAM,CAAE,YAAY,CACpB,KAAK,CAAE,eAAe,CACtB,MAAM,CAAE,eAAe,CACvB,UAAU,CAAE,eAAe,CAC3B,0BAA0B,CAAE,KAAK,CACjC,YAAY,CAAE,KAAK,CAIpB,SAAU,CACT,iBAAiB,CAAG,KAAK,CACzB,0BAA0B,CAAE,KAAK,CACjC,YAAY,CAAE,KAAK,CACjB,gBAAgB,CAAE,0BAAyB,CAC3C,MAAM,CAAE,yBAAwB,CAEnC,aAAc,CACb,0BAA0B,CAAE,KAAK,CACjC,gBAAgB,CAAE,eAAe,CAEjC,MAAM,CAAE,eAAe,CAIxB,iDAAkD,CACjD,0BAA0B,CAAE,KAAK,CACjC,YAAY,CAAE,KAAK,CACnB,UAAU,CAAE,kBAA+B,CAC3C,mEAAkB,CACjB,0BAA0B,CAAE,KAAK,CACjC,YAAY,CAAE,KAAK,CACnB,gBAAgB,CAAE,kBAA6C,CAMjE,gBAAiB,CAChB,iBAAiB,CAAG,KAAK,CACzB,0BAA0B,CAAE,KAAK,CACjC,YAAY,CAAE,KAAK,CACnB,gBAAgB,CAAE,eAAe,CACjC,oCAAoB,CACnB,0BAA0B,CAAE,KAAK,CACjC,YAAY,CAAE,KAAK,CACnB,gBAAgB,CAAE,eAAe,CAElC,uBAAO,CACN,0BAA0B,CAAE,KAAK,CACjC,YAAY,CAAE,KAAK,CACnB,gBAAgB,CAAE,eAAe,CAInC,IAAK,CACJ,MAAM,CAAE,CAAC,CAGV,mBAAsB,CACpB,iBAAiB,CAAE,KAAK,CAG1B,iBAAuB,CACrB,gBAAgB,CAAE,KAAK", +"mappings": "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", "sources": ["../light/_license.scss","../../bootstrap/stylesheets/bootstrap/_normalize.scss","../../bootstrap/stylesheets/bootstrap/_print.scss","../../bootstrap/stylesheets/bootstrap/_scaffolding.scss","../../bootstrap/stylesheets/bootstrap/mixins/_vendor-prefixes.scss","../light/_config.scss","../../bootstrap/stylesheets/bootstrap/_variables.scss","../../bootstrap/stylesheets/bootstrap/mixins/_tab-focus.scss","../../bootstrap/stylesheets/bootstrap/mixins/_image.scss","../../bootstrap/stylesheets/bootstrap/_type.scss","../../bootstrap/stylesheets/bootstrap/mixins/_text-emphasis.scss","../../bootstrap/stylesheets/bootstrap/mixins/_background-variant.scss","../../bootstrap/stylesheets/bootstrap/mixins/_clearfix.scss","../../bootstrap/stylesheets/bootstrap/mixins/_text-overflow.scss","../../font-awesome/scss/_path.scss","../../font-awesome/scss/_core.scss","../light/modules/_helpers.scss","../../bootstrap/stylesheets/bootstrap/mixins/_opacity.scss","../light/modules/_dialog.scss","../light/modules/_mixins.scss","../light/modules/_emoticons.scss","../light/modules/_content.scss","../light/modules/_content_embedded.scss","../../bootstrap/stylesheets/bootstrap/mixins/_border-radius.scss","../../font-awesome/scss/_variables.scss","../light/modules/_tinymce.scss","../light/modules/_print.scss"], "names": [], "file": "content.css" diff --git a/src/test/java/org/olat/core/util/xml/XMLDigitalSignatureUtilTest.java b/src/test/java/org/olat/core/util/xml/XMLDigitalSignatureUtilTest.java index c24d2b36287b4ca0d497799c23af1c798b33dc5e..61cdd7ac87ac4c5bd6791b13d890ba4ffb85f79e 100644 --- a/src/test/java/org/olat/core/util/xml/XMLDigitalSignatureUtilTest.java +++ b/src/test/java/org/olat/core/util/xml/XMLDigitalSignatureUtilTest.java @@ -40,6 +40,19 @@ import org.w3c.dom.NodeList; */ public class XMLDigitalSignatureUtilTest { + /** + * Preliminary test which read the certificate. The method is used in + * every other test of the class. + * + * @throws Exception + */ + @Test + public void readCertificatePrivateKeyPair() throws Exception { + X509CertificatePrivateKeyPair keyPair = getCertificatePrivateKeyPair(); + Assert.assertNotNull(keyPair); + Assert.assertNotNull(keyPair.getPrivateKey()); + Assert.assertNotNull(keyPair.getX509Cert()); + } /** * Check if the cycle sign -> validation works diff --git a/src/test/java/org/olat/ims/qti21/ui/components/AssessmentRenderFunctionsTest.java b/src/test/java/org/olat/ims/qti21/ui/components/AssessmentRenderFunctionsTest.java new file mode 100644 index 0000000000000000000000000000000000000000..8feee7bf9280a8f58f6b0f15ef5edadd8e48c7da --- /dev/null +++ b/src/test/java/org/olat/ims/qti21/ui/components/AssessmentRenderFunctionsTest.java @@ -0,0 +1,75 @@ +package org.olat.ims.qti21.ui.components; + +import org.junit.Assert; +import org.junit.Test; + +import uk.ac.ed.ph.jqtiplus.types.Identifier; +import uk.ac.ed.ph.jqtiplus.value.IdentifierValue; +import uk.ac.ed.ph.jqtiplus.value.IntegerValue; +import uk.ac.ed.ph.jqtiplus.value.MultipleValue; +import uk.ac.ed.ph.jqtiplus.value.NullValue; +import uk.ac.ed.ph.jqtiplus.value.OrderedValue; +import uk.ac.ed.ph.jqtiplus.value.Value; + +/** + * + * Initial date: 5 févr. 2018<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class AssessmentRenderFunctionsTest { + + @Test + public void valueContains_nullValue() { + NullValue nullVal = NullValue.INSTANCE; + Assert.assertFalse(AssessmentRenderFunctions.valueContains(null, Identifier.parseString("noid"))); + Assert.assertFalse(AssessmentRenderFunctions.valueContains(nullVal, Identifier.parseString("noid"))); + } + + @Test + public void valueContains_identifierValue() { + IdentifierValue identifierVal = new IdentifierValue(Identifier.parseString("reference-id")); + Assert.assertTrue(AssessmentRenderFunctions.valueContains(identifierVal, Identifier.parseString("reference-id"))); + Assert.assertFalse(AssessmentRenderFunctions.valueContains(identifierVal, Identifier.parseString("noid"))); + } + + @Test + public void valueContains_multipleValues() { + Value identifierValues = MultipleValue.createMultipleValue( + new IdentifierValue(Identifier.parseString("reference-id")), + new IdentifierValue(Identifier.parseString("reference-id"))); + + Assert.assertTrue(AssessmentRenderFunctions.valueContains(identifierValues, Identifier.parseString("reference-id"))); + Assert.assertFalse(AssessmentRenderFunctions.valueContains(identifierValues, Identifier.parseString("noid"))); + } + + @Test + public void valueContains_multipleAlienValues() { + Value identifierValues = MultipleValue.createMultipleValue( + new IntegerValue(6), + new IntegerValue(7)); + + Assert.assertFalse(AssessmentRenderFunctions.valueContains(identifierValues, Identifier.parseString("6"))); + Assert.assertFalse(AssessmentRenderFunctions.valueContains(identifierValues, Identifier.parseString("noid"))); + } + + @Test + public void valueContains_orderedValues() { + Value identifierValues = OrderedValue.createOrderedValue( + new IdentifierValue(Identifier.parseString("reference-id")), + new IdentifierValue(Identifier.parseString("reference-id"))); + + Assert.assertTrue(AssessmentRenderFunctions.valueContains(identifierValues, Identifier.parseString("reference-id"))); + Assert.assertFalse(AssessmentRenderFunctions.valueContains(identifierValues, Identifier.parseString("noid"))); + } + + @Test + public void valueContains_orderedAlienValues() { + Value identifierValues = OrderedValue.createOrderedValue( + new IntegerValue(6), + new IntegerValue(7)); + + Assert.assertFalse(AssessmentRenderFunctions.valueContains(identifierValues, Identifier.parseString("7"))); + Assert.assertFalse(AssessmentRenderFunctions.valueContains(identifierValues, Identifier.parseString("noid"))); + } +} diff --git a/src/test/java/org/olat/portfolio/manager/EPStructureManagerTest.java b/src/test/java/org/olat/portfolio/manager/EPStructureManagerTest.java index 7120df27658011c2ecc64689a672a1bd4be34b1e..fbcf19300e2cc08b6e9ca01a53b0825fd6220704 100644 --- a/src/test/java/org/olat/portfolio/manager/EPStructureManagerTest.java +++ b/src/test/java/org/olat/portfolio/manager/EPStructureManagerTest.java @@ -40,13 +40,12 @@ import org.olat.core.commons.persistence.DB; import org.olat.core.id.Identity; import org.olat.core.id.Persistable; import org.olat.core.id.Roles; -import org.olat.portfolio.manager.EPFrontendManager; -import org.olat.portfolio.manager.EPStructureManager; import org.olat.portfolio.model.artefacts.AbstractArtefact; import org.olat.portfolio.model.structel.EPStructureElement; import org.olat.portfolio.model.structel.EPStructureToStructureLink; import org.olat.portfolio.model.structel.EPStructuredMap; import org.olat.portfolio.model.structel.EPTargetResource; +import org.olat.portfolio.model.structel.ElementType; import org.olat.portfolio.model.structel.PortfolioStructure; import org.olat.portfolio.model.structel.PortfolioStructureMap; import org.olat.repository.RepositoryEntry; @@ -102,29 +101,55 @@ public class EPStructureManagerTest extends OlatTestCase { } @Test - public void testGetStructureElementsForUser(){ + public void testGetStructureElementsForUser() { Identity user = JunitTestHelper.createAndPersistIdentityAsRndUser("EP-1-"); PortfolioStructure el = epFrontendManager.createAndPersistPortfolioDefaultMap(user, "users-test-map", "a-map-to-test-get-afterwards"); - assertNotNull(el); + Assert.assertNotNull(el); dbInstance.commitAndCloseSession(); List<SecurityGroup> secGroups = securityManager.getSecurityGroupsForIdentity(user); - assertNotNull(secGroups); - assertTrue(secGroups.size() >= 1); + Assert.assertNotNull(secGroups); + Assert.assertTrue(secGroups.size() >= 1); - List<PortfolioStructure> elRes = epFrontendManager.getStructureElementsForUser(user); - assertNotNull(elRes); - assertTrue(elRes.size() == 1); - assertEquals( ((EPStructureElement)elRes.get(0)).getTitle(), "users-test-map"); + List<PortfolioStructure> elRes = epStructureManager.getStructureElementsForUser(user, ElementType.DEFAULT_MAP); + Assert.assertNotNull(elRes); + Assert.assertEquals(1, elRes.size()); + Assert.assertEquals("users-test-map", elRes.get(0).getTitle()); // get another map PortfolioStructure el2 = epFrontendManager.createAndPersistPortfolioDefaultMap(user, "users-test-map-2", "2-a-map-to-test-get-afterwards"); - assertNotNull(el2); + Assert.assertNotNull(el2); dbInstance.commitAndCloseSession(); - List<PortfolioStructure> elRes2 = epFrontendManager.getStructureElementsForUser(user); - assertNotNull(elRes2); - assertTrue(elRes2.size() == 2); + List<PortfolioStructure> elRes2 = epStructureManager.getStructureElementsForUser(user); + Assert.assertNotNull(elRes2); + Assert.assertEquals(2, elRes2.size()); + } + + @Test + public void testGetStructureElementsForUser_byElementTypes() { + Identity user = JunitTestHelper.createAndPersistIdentityAsRndUser("EP-1-"); + + PortfolioStructure el = epFrontendManager.createAndPersistPortfolioDefaultMap(user, "users-def-map", ""); + Assert.assertNotNull(el); + dbInstance.commitAndCloseSession(); + + //by default map + List<PortfolioStructure> defaultRes = epStructureManager.getStructureElementsForUser(user, ElementType.DEFAULT_MAP); + Assert.assertNotNull(defaultRes); + Assert.assertEquals(1, defaultRes.size()); + Assert.assertEquals("users-def-map", defaultRes.get(0).getTitle()); + + //by default map and structured + List<PortfolioStructure> multipleRes = epStructureManager.getStructureElementsForUser(user, ElementType.DEFAULT_MAP, ElementType.STRUCTURED_MAP); + Assert.assertNotNull(multipleRes); + Assert.assertEquals(1, multipleRes.size()); + Assert.assertEquals("users-def-map", multipleRes.get(0).getTitle()); + + //by structured + List<PortfolioStructure> structuredRes = epStructureManager.getStructureElementsForUser(user, ElementType.STRUCTURED_MAP); + Assert.assertNotNull(structuredRes); + Assert.assertTrue(structuredRes.isEmpty()); } @Test diff --git a/src/test/java/org/olat/selenium/BusinessGroupTest.java b/src/test/java/org/olat/selenium/BusinessGroupTest.java index ca6f172de2312406a3f995c9b55da2cc2e1ff229..0ac3b8593da514b2288a99e6427834b4d6c92259 100644 --- a/src/test/java/org/olat/selenium/BusinessGroupTest.java +++ b/src/test/java/org/olat/selenium/BusinessGroupTest.java @@ -311,8 +311,7 @@ public class BusinessGroupTest extends Deployments { .openAddDropMenu() .addTokenMethod() .configureTokenMethod(token, description) - .assertOnToken(token) - .save(); + .assertOnToken(token); //members see members group = GroupPage.getGroup(browser) @@ -801,6 +800,7 @@ public class BusinessGroupTest extends Deployments { Assert.assertEquals(1, participants); Assert.assertEquals(2, waitingList); } + /** * An author create a course, with an enrollment course element. It * configure it and create 3 groups and set the maximum enrollment counter to 2<br> @@ -813,7 +813,6 @@ public class BusinessGroupTest extends Deployments { * @throws IOException * @throws URISyntaxException */ - @Test @RunAsClient public void enrollmentWithMultiEnrollment(@InitialPage LoginPage authorLoginPage, diff --git a/src/test/java/org/olat/selenium/ImsQTI21EditorTest.java b/src/test/java/org/olat/selenium/ImsQTI21EditorTest.java index 75a334bfecb8d7da982d4b7a50a8ad94146195f2..d9373778750c9e7884a1474bfdb7888422170c3b 100644 --- a/src/test/java/org/olat/selenium/ImsQTI21EditorTest.java +++ b/src/test/java/org/olat/selenium/ImsQTI21EditorTest.java @@ -50,6 +50,7 @@ import org.olat.selenium.page.qti.QTI21MatchEditorPage; import org.olat.selenium.page.qti.QTI21MultipleChoiceEditorPage; import org.olat.selenium.page.qti.QTI21Page; import org.olat.selenium.page.qti.QTI21SingleChoiceEditorPage; +import org.olat.selenium.page.qti.QTI21Page.TrueFalse; import org.olat.selenium.page.repository.RepositoryAccessPage.UserAccess; import org.olat.test.JunitTestHelper; import org.olat.test.rest.UserRestClient; @@ -153,6 +154,85 @@ public class ImsQTI21EditorTest extends Deployments { .assertOnAssessmentTestMaxScore(9); } + /** + * Create a test, import a CSV with some match variants, + * remove the first single choice which come if someone + * create a test. Change the delivery settings of the test + * to show the detailled results.<br> + * Run the test and check the results. + * + * @param loginPage + * @throws IOException + * @throws URISyntaxException + */ + @Test + @RunAsClient + public void importQuestionsCSVMatchVariants(@InitialPage LoginPage authorLoginPage) + throws IOException, URISyntaxException { + UserVO author = new UserRestClient(deploymentUrl).createAuthor(); + authorLoginPage.loginAs(author.getLogin(), author.getPassword()); + + //upload a test + String qtiTestTitle = "ExcelMatch QTI 2.1 " + UUID.randomUUID(); + navBar + .openAuthoringEnvironment() + .createQTI21Test(qtiTestTitle) + .clickToolbarBack(); + + QTI21Page qtiPage = QTI21Page + .getQTI12Page(browser); + QTI21EditorPage qtiEditor = qtiPage + .edit(); + + // import a single choice, a multiple and 2 gap texts + qtiEditor + .importTable() + .importFile("qti21/import_qti21_excel_match.txt") + .next() + .assertOnNumberOfQuestions(3) + .finish(); + + //remove the single choice which come from the creation + // of the test + qtiEditor + .selectNode("Single choice") + .deleteNode(); + + // go to options and show the results + qtiPage + .clickToolbarBack() + .options() + .showResults(Boolean.TRUE, QTI21AssessmentResultsOptions.allOptions()) + .save(); + + //go to the test + qtiPage + .clickToolbarBack() + .assertOnAssessmentItem() + .answerMatch("Berlin", "Deutschland", true) + .answerMatch("Bern", "Schweiz", true) + .answerMatch("Paris", "Frankreich", true) + .saveAnswer() + .nextAnswer() + .assertOnAssessmentItem("Afrika") + .answerMatchDropSourceToTarget("Nairobi", "Kenia") + .answerMatchDropSourceToTarget("Windhoek", "Namibia") + .answerMatchDropSourceToTarget("Algier", "Algerien") + .saveAnswer() + .assertOnAssessmentItem("Europa") + .answerMatch("Paris", TrueFalse.right, true) + .answerMatch("Bern", TrueFalse.right, true) + .answerMatch("Stockholm", TrueFalse.wrong, true) + .saveAnswer() + .endTest(); + + //check the results + qtiPage + .assertOnAssessmentResults() + .assertOnAssessmentTestScore(9) + .assertOnAssessmentTestMaxScore(9); + } + /** * Test different settings in the single choice editor. An author * make a test with 2 single choices, one with score all answer correct, @@ -2525,6 +2605,184 @@ public class ImsQTI21EditorTest extends Deployments { .assertOnAssessmentResults() .assertOnAssessmentTestScore(12);// 4 points from the first question, 8 from the second } + + + /** + * An author make a test with 2 matches of the True/false variant. A match + * with score "all answers", a second with score "per answers".<br> + * A first user make the test, but doesn't answer all questions + * correctly, log out and a second user make the perfect test. + * + * @param authorLoginPage + * @param participantBrowser + * @throws IOException + * @throws URISyntaxException + */ + @Test + @RunAsClient + public void qti21EditorMatchTrueFalse(@InitialPage LoginPage authorLoginPage, + @Drone @User WebDriver participantBrowser) + throws IOException, URISyntaxException { + UserVO author = new UserRestClient(deploymentUrl).createAuthor(); + UserVO rei = new UserRestClient(deploymentUrl).createRandomUser("Rei"); + UserVO asuka = new UserRestClient(deploymentUrl).createRandomUser("Asuka"); + authorLoginPage.loginAs(author.getLogin(), author.getPassword()); + + String qtiTestTitle = "True false QTI 2.1 " + UUID.randomUUID(); + navBar + .openAuthoringEnvironment() + .createQTI21Test(qtiTestTitle) + .clickToolbarBack(); + + QTI21Page qtiPage = QTI21Page + .getQTI12Page(browser); + QTI21EditorPage qtiEditor = qtiPage + .edit(); + //start a blank test + qtiEditor + .selectNode("Single choice") + .deleteNode(); + + //add a match, score "all answers" + QTI21MatchEditorPage matchEditor = qtiEditor + .addMatchTrueFalse(); + matchEditor + .setSource(0, "Eclipse is a Java IDE") + .setSource(1, "vim is Database viewer") + .setMatch(0, 1, true) + .setMatch(1, 2, true) + .save(); + // change max score + matchEditor + .selectScores() + .setMaxScore("4") + .save(); + // set some feedbacks + matchEditor + .selectFeedbacks() + .setHint("Hint", "This is only an hint") + .setCorrectSolution("Correct solution", "This is the correct solution") + .setCorrectFeedback("Correct feedback", "This is correct") + .setIncorrectFeedback("Incorrect", "Your answer is not correct") + .save(); + + // second match + matchEditor = qtiEditor + .addMatchTrueFalse() + .setSource(0, "Java has several IDE like Eclipse") + .setSource(1, "C is object oriented") + .addRow() + .setSource(2, "What do you think of PHP?") + .setMatch(0, 1, true) + .setMatch(1, 2, true) + .setMatch(2, 0, true) + .save(); + // select score "per answer" and set the scores + matchEditor + .selectScores() + .selectAssessmentMode(ScoreEvaluation.perAnswer) + .setMaxScore("3") + .setScore(0, 0, "0.0") + .setScore(0, 1, "1.0") + .setScore(0, 2, "0.0") + .setScore(1, 0, "0.0") + .setScore(1, 1, "0.0") + .setScore(1, 2, "1.0") + .setScore(2, 0, "1.0") + .setScore(2, 1, "0.0") + .setScore(2, 2, "0.0") + .save(); + matchEditor + .selectFeedbacks() + .setHint("Hint", "The hint") + .setCorrectSolution("Correct solution", "This is the correct solution") + .setCorrectFeedback("Correct feedback", "This is correct") + .setIncorrectFeedback("Incorrect", "Your answer is not correct") + .save(); + + + qtiPage + .clickToolbarBack(); + // access to all + qtiPage + .accessConfiguration() + .setUserAccess(UserAccess.guest) + .clickToolbarBack(); + // show results + qtiPage + .options() + .showResults(Boolean.TRUE, QTI21AssessmentResultsOptions.allOptions()) + .save(); + + //a user search the content package + LoginPage reiLoginPage = LoginPage.getLoginPage(participantBrowser, deploymentUrl); + reiLoginPage + .loginAs(rei.getLogin(), rei.getPassword()) + .resume(); + NavigationPage reiNavBar = new NavigationPage(participantBrowser); + reiNavBar + .openMyCourses() + .openSearch() + .extendedSearch(qtiTestTitle) + .select(qtiTestTitle) + .start(); + + // make the test + QTI21Page reiQtiPage = QTI21Page + .getQTI12Page(participantBrowser); + reiQtiPage + .assertOnAssessmentItem() + .answerMatch("Eclipse", TrueFalse.right, true) + .answerMatch("vim", TrueFalse.right, true) + .saveAnswer() + .assertFeedback("Incorrect") + .assertCorrectSolution("Correct solution") + .hint() + .assertFeedback("Hint") + .answerMatch("vim", TrueFalse.wrong, true) + .saveAnswer() + .assertFeedback("Correct feedback") + .nextAnswer() + .answerMatch("Java", TrueFalse.right, true) + .answerMatch("oriented", TrueFalse.wrong, true) + .answerMatch("PHP", TrueFalse.wrong, true) + .saveAnswer() + .assertCorrectSolution("Correct solution") + .assertFeedback("Incorrect") + .endTest() + .assertOnAssessmentResults() + .assertOnAssessmentTestScore(6);// 4 points from the first question, 2 from the second + + + //a second user search the content package + LoginPage asukaLoginPage = LoginPage.getLoginPage(participantBrowser, deploymentUrl); + asukaLoginPage + .loginAs(asuka.getLogin(), asuka.getPassword()) + .resume(); + NavigationPage asukaNavBar = new NavigationPage(participantBrowser); + asukaNavBar + .openMyCourses() + .openSearch() + .extendedSearch(qtiTestTitle) + .select(qtiTestTitle) + .start(); + + // make the test + QTI21Page + .getQTI12Page(participantBrowser) + .assertOnAssessmentItem() + .answerMatch("Eclipse", TrueFalse.right, true) + .answerMatch("vim", TrueFalse.wrong, true) + .saveAnswer() + .assertFeedback("Correct feedback") + .nextAnswer() + .answerMatch("Java", TrueFalse.right, true) + .answerMatch("oriented", TrueFalse.wrong, true) + .saveAnswer() + .endTest() + .assertOnAssessmentResults() + .assertOnAssessmentTestScore(7);// 4 points from the first question, 6 from the second + } /** * An author make a test with 1 upload and feedbacks.<br> diff --git a/src/test/java/org/olat/selenium/ImsQTI21InteractionsTest.java b/src/test/java/org/olat/selenium/ImsQTI21InteractionsTest.java new file mode 100644 index 0000000000000000000000000000000000000000..781d4edff6a3977fce2d058b0575f425856f8a86 --- /dev/null +++ b/src/test/java/org/olat/selenium/ImsQTI21InteractionsTest.java @@ -0,0 +1,687 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.selenium; + +import java.io.File; +import java.io.IOException; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.UUID; + +import org.jboss.arquillian.container.test.api.RunAsClient; +import org.jboss.arquillian.drone.api.annotation.Drone; +import org.jboss.arquillian.graphene.page.InitialPage; +import org.jboss.arquillian.graphene.page.Page; +import org.jboss.arquillian.junit.Arquillian; +import org.jboss.arquillian.test.api.ArquillianResource; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.olat.ims.qti21.QTI21AssessmentResultsOptions; +import org.olat.selenium.page.LoginPage; +import org.olat.selenium.page.NavigationPage; +import org.olat.selenium.page.qti.QTI21Page; +import org.olat.test.JunitTestHelper; +import org.olat.test.rest.UserRestClient; +import org.olat.user.restapi.UserVO; +import org.openqa.selenium.WebDriver; + + +/** + * This suite tests the interactions in runtime and only in runtime. The source used + * come from the IMS examples. + * + * <ul> + * <li>Hotspot + * <li>Associate + * <li>Graphic associate + * <li>Match + * <li>Graphic Gap Match (with click and drop) + * <li>End interaction with inline and modal feedbacks (classic hint) + * <li>Select point interaction + * <li>Position object interaction + * <li>Order interaction + * <li>Graphic order interaction + * <li>Inline choice + * <li>Slider + * </ul> + * + * Initial date: 26 janv. 2018<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +@RunWith(Arquillian.class) +public class ImsQTI21InteractionsTest extends Deployments { + + @Drone + private WebDriver browser; + @ArquillianResource + private URL deploymentUrl; + @Page + private NavigationPage navBar; + + /** + * Check if the hotspot interaction send a "correct" feedback. + * + * @param authorLoginPage + * @throws IOException + * @throws URISyntaxException + */ + @Test + @RunAsClient + public void qti21HotspotInteraction(@InitialPage LoginPage authorLoginPage) + throws IOException, URISyntaxException { + UserVO author = new UserRestClient(deploymentUrl).createAuthor(); + authorLoginPage.loginAs(author.getLogin(), author.getPassword()); + + //upload a test + String qtiTestTitle = "Hotspot QTI 2.1 " + UUID.randomUUID(); + URL qtiTestUrl = JunitTestHelper.class.getResource("file_resources/qti21/simple_QTI_21_hotspot.zip"); + File qtiTestFile = new File(qtiTestUrl.toURI()); + navBar + .openAuthoringEnvironment() + .uploadResource(qtiTestTitle, qtiTestFile) + .clickToolbarRootCrumb(); + + QTI21Page qtiPage = QTI21Page + .getQTI12Page(browser); + qtiPage + .options() + .showResults(Boolean.TRUE, QTI21AssessmentResultsOptions.allOptions()) + .save(); + // to the test and spot it + qtiPage + .clickToolbarBack() + .assertOnAssessmentItem() + .answerHotspot("circle") + .saveAnswer() + .assertFeedback("Correct!") + .endTest(); + //check the results + qtiPage + .assertOnAssessmentResults() + .assertOnAssessmentTestScore(1) + .assertOnAssessmentTestMaxScore(1); + } + + /** + * Check if the associate interaction return its 4 points. + * + * @param authorLoginPage + * @throws IOException + * @throws URISyntaxException + */ + @Test + @RunAsClient + public void qti21AssociateInteraction(@InitialPage LoginPage authorLoginPage) + throws IOException, URISyntaxException { + UserVO author = new UserRestClient(deploymentUrl).createAuthor(); + authorLoginPage.loginAs(author.getLogin(), author.getPassword()); + + //upload a test + String qtiTestTitle = "Associate QTI 2.1 " + UUID.randomUUID(); + URL qtiTestUrl = JunitTestHelper.class.getResource("file_resources/qti21/simple_QTI_21_associate_ims.zip"); + File qtiTestFile = new File(qtiTestUrl.toURI()); + navBar + .openAuthoringEnvironment() + .uploadResource(qtiTestTitle, qtiTestFile) + .clickToolbarRootCrumb(); + + QTI21Page qtiPage = QTI21Page + .getQTI12Page(browser); + qtiPage + .options() + .showResults(Boolean.TRUE, QTI21AssessmentResultsOptions.allOptions()) + .save(); + // to the test and spot it + qtiPage + .clickToolbarBack() + .assertOnAssessmentItem() + .answerAssociate("Antonio", 1, true) + .answerAssociate("Prospero", 1, false) + .answerAssociate("Capulet", 2, true) + .answerAssociate("Montague", 2, false) + .answerAssociate("Demetrius", 3, true) + .answerAssociate("Lysander", 3, false) + .saveAnswer() + .endTest() + .closeTest(); + //check the results + qtiPage + .assertOnAssessmentResults() + .assertOnAssessmentItemScore("Shakespearian Rivals", 4); + } + + /** + * Check if the graphic associate interaction return its 2 points. + * + * @param authorLoginPage + * @throws IOException + * @throws URISyntaxException + */ + @Test + @RunAsClient + public void qti21GraphicAssociateInteraction(@InitialPage LoginPage authorLoginPage) + throws IOException, URISyntaxException { + UserVO author = new UserRestClient(deploymentUrl).createAuthor(); + authorLoginPage.loginAs(author.getLogin(), author.getPassword()); + + //upload a test + String qtiTestTitle = "Graphic associate QTI 2.1 " + UUID.randomUUID(); + URL qtiTestUrl = JunitTestHelper.class.getResource("file_resources/qti21/simple_QTI_21_graphic_associate_ims.zip"); + File qtiTestFile = new File(qtiTestUrl.toURI()); + navBar + .openAuthoringEnvironment() + .uploadResource(qtiTestTitle, qtiTestFile) + .clickToolbarRootCrumb(); + + QTI21Page qtiPage = QTI21Page + .getQTI12Page(browser); + qtiPage + .options() + .showResults(Boolean.TRUE, QTI21AssessmentResultsOptions.allOptions()) + .save(); + // to the test and spot it + qtiPage + .clickToolbarBack() + .assertOnAssessmentItem() + .answerGraphicAssociate("B") + .answerGraphicAssociate("C") + .answerGraphicAssociate("C") + .answerGraphicAssociate("D") + .saveAnswer() + .endTest() + .closeTest(); + //check the results + qtiPage + .assertOnAssessmentResults() + .assertOnAssessmentItemScore("Low-cost Flying", 2); + } + + /** + * Check if the classic match interaction return its 3 points. + * + * @param authorLoginPage + * @throws IOException + * @throws URISyntaxException + */ + @Test + @RunAsClient + public void qti21MatchInteraction(@InitialPage LoginPage authorLoginPage) + throws IOException, URISyntaxException { + UserVO author = new UserRestClient(deploymentUrl).createAuthor(); + authorLoginPage.loginAs(author.getLogin(), author.getPassword()); + + //upload a test + String qtiTestTitle = "Match QTI 2.1 " + UUID.randomUUID(); + URL qtiTestUrl = JunitTestHelper.class.getResource("file_resources/qti21/simple_QTI_21_match_ims.zip"); + File qtiTestFile = new File(qtiTestUrl.toURI()); + navBar + .openAuthoringEnvironment() + .uploadResource(qtiTestTitle, qtiTestFile) + .clickToolbarRootCrumb(); + + QTI21Page qtiPage = QTI21Page + .getQTI12Page(browser); + qtiPage + .options() + .showResults(Boolean.TRUE, QTI21AssessmentResultsOptions.allOptions()) + .save(); + // to the test and spot it + qtiPage + .clickToolbarBack() + .assertOnAssessmentItem() + .answerMatch("Prospero", "Romeo and Juliet", true) + .answerMatch("Capulet", "Romeo and Juliet", true) + .answerMatch("Demetrius", "A Midsummer", true) + .answerMatch("Lysander", "A Midsummer", true) + //ooops + .answerMatch("Prospero", "Romeo and Juliet", false) + .answerMatch("Prospero", "The Tempest", true) + .saveAnswer() + .endTest(); + //check the results + qtiPage + .assertOnAssessmentResults() + .assertOnAssessmentItemScore("Characters and Plays", 3); + } + + /** + * Check if the order interaction return its 1 point. + * + * @param authorLoginPage + * @throws IOException + * @throws URISyntaxException + */ + @Test + @RunAsClient + public void qti21OrderInteraction(@InitialPage LoginPage authorLoginPage) + throws IOException, URISyntaxException { + UserVO author = new UserRestClient(deploymentUrl).createAuthor(); + authorLoginPage.loginAs(author.getLogin(), author.getPassword()); + + //upload a test + String qtiTestTitle = "Order QTI 2.1 " + UUID.randomUUID(); + URL qtiTestUrl = JunitTestHelper.class.getResource("file_resources/qti21/simple_QTI_21_order_ims.zip"); + File qtiTestFile = new File(qtiTestUrl.toURI()); + navBar + .openAuthoringEnvironment() + .uploadResource(qtiTestTitle, qtiTestFile) + .clickToolbarRootCrumb(); + + QTI21Page qtiPage = QTI21Page + .getQTI12Page(browser); + qtiPage + .options() + .showResults(Boolean.TRUE, QTI21AssessmentResultsOptions.allOptions()) + .save(); + // to the test and spot it + qtiPage + .clickToolbarBack() + .assertOnAssessmentItem() + .answerOrderDropItem("Jenson") + .answerOrderDropItem("Rubens") + .answerOrderDropItem("Michael") + .saveAnswer() + .endTest() + .closeTest(); + //check the results + qtiPage + .assertOnAssessmentResults() + .assertOnAssessmentItemScore("Grand Prix of Bahrain", 1); + } + + /** + * Check if hint with modal and inline feedbacks used + * with choice interaction. + * + * @param authorLoginPage + * @throws IOException + * @throws URISyntaxException + */ + @Test + @RunAsClient + public void qti21EndInteraction(@InitialPage LoginPage authorLoginPage) + throws IOException, URISyntaxException { + UserVO author = new UserRestClient(deploymentUrl).createAuthor(); + authorLoginPage.loginAs(author.getLogin(), author.getPassword()); + + //upload a test + String qtiTestTitle = "End QTI 2.1 " + UUID.randomUUID(); + URL qtiTestUrl = JunitTestHelper.class.getResource("file_resources/qti21/simple_QTI_21_end_ims.zip"); + File qtiTestFile = new File(qtiTestUrl.toURI()); + navBar + .openAuthoringEnvironment() + .uploadResource(qtiTestTitle, qtiTestFile) + .clickToolbarRootCrumb(); + + QTI21Page qtiPage = QTI21Page + .getQTI12Page(browser); + qtiPage + .options() + .showResults(Boolean.TRUE, QTI21AssessmentResultsOptions.allOptions()) + .save(); + // to the test and spot it + qtiPage + .clickToolbarBack() + .assertOnAssessmentItem() + .hint() + .assertFeedbackText("Tony lives in the United Kingdom") + .answerSingleChoice("Tony") + .saveAnswer() + .assertFeedbackText("No, the correct answer is Vicente Fox") + .assertFeedbackInline("No, he is the Prime Minister of England.") + .assertNoFeedbackText("Tony lives in the United Kingdom") + .answerSingleChoice("George") + .saveAnswer() + .assertFeedbackText("No, the correct answer is Vicente Fox") + .assertFeedbackInline("No, he is the President of the USA.") + .assertNoFeedbackText("Tony lives in the United Kingdom") + .assertNoFeedbackInline("No, he is the Prime Minister of England.") + .answerSingleChoice("Vicente") + .saveAnswer() + .assertFeedbackText("Yes, that is correct") + .assertNoFeedbackText("Tony lives in the United Kingdom") + .assertNoFeedbackInline("No, he is the Prime Minister of England.") + .assertNoFeedbackInline("No, he is the President of the USA.") + .endTest() + .closeTest(); + //check the results + qtiPage + .assertOnAssessmentResults() + .assertOnAssessmentItemScore("Mexican President", 1); + } + + /** + * Check if hint with modal and inline feedbacks used + * with choice interaction. + * + * @param authorLoginPage + * @throws IOException + * @throws URISyntaxException + */ + @Test + @RunAsClient + public void qti21GraphicGapInteraction(@InitialPage LoginPage authorLoginPage) + throws IOException, URISyntaxException { + UserVO author = new UserRestClient(deploymentUrl).createAuthor(); + authorLoginPage.loginAs(author.getLogin(), author.getPassword()); + + //upload a test + String qtiTestTitle = "Graphic Gap Match QTI 2.1 " + UUID.randomUUID(); + URL qtiTestUrl = JunitTestHelper.class.getResource("file_resources/qti21/simple_QTI_21_graphic_gap_match_ims.zip"); + File qtiTestFile = new File(qtiTestUrl.toURI()); + navBar + .openAuthoringEnvironment() + .uploadResource(qtiTestTitle, qtiTestFile) + .clickToolbarRootCrumb(); + + QTI21Page qtiPage = QTI21Page + .getQTI12Page(browser); + qtiPage + .options() + .showResults(Boolean.TRUE, QTI21AssessmentResultsOptions.allOptions()) + .save(); + // to the test and spot it + qtiPage + .clickToolbarBack() + .assertOnAssessmentItem() + .answerGraphicGapClick("GLA", "A") + .answerGraphicGapClick("EDI", "B") + .answerGraphicGapClick("MAN", "C") + .saveAnswer() + .endTest() + .closeTest(); + //check the results + qtiPage + .assertOnAssessmentResults() + .assertOnAssessmentItemScore("Airport Tags", 3); + } + + /** + * Check if the select point interaction returns 1 point + * if answered correctly. + * + * @param authorLoginPage + * @throws IOException + * @throws URISyntaxException + */ + @Test + @RunAsClient + public void qti21SelectPointInteraction(@InitialPage LoginPage authorLoginPage) + throws IOException, URISyntaxException { + UserVO author = new UserRestClient(deploymentUrl).createAuthor(); + authorLoginPage.loginAs(author.getLogin(), author.getPassword()); + + //upload a test + String qtiTestTitle = "Select point QTI 2.1 " + UUID.randomUUID(); + URL qtiTestUrl = JunitTestHelper.class.getResource("file_resources/qti21/simple_QTI_21_select_point_ims.zip"); + File qtiTestFile = new File(qtiTestUrl.toURI()); + navBar + .openAuthoringEnvironment() + .uploadResource(qtiTestTitle, qtiTestFile) + .clickToolbarRootCrumb(); + + QTI21Page qtiPage = QTI21Page + .getQTI12Page(browser); + qtiPage + .options() + .showResults(Boolean.TRUE, QTI21AssessmentResultsOptions.allOptions()) + .save(); + // to the test and spot it + qtiPage + .clickToolbarBack() + .assertOnAssessmentItem() + .answerSelectPoint(100, 110) + .saveAnswer() + .endTest() + .closeTest(); + //check the results + qtiPage + .assertOnAssessmentResults() + .assertOnAssessmentItemScore("Where is Edinburgh", 1); + } + + /** + * Check if the graphic order interaction returns 1 point + * if answered correctly. + * + * @param authorLoginPage + * @throws IOException + * @throws URISyntaxException + */ + @Test + @RunAsClient + public void qti21GraphicOrderInteraction(@InitialPage LoginPage authorLoginPage) + throws IOException, URISyntaxException { + UserVO author = new UserRestClient(deploymentUrl).createAuthor(); + authorLoginPage.loginAs(author.getLogin(), author.getPassword()); + + //upload a test + String qtiTestTitle = "Graphic order QTI 2.1 " + UUID.randomUUID(); + URL qtiTestUrl = JunitTestHelper.class.getResource("file_resources/qti21/simple_QTI_21_graphic_order_ims.zip"); + File qtiTestFile = new File(qtiTestUrl.toURI()); + navBar + .openAuthoringEnvironment() + .uploadResource(qtiTestTitle, qtiTestFile) + .clickToolbarRootCrumb(); + + QTI21Page qtiPage = QTI21Page + .getQTI12Page(browser); + qtiPage + .options() + .showResults(Boolean.TRUE, QTI21AssessmentResultsOptions.allOptions()) + .save(); + // to the test and spot it + qtiPage + .clickToolbarBack() + .assertOnAssessmentItem() + .answerGraphicOrderById("A") + .answerGraphicOrderById("D") + .answerGraphicOrderById("C") + .answerGraphicOrderById("B") + .saveAnswer() + .endTest() + .closeTest(); + //check the results + qtiPage + .assertOnAssessmentResults() + .assertOnAssessmentItemScore("Flying Home", 1); + } + + /** + * Check if the position object interaction returns 3 points + * if answered correctly. + * + * @param authorLoginPage + * @throws IOException + * @throws URISyntaxException + */ + @Test + @RunAsClient + public void qti21PositionObjectInteraction(@InitialPage LoginPage authorLoginPage) + throws IOException, URISyntaxException { + UserVO author = new UserRestClient(deploymentUrl).createAuthor(); + authorLoginPage.loginAs(author.getLogin(), author.getPassword()); + + //upload a test + String qtiTestTitle = "Position object QTI 2.1 " + UUID.randomUUID(); + URL qtiTestUrl = JunitTestHelper.class.getResource("file_resources/qti21/simple_QTI_21_position_object_ims.zip"); + File qtiTestFile = new File(qtiTestUrl.toURI()); + navBar + .openAuthoringEnvironment() + .uploadResource(qtiTestTitle, qtiTestFile) + .clickToolbarRootCrumb(); + + QTI21Page qtiPage = QTI21Page + .getQTI12Page(browser); + qtiPage + .options() + .showResults(Boolean.TRUE, QTI21AssessmentResultsOptions.allOptions()) + .save(); + // to the test and spot it + qtiPage + .clickToolbarBack() + .assertOnAssessmentItem() + .answerPositionObject(0, 118, 184) + .answerPositionObject(1, 150, 235) + .answerPositionObject(2, 96, 114) + .saveAnswer() + .endTest() + .closeTest(); + //check the results + qtiPage + .assertOnAssessmentResults() + .assertOnAssessmentItemScore("Airport Locations", 3); + } + + /** + * Check if the position object interaction returns 3 points + * if answered correctly. + * + * @param authorLoginPage + * @throws IOException + * @throws URISyntaxException + */ + @Test + @RunAsClient + public void qti21InlineChoiceInteraction(@InitialPage LoginPage authorLoginPage) + throws IOException, URISyntaxException { + UserVO author = new UserRestClient(deploymentUrl).createAuthor(); + authorLoginPage.loginAs(author.getLogin(), author.getPassword()); + + //upload a test + String qtiTestTitle = "Inline choice QTI 2.1 " + UUID.randomUUID(); + URL qtiTestUrl = JunitTestHelper.class.getResource("file_resources/qti21/simple_QTI_21_inline_choice_ims.zip"); + File qtiTestFile = new File(qtiTestUrl.toURI()); + navBar + .openAuthoringEnvironment() + .uploadResource(qtiTestTitle, qtiTestFile) + .clickToolbarRootCrumb(); + + QTI21Page qtiPage = QTI21Page + .getQTI12Page(browser); + qtiPage + .options() + .showResults(Boolean.TRUE, QTI21AssessmentResultsOptions.allOptions()) + .save(); + // to the test and spot it + qtiPage + .clickToolbarBack() + .assertOnAssessmentItem() + .answerInlineChoice("Y") + .saveAnswer() + .endTest() + .closeTest(); + //check the results + qtiPage + .assertOnAssessmentResults() + .assertOnAssessmentItemScore("Richard III", 1); + } + + /** + * Check if the slider interaction returns 1 point + * if answered correctly. + * + * @param authorLoginPage + * @throws IOException + * @throws URISyntaxException + */ + @Test + @RunAsClient + public void qti21SliderInteraction(@InitialPage LoginPage authorLoginPage) + throws IOException, URISyntaxException { + UserVO author = new UserRestClient(deploymentUrl).createAuthor(); + authorLoginPage.loginAs(author.getLogin(), author.getPassword()); + + //upload a test + String qtiTestTitle = "Slider QTI 2.1 " + UUID.randomUUID(); + URL qtiTestUrl = JunitTestHelper.class.getResource("file_resources/qti21/simple_QTI_21_slider_ims.zip"); + File qtiTestFile = new File(qtiTestUrl.toURI()); + navBar + .openAuthoringEnvironment() + .uploadResource(qtiTestTitle, qtiTestFile) + .clickToolbarRootCrumb(); + + QTI21Page qtiPage = QTI21Page + .getQTI12Page(browser); + qtiPage + .options() + .showResults(Boolean.TRUE, QTI21AssessmentResultsOptions.allOptions()) + .save(); + // to the test and spot it + qtiPage + .clickToolbarBack() + .assertOnAssessmentItem() + .answerVerticalSlider(16) + .saveAnswer() + .endTest() + .closeTest(); + //check the results + qtiPage + .assertOnAssessmentResults() + .assertOnAssessmentItemScore("Jedi Knights", 1); + } + + /** + * Check if the gap match returns 3 points + * if answered correctly. + * + * @param authorLoginPage + * @throws IOException + * @throws URISyntaxException + */ + @Test + @RunAsClient + public void qti21GapMatchInteraction(@InitialPage LoginPage authorLoginPage) + throws IOException, URISyntaxException { + UserVO author = new UserRestClient(deploymentUrl).createAuthor(); + authorLoginPage.loginAs(author.getLogin(), author.getPassword()); + + //upload a test + String qtiTestTitle = "Gap match QTI 2.1 " + UUID.randomUUID(); + URL qtiTestUrl = JunitTestHelper.class.getResource("file_resources/qti21/simple_QTI_21_gap_match_ims.zip"); + File qtiTestFile = new File(qtiTestUrl.toURI()); + navBar + .openAuthoringEnvironment() + .uploadResource(qtiTestTitle, qtiTestFile) + .clickToolbarRootCrumb(); + + QTI21Page qtiPage = QTI21Page + .getQTI12Page(browser); + qtiPage + .options() + .showResults(Boolean.TRUE, QTI21AssessmentResultsOptions.allOptions()) + .save(); + // to the test and spot it + qtiPage + .clickToolbarBack() + .assertOnAssessmentItem() + .answerGapMatch(1, "winter", true) + .answerGapMatch(2, "summer", true) + .saveAnswer() + .endTest() + .closeTest(); + //check the results + qtiPage + .assertOnAssessmentResults() + .assertOnAssessmentItemScore("Richard III", 3); + } + +} diff --git a/src/test/java/org/olat/selenium/ImsQTI21Test.java b/src/test/java/org/olat/selenium/ImsQTI21Test.java index 35ad90f665e1c9356886994c1ddbb01f97b35b2d..62cfbc4a287c5ae3fcee7be7f71c4bc6262559d3 100644 --- a/src/test/java/org/olat/selenium/ImsQTI21Test.java +++ b/src/test/java/org/olat/selenium/ImsQTI21Test.java @@ -674,50 +674,6 @@ public class ImsQTI21Test extends Deployments { .assertOnCourseAssessmentTestScore(1) .assertOnAssessmentResults(); } - - /** - * Check if the hotspot interaction send a "correct" feedback. - * - * @param authorLoginPage - * @throws IOException - * @throws URISyntaxException - */ - @Test - @RunAsClient - public void qti21GraphicInteraction(@InitialPage LoginPage authorLoginPage) - throws IOException, URISyntaxException { - UserVO author = new UserRestClient(deploymentUrl).createAuthor(); - authorLoginPage.loginAs(author.getLogin(), author.getPassword()); - - //upload a test - String qtiTestTitle = "Simple QTI 2.1 " + UUID.randomUUID(); - URL qtiTestUrl = JunitTestHelper.class.getResource("file_resources/qti21/simple_QTI_21_hotspot.zip"); - File qtiTestFile = new File(qtiTestUrl.toURI()); - navBar - .openAuthoringEnvironment() - .uploadResource(qtiTestTitle, qtiTestFile) - .clickToolbarRootCrumb(); - - QTI21Page qtiPage = QTI21Page - .getQTI12Page(browser); - qtiPage - .options() - .showResults(Boolean.TRUE, QTI21AssessmentResultsOptions.allOptions()) - .save(); - // to the test and spot it - qtiPage - .clickToolbarBack() - .assertOnAssessmentItem() - .answerHotspot("circle") - .saveAnswer() - .assertFeedback("Correct!") - .endTest(); - //check the results - qtiPage - .assertOnAssessmentResults() - .assertOnAssessmentTestScore(1) - .assertOnAssessmentTestMaxScore(1); - } /** * Upload a test in QTI 2.1 format, create a course, bind diff --git a/src/test/java/org/olat/selenium/page/qti/QTI21EditorPage.java b/src/test/java/org/olat/selenium/page/qti/QTI21EditorPage.java index 4a84cb36731510d90ec9adb679fc1a15786365d2..3e3f3a096b93d8d4f30e7b4e5fb40e8731f0704b 100644 --- a/src/test/java/org/olat/selenium/page/qti/QTI21EditorPage.java +++ b/src/test/java/org/olat/selenium/page/qti/QTI21EditorPage.java @@ -122,6 +122,11 @@ public class QTI21EditorPage { return new QTI21MatchEditorPage(browser); } + public QTI21MatchEditorPage addMatchTrueFalse() { + addQuestion(QTI21QuestionType.matchtruefalse); + return new QTI21MatchEditorPage(browser); + } + public QTI21LobEditorPage addUpload() { addQuestion(QTI21QuestionType.upload); return new QTI21LobEditorPage(browser); diff --git a/src/test/java/org/olat/selenium/page/qti/QTI21Page.java b/src/test/java/org/olat/selenium/page/qti/QTI21Page.java index e0ec4b53898de7b3cb520b418a92896a04557b76..08e92e1e004c8bb8100484677097b23f2084086a 100644 --- a/src/test/java/org/olat/selenium/page/qti/QTI21Page.java +++ b/src/test/java/org/olat/selenium/page/qti/QTI21Page.java @@ -27,9 +27,11 @@ import org.olat.selenium.page.NavigationPage; import org.olat.selenium.page.graphene.OOGraphene; import org.olat.selenium.page.repository.RepositoryAccessPage; import org.openqa.selenium.By; +import org.openqa.selenium.Dimension; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.interactions.Actions; +import org.openqa.selenium.support.ui.Select; /** * @@ -125,6 +127,20 @@ public class QTI21Page { return this; } + /** + * Select the key of the inline choice interaction. + * + * @param key The key to select + * @return Itself + */ + public QTI21Page answerInlineChoice(String key) { + By inlineBy = By.xpath("//span[@class='inlineChoiceInteraction']/select"); + OOGraphene.waitElement(inlineBy, browser); + WebElement inlineEl = browser.findElement(inlineBy); + new Select(inlineEl).selectByValue(key); + return this; + } + public QTI21Page answerHotspot(String shape) { OOGraphene.waitElement(By.className("hotspotInteraction"), browser); By areaBy = By.xpath("//div[contains(@class,'hotspotInteraction')]//map/area[@shape='" + shape + "']"); @@ -134,6 +150,20 @@ public class QTI21Page { return this; } + /** + * Select the area with the specified data-qti-id. + * @param id The id save in data-qti-id + * @return Itself + */ + public QTI21Page answerGraphicOrderById(String id) { + OOGraphene.waitElement(By.className("graphicOrderInteraction"), browser); + By areaBy = By.xpath("//div[contains(@class,'graphicOrderInteraction')]//map/area[@data-qti-id='" + id + "']"); + List<WebElement> elements = browser.findElements(areaBy); + Assert.assertEquals("Hotspot with data-qti-id " + id, 1, elements.size()); + elements.get(0).click(); + return this; + } + public QTI21Page answerHottext(int index) { OOGraphene.waitElement(By.className("hottextInteraction"), browser); By checkBy = By.xpath("//div[contains(@class,'hottextInteraction')]//p/span[@class='hottext'][" + index + "]/input[@type='checkbox']"); @@ -196,6 +226,14 @@ public class QTI21Page { return this; } + /** + * The method check text within a <p> element. + * + * @param source Text in the source + * @param target Text in the target + * @param match Select or deselect + * @return Itself + */ public QTI21Page answerMatch(String source, String target, boolean match) { By matchBy = By.xpath("//div[contains(@class,'matchInteraction')]/table//tr[th/p[contains(text(),'" + source + "')]]/td[count(//div[contains(@class,'matchInteraction')]/table//tr/th[p[contains(text(),'" + target + "')]]/preceding-sibling::th)]/input"); WebElement matchEl = browser.findElement(matchBy); @@ -203,6 +241,13 @@ public class QTI21Page { return this; } + public QTI21Page answerMatch(String source, TrueFalse target, boolean match) { + By matchBy = By.xpath("//div[contains(@class,'matchInteraction')]/table//tr[td/p[contains(text(),'" + source + "')]]/td[" + (target.ordinal() + 1) + "]/input"); + WebElement matchEl = browser.findElement(matchBy); + OOGraphene.check(matchEl, match); + return this; + } + public QTI21Page answerMatchDropSourceToTarget(String source, String target) { By sourceBy = By.xpath("//li[contains(@class,'o_match_dnd_source')]/p[contains(text(),'" + source + "')]"); OOGraphene.waitElement(sourceBy, 5, browser); @@ -245,6 +290,151 @@ public class QTI21Page { return this; } + public QTI21Page answerAssociate(String source, int index, boolean left) { + By itemBy = By.xpath("//div[contains(@class,'o_associate_items')]/div[contains(@class,'o_associate_item')][contains(text(),'" + source + "')]"); + WebElement itemEl = browser.findElement(itemBy); + By targetBy = By.xpath("//div[@class='association'][" + index + "]/div[contains(@class,'association_box')][contains(@class,'" + (left ? "left" : "right") + "')]"); + WebElement targetEl = browser.findElement(targetBy); + new Actions(browser) + .moveToElement(itemEl, 10, 10) + .clickAndHold() + .moveToElement(targetEl, 10, 10) + .release() + .build() + .perform(); + return this; + } + + public QTI21Page answerGraphicAssociate(String id) { + OOGraphene.waitElement(By.className("graphicAssociateInteraction"), browser); + By areaBy = By.xpath("//div[contains(@class,'graphicAssociateInteraction')]//map/area[@data-qti-id='" + id + "']"); + List<WebElement> elements = browser.findElements(areaBy); + Assert.assertEquals("Area by " + id, 1, elements.size()); + elements.get(0).click(); + return this; + } + + public QTI21Page answerOrderDropItem(String source) { + By sourceBy = By.xpath("//li[contains(@class,'o_assessmentitem_order_item')][text()[contains(.,'" + source + "')]]"); + OOGraphene.waitElement(sourceBy, 5, browser); + WebElement sourceEl = browser.findElement(sourceBy); + By targetBy = By.xpath("//div[@class='orderInteraction']//div[contains(@class,'target')]/ul"); + WebElement targetEl = browser.findElement(targetBy); + new Actions(browser) + .moveToElement(sourceEl, 30, 30) + .clickAndHold() + .moveToElement(targetEl, 30, 30) + .release() + .build() + .perform(); + + By sourceDroppedBy = By.xpath("//div[@class='orderInteraction']//div[contains(@class,'target')]/ul/li[text()[contains(.,'" + source + "')]]"); + OOGraphene.waitElement(sourceDroppedBy, 5, browser); + return this; + } + + /** + * Select the gap match + * + * @param source The row to check + * @param target Text in the target + * @param match Select or deselect + * @return Itself + */ + public QTI21Page answerGapMatch(int row, String target, boolean match) { + By matchBy = By.xpath("//div[contains(@class,'gapMatchInteraction')]/table//tr[th[contains(text(),'" + row + "')]]/td[count(//div[contains(@class,'gapMatchInteraction')]/table//tr/th[text()[contains(.,'" + target + "')]]/preceding-sibling::th)]/input"); + WebElement matchEl = browser.findElement(matchBy); + OOGraphene.check(matchEl, match); + return this; + } + + /** + * Use the click and drop. + * + * @param item The identifier of the item + * @param gap The identifier of the gap + * @return Itself + */ + public QTI21Page answerGraphicGapClick(String item, String gap) { + By sourceBy = By.xpath("//div[contains(@class,'gap_container')]/div[contains(@class,'o_gap_item')][@data-qti-id='" + item + "']"); + OOGraphene.waitElement(sourceBy, 5, browser); + WebElement sourceEl = browser.findElement(sourceBy); + sourceEl.click(); + By targetBy = By.xpath("//div[@class='graphicGapMatchInteraction']//map/area[@data-qti-id='" + gap + "']"); + WebElement targetEl = browser.findElement(targetBy); + targetEl.click(); + return this; + } + + /** + * Select the point based on coordinates. + * + * @param x The x coordinate + * @param y The y coordinate + * @return Itself + */ + public QTI21Page answerSelectPoint(int x, int y) { + By canvasBy = By.xpath("//div[contains(@class,'selectPointInteraction')]/div/canvas"); + WebElement canvasEl = browser.findElement(canvasBy); + new Actions(browser) + .moveToElement(canvasEl, x, y) + .click() + .build() + .perform(); + return this; + } + + /** + * Select the object by its index (start with 0) and + * move it on the image and the specified coodinates. + * + * @param index The index of the object + * @param x The x target coordinate + * @param y The y target coordinate + * @return Itself + */ + public QTI21Page answerPositionObject(int index, int x, int y) { + By itemBy = By.xpath("//div[contains(@class,'positionObjectStage')]//div[@id='object-item-" + index + "']"); + OOGraphene.waitElement(itemBy, browser); + WebElement itemEl = browser.findElement(itemBy); + By targetBy = By.xpath("//div[@class='positionObjectStage']//img[contains(@id,'qtiworks_id_container_')]"); + WebElement targetEl = browser.findElement(targetBy); + new Actions(browser) + .moveToElement(itemEl, 5, 5) + .clickAndHold() + .moveToElement(targetEl, x, y) + .release() + .build() + .perform(); + return this; + } + + /** + * Select the point based on coordinates. + * + * @param x The x coordinate + * @return Itself + */ + public QTI21Page answerVerticalSlider(int val) { + By sliderBy = By.xpath("//div[contains(@class,'sliderInteraction')]/div[contains(@class,'sliderVertical')]/div[contains(@class,'sliderWidget')]"); + OOGraphene.waitElement(sliderBy, browser); + WebElement sliderEl = browser.findElement(sliderBy); + Dimension size = sliderEl.getSize(); + float height = (size.getHeight() / 100f) * val; + float scaledY = size.getHeight() - height; + + new Actions(browser) + .moveToElement(sliderEl, 5, Math.round(scaledY)) + .click() + .build() + .perform(); + + + By valueBy = By.xpath("//div[contains(@class,'sliderInteraction')]/div[contains(@class,'sliderVertical')]/div[contains(@class,'sliderValue')]/span[text()='" + val + "']"); + OOGraphene.waitElement(valueBy, browser); + return this; + } + public QTI21Page answerUpload(File file) { By inputBy = By.cssSelector(".uploadInteraction input[type='file']"); OOGraphene.uploadFile(inputBy, file, browser); @@ -313,12 +503,61 @@ public class QTI21Page { return this; } + /** + * Check if the feedback with the specified content is visible. + * + * @param text Text of the feedback. + * @return Itself + */ + public QTI21Page assertFeedbackText(String text) { + By feedbackBy = By.xpath("//div[contains(@class,'modalFeedback')][text()[contains(normalize-space(.),'" + text + "')]]"); + OOGraphene.waitElement(feedbackBy, 5, browser); + return this; + } + + /** + * Check if an inline feedback with the specified text + * is visible. + * + * @param text The text of the inline feedback + * @return Itself + */ + public QTI21Page assertFeedbackInline(String text) { + By feedbackBy = By.xpath("//span[contains(@class,'feedbackInline')][text()[contains(normalize-space(.),'" + text + "')]]"); + OOGraphene.waitElement(feedbackBy, 5, browser); + return this; + } + + /** + * Check that no inline feedback with the specified text + * is visible. + * + * @param text The text of the inline feedback + * @return Itself + */ + public QTI21Page assertNoFeedbackInline(String text) { + By feedbackBy = By.xpath("//span[contains(@class,'feedbackInline')][text()[contains(normalize-space(.),'" + text + "')]]"); + OOGraphene.waitElementDisappears(feedbackBy, 5, browser); + return this; + } + public QTI21Page assertNoFeedback(String title) { By feedbackBy = By.xpath("//div[contains(@class,'modalFeedback')]/h4[contains(text(),'" + title + "')]"); OOGraphene.waitElementDisappears(feedbackBy, 5, browser); return this; } + /** + * + * @param text The text of the feedback + * @return Itself + */ + public QTI21Page assertNoFeedbackText(String text) { + By feedbackBy = By.xpath("//div[contains(@class,'modalFeedback')][text()[contains(normalize-space(.),'\" + text + \"')]]"); + OOGraphene.waitElementDisappears(feedbackBy, 5, browser); + return this; + } + /** * Check that there are no feedbacks visible. * @@ -448,6 +687,12 @@ public class QTI21Page { return this; } + public QTI21Page assertOnAssessmentItemScore(String title, int score) { + By resultsBy = By.xpath("//div[contains(@class,'o_qti_item')][div/h4[text()[contains(.,'" + title + "')]]]//tr[contains(@class,'o_sel_assessmentitem_score')]//span[@class='o_sel_assessmentitem_score'][contains(text(),'" + score + "')]"); + OOGraphene.waitElement(resultsBy, 5, browser); + return this; + } + public QTI21Page assertOnAssessmentTestScore(String score) { By resultsBy = By.xpath("//div[contains(@class,'o_sel_results_details')]//tr[contains(@class,'o_sel_assessmenttest_scores')]/td/div/span[contains(@class,'o_sel_assessmenttest_score')][contains(text(),'" + score + "')]"); OOGraphene.waitElement(resultsBy, 5, browser); @@ -606,4 +851,10 @@ public class QTI21Page { OOGraphene.waitBusy(browser); return QTI21Page.getQTI12Page(browser); } + + public enum TrueFalse { + unanswered, + right, + wrong + } } diff --git a/src/test/java/org/olat/test/AllTestsJunit4.java b/src/test/java/org/olat/test/AllTestsJunit4.java index 891a3297bf51b3c2ed56146fa71d2be5537fa63f..bf0a00cfc17d8624946e43395e4bc9b4575d4e40 100644 --- a/src/test/java/org/olat/test/AllTestsJunit4.java +++ b/src/test/java/org/olat/test/AllTestsJunit4.java @@ -245,6 +245,7 @@ import org.junit.runners.Suite; org.olat.ims.qti21.model.xml.OnyxToQtiWorksAssessementTestsTest.class, org.olat.ims.qti21.model.xml.OpenOLATAssessementItemsTest.class, org.olat.ims.qti21.model.xml.QTI21ExplorerHandlerTest.class, + org.olat.ims.qti21.ui.components.AssessmentRenderFunctionsTest.class, org.olat.ims.lti.LTIManagerTest.class, org.olat.modules.qpool.manager.MetadataConverterHelperTest.class, org.olat.modules.qpool.manager.QuestionDAOTest.class, diff --git a/src/test/java/org/olat/test/ArquillianDeployments.java b/src/test/java/org/olat/test/ArquillianDeployments.java index 0f68293ddca31b06aae7268925616354f1b63b3f..3d7e841df87086bf5b58daa175e08f58199f83f1 100644 --- a/src/test/java/org/olat/test/ArquillianDeployments.java +++ b/src/test/java/org/olat/test/ArquillianDeployments.java @@ -47,10 +47,10 @@ public class ArquillianDeployments { public static final String WEBINF = "src/main/webapp/WEB-INF"; public static final String WEBINF_TOMCAT = "src/main/webapp-tomcat/WEB-INF"; public static final String TEST_RSRC = "src/test/resources"; - public static final String LIB_DIR = "target/openolat-lms-12.3-SNAPSHOT/WEB-INF/lib"; + public static final String LIB_DIR = "target/openolat-lms-12.4-SNAPSHOT/WEB-INF/lib"; public static WebArchive createDeployment() { - return createDeployment("openolat.war", new HashMap<String,String>()); + return createDeployment("openolat.war", new HashMap<>()); } public static WebArchive createDeployment(Map<String,String> overrideProperties) { diff --git a/src/test/java/org/olat/test/file_resources/qti21/import_qti21_excel_match.txt b/src/test/java/org/olat/test/file_resources/qti21/import_qti21_excel_match.txt new file mode 100644 index 0000000000000000000000000000000000000000..d54fbf1f6f2c46c4a822f71bfee226a7e26b352a --- /dev/null +++ b/src/test/java/org/olat/test/file_resources/qti21/import_qti21_excel_match.txt @@ -0,0 +1,29 @@ +Typ MATRIX +Title Hauptstädte Europas +Question Hauptstädte Europas +Feedback correct answer Bravo! Die Antwort ich absolut korrekt weil ban wirklich verbannen heisst. +Points 3 + Deutschland Frankreich Schweiz +Berlin 1 0 0 +Bern 0 0 1 +Paris 0 1 0 + + +Typ Drag&drop +Title Hauptstädte Afrika +Question Hauptstädte Afrika +Points 3 + Algerien Kenia Namibia +Nairobi 0 1 0 +Windhoek 0 0 1 +Algier 1 0 0 + + +Typ Truefalse +Title Hauptstädte Europa +Question Hauptstädte Europa +Points 3 + Unanswered Right Wrong +Paris ist in Frankreich 0 1 0 +Bern ist in Schweiz 0 1 0 +Stockholm ist in Danemark 0 0 1 \ No newline at end of file diff --git a/src/test/java/org/olat/test/file_resources/qti21/simple_QTI_21_associate_ims.zip b/src/test/java/org/olat/test/file_resources/qti21/simple_QTI_21_associate_ims.zip new file mode 100644 index 0000000000000000000000000000000000000000..9b934b71c3348f76ce414d70d79a12b9351a8701 Binary files /dev/null and b/src/test/java/org/olat/test/file_resources/qti21/simple_QTI_21_associate_ims.zip differ diff --git a/src/test/java/org/olat/test/file_resources/qti21/simple_QTI_21_end_ims.zip b/src/test/java/org/olat/test/file_resources/qti21/simple_QTI_21_end_ims.zip new file mode 100644 index 0000000000000000000000000000000000000000..734c7968e5c35530872d5bcefbcb9d2b1436040f Binary files /dev/null and b/src/test/java/org/olat/test/file_resources/qti21/simple_QTI_21_end_ims.zip differ diff --git a/src/test/java/org/olat/test/file_resources/qti21/simple_QTI_21_gap_match_ims.zip b/src/test/java/org/olat/test/file_resources/qti21/simple_QTI_21_gap_match_ims.zip new file mode 100644 index 0000000000000000000000000000000000000000..9054f45e1c0ad30c32989d55e8cf996d7404e888 Binary files /dev/null and b/src/test/java/org/olat/test/file_resources/qti21/simple_QTI_21_gap_match_ims.zip differ diff --git a/src/test/java/org/olat/test/file_resources/qti21/simple_QTI_21_graphic_associate_ims.zip b/src/test/java/org/olat/test/file_resources/qti21/simple_QTI_21_graphic_associate_ims.zip new file mode 100644 index 0000000000000000000000000000000000000000..b1a9e390d0d81196767f7c6e9c55ff25ecd17843 Binary files /dev/null and b/src/test/java/org/olat/test/file_resources/qti21/simple_QTI_21_graphic_associate_ims.zip differ diff --git a/src/test/java/org/olat/test/file_resources/qti21/simple_QTI_21_graphic_gap_match_ims.zip b/src/test/java/org/olat/test/file_resources/qti21/simple_QTI_21_graphic_gap_match_ims.zip new file mode 100644 index 0000000000000000000000000000000000000000..6658b1444f31f894869792333accde652bfa6e13 Binary files /dev/null and b/src/test/java/org/olat/test/file_resources/qti21/simple_QTI_21_graphic_gap_match_ims.zip differ diff --git a/src/test/java/org/olat/test/file_resources/qti21/simple_QTI_21_graphic_order_ims.zip b/src/test/java/org/olat/test/file_resources/qti21/simple_QTI_21_graphic_order_ims.zip new file mode 100644 index 0000000000000000000000000000000000000000..c6295034b81d860a7ca91e82d09162b4f116b184 Binary files /dev/null and b/src/test/java/org/olat/test/file_resources/qti21/simple_QTI_21_graphic_order_ims.zip differ diff --git a/src/test/java/org/olat/test/file_resources/qti21/simple_QTI_21_inline_choice_ims.zip b/src/test/java/org/olat/test/file_resources/qti21/simple_QTI_21_inline_choice_ims.zip new file mode 100644 index 0000000000000000000000000000000000000000..bc8ac24ad6b99d1a0f83c1df9e93b46cce59617f Binary files /dev/null and b/src/test/java/org/olat/test/file_resources/qti21/simple_QTI_21_inline_choice_ims.zip differ diff --git a/src/test/java/org/olat/test/file_resources/qti21/simple_QTI_21_match_ims.zip b/src/test/java/org/olat/test/file_resources/qti21/simple_QTI_21_match_ims.zip new file mode 100644 index 0000000000000000000000000000000000000000..78a2c3679a8e4469f6dc5b5ea29342b1d8752e16 Binary files /dev/null and b/src/test/java/org/olat/test/file_resources/qti21/simple_QTI_21_match_ims.zip differ diff --git a/src/test/java/org/olat/test/file_resources/qti21/simple_QTI_21_order_ims.zip b/src/test/java/org/olat/test/file_resources/qti21/simple_QTI_21_order_ims.zip new file mode 100644 index 0000000000000000000000000000000000000000..17feeda76f0d0c0e3b916432d6633a3cdaed2f6b Binary files /dev/null and b/src/test/java/org/olat/test/file_resources/qti21/simple_QTI_21_order_ims.zip differ diff --git a/src/test/java/org/olat/test/file_resources/qti21/simple_QTI_21_position_object_ims.zip b/src/test/java/org/olat/test/file_resources/qti21/simple_QTI_21_position_object_ims.zip new file mode 100644 index 0000000000000000000000000000000000000000..a4b7033e23ab14dd360fdf26656d25fad4b198db Binary files /dev/null and b/src/test/java/org/olat/test/file_resources/qti21/simple_QTI_21_position_object_ims.zip differ diff --git a/src/test/java/org/olat/test/file_resources/qti21/simple_QTI_21_select_point_ims.zip b/src/test/java/org/olat/test/file_resources/qti21/simple_QTI_21_select_point_ims.zip new file mode 100644 index 0000000000000000000000000000000000000000..61be744db788c68d9df72b535acefc60ba03ddc2 Binary files /dev/null and b/src/test/java/org/olat/test/file_resources/qti21/simple_QTI_21_select_point_ims.zip differ diff --git a/src/test/java/org/olat/test/file_resources/qti21/simple_QTI_21_slider_ims.zip b/src/test/java/org/olat/test/file_resources/qti21/simple_QTI_21_slider_ims.zip new file mode 100644 index 0000000000000000000000000000000000000000..5cb3f2b418ee8d38f31efea77864950ff644b1a2 Binary files /dev/null and b/src/test/java/org/olat/test/file_resources/qti21/simple_QTI_21_slider_ims.zip differ