001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com) 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * For further information about Alkacon Software, please see the 018 * company website: http://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: http://www.opencms.org 022 * 023 * You should have received a copy of the GNU Lesser General Public 024 * License along with this library; if not, write to the Free Software 025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 026 */ 027 028package org.opencms.ade.containerpage.client.ui; 029 030import org.opencms.ade.containerpage.client.CmsContainerpageController; 031import org.opencms.ade.containerpage.shared.CmsContainerElement; 032import org.opencms.ade.containerpage.shared.CmsElementLockInfo; 033import org.opencms.gwt.client.dnd.CmsDNDHandler.Orientation; 034import org.opencms.gwt.client.dnd.I_CmsDraggable; 035import org.opencms.gwt.client.dnd.I_CmsDropTarget; 036import org.opencms.gwt.client.ui.CmsHighlightingBorder; 037import org.opencms.gwt.client.util.CmsDomUtil; 038import org.opencms.gwt.client.util.CmsPositionBean; 039import org.opencms.util.CmsUUID; 040 041import java.util.ArrayList; 042import java.util.Collections; 043import java.util.Iterator; 044import java.util.List; 045 046import com.google.gwt.dom.client.Element; 047import com.google.gwt.dom.client.Style.Display; 048import com.google.gwt.dom.client.Style.Unit; 049import com.google.gwt.user.client.ui.RootPanel; 050import com.google.gwt.user.client.ui.Widget; 051 052/** 053 * Group-container element. To be used for content elements within a container-page.<p> 054 * The group-container acts as a draggable element and if edited as a container.<p> 055 * 056 * @since 8.0.0 057 */ 058public class CmsGroupContainerElementPanel extends CmsContainerPageElementPanel implements I_CmsDropContainer { 059 060 /** Processed children of the group. */ 061 private List<CmsContainerPageElementPanel> m_children; 062 063 /** The container type. */ 064 private String m_containerId; 065 066 /** The editing marker. Used to highlight the container background while editing. */ 067 private Element m_editingMarker; 068 069 /** The editing placeholder. Used within group-container editing. */ 070 private Element m_editingPlaceholder; 071 072 /** The cached highlighting position. */ 073 private CmsPositionBean m_ownPosition; 074 075 /** The placeholder element. */ 076 private Element m_placeholder; 077 078 /** The index of the current placeholder position. */ 079 private int m_placeholderIndex = -1; 080 081 /** The resource type name. */ 082 private String m_resourceType; 083 084 /** 085 * Constructor.<p> 086 * 087 * @param element the DOM element 088 * @param parent the drag parent 089 * @param clientId the client id 090 * @param sitePath the element site-path 091 * @param resourceType the resource type name 092 * @param noEditReason the no edit reason, if empty, editing is allowed 093 * @param title the resource title 094 * @param subTitle the sub title 095 * @param hasSettings should be true if the element has settings which can be edited 096 * @param hasViewPermission indicates if the current user has view permissions on the element resource 097 * @param hasWritePermission indicates if the current user has write permissions on the element resource 098 * @param releasedAndNotExpired <code>true</code> if the element resource is currently released and not expired 099 * @param elementView the element view of the element 100 * @param iconClasses the resource type icon CSS classes 101 */ 102 public CmsGroupContainerElementPanel( 103 Element element, 104 I_CmsDropContainer parent, 105 String clientId, 106 String sitePath, 107 String resourceType, 108 String noEditReason, 109 String title, 110 String subTitle, 111 boolean hasSettings, 112 boolean hasViewPermission, 113 boolean hasWritePermission, 114 boolean releasedAndNotExpired, 115 CmsUUID elementView, 116 String iconClasses) { 117 118 super( 119 element, 120 parent, 121 clientId, 122 sitePath, 123 noEditReason, 124 new CmsElementLockInfo(null, false), 125 title, 126 subTitle, 127 resourceType, 128 hasSettings, 129 hasViewPermission, 130 hasWritePermission, 131 releasedAndNotExpired, 132 true, 133 false, 134 null, 135 false, 136 elementView, 137 iconClasses, 138 false); 139 m_resourceType = resourceType; 140 } 141 142 /** 143 * @see org.opencms.ade.containerpage.client.ui.I_CmsDropContainer#addDndChild(org.opencms.gwt.client.dnd.I_CmsDropTarget) 144 */ 145 public void addDndChild(I_CmsDropTarget child) { 146 147 throw new UnsupportedOperationException("Element groups do not support nested containers"); 148 } 149 150 /** 151 * @see org.opencms.ade.containerpage.client.ui.I_CmsDropContainer#adoptElement(org.opencms.ade.containerpage.client.ui.CmsContainerPageElementPanel) 152 */ 153 public void adoptElement(CmsContainerPageElementPanel containerElement) { 154 155 assert getElement().equals(containerElement.getElement().getParentElement()); 156 getChildren().add(containerElement); 157 adopt(containerElement); 158 } 159 160 /** 161 * @see org.opencms.ade.containerpage.client.ui.I_CmsDropContainer#checkMaxElementsOnEnter() 162 */ 163 public void checkMaxElementsOnEnter() { 164 165 // TODO: implement 166 167 } 168 169 /** 170 * @see org.opencms.ade.containerpage.client.ui.I_CmsDropContainer#checkMaxElementsOnLeave() 171 */ 172 public void checkMaxElementsOnLeave() { 173 174 // TODO: implement 175 176 } 177 178 /** 179 * @see org.opencms.gwt.client.dnd.I_CmsDropTarget#checkPosition(int, int, Orientation) 180 */ 181 public boolean checkPosition(int x, int y, Orientation orientation) { 182 183 // ignore orientation 184 int scrollTop = getElement().getOwnerDocument().getScrollTop(); 185 // use cached position 186 int relativeTop = (y + scrollTop) - m_ownPosition.getTop(); 187 if ((relativeTop > 0) && (m_ownPosition.getHeight() > relativeTop)) { 188 // cursor is inside the height of the element, check horizontal position 189 int scrollLeft = getElement().getOwnerDocument().getScrollLeft(); 190 int relativeLeft = (x + scrollLeft) - m_ownPosition.getLeft(); 191 return (relativeLeft > 0) && (m_ownPosition.getWidth() > relativeLeft); 192 } 193 return false; 194 } 195 196 /** 197 * @see org.opencms.ade.containerpage.client.ui.I_CmsDropContainer#clearDnDChildren() 198 */ 199 public void clearDnDChildren() { 200 201 // nothing todo 202 } 203 204 /** 205 * Clears the editing placeholder reference.<p> 206 */ 207 public void clearEditingPlaceholder() { 208 209 m_editingPlaceholder = null; 210 m_editingMarker = null; 211 } 212 213 /** 214 * Returns the container id.<p> 215 * 216 * @return the container id 217 */ 218 public String getContainerId() { 219 220 return m_containerId; 221 } 222 223 /** 224 * @see org.opencms.gwt.client.dnd.I_CmsNestedDropTarget#getDnDChildren() 225 */ 226 public List<I_CmsDropTarget> getDnDChildren() { 227 228 return null; 229 } 230 231 /** 232 * Gets the consumed group elements.<p> 233 * 234 * @return the list of children 235 */ 236 public List<CmsContainerPageElementPanel> getGroupChildren() { 237 238 if (m_children == null) { 239 // can happen when saving element groups 240 return Collections.emptyList(); 241 } 242 return m_children; 243 } 244 245 /** 246 * @see org.opencms.gwt.client.dnd.I_CmsDropTarget#getPlaceholderIndex() 247 */ 248 public int getPlaceholderIndex() { 249 250 return m_placeholderIndex; 251 } 252 253 /** 254 * @see org.opencms.ade.containerpage.client.ui.I_CmsDropContainer#getPositionInfo() 255 */ 256 public CmsPositionBean getPositionInfo() { 257 258 return m_ownPosition; 259 } 260 261 /** 262 * @see org.opencms.gwt.client.dnd.I_CmsNestedDropTarget#hasDnDChildren() 263 */ 264 public boolean hasDnDChildren() { 265 266 return false; 267 } 268 269 /** 270 * @see org.opencms.ade.containerpage.client.ui.CmsContainerPageElementPanel#hideEditableListButtons() 271 */ 272 @Override 273 public void hideEditableListButtons() { 274 275 Iterator<Widget> it = iterator(); 276 while (it.hasNext()) { 277 Widget child = it.next(); 278 if (child instanceof CmsContainerPageElementPanel) { 279 ((CmsContainerPageElementPanel)child).hideEditableListButtons(); 280 } 281 } 282 } 283 284 /** 285 * @see org.opencms.ade.containerpage.client.ui.I_CmsDropContainer#highlightContainer() 286 */ 287 public void highlightContainer(boolean addSeparators) { 288 289 // separators neither needed nor implemented 290 highlightContainer(CmsPositionBean.getBoundingClientRect(getElement()), addSeparators); 291 } 292 293 /** 294 * @see org.opencms.ade.containerpage.client.ui.I_CmsDropContainer#highlightContainer(org.opencms.gwt.client.util.CmsPositionBean) 295 */ 296 public void highlightContainer(CmsPositionBean positionInfo, boolean separators) { 297 // separators neither needed nor implemented 298 299 // remove any remaining highlighting 300 if (m_highlighting != null) { 301 m_highlighting.removeFromParent(); 302 } 303 // cache the position info, to be used during drag and drop 304 m_ownPosition = positionInfo; 305 if (m_editingPlaceholder != null) { 306 m_editingPlaceholder.getStyle().setHeight(m_ownPosition.getHeight() + 10, Unit.PX); 307 } 308 if (m_editingMarker != null) { 309 m_editingMarker.getStyle().setHeight(m_ownPosition.getHeight() + 4, Unit.PX); 310 m_editingMarker.getStyle().setWidth(m_ownPosition.getWidth() + 4, Unit.PX); 311 } 312 m_highlighting = new CmsHighlightingBorder(m_ownPosition, CmsHighlightingBorder.BorderColor.red); 313 RootPanel.get().add(m_highlighting); 314 } 315 316 /** 317 * @see org.opencms.ade.containerpage.client.ui.CmsContainerPageElementPanel#initInlineEditor(org.opencms.ade.containerpage.client.CmsContainerpageController) 318 */ 319 @Override 320 public void initInlineEditor(CmsContainerpageController controller) { 321 322 // don to anything 323 } 324 325 /** 326 * @see org.opencms.gwt.client.dnd.I_CmsDropTarget#insertPlaceholder(com.google.gwt.dom.client.Element, int, int, Orientation) 327 */ 328 public void insertPlaceholder(Element placeholder, int x, int y, Orientation orientation) { 329 330 m_placeholderIndex = -1; 331 m_placeholder = placeholder; 332 m_placeholder.getStyle().setDisplay(Display.NONE); 333 repositionPlaceholder(x, y, orientation); 334 } 335 336 /** 337 * @see org.opencms.ade.containerpage.client.ui.I_CmsDropContainer#isDetailOnly() 338 */ 339 public boolean isDetailOnly() { 340 341 return false; 342 } 343 344 /** 345 * @see org.opencms.ade.containerpage.client.ui.I_CmsDropContainer#isDetailView() 346 */ 347 public boolean isDetailView() { 348 349 return false; 350 } 351 352 /** 353 * @see org.opencms.ade.containerpage.client.ui.I_CmsDropContainer#isEditable() 354 */ 355 public boolean isEditable() { 356 357 return hasWritePermission(); 358 } 359 360 /** 361 * Returns if this element represents a group container.<p> 362 * 363 * @return <code>true</code> if this element represents a group container 364 */ 365 public boolean isGroupContainer() { 366 367 return CmsContainerElement.GROUP_CONTAINER_TYPE_NAME.equals(m_resourceType); 368 } 369 370 /** 371 * Returns if this element represents an inherit container.<p> 372 * 373 * @return <code>true</code> if this element represents an inherit container 374 */ 375 public boolean isInheritContainer() { 376 377 return CmsContainerElement.INHERIT_CONTAINER_TYPE_NAME.equals(m_resourceType); 378 } 379 380 /** 381 * @see org.opencms.ade.containerpage.client.ui.I_CmsDropContainer#onConsumeChildren(java.util.List) 382 */ 383 public void onConsumeChildren(List<CmsContainerPageElementPanel> children) { 384 385 m_children = new ArrayList<CmsContainerPageElementPanel>(children); 386 } 387 388 /** 389 * @see org.opencms.gwt.client.dnd.I_CmsDropTarget#onDrop(org.opencms.gwt.client.dnd.I_CmsDraggable) 390 */ 391 public void onDrop(I_CmsDraggable draggable) { 392 393 // nothing to do 394 395 } 396 397 /** 398 * @see org.opencms.ade.containerpage.client.ui.I_CmsDropContainer#refreshHighlighting() 399 */ 400 public void refreshHighlighting() { 401 402 refreshHighlighting(CmsPositionBean.getBoundingClientRect(getElement())); 403 } 404 405 /** 406 * @see org.opencms.ade.containerpage.client.ui.I_CmsDropContainer#refreshHighlighting(org.opencms.gwt.client.util.CmsPositionBean) 407 */ 408 public void refreshHighlighting(CmsPositionBean positionInfo) { 409 410 m_ownPosition = positionInfo; 411 if (m_editingPlaceholder != null) { 412 m_editingPlaceholder.getStyle().setHeight(m_ownPosition.getHeight() + 10, Unit.PX); 413 } 414 if (m_editingMarker != null) { 415 m_editingMarker.getStyle().setHeight(m_ownPosition.getHeight() + 4, Unit.PX); 416 m_editingMarker.getStyle().setWidth(m_ownPosition.getWidth() + 4, Unit.PX); 417 } 418 if (m_highlighting != null) { 419 m_highlighting.setPosition(m_ownPosition); 420 } 421 } 422 423 /** 424 * @see org.opencms.ade.containerpage.client.ui.CmsContainerPageElementPanel#removeHighlighting() 425 */ 426 @Override 427 public void removeHighlighting() { 428 429 if (m_highlighting != null) { 430 m_highlighting.removeFromParent(); 431 m_highlighting = null; 432 } 433 } 434 435 /** 436 * @see org.opencms.gwt.client.dnd.I_CmsDropTarget#removePlaceholder() 437 */ 438 public void removePlaceholder() { 439 440 if (m_placeholder != null) { 441 m_placeholder.removeFromParent(); 442 m_placeholder = null; 443 } 444 m_placeholderIndex = -1; 445 } 446 447 /** 448 * @see org.opencms.gwt.client.dnd.I_CmsDropTarget#repositionPlaceholder(int, int, Orientation) 449 */ 450 public void repositionPlaceholder(int x, int y, Orientation orientation) { 451 452 int oldIndex = m_placeholderIndex; 453 switch (orientation) { 454 case HORIZONTAL: 455 m_placeholderIndex = CmsDomUtil.positionElementInside( 456 m_placeholder, 457 getElement(), 458 m_placeholderIndex, 459 x, 460 -1); 461 break; 462 case VERTICAL: 463 m_placeholderIndex = CmsDomUtil.positionElementInside( 464 m_placeholder, 465 getElement(), 466 m_placeholderIndex, 467 -1, 468 y); 469 break; 470 case ALL: 471 default: 472 m_placeholderIndex = CmsDomUtil.positionElementInside( 473 m_placeholder, 474 getElement(), 475 m_placeholderIndex, 476 x, 477 y); 478 break; 479 } 480 if (oldIndex != m_placeholderIndex) { 481 m_ownPosition = CmsPositionBean.getBoundingClientRect(getElement()); 482 } 483 } 484 485 /** 486 * Sets the container id.<p> 487 * 488 * @param containerId the container id to set 489 */ 490 public void setContainerId(String containerId) { 491 492 m_containerId = containerId; 493 } 494 495 /** 496 * Sets the editing marker. Used to highlight the container background while editing.<p> 497 * 498 * @param editingMarker the editing marker element 499 */ 500 public void setEditingMarker(Element editingMarker) { 501 502 m_editingMarker = editingMarker; 503 } 504 505 /** 506 * Sets the editing placeholder.<p> 507 * 508 * @param editingPlaceholder the editing placeholder element 509 */ 510 public void setEditingPlaceholder(Element editingPlaceholder) { 511 512 m_editingPlaceholder = editingPlaceholder; 513 } 514 515 /** 516 * @see org.opencms.ade.containerpage.client.ui.I_CmsDropContainer#setPlaceholderVisibility(boolean) 517 */ 518 public void setPlaceholderVisibility(boolean visible) { 519 520 if (visible) { 521 m_placeholder.getStyle().clearDisplay(); 522 } else { 523 m_placeholder.getStyle().setDisplay(Display.NONE); 524 } 525 } 526 527 /** 528 * @see org.opencms.ade.containerpage.client.ui.CmsContainerPageElementPanel#showEditableListButtons() 529 */ 530 @Override 531 public void showEditableListButtons() { 532 533 Iterator<Widget> it = iterator(); 534 while (it.hasNext()) { 535 Widget child = it.next(); 536 if (child instanceof CmsContainerPageElementPanel) { 537 ((CmsContainerPageElementPanel)child).showEditableListButtons(); 538 } 539 } 540 } 541 542 /** 543 * @see org.opencms.ade.containerpage.client.ui.CmsContainerPageElementPanel#updateOptionBarPosition() 544 */ 545 @Override 546 public void updateOptionBarPosition() { 547 548 for (Widget widget : this) { 549 if (widget instanceof CmsContainerPageElementPanel) { 550 ((CmsContainerPageElementPanel)widget).updateOptionBarPosition(); 551 } 552 } 553 } 554 555 /** 556 * @see org.opencms.ade.containerpage.client.ui.I_CmsDropContainer#updatePositionInfo() 557 */ 558 public void updatePositionInfo() { 559 560 m_ownPosition = CmsPositionBean.getBoundingClientRect(getElement()); 561 } 562}