diff --git a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/table/SortableFlexiTableModelDelegate.java b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/table/SortableFlexiTableModelDelegate.java index dc7c57381507107468da38f5019891e4c4cbe8c1..b2ee11bf8014481a777d430311cf76f6520b4529 100644 --- a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/table/SortableFlexiTableModelDelegate.java +++ b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/table/SortableFlexiTableModelDelegate.java @@ -167,6 +167,10 @@ public class SortableFlexiTableModelDelegate<T> { } return a.compareTo(b); } + + protected final int compareDoubles(double a, double b) { + return Double.compare(a, b); + } protected final int compareNullObjects(final Object a, final Object b) { boolean ba = (a == null); diff --git a/src/main/java/org/olat/course/nodes/cl/ui/CheckListAssessmentController.java b/src/main/java/org/olat/course/nodes/cl/ui/CheckListAssessmentController.java index df3461698648dc67e1e98794118c0906e8c75852..2284d4566e6fe6e6ae435c5e1b8772af5ef88c6f 100644 --- a/src/main/java/org/olat/course/nodes/cl/ui/CheckListAssessmentController.java +++ b/src/main/java/org/olat/course/nodes/cl/ui/CheckListAssessmentController.java @@ -202,7 +202,8 @@ public class CheckListAssessmentController extends FormBasicController implement FlexiTableColumnModel columnsModel = FlexiTableDataModelFactory.createFlexiTableColumnModel(); if(isAdministrativeUser) { - columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(Cols.username.i18nKey(), Cols.username.ordinal())); + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(Cols.username.i18nKey(), Cols.username.ordinal(), + true, Cols.username.name())); } int i=0; @@ -247,7 +248,7 @@ public class CheckListAssessmentController extends FormBasicController implement } List<CheckListAssessmentRow> datas = loadDatas(); - model = new CheckListAssessmentDataModel(checkboxList, datas, columnsModel); + model = new CheckListAssessmentDataModel(checkboxList, datas, columnsModel, getLocale()); table = uifactory.addTableElement(getWindowControl(), "checkbox-list", model, getTranslator(), formLayout); if(coachCourseEnv instanceof UserCourseEnvironmentImpl) { UserCourseEnvironmentImpl env = (UserCourseEnvironmentImpl)coachCourseEnv; diff --git a/src/main/java/org/olat/course/nodes/cl/ui/CheckListAssessmentDataModel.java b/src/main/java/org/olat/course/nodes/cl/ui/CheckListAssessmentDataModel.java index 6d0d718aaeda8197049e88215d39ae4dc1518326..5d04477f146e9ee7d5aaff40503db39b06875fe8 100644 --- a/src/main/java/org/olat/course/nodes/cl/ui/CheckListAssessmentDataModel.java +++ b/src/main/java/org/olat/course/nodes/cl/ui/CheckListAssessmentDataModel.java @@ -24,6 +24,7 @@ import java.io.OutputStream; import java.util.ArrayList; import java.util.Date; import java.util.List; +import java.util.Locale; import org.apache.commons.lang.StringEscapeUtils; import org.olat.core.commons.persistence.SortKey; @@ -36,7 +37,6 @@ import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiColum import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableColumnModel; import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableComponent; import org.olat.core.gui.components.form.flexible.impl.elements.table.SortableFlexiTableDataModel; -import org.olat.core.gui.components.form.flexible.impl.elements.table.SortableFlexiTableModelDelegate; import org.olat.core.gui.media.MediaResource; import org.olat.core.gui.render.EmptyURLBuilder; import org.olat.core.gui.render.StringOutput; @@ -70,13 +70,15 @@ public class CheckListAssessmentDataModel extends DefaultFlexiTableDataModel<Che public static final int USER_PROPS_OFFSET = 500; public static final int CHECKBOX_OFFSET = 5000; + private final Locale locale; private final CheckboxList checkboxList; private List<CheckListAssessmentRow> backupRows; public CheckListAssessmentDataModel(CheckboxList checkboxList, List<CheckListAssessmentRow> datas, - FlexiTableColumnModel columnModel) { + FlexiTableColumnModel columnModel, Locale locale) { super(datas, columnModel); backupRows = datas; + this.locale = locale; this.checkboxList = checkboxList; } @@ -89,13 +91,12 @@ public class CheckListAssessmentDataModel extends DefaultFlexiTableDataModel<Che @Override public DefaultFlexiTableDataModel<CheckListAssessmentRow> createCopyWithEmptyList() { - return new CheckListAssessmentDataModel(checkboxList, new ArrayList<CheckListAssessmentRow>(), getTableColumnModel()); + return new CheckListAssessmentDataModel(checkboxList, new ArrayList<CheckListAssessmentRow>(), getTableColumnModel(), locale); } @Override public void sort(SortKey orderBy) { - SortableFlexiTableModelDelegate<CheckListAssessmentRow> sorter - = new SortableFlexiTableModelDelegate<>(orderBy, this, null); + CheckListAssessmentDataModelSorter sorter = new CheckListAssessmentDataModelSorter(orderBy, this, locale); List<CheckListAssessmentRow> views = sorter.sort(); super.setObjects(views); } diff --git a/src/main/java/org/olat/course/nodes/cl/ui/CheckListAssessmentDataModelSorter.java b/src/main/java/org/olat/course/nodes/cl/ui/CheckListAssessmentDataModelSorter.java new file mode 100644 index 0000000000000000000000000000000000000000..d1916d141f552ec72955d538ae90f246b34eca99 --- /dev/null +++ b/src/main/java/org/olat/course/nodes/cl/ui/CheckListAssessmentDataModelSorter.java @@ -0,0 +1,92 @@ +/** + * <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.course.nodes.cl.ui; + +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Locale; + +import org.olat.core.commons.persistence.SortKey; +import org.olat.core.gui.components.form.flexible.elements.MultipleSelectionElement; +import org.olat.core.gui.components.form.flexible.impl.elements.table.SortableFlexiTableModelDelegate; + +/** + * + * Initial date: 5 févr. 2017<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class CheckListAssessmentDataModelSorter extends SortableFlexiTableModelDelegate<CheckListAssessmentRow> { + + public CheckListAssessmentDataModelSorter(SortKey orderBy, CheckListAssessmentDataModel model, Locale locale) { + super(orderBy, model, locale); + } + + @Override + protected void sort(List<CheckListAssessmentRow> rows) { + int columnIndex = getColumnIndex(); + if(columnIndex >= CheckListAssessmentDataModel.CHECKBOX_OFFSET) { + int checkBoxIndex = columnIndex - CheckListAssessmentDataModel.CHECKBOX_OFFSET; + Collections.sort(rows, new CheckBoxComparator(checkBoxIndex)); + + } else { + super.sort(rows); + } + } + + private class CheckBoxComparator implements Comparator<CheckListAssessmentRow> { + + private final int checkBoxIndex; + + public CheckBoxComparator(int checkBoxIndex) { + this.checkBoxIndex = checkBoxIndex; + } + + @Override + public int compare(CheckListAssessmentRow o1, CheckListAssessmentRow o2) { + if(o1 == null || o2 == null) { + return compareNullObjects(o1, o2); + } + + boolean c1 = isCheck(o1); + boolean c2 = isCheck(o2); + int c = compareBooleans(c1, c2); + return c; + } + + private boolean isCheck(CheckListAssessmentRow row) { + if(row.getCheckedEl() != null) { + //edit mode + MultipleSelectionElement[] checked = row.getCheckedEl(); + if(checked != null && checkBoxIndex >= 0 && checkBoxIndex < checked.length) { + return checked[checkBoxIndex].isAtLeastSelected(1); + } + } + + Boolean[] checked = row.getChecked(); + if(checked != null && checkBoxIndex >= 0 && checkBoxIndex < checked.length + && checked[checkBoxIndex] != null) { + return checked[checkBoxIndex].booleanValue(); + } + return false; + } + } +} diff --git a/src/main/java/org/olat/course/nodes/cl/ui/CheckboxAssessmentController.java b/src/main/java/org/olat/course/nodes/cl/ui/CheckboxAssessmentController.java index 208d65a756a51f298d42340326bf846696635973..940cf1297817f80ea662d19804f70c4cc9f1d55a 100644 --- a/src/main/java/org/olat/course/nodes/cl/ui/CheckboxAssessmentController.java +++ b/src/main/java/org/olat/course/nodes/cl/ui/CheckboxAssessmentController.java @@ -130,10 +130,10 @@ public class CheckboxAssessmentController extends FormBasicController { protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { setFormDescription("assessment.checkbox.description"); - FlexiTableColumnModel columnsModel = FlexiTableDataModelFactory.createFlexiTableColumnModel(); if(isAdministrativeUser) { - columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(Cols.username.i18nKey(), Cols.username.ordinal())); + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(Cols.username.i18nKey(), Cols.username.ordinal(), + true, Cols.username.name())); } int i=0; @@ -157,9 +157,11 @@ public class CheckboxAssessmentController extends FormBasicController { } } - columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(Cols.check.i18nKey(), Cols.check.ordinal())); + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(Cols.check.i18nKey(), Cols.check.ordinal(), + true, Cols.check.name())); if(withScore) { - columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(Cols.points.i18nKey(), Cols.points.ordinal())); + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(Cols.points.i18nKey(), Cols.points.ordinal(), + true, Cols.points.name())); } int numOfCheckbox = checkboxList.getList().size(); String[] keys = new String[numOfCheckbox]; @@ -217,7 +219,7 @@ public class CheckboxAssessmentController extends FormBasicController { boxRows.add(row); } - model = new CheckboxAssessmentDataModel(boxRows, columnsModel); + model = new CheckboxAssessmentDataModel(boxRows, columnsModel, getLocale()); table = uifactory.addTableElement(getWindowControl(), "checkbox-list", model, getTranslator(), formLayout); table.setCustomizeColumns(true); table.setEditMode(true); diff --git a/src/main/java/org/olat/course/nodes/cl/ui/CheckboxAssessmentDataModel.java b/src/main/java/org/olat/course/nodes/cl/ui/CheckboxAssessmentDataModel.java index 0bfd163eee68cb8382fd20f1b5c153388a168ba1..94ad376fdb7b51743f86d274e070e9ee3a12a444 100644 --- a/src/main/java/org/olat/course/nodes/cl/ui/CheckboxAssessmentDataModel.java +++ b/src/main/java/org/olat/course/nodes/cl/ui/CheckboxAssessmentDataModel.java @@ -21,12 +21,12 @@ package org.olat.course.nodes.cl.ui; import java.util.ArrayList; import java.util.List; +import java.util.Locale; import org.olat.core.commons.persistence.SortKey; import org.olat.core.gui.components.form.flexible.impl.elements.table.DefaultFlexiTableDataModel; import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableColumnModel; import org.olat.core.gui.components.form.flexible.impl.elements.table.SortableFlexiTableDataModel; -import org.olat.core.gui.components.form.flexible.impl.elements.table.SortableFlexiTableModelDelegate; /** * @@ -36,20 +36,22 @@ import org.olat.core.gui.components.form.flexible.impl.elements.table.SortableFl */ public class CheckboxAssessmentDataModel extends DefaultFlexiTableDataModel<CheckboxAssessmentRow> implements SortableFlexiTableDataModel<CheckboxAssessmentRow> { + + private final Locale locale; - public CheckboxAssessmentDataModel(List<CheckboxAssessmentRow> datas, FlexiTableColumnModel columnModel) { + public CheckboxAssessmentDataModel(List<CheckboxAssessmentRow> datas, FlexiTableColumnModel columnModel, Locale locale) { super(datas, columnModel); + this.locale = locale; } @Override public DefaultFlexiTableDataModel<CheckboxAssessmentRow> createCopyWithEmptyList() { - return new CheckboxAssessmentDataModel(new ArrayList<CheckboxAssessmentRow>(), getTableColumnModel()); + return new CheckboxAssessmentDataModel(new ArrayList<CheckboxAssessmentRow>(), getTableColumnModel(), locale); } @Override public void sort(SortKey orderBy) { - SortableFlexiTableModelDelegate<CheckboxAssessmentRow> sorter - = new SortableFlexiTableModelDelegate<>(orderBy, this, null); + CheckboxAssessmentDataModelSorter sorter = new CheckboxAssessmentDataModelSorter(orderBy, this, locale); List<CheckboxAssessmentRow> views = sorter.sort(); super.setObjects(views); } diff --git a/src/main/java/org/olat/course/nodes/cl/ui/CheckboxAssessmentDataModelSorter.java b/src/main/java/org/olat/course/nodes/cl/ui/CheckboxAssessmentDataModelSorter.java new file mode 100644 index 0000000000000000000000000000000000000000..657ca3acb19b966b7994211ad5aaa9956056ed70 --- /dev/null +++ b/src/main/java/org/olat/course/nodes/cl/ui/CheckboxAssessmentDataModelSorter.java @@ -0,0 +1,88 @@ +package org.olat.course.nodes.cl.ui; + +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Locale; + +import org.olat.core.commons.persistence.SortKey; +import org.olat.core.gui.components.form.flexible.elements.MultipleSelectionElement; +import org.olat.core.gui.components.form.flexible.elements.TextElement; +import org.olat.core.gui.components.form.flexible.impl.elements.table.SortableFlexiTableModelDelegate; +import org.olat.core.util.StringHelper; +import org.olat.course.nodes.cl.ui.CheckboxAssessmentDataModel.Cols; + +/** + * + * Initial date: 5 févr. 2017<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class CheckboxAssessmentDataModelSorter extends SortableFlexiTableModelDelegate<CheckboxAssessmentRow> { + + public CheckboxAssessmentDataModelSorter(SortKey orderBy, CheckboxAssessmentDataModel model, Locale locale) { + super(orderBy, model, locale); + } + + @Override + protected void sort(List<CheckboxAssessmentRow> rows) { + int columnIndex = getColumnIndex(); + if(columnIndex == Cols.check.ordinal()) { + Collections.sort(rows, new CheckBoxComparator()); + + } else if(columnIndex == Cols.points.ordinal()) { + Collections.sort(rows, new PointsComparator()); + } else { + super.sort(rows); + } + } + + private class PointsComparator implements Comparator<CheckboxAssessmentRow> { + @Override + public int compare(CheckboxAssessmentRow o1, CheckboxAssessmentRow o2) { + if(o1 == null || o2 == null) { + return compareNullObjects(o1, o2); + } + + TextElement e1 = o1.getPointEl(); + TextElement e2 = o2.getPointEl(); + if(e1 == null || e2 == null) { + return compareNullObjects(e1, e2); + } + + double t1 = parseDouble(e1); + double t2 = parseDouble(e2); + return compareDoubles(t1, t2); + } + + private double parseDouble(TextElement el) { + if(el != null && StringHelper.containsNonWhitespace(el.getValue())) { + try { + return Double.parseDouble(el.getValue()); + } catch (NumberFormatException e) { + //ignore parsing error, the validation take this + } + } + return 0.0d; + } + } + + private class CheckBoxComparator implements Comparator<CheckboxAssessmentRow> { + @Override + public int compare(CheckboxAssessmentRow o1, CheckboxAssessmentRow o2) { + if(o1 == null || o2 == null) { + return compareNullObjects(o1, o2); + } + + MultipleSelectionElement e1 = o1.getCheckedEl(); + MultipleSelectionElement e2 = o2.getCheckedEl(); + if(e1 == null || e2 == null) { + return compareNullObjects(e1, e2); + } + + boolean b1 = e1.isAtLeastSelected(1); + boolean b2 = e2.isAtLeastSelected(1); + return compareBooleans(b1, b2); + } + } +}