From f717372cd950ccc3dc883f56fad894e70d2c066d Mon Sep 17 00:00:00 2001
From: srosse <stephane.rosse@frentix.com>
Date: Wed, 23 Oct 2019 18:43:40 +0200
Subject: [PATCH] OO-4317: don't convert button for corrupted QTI 1.2 questions

---
 .../olat/ims/qti/QTI12EditorController.java   |  5 ++
 .../qti/qpool/QTIQPoolServiceProvider.java    |  5 +-
 .../ims/qti21/pool/QTI21EditorController.java |  5 ++
 .../qti21/pool/QTI21QPoolServiceProvider.java |  6 +--
 .../qti21/ui/_i18n/LocalStrings_fr.properties |  2 +-
 .../qpool/QPoolItemEditorController.java      |  2 +
 .../java/org/olat/modules/qpool/QPoolSPI.java |  2 +-
 .../qpool/impl/FileQPoolServiceProvider.java  |  9 ++--
 .../qpool/impl/TextQPoolServiceProvider.java  |  9 ++--
 .../qpool/ui/FilePreviewController.java       | 18 ++++++-
 .../ui/QuestionItemDetailsController.java     | 15 ++++--
 .../qpool/ui/TextPreviewController.java       | 52 +++++++++++--------
 .../qpool/ui/_content/item_details.html       | 12 ++++-
 .../qpool/ui/_i18n/LocalStrings_de.properties |  1 +
 .../qpool/ui/_i18n/LocalStrings_en.properties |  1 +
 .../qpool/ui/_i18n/LocalStrings_fr.properties |  1 +
 .../ui/_i18n/LocalStrings_pt_BR.properties    |  1 +
 17 files changed, 100 insertions(+), 46 deletions(-)

diff --git a/src/main/java/org/olat/ims/qti/QTI12EditorController.java b/src/main/java/org/olat/ims/qti/QTI12EditorController.java
index c8e209b820d..767b71039b8 100644
--- a/src/main/java/org/olat/ims/qti/QTI12EditorController.java
+++ b/src/main/java/org/olat/ims/qti/QTI12EditorController.java
@@ -91,6 +91,11 @@ public class QTI12EditorController extends BasicController implements QPoolItemE
 		putInitialPanel(mainVC);
 	}
 	
+	@Override
+	public boolean isValid() {
+		return item != null;
+	}
+
 	@Override
 	public QuestionItem getItem() {
 		return qitem;
diff --git a/src/main/java/org/olat/ims/qti/qpool/QTIQPoolServiceProvider.java b/src/main/java/org/olat/ims/qti/qpool/QTIQPoolServiceProvider.java
index 9370bd32bc3..64a44c4e957 100644
--- a/src/main/java/org/olat/ims/qti/qpool/QTIQPoolServiceProvider.java
+++ b/src/main/java/org/olat/ims/qti/qpool/QTIQPoolServiceProvider.java
@@ -30,6 +30,7 @@ import java.util.zip.ZipOutputStream;
 
 import javax.xml.XMLConstants;
 
+import org.apache.logging.log4j.Logger;
 import org.dom4j.Document;
 import org.dom4j.Element;
 import org.olat.core.commons.persistence.DB;
@@ -41,7 +42,6 @@ import org.olat.core.gui.translator.Translator;
 import org.olat.core.helpers.Settings;
 import org.olat.core.id.Identity;
 import org.olat.core.id.OLATResourceable;
-import org.apache.logging.log4j.Logger;
 import org.olat.core.logging.Tracing;
 import org.olat.core.util.FileUtils;
 import org.olat.core.util.Util;
@@ -69,6 +69,7 @@ import org.olat.ims.resources.IMSEntityResolver;
 import org.olat.modules.qpool.ExportFormatOptions;
 import org.olat.modules.qpool.ExportFormatOptions.Outcome;
 import org.olat.modules.qpool.QItemFactory;
+import org.olat.modules.qpool.QPoolItemEditorController;
 import org.olat.modules.qpool.QPoolSPI;
 import org.olat.modules.qpool.QPoolService;
 import org.olat.modules.qpool.QuestionItem;
@@ -381,7 +382,7 @@ public class QTIQPoolServiceProvider implements QPoolSPI {
 	}
 
 	@Override
-	public Controller getEditableController(UserRequest ureq, WindowControl wControl, QuestionItem item) {
+	public QPoolItemEditorController getEditableController(UserRequest ureq, WindowControl wControl, QuestionItem item) {
 		return new QTI12EditorController(ureq, wControl, item);
 	}
 
diff --git a/src/main/java/org/olat/ims/qti21/pool/QTI21EditorController.java b/src/main/java/org/olat/ims/qti21/pool/QTI21EditorController.java
index 8a9243b1bd1..830c573a41d 100644
--- a/src/main/java/org/olat/ims/qti21/pool/QTI21EditorController.java
+++ b/src/main/java/org/olat/ims/qti21/pool/QTI21EditorController.java
@@ -88,6 +88,11 @@ public class QTI21EditorController extends BasicController implements QPoolItemE
 		putInitialPanel(mainVC);
 	}
 	
+	@Override
+	public boolean isValid() {
+		return true;
+	}
+
 	@Override
 	public QuestionItem getItem() {
 		return questionItem;
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 f6d6ddbcd2f..d7e05d8982b 100644
--- a/src/main/java/org/olat/ims/qti21/pool/QTI21QPoolServiceProvider.java
+++ b/src/main/java/org/olat/ims/qti21/pool/QTI21QPoolServiceProvider.java
@@ -39,13 +39,13 @@ import java.util.zip.ZipOutputStream;
 
 import javax.xml.XMLConstants;
 
+import org.apache.logging.log4j.Logger;
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.control.Controller;
 import org.olat.core.gui.control.WindowControl;
 import org.olat.core.gui.media.MediaResource;
 import org.olat.core.helpers.Settings;
 import org.olat.core.id.Identity;
-import org.apache.logging.log4j.Logger;
 import org.olat.core.logging.Tracing;
 import org.olat.core.util.FileUtils;
 import org.olat.core.util.StringHelper;
@@ -76,6 +76,7 @@ import org.olat.imscp.xml.manifest.ResourceType;
 import org.olat.modules.qpool.ExportFormatOptions;
 import org.olat.modules.qpool.ExportFormatOptions.Outcome;
 import org.olat.modules.qpool.QItemFactory;
+import org.olat.modules.qpool.QPoolItemEditorController;
 import org.olat.modules.qpool.QPoolSPI;
 import org.olat.modules.qpool.QPoolService;
 import org.olat.modules.qpool.QuestionItem;
@@ -321,7 +322,7 @@ public class QTI21QPoolServiceProvider implements QPoolSPI {
 	}
 
 	@Override
-	public Controller getEditableController(UserRequest ureq, WindowControl wControl, QuestionItem qitem) {
+	public QPoolItemEditorController getEditableController(UserRequest ureq, WindowControl wControl, QuestionItem qitem) {
 		return new QTI21EditorController(ureq, wControl, qitem, false);
 	}
 
@@ -329,7 +330,6 @@ public class QTI21QPoolServiceProvider implements QPoolSPI {
 	public Controller getReadOnlyController(UserRequest ureq, WindowControl wControl, QuestionItem item) {
 		return new QTI21EditorController(ureq, wControl, item, true);
 	}
-	
 
 	public QuestionItem createItem(Identity identity, QTI21QuestionType type, String title, Locale locale) {
 		AssessmentItemBuilder itemBuilder = AssessmentItemBuilderFactory.get(type, locale);
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 46a32b1831f..b516580424d 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
@@ -103,7 +103,7 @@ drawing.opacity=Opacit\u00E9
 error.as.directed=Veuillez r\u00E9pondre \u00E0 la question comme indiqu\u00E9.
 error.as.directed.kprim=Veuillez r\u00E9pondre \u00E0 la question comme indiqu\u00E9.
 error.assessment.item=Le fichier n'a pas pu \u00EAtre lu. Il semble soit corrompu soit au mauvais format.
-error.assessment.item.missing=Le fichier de la question n'a pas \u00EAtre d\u00E9chiffr\u00E9.
+error.assessment.item.missing=Le fichier de la question n'a pas \u00EAtre lu.
 error.choice=Vous devez choisir une des options suivantes.
 error.digital.certificate.cannotread=Le certificat n'a pas pu \u00EAtre lu.
 error.digital.certificate.noPrivateKey=La "cl\u00E9 priv\u00E9e" n'a pas \u00E9t\u00E9 trouv\u00E9e. Elle est obligatoire.
diff --git a/src/main/java/org/olat/modules/qpool/QPoolItemEditorController.java b/src/main/java/org/olat/modules/qpool/QPoolItemEditorController.java
index a2ed5cfa1d3..e0b128b2257 100644
--- a/src/main/java/org/olat/modules/qpool/QPoolItemEditorController.java
+++ b/src/main/java/org/olat/modules/qpool/QPoolItemEditorController.java
@@ -30,5 +30,7 @@ import org.olat.core.gui.control.Controller;
 public interface QPoolItemEditorController extends Controller {
 	
 	public QuestionItem getItem();
+	
+	public boolean isValid();
 
 }
diff --git a/src/main/java/org/olat/modules/qpool/QPoolSPI.java b/src/main/java/org/olat/modules/qpool/QPoolSPI.java
index 2b741bc40e0..0dba226e108 100644
--- a/src/main/java/org/olat/modules/qpool/QPoolSPI.java
+++ b/src/main/java/org/olat/modules/qpool/QPoolSPI.java
@@ -124,7 +124,7 @@ public interface QPoolSPI {
 	 * @param item
 	 * @return
 	 */
-	public Controller getEditableController(UserRequest ureq, WindowControl wControl, QuestionItem item);
+	public QPoolItemEditorController getEditableController(UserRequest ureq, WindowControl wControl, QuestionItem item);
 	
 	/**
 	 * Return the editable controller in a read only modus. This controller is e.g.
diff --git a/src/main/java/org/olat/modules/qpool/impl/FileQPoolServiceProvider.java b/src/main/java/org/olat/modules/qpool/impl/FileQPoolServiceProvider.java
index 61ed07a21cb..ad98d68a3be 100644
--- a/src/main/java/org/olat/modules/qpool/impl/FileQPoolServiceProvider.java
+++ b/src/main/java/org/olat/modules/qpool/impl/FileQPoolServiceProvider.java
@@ -27,6 +27,7 @@ import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.control.Controller;
 import org.olat.core.gui.control.WindowControl;
 import org.olat.modules.qpool.QItemFactory;
+import org.olat.modules.qpool.QPoolItemEditorController;
 import org.olat.modules.qpool.QPoolService;
 import org.olat.modules.qpool.QuestionItem;
 import org.olat.modules.qpool.QuestionType;
@@ -86,8 +87,7 @@ public class FileQPoolServiceProvider extends AbstractQPoolServiceProvider {
 
 	@Override
 	public Controller getPreviewController(UserRequest ureq, WindowControl wControl, QuestionItem item, boolean summary) {
-		FilePreviewController fileController = new FilePreviewController(ureq, wControl, item);
-		return fileController;
+		return new FilePreviewController(ureq, wControl, item);
 	}
 
 	@Override
@@ -96,9 +96,8 @@ public class FileQPoolServiceProvider extends AbstractQPoolServiceProvider {
 	}
 
 	@Override
-	public Controller getEditableController(UserRequest ureq,	WindowControl wControl, QuestionItem item) {
-		FilePreviewController fileController = new FilePreviewController(ureq, wControl, item);
-		return fileController;
+	public QPoolItemEditorController getEditableController(UserRequest ureq,	WindowControl wControl, QuestionItem item) {
+		return new FilePreviewController(ureq, wControl, item);
 	}
 
 	@Override
diff --git a/src/main/java/org/olat/modules/qpool/impl/TextQPoolServiceProvider.java b/src/main/java/org/olat/modules/qpool/impl/TextQPoolServiceProvider.java
index de5c43b21c6..cb63334ccd4 100644
--- a/src/main/java/org/olat/modules/qpool/impl/TextQPoolServiceProvider.java
+++ b/src/main/java/org/olat/modules/qpool/impl/TextQPoolServiceProvider.java
@@ -27,6 +27,7 @@ import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.control.Controller;
 import org.olat.core.gui.control.WindowControl;
 import org.olat.modules.qpool.QItemFactory;
+import org.olat.modules.qpool.QPoolItemEditorController;
 import org.olat.modules.qpool.QPoolService;
 import org.olat.modules.qpool.QuestionItem;
 import org.olat.modules.qpool.QuestionType;
@@ -84,8 +85,7 @@ public class TextQPoolServiceProvider extends AbstractQPoolServiceProvider {
 
 	@Override
 	public Controller getPreviewController(UserRequest ureq, WindowControl wControl, QuestionItem item, boolean summary) {
-		TextPreviewController txtController = new TextPreviewController(ureq, wControl, item, summary);
-		return txtController;
+		return new TextPreviewController(ureq, wControl, item, summary);
 	}
 
 	@Override
@@ -94,9 +94,8 @@ public class TextQPoolServiceProvider extends AbstractQPoolServiceProvider {
 	}
 
 	@Override
-	public Controller getEditableController(UserRequest ureq, WindowControl wControl, QuestionItem item) {
-		TextPreviewController txtController = new TextPreviewController(ureq, wControl, item, false);
-		return txtController;
+	public QPoolItemEditorController getEditableController(UserRequest ureq, WindowControl wControl, QuestionItem item) {
+		return new TextPreviewController(ureq, wControl, item, false);
 	}
 
 	@Override
diff --git a/src/main/java/org/olat/modules/qpool/ui/FilePreviewController.java b/src/main/java/org/olat/modules/qpool/ui/FilePreviewController.java
index 9803027ab94..8b6cb9fdcee 100644
--- a/src/main/java/org/olat/modules/qpool/ui/FilePreviewController.java
+++ b/src/main/java/org/olat/modules/qpool/ui/FilePreviewController.java
@@ -27,8 +27,9 @@ import org.olat.core.gui.control.Event;
 import org.olat.core.gui.control.WindowControl;
 import org.olat.core.gui.control.controller.BasicController;
 import org.olat.core.util.vfs.VFSLeaf;
-import org.olat.modules.qpool.QuestionItem;
+import org.olat.modules.qpool.QPoolItemEditorController;
 import org.olat.modules.qpool.QPoolService;
+import org.olat.modules.qpool.QuestionItem;
 
 /**
  * 
@@ -36,12 +37,15 @@ import org.olat.modules.qpool.QPoolService;
  * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
  *
  */
-public class FilePreviewController extends BasicController {
+public class FilePreviewController extends BasicController implements QPoolItemEditorController {
 
 	private final VelocityContainer mainVC;
+
+	private final QuestionItem qitem;
 	
 	public FilePreviewController(UserRequest ureq, WindowControl wControl, QuestionItem qitem) {
 		super(ureq, wControl);
+		this.qitem = qitem;
 		QPoolService qpoolService = CoreSpringFactory.getImpl(QPoolService.class);
 		mainVC = createVelocityContainer("file_preview");
 		
@@ -53,6 +57,16 @@ public class FilePreviewController extends BasicController {
 		putInitialPanel(mainVC);
 	}
 
+	@Override
+	public QuestionItem getItem() {
+		return qitem;
+	}
+
+	@Override
+	public boolean isValid() {
+		return true;
+	}
+
 	@Override
 	protected void doDispose() {
 		//
diff --git a/src/main/java/org/olat/modules/qpool/ui/QuestionItemDetailsController.java b/src/main/java/org/olat/modules/qpool/ui/QuestionItemDetailsController.java
index 58229966c92..2616db26074 100644
--- a/src/main/java/org/olat/modules/qpool/ui/QuestionItemDetailsController.java
+++ b/src/main/java/org/olat/modules/qpool/ui/QuestionItemDetailsController.java
@@ -54,6 +54,7 @@ import org.olat.group.model.BusinessGroupSelectionEvent;
 import org.olat.group.ui.main.SelectBusinessGroupController;
 import org.olat.ims.qti.QTIConstants;
 import org.olat.modules.qpool.Pool;
+import org.olat.modules.qpool.QPoolItemEditorController;
 import org.olat.modules.qpool.QPoolSPI;
 import org.olat.modules.qpool.QPoolSecurityCallback;
 import org.olat.modules.qpool.QPoolService;
@@ -132,6 +133,7 @@ public class QuestionItemDetailsController extends BasicController implements To
 	private final int numberOfItems;
 	private Boolean showMetadatas;
 	private LockResult lock;
+	private boolean valid = true;
 	private boolean questionEdited = false;
 	
 	@Autowired
@@ -195,9 +197,12 @@ public class QuestionItemDetailsController extends BasicController implements To
 			showWarning("locked.readonly", new String[] {displayName});
 		}
 		
+		
 		if (spi != null) {
 			if (canEditContent) {
-				questionCtrl = spi.getEditableController(ureq, getWindowControl(), item);
+				QPoolItemEditorController editQuestionCtrl = spi.getEditableController(ureq, getWindowControl(), item);
+				valid = editQuestionCtrl.isValid();
+				questionCtrl = editQuestionCtrl;
 			} else {
 				questionCtrl = spi.getReadOnlyController(ureq, getWindowControl(), item);
 			}
@@ -211,7 +216,11 @@ public class QuestionItemDetailsController extends BasicController implements To
 		listenTo(questionCtrl);
 
 		if(mainVC != null) {
-			mainVC.put("type_specifics", questionCtrl.getInitialComponent());
+			if(valid) {
+				mainVC.put("type_specifics", questionCtrl.getInitialComponent());
+			} else {
+				mainVC.contextPut("corrupted", Boolean.TRUE);
+			}
 		}
 	}
 
@@ -247,7 +256,7 @@ public class QuestionItemDetailsController extends BasicController implements To
 		copyItemLink.setIconLeftCSS("o_icon o_icon-fw o_icon_qitem_copy");
 		commandDropdown.addComponent(copyItemLink);
 		
-		if (QTIConstants.QTI_12_FORMAT.equals(metadatasCtrl.getItem().getFormat())) {
+		if (QTIConstants.QTI_12_FORMAT.equals(metadatasCtrl.getItem().getFormat()) && valid) {
 			convertItemLink = LinkFactory.createToolLink("convert", translate("convert.item"), this);
 			convertItemLink.setIconLeftCSS("o_icon o_icon-fw o_icon_qitem_convert");
 			commandDropdown.addComponent(convertItemLink);
diff --git a/src/main/java/org/olat/modules/qpool/ui/TextPreviewController.java b/src/main/java/org/olat/modules/qpool/ui/TextPreviewController.java
index c49e34f8e08..75e58515b56 100644
--- a/src/main/java/org/olat/modules/qpool/ui/TextPreviewController.java
+++ b/src/main/java/org/olat/modules/qpool/ui/TextPreviewController.java
@@ -23,8 +23,6 @@ import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.StringWriter;
 
-import org.apache.commons.io.IOUtils;
-import org.olat.core.CoreSpringFactory;
 import org.olat.core.gui.UserRequest;
 import org.olat.core.gui.components.Component;
 import org.olat.core.gui.components.velocity.VelocityContainer;
@@ -32,8 +30,10 @@ import org.olat.core.gui.control.Event;
 import org.olat.core.gui.control.WindowControl;
 import org.olat.core.gui.control.controller.BasicController;
 import org.olat.core.util.vfs.VFSLeaf;
-import org.olat.modules.qpool.QuestionItem;
+import org.olat.modules.qpool.QPoolItemEditorController;
 import org.olat.modules.qpool.QPoolService;
+import org.olat.modules.qpool.QuestionItem;
+import org.springframework.beans.factory.annotation.Autowired;
 
 /**
  * 
@@ -41,14 +41,15 @@ import org.olat.modules.qpool.QPoolService;
  * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
  *
  */
-public class TextPreviewController extends BasicController {
+public class TextPreviewController extends BasicController implements QPoolItemEditorController {
 
 	private final VelocityContainer mainVC;
-	private final QPoolService qpoolService;
+	
+	@Autowired
+	private QPoolService qpoolService;
 	
 	public TextPreviewController(UserRequest ureq, WindowControl wControl, QuestionItem qitem, boolean summary) {
 		super(ureq, wControl);
-		qpoolService = CoreSpringFactory.getImpl(QPoolService.class);
 		mainVC = createVelocityContainer("text_preview");
 		
 		VFSLeaf leaf = qpoolService.getRootLeaf(qitem);
@@ -64,34 +65,41 @@ public class TextPreviewController extends BasicController {
 		putInitialPanel(mainVC);
 	}
 
+	@Override
+	public QuestionItem getItem() {
+		return null;
+	}
+
+	@Override
+	public boolean isValid() {
+		return true;
+	}
+
 	@Override
 	protected void doDispose() {
 		//
 	}
 	
 	protected String readSummary(VFSLeaf leaf) {
-    StringWriter out = new StringWriter();
-    InputStream in = leaf.getInputStream();
-    InputStreamReader inr = new InputStreamReader(in);
-		try {
+		StringWriter out = new StringWriter();
+   
+		try( InputStream in = leaf.getInputStream();
+			    InputStreamReader inr = new InputStreamReader(in)) {
 			char[] buffer = new char[4096];
 			
 			int count = 0;
-	    int n = 0;
-	    while (-1 != (n = inr.read(buffer))) {
-	        out.write(buffer, 0, n);
-	        count += n;
-	        if(count >= 10000) {
-	        	break;
-	        }
-	    }
+		    int n = 0;
+		    while (-1 != (n = inr.read(buffer))) {
+		        out.write(buffer, 0, n);
+		        count += n;
+		        if(count >= 10000) {
+		        	break;
+		        }
+		    }
 		} catch (Exception e) {
 			logError("", e);
-		} finally {
-			IOUtils.closeQuietly(inr);
-			IOUtils.closeQuietly(in);
 		}
-  	return out.toString();
+		return out.toString();
 	}
 
 	@Override
diff --git a/src/main/java/org/olat/modules/qpool/ui/_content/item_details.html b/src/main/java/org/olat/modules/qpool/ui/_content/item_details.html
index 91228600d8f..a6edb9efbcc 100644
--- a/src/main/java/org/olat/modules/qpool/ui/_content/item_details.html
+++ b/src/main/java/org/olat/modules/qpool/ui/_content/item_details.html
@@ -13,7 +13,11 @@
 <div class="row">
 	#if($metadataSwitch)
 		<div class="col-md-8">
-			$r.render("type_specifics")
+			#if($r.isTrue($corrupted))
+				<div class="o_error">$r.translate("error.corrupted.question")</div>
+			#elseif($r.available("type_specifics"))
+				$r.render("type_specifics")
+			#end
 			$r.render("comments")
 		</div>
 		<div class="col-md-4">
@@ -21,7 +25,11 @@
 		</div>
 	#else
 	<div class="col-md-12">
-		$r.render("type_specifics")
+		#if($r.isTrue($corrupted))
+			<div class="o_error">$r.translate("error.corrupted.question")</div>
+		#elseif($r.available("type_specifics"))
+			$r.render("type_specifics")
+		#end
 		$r.render("comments")
 	</div>
 	#end
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 810a9eb0e7e..93a2c38898d 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
@@ -60,6 +60,7 @@ educational.learningTime.day=d
 educational.learningTime.hour=h
 educational.learningTime.minute=m
 educational.learningTime.second=s
+error.corrupted.question=Die Datei der Frage konnte nicht gelesen werden.
 error.input.toolong=Leider ist Ihr gerade eingegebener Text mit {1} Zeichen zu lang. Bitte beschr\u00E4nken Sie sich auf maximal {0} Zeichen.
 error.qti.deprecated=Diese Version von QTI wird nicht mehr unterst\u00FCtzt. Bitte auf das neue QTI 2.1 konvertieren.
 error.select.one=Sie m\u00FCssen mindestens eine Frage w\u00E4hlen.
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 26396d809ec..1045cc6a1e7 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
@@ -60,6 +60,7 @@ educational.learningTime.day=d
 educational.learningTime.hour=h
 educational.learningTime.minute=m
 educational.learningTime.second=s
+error.corrupted.question=The file of the question cannot be read.
 error.input.toolong=The text you entered is to long ({1} characters). Only {1} characters are allowed.
 error.qti.deprecated=This version of QTI is deprecated. Please consider to convert your test to QTI 2.1.
 error.select.one=You need to select at least one question.
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 3cebff480b2..c9bc01c6dd1 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
@@ -60,6 +60,7 @@ educational.learningTime.day=j
 educational.learningTime.hour=h
 educational.learningTime.minute=m
 educational.learningTime.second=s
+error.corrupted.question=Le fichier de la question n'a pas \u00EAtre lu.
 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.qti.deprecated=Cette version de QTI est obsol\u00E8te. Pensez s'il vous pla\u00EEt \u00E0 convertir votre test au format QTI 2.1.
 error.select.one=Vous devez s\u00E9lectionner au moins une question.
diff --git a/src/main/java/org/olat/modules/qpool/ui/_i18n/LocalStrings_pt_BR.properties b/src/main/java/org/olat/modules/qpool/ui/_i18n/LocalStrings_pt_BR.properties
index ee89e22fc04..6338518c8e8 100644
--- a/src/main/java/org/olat/modules/qpool/ui/_i18n/LocalStrings_pt_BR.properties
+++ b/src/main/java/org/olat/modules/qpool/ui/_i18n/LocalStrings_pt_BR.properties
@@ -61,6 +61,7 @@ educational.learningTime.day=d
 educational.learningTime.hour=h
 educational.learningTime.minute=m
 educational.learningTime.second=s
+error.corrupted.question=O arquivo da pergunta n\u00E3o pode ser lido.
 error.input.toolong=O texto que voc\u00EA digitou \u00E9 muito grande ({1} caracteres). Apenas {1} caracteres s\u00E3o permitidos.
 error.qti.deprecated=Esta vers\u00E3o do QTI est\u00E1 obsoleta. Por favor, considere converter seu teste para o QTI 2.1.
 error.select.one=Voc\u00EA precisa selecionar pelo menos uma quest\u00E3o.
-- 
GitLab