/*
This file is part of LONCAPA-Daxe.
LONCAPA-Daxe is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
LONCAPA-Daxe is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Daxe. If not, see <http://www.gnu.org/licenses/>.
*/
part of loncapa_daxe;
/**
* This is used by RadioResponse for simple UI.
*/
class RadioFoilgroup extends LCDBlock {
x.Element foilRef;
String simpleFoilNamePrefix = 'radiofoil'; // can be changed to 'foil' or 'Foil' or 'radioFoil'
RadioFoilgroup.fromRef(x.Element elementRef) : super.fromRef(elementRef) {
initRadioFoilgroup();
}
RadioFoilgroup.fromNode(x.Node node, DaxeNode parent) : super.fromNode(node, parent) {
initRadioFoilgroup();
simpleUI = parent is RadioResponse && parent.simpleUI && simpleUIPossibleNoThrow();
if (simpleUI)
setupSimpleUI();
}
void initRadioFoilgroup() {
List<x.Element> foilRefs = doc.cfg.elementReferences('foil');
foilRef = doc.cfg.findSubElement(ref, foilRefs);
}
@override
bool simpleUIPossible() {
if (attributes.length != 0)
throw new SimpleUIException('foilgroup: ' + LCDStrings.get('no_attribute'));
bool trueFoil = false;
for (DaxeNode dn=firstChild; dn!= null; dn=dn.nextSibling) {
if (dn is RadioFoil) {
if (!dn.simpleUIPossible())
return false;
if (dn.getAttribute('value') == 'true') {
if (trueFoil)
throw new SimpleUIException(LCDStrings.get('there_can_be_only_one'));
// NOTE: radiobuttonresponse supports several true foils, only one is shown at a time
trueFoil = true;
}
} else if (dn.nodeType == DaxeNode.ELEMENT_NODE) {
String title = doc.cfg.elementTitle(dn.ref);
throw new SimpleUIException(LCDStrings.get('element_prevents') + ' ' + dn.nodeName +
(title != null ? " ($title)" : ''));
} else if (dn.nodeType == DaxeNode.TEXT_NODE && dn.nodeValue.trim() != '') {
return false;
} else {
return false;
}
}
return true;
}
void setupRestrictions() {
if (restrictedInserts == null)
restrictedInserts = ['foil'];
}
/**
* Returns the RadioFoil children
*/
List<RadioFoil> getFoils() {
List<RadioFoil> list = new List<RadioFoil>();
for (DaxeNode dn in childNodes) {
if (dn is RadioFoil)
list.add(dn);
}
return list;
}
@override
void setupSimpleUI() {
simpleUI = true;
setupRestrictions();
// Removes the name attributes, remove unused foils, add a foil if there is none
if (getFoils().length == 0) {
addFirstFoil();
} else {
for (RadioFoil foil in getFoils()) {
if (foil.getAttribute('name') != null) {
RegExp regexp = new RegExp("^([a-zA-Z]+)[0-9]+\$");
Iterable<Match> matches = regexp.allMatches(foil.getAttribute('name'));
if (matches.length > 0) {
Match m = matches.elementAt(0);
simpleFoilNamePrefix = m.group(1);
}
foil.removeAttribute('name');
}
if (foil.getAttribute('value') == 'unused')
removeChild(foil);
}
}
}
@override
h.Element html() {
simpleUI = parent is RadioResponse && (parent as RadioResponse).simpleUI;
if (!simpleUI)
return super.html();
setupRestrictions();
h.DivElement div = new h.DivElement();
div.id = id;
div.classes.add('radio-foilgroup');
h.TableElement table = new h.TableElement();
table.id = "contents-$id";
for (DaxeNode dn=firstChild; dn!= null; dn=dn.nextSibling) {
// dn should be a RadioFoil but in some rare cases it is not and the result might be a div...
table.append(dn.html());
}
div.append(table);
h.ButtonElement bAdd = new h.ButtonElement();
bAdd.attributes['type'] = 'button';
bAdd.text = LCDStrings.get('add_foil');
bAdd.onClick.listen((h.MouseEvent event) => addUndoableFoil());
div.append(bAdd);
return div;
}
/**
* Adds a foil (not using an UndoableEdit)
*/
void addFirstFoil() {
RadioFoil foil = new RadioFoil.fromRef(foilRef);
foil.setAttribute('value', 'true');
foil.state = 1;
appendChild(foil);
}
/**
* Adds a foil at the end (using an UndoableEdit)
*/
void addUndoableFoil() {
RadioFoil foil = new RadioFoil.fromRef(foilRef);
foil.setAttribute('value', 'false');
foil.state = 1;
Position pos = new Position(this, offsetLength);
doc.insertNode(foil, pos);
page.moveCursorTo(new Position(foil, 0));
page.updateAfterPathChange();
}
/**
* Removes the given foil (called when the user click on the button).
*/
void removeFoil(RadioFoil foil) {
doc.doNewEdit(new UndoableEdit.removeNode(foil));
}
/**
* Selects the given foil.
*/
void selectFoil(RadioFoil foilToSelect) {
UndoableEdit edit = new UndoableEdit.compound(LCDStrings.get('foil_selection'));
for (RadioFoil foil in getFoils()) {
DaxeAttr attr = new DaxeAttr('value', foil == foilToSelect ? 'true' : 'false');
edit.addSubEdit(new UndoableEdit.changeAttribute(foil, attr));
}
doc.doNewEdit(edit);
}
}
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>