diff --git a/olat3/webapp/WEB-INF/src/org/olat/portfolio/manager/EPFrontendManager.java b/olat3/webapp/WEB-INF/src/org/olat/portfolio/manager/EPFrontendManager.java index f4e84a6a9dd68d24a355d757d3b64e8cd145f0ec..89b302a50459cb0b71426c2394788d0dd8ff3ec2 100755 --- a/olat3/webapp/WEB-INF/src/org/olat/portfolio/manager/EPFrontendManager.java +++ b/olat3/webapp/WEB-INF/src/org/olat/portfolio/manager/EPFrontendManager.java @@ -206,10 +206,19 @@ public class EPFrontendManager extends BasicManager { * @param newParStruct * @return true if no exception occured */ - public boolean moveStructureToNewParentStructure(PortfolioStructure structToBeMvd, PortfolioStructure oldParStruct, PortfolioStructure newParStruct){ - return structureManager.moveStructureToNewParentStructure(structToBeMvd, oldParStruct, newParStruct); + public boolean moveStructureToNewParentStructure(PortfolioStructure structToBeMvd, PortfolioStructure oldParStruct, PortfolioStructure newParStruct, int destinationPos){ + return structureManager.moveStructureToNewParentStructure(structToBeMvd, oldParStruct, newParStruct, destinationPos); } + /** + * move a structures order within the same parent, allows manual sorting. + * @param structToBeMvd + * @param destinationPos where it should be placed + * @return true if it went ok, false otherwise + */ + public boolean moveStructureToPosition(PortfolioStructure structToBeMvd, int destinationPos){ + return structureManager.reOrderStructures(loadStructureParent(structToBeMvd), structToBeMvd, destinationPos); + } /** * set the reflexion for the link structureElement <-> artefact @@ -765,7 +774,7 @@ public class EPFrontendManager extends BasicManager { */ public PortfolioStructure createAndPersistPortfolioStructureElement(PortfolioStructure root, String title, String description) { EPStructureElement newStruct = (EPStructureElement) structureManager.createPortfolioStructure(root, title, description); - if (root != null) structureManager.addStructureToStructure(root, newStruct); + if (root != null) structureManager.addStructureToStructure(root, newStruct, -1); structureManager.savePortfolioStructure(newStruct); return newStruct; } @@ -779,7 +788,7 @@ public class EPFrontendManager extends BasicManager { */ public PortfolioStructure createAndPersistPortfolioPage(PortfolioStructure root, String title, String description) { EPPage newPage = (EPPage) structureManager.createPortfolioPage(root, title, description); - if (root != null) structureManager.addStructureToStructure(root, newPage); + if (root != null) structureManager.addStructureToStructure(root, newPage, -1); structureManager.savePortfolioStructure(newPage); return newPage; } diff --git a/olat3/webapp/WEB-INF/src/org/olat/portfolio/manager/EPStructureManager.java b/olat3/webapp/WEB-INF/src/org/olat/portfolio/manager/EPStructureManager.java index d0ebd8114100be1ac4b030dc1dc7d1c26b2b0353..195bf275e95cfe3a30bfa5aec27ef478bd5180fd 100755 --- a/olat3/webapp/WEB-INF/src/org/olat/portfolio/manager/EPStructureManager.java +++ b/olat3/webapp/WEB-INF/src/org/olat/portfolio/manager/EPStructureManager.java @@ -796,8 +796,9 @@ public class EPStructureManager extends BasicManager { * Add a child structure to the parent structure. * @param parentStructure * @param childStructure + * @param destinationPos set to -1 to append at the end! */ - public void addStructureToStructure(PortfolioStructure parentStructure, PortfolioStructure childStructure) { + public void addStructureToStructure(PortfolioStructure parentStructure, PortfolioStructure childStructure, int destinationPos) { if (parentStructure == null || childStructure == null) throw new NullPointerException(); if(childStructure instanceof EPStructureElement) { //save eventual changes @@ -811,15 +812,19 @@ public class EPStructureManager extends BasicManager { //refresh internal link to its root element ((EPStructureElement)childStructure).setRoot((EPStructureElement) parentStructure); - ((EPStructureElement)parentStructure).getInternalChildren().add(link); + if (destinationPos == -1) { + ((EPStructureElement)parentStructure).getInternalChildren().add(link); + } else { + ((EPStructureElement)parentStructure).getInternalChildren().add(destinationPos, link); + } } } - protected boolean moveStructureToNewParentStructure(PortfolioStructure structToBeMvd, PortfolioStructure oldParStruct, PortfolioStructure newParStruct){ + protected boolean moveStructureToNewParentStructure(PortfolioStructure structToBeMvd, PortfolioStructure oldParStruct, PortfolioStructure newParStruct, int destinationPos){ if (structToBeMvd == null || oldParStruct == null || newParStruct == null) throw new NullPointerException(); try { // try catch, as used in d&d TOC-tree, should still continue on error removeStructure(oldParStruct, structToBeMvd); - addStructureToStructure(newParStruct, structToBeMvd); + addStructureToStructure(newParStruct, structToBeMvd, destinationPos); } catch (Exception e) { logError("could not move structure " + structToBeMvd.getKey() + " from " + oldParStruct.getKey() + " to " + newParStruct.getKey(), e); return false; @@ -983,9 +988,24 @@ public class EPStructureManager extends BasicManager { } } - private int indexOf(List<EPStructureToStructureLink> artefactLinks, PortfolioStructure structure) { + protected boolean reOrderStructures(PortfolioStructure parent, PortfolioStructure orderSubject, int orderDest){ + EPStructureElement structureEl = (EPStructureElement)dbInstance.loadObject((EPStructureElement)parent); + List<EPStructureToStructureLink> structureLinks = structureEl.getInternalChildren(); + + int oldPos = indexOf(structureLinks, orderSubject); + if (oldPos != orderDest && oldPos != -1) { + EPStructureToStructureLink link = structureLinks.remove(oldPos); + while (orderDest > structureLinks.size()) orderDest--; // place at end + structureLinks.add(orderDest, link); + dbInstance.updateObject(structureEl); + return true; + } + return false; + } + + private int indexOf(List<EPStructureToStructureLink> structLinks, PortfolioStructure structure) { int count = 0; - for(EPStructureToStructureLink link:artefactLinks) { + for(EPStructureToStructureLink link:structLinks) { if(link.getChild().getKey().equals(structure.getKey())) { return count; } diff --git a/olat3/webapp/WEB-INF/src/org/olat/portfolio/model/structel/EPStructureElement.java b/olat3/webapp/WEB-INF/src/org/olat/portfolio/model/structel/EPStructureElement.java index 3eedb7cf8e37570fe5a43b0ed393e28f2809497c..f0aa61199b895220cec1976e02f17a55ef8dfed4 100755 --- a/olat3/webapp/WEB-INF/src/org/olat/portfolio/model/structel/EPStructureElement.java +++ b/olat3/webapp/WEB-INF/src/org/olat/portfolio/model/structel/EPStructureElement.java @@ -64,29 +64,6 @@ public class EPStructureElement extends PersistentObject implements PortfolioStr this.structureElSource = structureElSource; } - /** - * @uml.property name="order" - */ - private String order; - - /** - * Getter of the property <tt>order</tt> - * @return Returns the order. - * @uml.property name="order" - */ - public String getOrder() { - return order; - } - - /** - * Setter of the property <tt>order</tt> - * @param order The order to set. - * @uml.property name="order" - */ - public void setOrder(String order) { - this.order = order; - } - /** * @uml.property name="title" */ diff --git a/olat3/webapp/WEB-INF/src/org/olat/portfolio/ui/structel/edit/EPTOCController.java b/olat3/webapp/WEB-INF/src/org/olat/portfolio/ui/structel/edit/EPTOCController.java index 9e2ba650f854194af0479da927d748763f08d47a..d2e120d673377d6cfb17a0f87b0f0fc349782bd2 100644 --- a/olat3/webapp/WEB-INF/src/org/olat/portfolio/ui/structel/edit/EPTOCController.java +++ b/olat3/webapp/WEB-INF/src/org/olat/portfolio/ui/structel/edit/EPTOCController.java @@ -93,7 +93,7 @@ public class EPTOCController extends BasicController { eSTMgr = (EPStructureManager) CoreSpringFactory.getBean("epStructureManager"); this.rootNode = rootNode; AjaxTreeModel treeModel = buildTreeModel(); - treeCtr = new TreeController(ureq, getWindowControl(), translate("toc.root"), treeModel, null); + treeCtr = new TreeController(ureq, getWindowControl(), translate("toc.root"), treeModel, "myjsCallback"); treeCtr.setTreeSorting(false, false, false); listenTo(treeCtr); tocV.put("tocTree", treeCtr.getInitialComponent()); @@ -186,19 +186,23 @@ public class EPTOCController extends BasicController { if (structs != null && structs.size() != 0) { for (PortfolioStructure portfolioStructure : structs) { String childNodeId = String.valueOf(portfolioStructure.getKey()); - child = new AjaxTreeNode(childNodeId, portfolioStructure.getTitle()); boolean hasStructureChild = eSTMgr.countStructureChildren(portfolioStructure) > 0; boolean hasArtefacts = eSTMgr.countArtefacts(portfolioStructure) > 0; boolean hasChilds = hasStructureChild || hasArtefacts; - - //TODO: epf: RH: seems to be a bug, nothing can be dropped on a leaf, why that?? + child = new AjaxTreeNode(childNodeId, portfolioStructure.getTitle()); + if (isLogDebugEnabled()){ + child = new AjaxTreeNode(childNodeId, portfolioStructure.getTitle() + "drop:" + !isRoot + "drag:" + !isRoot + "leaf:"+!hasChilds); + } + // seems to be a bug, nothing can be dropped on a leaf, therefore we need to tweak with expanded/expandable ourself! // child.put(AjaxTreeNode.CONF_LEAF, !hasChilds); child.put(AjaxTreeNode.CONF_IS_TYPE_LEAF, !hasChilds); child.put(AjaxTreeNode.CONF_ALLOWDRAG, !isRoot); - boolean isOpen = hasStructureChild ; - //boolean isOpen =(((EPStructureElement) portfolioStructure).getChildren().size() != 0); - child.put(AjaxTreeNode.CONF_EXPANDED, isOpen); - child.put(AjaxTreeNode.CONF_ALLOWDROP, !isRoot ); + + child.put(AjaxTreeNode.CONF_EXPANDED, hasStructureChild); + child.put(AjaxTreeNode.CONF_EXPANDABLE, hasChilds); + child.put(AjaxTreeNode.CONF_ALLOWDROP, true); + child.put(AjaxTreeNode.CONF_ISTARGET, !isRoot); + child.put(AjaxTreeNode.CONF_ICON_CSS_CLASS, portfolioStructure.getIcon()); String description = FilterFactory.getHtmlTagAndDescapingFilter().filter(portfolioStructure.getDescription()); child.put(AjaxTreeNode.CONF_QTIP, description); @@ -336,7 +340,8 @@ public class EPTOCController extends BasicController { MoveTreeNodeEvent moveEvent = (MoveTreeNodeEvent) event; String movedNode = moveEvent.getNodeId(); String oldParent = moveEvent.getOldParentNodeId(); - String newParent = moveEvent.getNewParentNodeId(); + String newParent = moveEvent.getNewParentNodeId(); + int newPos = moveEvent.getPosition(); boolean isArtefactNode = movedNode.startsWith(ARTEFACT_NODE_IDENTIFIER); if (isArtefactNode) { String nodeId = getArtefactIdFromNodeId(movedNode); @@ -355,7 +360,7 @@ public class EPTOCController extends BasicController { } } else { if (checkNewStructureTarget(movedNode, oldParent, newParent)){ - if (moveStructureToNewParent(movedNode, oldParent, newParent)) { + if (moveStructureToNewParent(movedNode, oldParent, newParent, newPos)) { if (isLogDebugEnabled()) logInfo("moved structure " + movedNode + " from structure " + oldParent + " to " + newParent, null); moveEvent.setResult(true, null, null); // refresh the view @@ -452,32 +457,24 @@ public class EPTOCController extends BasicController { */ private boolean checkNewStructureTarget(String subjectStructId, String oldParStructId, String newParStructId){ PortfolioStructure structToBeMvd; - PortfolioStructure oldParStruct; PortfolioStructure newParStruct; + if (oldParStructId.equals(newParStructId)) return true; // seems only to be a move in order if (newParStructId.equals(ROOT_NODE_IDENTIFIER)) return false; try { structToBeMvd = ePFMgr.loadPortfolioStructureByKey(new Long(subjectStructId)); - oldParStruct = ePFMgr.loadPortfolioStructureByKey(new Long(oldParStructId)); newParStruct = ePFMgr.loadPortfolioStructureByKey(new Long(newParStructId)); } catch (Exception e) { logError("could not check for valid structure target", e); return false; } - if (newParStruct instanceof EPAbstractMap) return false; - if (oldParStruct.getKey().equals(newParStruct.getKey())) return false; if (structToBeMvd instanceof EPPage && newParStruct instanceof EPPage) return false; if (structToBeMvd instanceof EPStructureElement && !(newParStruct instanceof EPPage)) return false; - - // how to allow changing of order?? - //TODO: epf: RH: allow move, it seems this needs to fix in js on gui -// if (structToBeMvd instanceof EPPage && (newParStruct instanceof EPPage || newParStruct instanceof ) return false; -// if (structToBeMvd instanceof EPStructureElement) return true; - + return true; } // really do the move - private boolean moveStructureToNewParent(String subjectStructId, String oldParStructId, String newParStructId){ + private boolean moveStructureToNewParent(String subjectStructId, String oldParStructId, String newParStructId, int newPos){ PortfolioStructure structToBeMvd; PortfolioStructure oldParStruct; PortfolioStructure newParStruct; @@ -489,7 +486,13 @@ public class EPTOCController extends BasicController { logError("could not load: structure to be moved, old or new structure while trying to move", e); return false; } - return ePFMgr.moveStructureToNewParentStructure(structToBeMvd, oldParStruct, newParStruct); + + if (oldParStructId.equals(newParStructId)) { + // this is only a position move + return ePFMgr.moveStructureToPosition(structToBeMvd, newPos); + } + + return ePFMgr.moveStructureToNewParentStructure(structToBeMvd, oldParStruct, newParStruct, newPos); } /** diff --git a/olat3/webapp/WEB-INF/src/org/olat/portfolio/ui/structel/edit/_content/toc.html b/olat3/webapp/WEB-INF/src/org/olat/portfolio/ui/structel/edit/_content/toc.html index a13642bb53600b5e10afbb706f4cb727b9808fa8..9ed0c014b72bb9331526a059a4be6822c14f812d 100644 --- a/olat3/webapp/WEB-INF/src/org/olat/portfolio/ui/structel/edit/_content/toc.html +++ b/olat3/webapp/WEB-INF/src/org/olat/portfolio/ui/structel/edit/_content/toc.html @@ -1,2 +1,43 @@ #if($r.available("addElement")) $r.render("addElement") #end $r.render("deleteButton")<br/><br/> + +<script type="text/javascript"> +/* <![CDATA[ */ +function myjsCallback(dragOverEvent) { + // the following members can be getted from the dragOverEvent: + // tree - The TreePanel + // target - The node being targeted for the drop + // data - The drag data from the drag source + // point - The point of the drop - append, above or below + // source - The drag source + // rawEvent - Raw mouse event + // dropNode - Drop node(s) provided by the source. + // cancel - Set this to true to signal drop not allowed. + + var node = dragOverEvent.dropNode; + var nodeDeep = node.getDepth(); + + // append -> add as child; above -> at same level above; below -> at same level above + var newParent = (dragOverEvent.point == 'append' ? dragOverEvent.target : dragOverEvent.target.parentNode); + + var allowChild = newParent.allowChildren; + // no drop on artefacts + if (!allowChild) return false; + var parentDeep = newParent.getDepth(); + + //console.log(node.attributes.text + " nodeDeep: " + nodeDeep + " targetDeep: "+ parentDeep); + + // no drop on root + if (parentDeep == 0) return false; + // no drop on map/root + if (nodeDeep == 3 && (parentDeep == 1 || parentDeep == 0)) return false; + // moving a page/struct to struct is not possible + if (nodeDeep <= 3 && parentDeep==3 && node.allowChildren) return false; + // moving a page to page is not possible + if (nodeDeep == 2 && parentDeep==2 && node.allowChildren) return false; + + return true; +} +/* ]]> */ +</script> + $r.render("tocTree") \ No newline at end of file diff --git a/olatcore/src/main/java/org/olat/core/gui/control/generic/ajax/tree/AjaxTreeNode.java b/olatcore/src/main/java/org/olat/core/gui/control/generic/ajax/tree/AjaxTreeNode.java index cc24885d35cc0f9ed8b4006d40ce05db7f820c99..4ac3cc261109fb43506ca39975454ad39cf56462 100644 --- a/olatcore/src/main/java/org/olat/core/gui/control/generic/ajax/tree/AjaxTreeNode.java +++ b/olatcore/src/main/java/org/olat/core/gui/control/generic/ajax/tree/AjaxTreeNode.java @@ -55,7 +55,8 @@ public class AjaxTreeNode extends JSONObject { public static String CONF_ID = "id"; - public static String CONF_LEAF = "leaf"; // false: adds + icon next to item + /** false: adds + icon next to item */ + public static String CONF_LEAF = "leaf"; public static String CONF_QTIP = "qtip"; @@ -68,12 +69,20 @@ public class AjaxTreeNode extends JSONObject { public static String CONF_UIPROVIDER = "uiProvider"; public static String CONF_DISABLED = "disabled"; - - public static String CONF_EXPANDED = "expanded"; // true to start the node expanded + + /** true to start the node expanded */ + public static String CONF_EXPANDED = "expanded"; + + /** force to show +/- icon */ + public static String CONF_EXPANDABLE = "expandable"; + /** disallow element itself as target but allow to add/move children (allowdrop=true) */ + public static String CONF_ISTARGET = "isTarget"; + // custom attributes - public static String CONF_IS_TYPE_LEAF = "isTypeLeaf"; // orders leafs below folders + /** orders leafs below folders */ + public static String CONF_IS_TYPE_LEAF = "isTypeLeaf"; /** * Constructor