Package org.olat.course.editor

Source Code of org.olat.course.editor.MoveCopySubtreeController

/**
* 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) since 2004 at Multimedia- & E-Learning Services (MELS),<br>
* University of Zurich, Switzerland.
* <p>
*/

package org.olat.course.editor;

import org.olat.core.gui.UserRequest;
import org.olat.core.gui.components.Component;
import org.olat.core.gui.components.tree.SelectionTree;
import org.olat.core.gui.components.tree.TreeEvent;
import org.olat.core.gui.components.velocity.VelocityContainer;
import org.olat.core.gui.control.Controller;
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.gui.control.generic.messages.MessageUIFactory;
import org.olat.core.id.OLATResourceable;
import org.olat.core.logging.activity.CourseLoggingAction;
import org.olat.core.logging.activity.ThreadLocalUserActivityLogger;
import org.olat.core.util.nodes.INode;
import org.olat.core.util.tree.TreeVisitor;
import org.olat.core.util.tree.Visitor;
import org.olat.course.CourseFactory;
import org.olat.course.CourseModule;
import org.olat.course.ICourse;
import org.olat.course.nodes.CourseNode;
import org.olat.course.tree.CourseEditorTreeNode;
import org.olat.course.tree.InsertTreeModel;
import org.olat.course.tree.TreePosition;
import org.olat.util.logging.activity.LoggingResourceable;
/**
*
* Description:<br>
* TODO: guido Class Description for MoveCopySubtreeController
*
*/
public class MoveCopySubtreeController extends BasicController {
 
  private static final String LOG_COURSENODE_COPIED = "COURSENODE_COPIED";
  private static final String LOG_COURSENODE_MOVED = "COURSENODE_MOVED";
 
  private CourseEditorTreeNode moveCopyFrom;
  private boolean copy;

  private SelectionTree insertTree;
  private InsertTreeModel insertModel;
  private String copyNodeId = null;
  private OLATResourceable ores;

  public MoveCopySubtreeController(UserRequest ureq, WindowControl wControl, OLATResourceable ores, CourseEditorTreeNode moveCopyFrom, boolean copy) {
    super(ureq, wControl);
    this.ores = ores;
    this.moveCopyFrom = moveCopyFrom;
    this.copy = copy;

    ICourse course = CourseFactory.getCourseEditSession(ores.getResourceableId());
    addLoggingResourceable(LoggingResourceable.wrap(course));
    addLoggingResourceable(LoggingResourceable.wrap(moveCopyFrom.getCourseNode()));

    insertTree = new SelectionTree("copy_node_selection", getTranslator());
    insertTree.setFormButtonKey("insertAtSelectedTreepos");
    insertTree.addListener(this);
    insertModel = new InsertTreeModel(course.getEditorTreeModel());
    insertTree.setTreeModel(insertModel);   
   
    VelocityContainer mainVC = createVelocityContainer("moveCopyNode");
   
    if(insertModel.totalNodeCount() > CourseModule.getCourseNodeLimit()){
      String msg = getTranslator().translate("warning.containsXXXormore.nodes",
          new String[]{String.valueOf(insertModel.totalNodeCount()),String.valueOf(CourseModule.getCourseNodeLimit()+1)});
      Controller tmp = MessageUIFactory.createWarnMessage(ureq, wControl, null, msg);
      listenTo(tmp);
      mainVC.put("nodelimitexceededwarning", tmp.getInitialComponent());
    }
   
    mainVC.put("selection", insertTree);
   
    this.putInitialPanel(mainVC);
  }

  public void event(UserRequest ureq, Component source, Event event) {
    ICourse course = CourseFactory.getCourseEditSession(ores.getResourceableId());
    copyNodeId = null; // initialize copyNodeId with null because a new event happens and old value is invalid.
    if (source == insertTree) {
      TreeEvent te = (TreeEvent) event;
      if (te.getCommand().equals(TreeEvent.COMMAND_TREENODE_CLICKED)) {
        // user chose a position to insert a new node
        String nodeId = te.getNodeId();
        TreePosition tp = insertModel.getTreePosition(nodeId);
        CourseNode selectedNode = insertModel.getCourseNode(tp.getParentTreeNode());
        CourseEditorTreeNode insertParent = course.getEditorTreeModel().getCourseEditorNodeById(selectedNode.getIdent());

        // check if insert position is within the to-be-copied tree
        if (checkIfIsChild(insertParent, moveCopyFrom)) {         
          this.showError("movecopynode.error.overlap");
          fireEvent(ureq, Event.CANCELLED_EVENT);
          return;
        }

        int insertPos = tp.getChildpos();
        if (copy) { // do a copy
          // copy subtree and save model
          recursiveCopy(moveCopyFrom, insertParent, insertPos, true, CourseFactory.getCourseEditSession(ores.getResourceableId()));         
          CourseFactory.saveCourseEditorTreeModel(course.getResourceableId());

          ThreadLocalUserActivityLogger.log(CourseLoggingAction.COURSE_EDITOR_NODE_COPIED, getClass());
          fireEvent(ureq, Event.DONE_EVENT);
        } else { // move only
          if (insertParent.getIdent().equals(moveCopyFrom.getParent().getIdent())) {
            // same parent, adjust insertPos
            if (insertPos > moveCopyFrom.getPosition()) insertPos--;
          }
          insertParent.insert(moveCopyFrom, insertPos);

          moveCopyFrom.setDirty(true);
          //mark subtree as dirty
          TreeVisitor tv = new TreeVisitor( new Visitor() {
            public void visit(INode node) {
              CourseEditorTreeNode cetn = (CourseEditorTreeNode)node;
              cetn.setDirty(true);
            }
          },moveCopyFrom,true);
          tv.visitAll();         
          CourseFactory.saveCourseEditorTreeModel(course.getResourceableId()); // TODO: pb: Review : Add by chg to FIX OLAT-1662
          this.showInfo("movecopynode.info.condmoved");

          ThreadLocalUserActivityLogger.log(CourseLoggingAction.COURSE_EDITOR_NODE_MOVED, getClass());
          fireEvent(ureq, Event.DONE_EVENT);
        }
      } else {
        fireEvent(ureq, Event.CANCELLED_EVENT);
      }
    }
  }

  private void recursiveCopy(CourseEditorTreeNode copyFrom2, CourseEditorTreeNode insertParent, int pos, boolean firstIteration, ICourse course) {   
    // create copy of course node
    CourseNode copyOfNode = copyFrom2.getCourseNode().createInstanceForCopy(firstIteration);
    copyNodeId = copyOfNode.getIdent();
    // Insert at desired position   
    course.getEditorTreeModel().insertCourseNodeAt(copyOfNode, insertParent.getCourseNode(), pos);
    CourseEditorTreeNode insertedEditorTreeNode = course.getEditorTreeModel().getCourseEditorNodeById(copyOfNode.getIdent());
    for (int i = 0; i < copyFrom2.getChildCount(); i++) {
      recursiveCopy(course.getEditorTreeModel().getCourseEditorNodeById(copyFrom2.getChildAt(i).getIdent()), insertedEditorTreeNode, i, false, course);
    }
  }

  /**
   * Check if prospectChild is a child of sourceTree.
   *
   * @param prospectChild
   * @param sourceTree
   * @return
   */
  private boolean checkIfIsChild(CourseEditorTreeNode prospectChild, CourseEditorTreeNode sourceTree) {
    // FIXME:ms:b would it be simpler to check the parents?
    // INode par;
    // for (par = prospectChild.getParent(); par != null && par != sourceTree;
    // par = par.getParent());
    // return (par == sourceTree);
    ICourse course = CourseFactory.getCourseEditSession(ores.getResourceableId());
    if (sourceTree.getIdent().equals(prospectChild.getIdent())) return true;
    for (int i = 0; i < sourceTree.getChildCount(); i++) {
      INode child = sourceTree.getChildAt(i);
      if (checkIfIsChild(prospectChild, course.getEditorTreeModel().getCourseEditorNodeById(child.getIdent()))) return true;
    }
    return false;
  }

  protected void doDispose() {
    // nothing to dispose
  }

  /**
   * Returns node-id of a new copied node.
   * @return Returns null when no copy-workflow happens.
   */
  public String getCopyNodeId() {
    return copyNodeId;
  }

}
TOP

Related Classes of org.olat.course.editor.MoveCopySubtreeController

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.