Package org.olat.course.nodes.st

Source Code of org.olat.course.nodes.st.STCourseNodeDisplayConfigFormController

/**
* OLAT - Online Learning and Training<br>
* http://www.olat.org
* <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
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <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>
* Copyright (c) frentix GmbH<br>
* http://www.frentix.com<br>
* <p>
*/
package org.olat.course.nodes.st;

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.FormUIFactory;
import org.olat.core.gui.components.form.flexible.elements.MultipleSelectionElement;
import org.olat.core.gui.components.form.flexible.elements.SingleSelection;
import org.olat.core.gui.components.form.flexible.elements.SpacerElement;
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.rules.RulesFactory;
import org.olat.core.gui.control.Controller;
import org.olat.core.gui.control.Event;
import org.olat.core.gui.control.WindowControl;
import org.olat.course.tree.CourseEditorTreeNode;
import org.olat.modules.ModuleConfiguration;

/**
* <h3>Description:</h3> The STCourseNodeDisplayConfigFormController displays
* the layout configuration form for an ST node. It lets the user decide if he
* wants to display a custom file layout, a system generated TOC layout or a
* system generated peekview layout. In both system generated layouts he can
* further define the number of columns (1 or 2).
* <p>
* When the peek view configuration is used, the children that should be
* displayed in the peekview must be selected manually. For performance reasons
* only 5 direct children can be selected by default. This behavior can be
* overridden by using the spring setter method setMaxPeekviewChildNodes() on
* the org.olat.course.nodes.st.STCourseNodeConfiguration bean
* <p>
* <h4>Events fired by this Controller</h4>
* <ul>
* <li>Event.DONE_EVENT when the form is submitted</li>
* </ul>
* <p>
* Initial Date: 15.09.2009 <br>
*
* @author gnaegi, gnaegi@frentix.com, www.frentix.com
*/
public class STCourseNodeDisplayConfigFormController extends FormBasicController {
  private static final String[] keys_displayType = new String[] { "system", "peekview", "file" };

  // read current configuration
  private String displayConfig = null;
  private int columnsConfig = 1;
  private SingleSelection displayTypeRadios;
  private MultipleSelectionElement displayTwoColumns;
  private MultipleSelectionElement selectedPeekviewChildren;
  private String[] selectedPeekviewChildKeys;
  private String[] selectedPeekviewChildValues;
  private String[] selectedPeekviewChildCssClasses;
  private String selectedPeekviewChildNodesConfig = null;

  /**
   * Constructor for the config form
   *
   * @param ureq
   * @param wControl
   * @param config the module configuration
   * @param node the course editor node
   */
  STCourseNodeDisplayConfigFormController(UserRequest ureq, WindowControl wControl, ModuleConfiguration config, CourseEditorTreeNode node) {
    super(ureq, wControl);
    // Read current configuration
    this.displayConfig = config.getStringValue(STCourseNodeEditController.CONFIG_KEY_DISPLAY_TYPE,
        STCourseNodeEditController.CONFIG_VALUE_DISPLAY_TOC);
    this.columnsConfig = config.getIntegerSafe(STCourseNodeEditController.CONFIG_KEY_COLUMNS, 1);
    // Build data model for the selected child peekview checkboxes
    int childCount = node.getChildCount();
    selectedPeekviewChildKeys = new String[childCount];
    selectedPeekviewChildValues = new String[childCount];
    selectedPeekviewChildCssClasses = new String[childCount];
    for (int i = 0; i < childCount; i++) {
      CourseEditorTreeNode child = node.getCourseEditorTreeNodeChildAt(i);
      selectedPeekviewChildKeys[i] = child.getIdent();
      selectedPeekviewChildValues[i] = child.getTitle() + " (" + child.getIdent() + ")";
      selectedPeekviewChildCssClasses[i] = child.getIconCssClass() + " b_with_small_icon_left";
    }
    selectedPeekviewChildNodesConfig = config.getStringValue(STCourseNodeEditController.CONFIG_KEY_PEEKVIEW_CHILD_NODES, "");
    // initialize the form now
    initForm(ureq);
  }

  /**
   * @see org.olat.core.gui.components.form.flexible.impl.FormBasicController#doDispose()
   */
  @Override
  protected void doDispose() {
  // nothing to dispose
  }

  /**
   * @see org.olat.core.gui.components.form.flexible.impl.FormBasicController#formOK(org.olat.core.gui.UserRequest)
   */
  @Override
  protected void formOK(UserRequest ureq) {
    fireEvent(ureq, Event.DONE_EVENT);
  }

  /**
   * @see org.olat.core.gui.components.form.flexible.impl.FormBasicController#initForm(org.olat.core.gui.components.form.flexible.FormItemContainer,
   *      org.olat.core.gui.control.Controller, org.olat.core.gui.UserRequest)
   */
  @Override
  protected void initForm(FormItemContainer formLayout, @SuppressWarnings("unused") Controller listener,
      @SuppressWarnings("unused") UserRequest ureq) {
    setFormTitle("config.fieldset.view");
    setFormContextHelp("org.olat.course.nodes.st", "ced-st-overview.html", "help.st.design");
    //
    FormUIFactory formFact = FormUIFactory.getInstance();
    // Display type
    String[] values_displayType = new String[] { translate("form.system"), translate("form.peekview"), translate("form.self") };
    displayTypeRadios = formFact.addRadiosVertical("selforsystemoverview", formLayout, keys_displayType, values_displayType);
    displayTypeRadios.addActionListener(this, FormEvent.ONCLICK);
    if (displayConfig.equals(STCourseNodeEditController.CONFIG_VALUE_DISPLAY_FILE)) {
      displayTypeRadios.select("file", true);
    } else if (displayConfig.equals(STCourseNodeEditController.CONFIG_VALUE_DISPLAY_PEEKVIEW)) {
      displayTypeRadios.select("peekview", true);
    } else {
      displayTypeRadios.select("system", true);
    }
    // Peekview details configuration - allow only MAX_PEEKVIEW_CHILD_NODES
    // peekviews to be selected
    if (selectedPeekviewChildKeys.length > 0) {
      SpacerElement spacerChild = formFact.addSpacerElement("spacerChild", formLayout, true);
      selectedPeekviewChildren = formFact.addCheckboxesVertical("selectedPeekviewChildren", formLayout, selectedPeekviewChildKeys,
          selectedPeekviewChildValues, selectedPeekviewChildCssClasses, 1);
      selectedPeekviewChildren.setLabel("selectedPeekviewChildren",
          new String[] { STCourseNodeConfiguration.MAX_PEEKVIEW_CHILD_NODES + "" });
      // visibility rules for peekview children selection
      RulesFactory.createHideRule(displayTypeRadios, "file", selectedPeekviewChildren, formLayout);
      RulesFactory.createHideRule(displayTypeRadios, "system", selectedPeekviewChildren, formLayout);
      RulesFactory.createShowRule(displayTypeRadios, "peekview", selectedPeekviewChildren, formLayout);
      RulesFactory.createHideRule(displayTypeRadios, "file", spacerChild, formLayout);
      RulesFactory.createHideRule(displayTypeRadios, "system", spacerChild, formLayout);
      RulesFactory.createShowRule(displayTypeRadios, "peekview", spacerChild, formLayout);
      // Pre-select configured keys. Discard configured selections that are not
      // found (e.g. deleted or moved nodes)
      String[] preSelectedChildNodes = (selectedPeekviewChildNodesConfig == null ? new String[0] : selectedPeekviewChildNodesConfig
          .split(","));
      for (String preSelectedNode : preSelectedChildNodes) {
        for (String selectableNode : selectedPeekviewChildKeys) {
          if (preSelectedNode.equals(selectableNode)) {
            selectedPeekviewChildren.select(selectableNode, true);
            break;
          }
        }
      }
      // Allow only MAX_PEEKVIEW_CHILD_NODES child nodes to be enabled
      if (selectedPeekviewChildren.getSelectedKeys().size() >= STCourseNodeConfiguration.MAX_PEEKVIEW_CHILD_NODES) {
        for (int i = 0; i < selectedPeekviewChildKeys.length; i++) {
          if (!selectedPeekviewChildren.isSelected(i)) {
            selectedPeekviewChildren.setEnabled(selectedPeekviewChildKeys[i], false);
          }
        }
      }
      // Pre-select the first MAX_PEEKVIEW_CHILD_NODES child nodes if none is
      // selected to reflect meaningfull default configuration
      if (selectedPeekviewChildren.getSelectedKeys().size() == 0) {
        for (int i = 0; i < selectedPeekviewChildKeys.length; i++) {
          if (i < STCourseNodeConfiguration.MAX_PEEKVIEW_CHILD_NODES) {
            selectedPeekviewChildren.select(selectedPeekviewChildKeys[i], true);
          } else {
            selectedPeekviewChildren.setEnabled(selectedPeekviewChildKeys[i], false);
          }
        }
      }
      // Add as listener for any changes
      selectedPeekviewChildren.addActionListener(this, FormEvent.ONCLICK);
    }
    //
    // Number of rows (only available in system or peekview type)
    SpacerElement spacerCols = formFact.addSpacerElement("spacerCols", formLayout, true);
    displayTwoColumns = formFact
        .addCheckboxesVertical("displayTwoColumns", formLayout, new String[] { "on" }, new String[] { "" }, null, 1);
    displayTwoColumns.setLabel("displayTwoColumns", null);
    if (columnsConfig == 2) {
      displayTwoColumns.selectAll();
    }
    if (displayConfig.equals(STCourseNodeEditController.CONFIG_VALUE_DISPLAY_FILE)) {
      displayTwoColumns.setVisible(false);
    }
    //
    // Visibility rules for display columns switch
    RulesFactory.createHideRule(displayTypeRadios, "file", displayTwoColumns, formLayout);
    RulesFactory.createShowRule(displayTypeRadios, "peekview", displayTwoColumns, formLayout);
    RulesFactory.createShowRule(displayTypeRadios, "system", displayTwoColumns, formLayout);
    RulesFactory.createHideRule(displayTypeRadios, "file", spacerCols, formLayout);
    RulesFactory.createShowRule(displayTypeRadios, "peekview", spacerCols, formLayout);
    RulesFactory.createShowRule(displayTypeRadios, "system", spacerCols, formLayout);
    //
    formFact.addFormSubmitButton("submit", formLayout);
  }

  /**
   * @see org.olat.core.gui.components.form.flexible.impl.FormBasicController#formInnerEvent(org.olat.core.gui.UserRequest,
   *      org.olat.core.gui.components.form.flexible.FormItem,
   *      org.olat.core.gui.components.form.flexible.impl.FormEvent)
   */
  @Override
  protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) {
    super.formInnerEvent(ureq, source, event);
    if (source == selectedPeekviewChildren) {
      if (selectedPeekviewChildren.getSelectedKeys().size() == 0) {
        // There must be at least one selected child
        selectedPeekviewChildren.setErrorKey("form.peekview.error.mandatory.child", null);
        return;
      }
      // Clean potential previous error and continue with rules to
      // enable/disable the checkboxes to ensure that users can't select more
      // than the allowed number of child nodes
      selectedPeekviewChildren.clearError();
      if (selectedPeekviewChildren.getSelectedKeys().size() >= STCourseNodeConfiguration.MAX_PEEKVIEW_CHILD_NODES) {
        // Max reached, disabled all not already enabled checkboxes.
        for (int i = 0; i < selectedPeekviewChildKeys.length; i++) {
          if (!selectedPeekviewChildren.isSelected(i)) {
            selectedPeekviewChildren.setEnabled(selectedPeekviewChildKeys[i], false);
          }
        }
        showInfo("form.peekview.max.reached", STCourseNodeConfiguration.MAX_PEEKVIEW_CHILD_NODES + "");
      } else {
        // Enable all checkboxes
        selectedPeekviewChildren.setEnabled(true);
      }
    }
  }

  /**
   * @see org.olat.core.gui.components.form.flexible.impl.FormBasicController#validateFormLogic(org.olat.core.gui.UserRequest)
   */
  @Override
  protected boolean validateFormLogic(UserRequest ureq) {
    if ( ! super.validateFormLogic(ureq)) {
      return false;
    }
    // Check if at least one child is selected when peekview is enabled, but only when children are available.
    String displayType = displayTypeRadios.getSelectedKey();
    if (STCourseNodeEditController.CONFIG_VALUE_DISPLAY_PEEKVIEW.equals(displayType) && selectedPeekviewChildKeys.length > 0) {
        if (selectedPeekviewChildren.getSelectedKeys().size() == 0) {
          // There must be at least one selected child
          selectedPeekviewChildren.setErrorKey("form.peekview.error.mandatory.child", null);         
          return false;
        }
    }
    return true;
  }

  /**
   * Update the given module config object from the data in the form
   *
   * @param moduleConfig
   */
  public void updateModuleConfiguration(ModuleConfiguration moduleConfig) {
    String displayType = displayTypeRadios.getSelectedKey();
    if (STCourseNodeEditController.CONFIG_VALUE_DISPLAY_FILE.equals(displayType)) {
      // manual file view selected, remove columns config
      moduleConfig.setStringValue(STCourseNodeEditController.CONFIG_KEY_DISPLAY_TYPE, STCourseNodeEditController.CONFIG_VALUE_DISPLAY_FILE);
      moduleConfig.setBooleanEntry(STCourseNodeEditController.CONFIG_KEY_ALLOW_RELATIVE_LINKS, false);
      // remove config values from other setup
      moduleConfig.remove(STCourseNodeEditController.CONFIG_KEY_COLUMNS);
      moduleConfig.remove(STCourseNodeEditController.CONFIG_KEY_PEEKVIEW_CHILD_NODES);
    } else {
      // auto generated view selected, set TOC or peekview
      if (STCourseNodeEditController.CONFIG_VALUE_DISPLAY_PEEKVIEW.equals(displayType)) {
        moduleConfig.setStringValue(STCourseNodeEditController.CONFIG_KEY_DISPLAY_TYPE,
            STCourseNodeEditController.CONFIG_VALUE_DISPLAY_PEEKVIEW);
        // update selected peekview children
        if (selectedPeekviewChildren == null || selectedPeekviewChildren.getSelectedKeys().size() == 0) {
          moduleConfig.remove(STCourseNodeEditController.CONFIG_KEY_PEEKVIEW_CHILD_NODES);
        } else {
          selectedPeekviewChildNodesConfig = "";
          for (String childKey : selectedPeekviewChildren.getSelectedKeys()) {
            if (selectedPeekviewChildNodesConfig.length() != 0) {
              // separate node id's with commas
              selectedPeekviewChildNodesConfig += ",";
            }
            selectedPeekviewChildNodesConfig += childKey;
          }
          moduleConfig.set(STCourseNodeEditController.CONFIG_KEY_PEEKVIEW_CHILD_NODES, selectedPeekviewChildNodesConfig);
        }
      } else {
        // the old auto generated TOC view without peekview
        moduleConfig
            .setStringValue(STCourseNodeEditController.CONFIG_KEY_DISPLAY_TYPE, STCourseNodeEditController.CONFIG_VALUE_DISPLAY_TOC);
        // remove config values from peekview setup
        moduleConfig.remove(STCourseNodeEditController.CONFIG_KEY_PEEKVIEW_CHILD_NODES);
      }
      // in both cases, also set the columns configuration
      int cols = (displayTwoColumns.isSelected(0) ? 2 : 1);
      moduleConfig.setIntValue(STCourseNodeEditController.CONFIG_KEY_COLUMNS, Integer.valueOf(cols));
      // and clean up any file references
      moduleConfig.remove(STCourseNodeEditController.CONFIG_KEY_FILE);
      moduleConfig.remove(STCourseNodeEditController.CONFIG_KEY_ALLOW_RELATIVE_LINKS);
    }
  }

}
TOP

Related Classes of org.olat.course.nodes.st.STCourseNodeDisplayConfigFormController

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.