File:  [LON-CAPA] / modules / damieng / graphical_editor / loncapa_daxe / web / nodes / lcd_parameter.dart
Revision 1.11: download - view: text, annotated - select for diffs
Tue Feb 28 20:40:59 2017 UTC (7 years, 3 months ago) by damieng
Branches: MAIN
CVS tags: HEAD
updates following changes in Daxe Config API

/*
  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;

/**
 * Display for the parameter and responseparam elements, based on LCDBlock
 * Jaxe display type: 'parameter'.
 */
class LCDParameter extends LCDBlock {
  static HashMap<String,HashMap<String, LCParameter>> parameters = null;
  
  LCDParameter.fromRef(x.Element elementRef) : super.fromRef(elementRef);
  
  LCDParameter.fromNode(x.Node node, DaxeNode parent) : super.fromNode(node, parent) {
    if (parent is LCDBlock && parent.simpleUI &&
        (parent is NumericalResponse || parent is FormulaResponse || parent is EssayResponse))
      simpleUI = true;
  }
  
  Future<bool> _readParameters() {
    Completer<bool> completer = new Completer<bool>();
    x.DOMParser dp = new x.DOMParser();
    dp.parseFromURL('parameters.xml').then((x.Document xdoc) {
      parameters = new HashMap<String,HashMap<String, LCParameter>>();
      x.Element root = xdoc.documentElement;
      for (x.Element context in _getChildrenWithName(root, 'context')) {
        String ancestor = context.getAttribute('ancestor');
        HashMap<String, LCParameter> params = new LinkedHashMap<String, LCParameter>();
        parameters[ancestor] = params;
        for (x.Element parameter in _getChildrenWithName(context, 'parameter')) {
          LCParameter param = new LCParameter();
          for (x.Node n=parameter.firstChild; n!=null; n=n.nextSibling) {
            if (n.nodeType == x.Node.ELEMENT_NODE && n.firstChild != null && n.firstChild.nodeType == x.Node.TEXT_NODE) {
              if (n.nodeName == 'name')
                param.name = n.firstChild.nodeValue;
              else if (n.nodeName == 'type')
                param.type = n.firstChild.nodeValue;
              else if (n.nodeName == 'default')
                param.def = n.firstChild.nodeValue;
              else if (n.nodeName == 'title') {
                String lang = (n as x.Element).getAttribute('lang');
                if (lang != null) {
                  if (param.titles == null)
                    param.titles = new HashMap<String, String>();
                  param.titles[lang] = n.firstChild.nodeValue;
                }
              }
            }
          }
          params[param.name] = param;
        }
      }
      completer.complete(true);
    }).catchError((e) => (e) {
      print(e);
      completer.complete(false);
    });
    return(completer.future);
  }
  
  List<x.Element> _getChildrenWithName(x.Element parent, String name) {
    List<x.Element> l = new List<x.Element>();
    for (x.Node n=parent.firstChild; n!=null; n=n.nextSibling) {
      if (n.nodeType == x.Node.ELEMENT_NODE && n.nodeName == name) {
        l.add(n);
      }
    }
    return l;
  }
  
  @override
  h.Element html() {
    simpleUI = ((parent as LCDBlock).simpleUI &&
        (parent is NumericalResponse || parent is FormulaResponse || parent is EssayResponse));
    if (simpleUI) {
      // the whole responseparam node is reduced to its default attribute
      // the description or (if not present) the name attribute is used as a title
      x.Element defaultRef = null;
      for (x.Element refAttr in attRefs) {
        String name = doc.cfg.attributeName(refAttr);
        if (name == 'default') {
          defaultRef = refAttr;
          break;
        }
      }
      assert(defaultRef != null);
      h.TableRowElement tr = attributeHTML(defaultRef);
      if (tr.firstChild.firstChild != null)
        tr.firstChild.firstChild.remove(); // remove help button
      tr.id = id;
      String title = getAttribute('description');
      if (title == null)
        title = getAttribute('name');
      tr.childNodes[1].text = title;
      return(tr);
    } else {
      h.Element div = super.html();
      if (state != 0)
        return div;
      Menu menu = new Menu(LCDStrings.get('template'));
      _addTemplates(menu); // this might be async if the config is read
      if (parameters == null || menu.items.length > 0) {
        h.DivElement headerDiv = div.firstChild;
        h.TableElement table = headerDiv.lastChild;
        h.DivElement templateDiv = new h.DivElement();
        h.DivElement menuDiv = page.mbar.createMenuDiv(menu);
        h.DivElement menuButtonDiv = new h.DivElement();
        menuButtonDiv.classes.add('toolbar-menu');
        menuButtonDiv.append(menuDiv);
        templateDiv.append(menuButtonDiv);
        headerDiv.insertBefore(templateDiv, table);
      }
      return div;
    }
  }
  
  @override
  void updateAttributes() {
    if (!simpleUI) {
      super.updateAttributes();
      return;
    }
    parent.updateHTML();
  }
  
  void _addTemplates(Menu menu) {
    if (parameters == null) {
      _readParameters().then((bool read) {
        if (!read)
          return;
        updateHTML();
      });
      return;
    }
    HashMap<String, LCParameter> context = _getContext();
    if (context == null)
      return;
    for (LCParameter param in context.values) {
      String title = param.titles[LCDStrings.systemLocale];
      if (title == null)
        title = param.titles['en'];
      menu.add(new MenuItem(title, ()=>chooseTemplate(param)));
    }
  }
  
  HashMap<String, LCParameter> _getContext() {
    for (DaxeNode ancestor=parent; ancestor!=null; ancestor=ancestor.parent) {
      if (parameters[ancestor.nodeName] != null) {
        HashMap<String, LCParameter> context = parameters[ancestor.nodeName];
        return context;
      }
    }
    return null;
  }
  
  void chooseTemplate(LCParameter param) {
    LinkedHashMap<String, DaxeAttr> attmap = getAttributesMapCopy();
    attmap['name'] = new DaxeAttr.NS(null, 'name', param.name);
    if (param.type != null)
      attmap['type'] = new DaxeAttr.NS(null, 'type', param.type);
    else
      attmap.remove('type');
    if (param.def != null)
      attmap['default'] = new DaxeAttr.NS(null, 'default', param.def);
    else
      attmap.remove('default');
    if (param.titles != null) {
      String title = param.titles['en']; // using English if possible for the description attribute
      if (title == null)
        title = param.titles[LCDStrings.systemLocale];
      if (title != null)
        attmap['description'] = new DaxeAttr.NS(null, 'description', title);
      else
        attmap.remove('title');
    }
    attmap.remove('id');
    attmap.remove('display');
    UndoableEdit edit = new UndoableEdit.changeAttributes(this, new List.from(attmap.values));
    doc.doNewEdit(edit);
  }
}

class LCParameter {
  String name;
  String type;
  String def;
  HashMap<String, String> titles;
}

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>