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 m_resourceType = resourceType; 139 } 140 141 /** 142 * @see org.opencms.ade.containerpage.client.ui.I_CmsDropContainer#addDndChild(org.opencms.gwt.client.dnd.I_CmsDropTarget) 143 */ 144 public void addDndChild(I_CmsDropTarget child) { 145 146 throw new UnsupportedOperationException("Element groups do not support nested containers"); 147 } 148 149 /** 150 * @see org.opencms.ade.containerpage.client.ui.I_CmsDropContainer#adoptElement(org.opencms.ade.containerpage.client.ui.CmsContainerPageElementPanel) 151 */ 152 public void adoptElement(CmsContainerPageElementPanel containerElement) { 153 154 assert getElement().equals(containerElement.getElement().getParentElement()); 155 getChildren().add(containerElement); 156 adopt(containerElement); 157 } 158 159 /** 160 * @see org.opencms.ade.containerpage.client.ui.I_CmsDropContainer#checkMaxElementsOnEnter() 161 */ 162 public void checkMaxElementsOnEnter() { 163 164 // TODO: implement 165 166 } 167 168 /** 169 * @see org.opencms.ade.containerpage.client.ui.I_CmsDropContainer#checkMaxElementsOnLeave() 170 */ 171 public void checkMaxElementsOnLeave() { 172 173 // TODO: implement 174 175 } 176 177 /** 178 * @see org.opencms.gwt.client.dnd.I_CmsDropTarget#checkPosition(int, int, Orientation) 179 */ 180 public boolean checkPosition(int x, int y, Orientation orientation) { 181 182 // ignore orientation 183 int scrollTop = getElement().getOwnerDocument().getScrollTop(); 184 // use cached position 185 int relativeTop = (y + scrollTop) - m_ownPosition.getTop(); 186 if ((relativeTop > 0) && (m_ownPosition.getHeight() > relativeTop)) { 187 // cursor is inside the height of the element, check horizontal position 188 int scrollLeft = getElement().getOwnerDocument().getScrollLeft(); 189 int relativeLeft = (x + scrollLeft) - m_ownPosition.getLeft(); 190 return (relativeLeft > 0) && (m_ownPosition.getWidth() > relativeLeft); 191 } 192 return false; 193 } 194 195 /** 196 * @see org.opencms.ade.containerpage.client.ui.I_CmsDropContainer#clearDnDChildren() 197 */ 198 public void clearDnDChildren() { 199 200 // nothing todo 201 } 202 203 /** 204 * Clears the editing placeholder reference.<p> 205 */ 206 public void clearEditingPlaceholder() { 207 208 m_editingPlaceholder = null; 209 m_editingMarker = null; 210 } 211 212 /** 213 * Returns the container id.<p> 214 * 215 * @return the container id 216 */ 217 public String getContainerId() { 218 219 return m_containerId; 220 } 221 222 /** 223 * @see org.opencms.gwt.client.dnd.I_CmsNestedDropTarget#getDnDChildren() 224 */ 225 public List<I_CmsDropTarget> getDnDChildren() { 226 227 return null; 228 } 229 230 /** 231 * Gets the consumed group elements.<p> 232 * 233 * @return the list of children 234 */ 235 public List<CmsContainerPageElementPanel> getGroupChildren() { 236 237 if (m_children == null) { 238 // can happen when saving element groups 239 return Collections.emptyList(); 240 } 241 return m_children; 242 } 243 244 /** 245 * @see org.opencms.gwt.client.dnd.I_CmsDropTarget#getPlaceholderIndex() 246 */ 247 public int getPlaceholderIndex() { 248 249 return m_placeholderIndex; 250 } 251 252 /** 253 * @see org.opencms.ade.containerpage.client.ui.I_CmsDropContainer#getPositionInfo() 254 */ 255 public CmsPositionBean getPositionInfo() { 256 257 return m_ownPosition; 258 } 259 260 /** 261 * @see org.opencms.gwt.client.dnd.I_CmsNestedDropTarget#hasDnDChildren() 262 */ 263 public boolean hasDnDChildren() { 264 265 return false; 266 } 267 268 /** 269 * @see org.opencms.ade.containerpage.client.ui.CmsContainerPageElementPanel#hideEditableListButtons() 270 */ 271 @Override 272 public void hideEditableListButtons() { 273 274 Iterator<Widget> it = iterator(); 275 while (it.hasNext()) { 276 Widget child = it.next(); 277 if (child instanceof CmsContainerPageElementPanel) { 278 ((CmsContainerPageElementPanel)child).hideEditableListButtons(); 279 } 280 } 281 } 282 283 /** 284 * @see org.opencms.ade.containerpage.client.ui.I_CmsDropContainer#highlightContainer() 285 */ 286 public void highlightContainer() { 287 288 highlightContainer(CmsPositionBean.getBoundingClientRect(getElement())); 289 } 290 291 /** 292 * @see org.opencms.ade.containerpage.client.ui.I_CmsDropContainer#highlightContainer(org.opencms.gwt.client.util.CmsPositionBean) 293 */ 294 public void highlightContainer(CmsPositionBean positionInfo) { 295 296 // remove any remaining highlighting 297 if (m_highlighting != null) { 298 m_highlighting.removeFromParent(); 299 } 300 // cache the position info, to be used during drag and drop 301 m_ownPosition = positionInfo; 302 if (m_editingPlaceholder != null) { 303 m_editingPlaceholder.getStyle().setHeight(m_ownPosition.getHeight() + 10, Unit.PX); 304 } 305 if (m_editingMarker != null) { 306 m_editingMarker.getStyle().setHeight(m_ownPosition.getHeight() + 4, Unit.PX); 307 m_editingMarker.getStyle().setWidth(m_ownPosition.getWidth() + 4, Unit.PX); 308 } 309 m_highlighting = new CmsHighlightingBorder(m_ownPosition, CmsHighlightingBorder.BorderColor.red); 310 RootPanel.get().add(m_highlighting); 311 } 312 313 /** 314 * @see org.opencms.ade.containerpage.client.ui.CmsContainerPageElementPanel#initInlineEditor(org.opencms.ade.containerpage.client.CmsContainerpageController) 315 */ 316 @Override 317 public void initInlineEditor(CmsContainerpageController controller) { 318 319 // don to anything 320 } 321 322 /** 323 * @see org.opencms.gwt.client.dnd.I_CmsDropTarget#insertPlaceholder(com.google.gwt.dom.client.Element, int, int, Orientation) 324 */ 325 public void insertPlaceholder(Element placeholder, int x, int y, Orientation orientation) { 326 327 m_placeholderIndex = -1; 328 m_placeholder = placeholder; 329 m_placeholder.getStyle().setDisplay(Display.NONE); 330 repositionPlaceholder(x, y, orientation); 331 } 332 333 /** 334 * @see org.opencms.ade.containerpage.client.ui.I_CmsDropContainer#isDetailOnly() 335 */ 336 public boolean isDetailOnly() { 337 338 return false; 339 } 340 341 /** 342 * @see org.opencms.ade.containerpage.client.ui.I_CmsDropContainer#isDetailView() 343 */ 344 public boolean isDetailView() { 345 346 return false; 347 } 348 349 /** 350 * @see org.opencms.ade.containerpage.client.ui.I_CmsDropContainer#isEditable() 351 */ 352 public boolean isEditable() { 353 354 return hasWritePermission(); 355 } 356 357 /** 358 * Returns if this element represents a group container.<p> 359 * 360 * @return <code>true</code> if this element represents a group container 361 */ 362 public boolean isGroupContainer() { 363 364 return CmsContainerElement.GROUP_CONTAINER_TYPE_NAME.equals(m_resourceType); 365 } 366 367 /** 368 * Returns if this element represents an inherit container.<p> 369 * 370 * @return <code>true</code> if this element represents an inherit container 371 */ 372 public boolean isInheritContainer() { 373 374 return CmsContainerElement.INHERIT_CONTAINER_TYPE_NAME.equals(m_resourceType); 375 } 376 377 /** 378 * @see org.opencms.ade.containerpage.client.ui.I_CmsDropContainer#onConsumeChildren(java.util.List) 379 */ 380 public void onConsumeChildren(List<CmsContainerPageElementPanel> children) { 381 382 m_children = new ArrayList<CmsContainerPageElementPanel>(children); 383 } 384 385 /** 386 * @see org.opencms.gwt.client.dnd.I_CmsDropTarget#onDrop(org.opencms.gwt.client.dnd.I_CmsDraggable) 387 */ 388 public void onDrop(I_CmsDraggable draggable) { 389 390 // nothing to do 391 392 } 393 394 /** 395 * @see org.opencms.ade.containerpage.client.ui.I_CmsDropContainer#refreshHighlighting() 396 */ 397 public void refreshHighlighting() { 398 399 refreshHighlighting(CmsPositionBean.getBoundingClientRect(getElement())); 400 } 401 402 /** 403 * @see org.opencms.ade.containerpage.client.ui.I_CmsDropContainer#refreshHighlighting(org.opencms.gwt.client.util.CmsPositionBean) 404 */ 405 public void refreshHighlighting(CmsPositionBean positionInfo) { 406 407 m_ownPosition = positionInfo; 408 if (m_editingPlaceholder != null) { 409 m_editingPlaceholder.getStyle().setHeight(m_ownPosition.getHeight() + 10, Unit.PX); 410 } 411 if (m_editingMarker != null) { 412 m_editingMarker.getStyle().setHeight(m_ownPosition.getHeight() + 4, Unit.PX); 413 m_editingMarker.getStyle().setWidth(m_ownPosition.getWidth() + 4, Unit.PX); 414 } 415 if (m_highlighting != null) { 416 m_highlighting.setPosition(m_ownPosition); 417 } 418 } 419 420 /** 421 * @see org.opencms.ade.containerpage.client.ui.CmsContainerPageElementPanel#removeHighlighting() 422 */ 423 @Override 424 public void removeHighlighting() { 425 426 if (m_highlighting != null) { 427 m_highlighting.removeFromParent(); 428 m_highlighting = null; 429 } 430 } 431 432 /** 433 * @see org.opencms.gwt.client.dnd.I_CmsDropTarget#removePlaceholder() 434 */ 435 public void removePlaceholder() { 436 437 if (m_placeholder != null) { 438 m_placeholder.removeFromParent(); 439 m_placeholder = null; 440 } 441 m_placeholderIndex = -1; 442 } 443 444 /** 445 * @see org.opencms.gwt.client.dnd.I_CmsDropTarget#repositionPlaceholder(int, int, Orientation) 446 */ 447 public void repositionPlaceholder(int x, int y, Orientation orientation) { 448 449 int oldIndex = m_placeholderIndex; 450 switch (orientation) { 451 case HORIZONTAL: 452 m_placeholderIndex = CmsDomUtil.positionElementInside( 453 m_placeholder, 454 getElement(), 455 m_placeholderIndex, 456 x, 457 -1); 458 break; 459 case VERTICAL: 460 m_placeholderIndex = CmsDomUtil.positionElementInside( 461 m_placeholder, 462 getElement(), 463 m_placeholderIndex, 464 -1, 465 y); 466 break; 467 case ALL: 468 default: 469 m_placeholderIndex = CmsDomUtil.positionElementInside( 470 m_placeholder, 471 getElement(), 472 m_placeholderIndex, 473 x, 474 y); 475 break; 476 } 477 if (oldIndex != m_placeholderIndex) { 478 m_ownPosition = CmsPositionBean.getBoundingClientRect(getElement()); 479 } 480 } 481 482 /** 483 * Sets the container id.<p> 484 * 485 * @param containerId the container id to set 486 */ 487 public void setContainerId(String containerId) { 488 489 m_containerId = containerId; 490 } 491 492 /** 493 * Sets the editing marker. Used to highlight the container background while editing.<p> 494 * 495 * @param editingMarker the editing marker element 496 */ 497 public void setEditingMarker(Element editingMarker) { 498 499 m_editingMarker = editingMarker; 500 } 501 502 /** 503 * Sets the editing placeholder.<p> 504 * 505 * @param editingPlaceholder the editing placeholder element 506 */ 507 public void setEditingPlaceholder(Element editingPlaceholder) { 508 509 m_editingPlaceholder = editingPlaceholder; 510 } 511 512 /** 513 * @see org.opencms.ade.containerpage.client.ui.I_CmsDropContainer#setPlaceholderVisibility(boolean) 514 */ 515 public void setPlaceholderVisibility(boolean visible) { 516 517 if (visible) { 518 m_placeholder.getStyle().clearDisplay(); 519 } else { 520 m_placeholder.getStyle().setDisplay(Display.NONE); 521 } 522 } 523 524 /** 525 * @see org.opencms.ade.containerpage.client.ui.CmsContainerPageElementPanel#showEditableListButtons() 526 */ 527 @Override 528 public void showEditableListButtons() { 529 530 Iterator<Widget> it = iterator(); 531 while (it.hasNext()) { 532 Widget child = it.next(); 533 if (child instanceof CmsContainerPageElementPanel) { 534 ((CmsContainerPageElementPanel)child).showEditableListButtons(); 535 } 536 } 537 } 538 539 /** 540 * @see org.opencms.ade.containerpage.client.ui.CmsContainerPageElementPanel#updateOptionBarPosition() 541 */ 542 @Override 543 public void updateOptionBarPosition() { 544 545 for (Widget widget : this) { 546 if (widget instanceof CmsContainerPageElementPanel) { 547 ((CmsContainerPageElementPanel)widget).updateOptionBarPosition(); 548 } 549 } 550 } 551 552 /** 553 * @see org.opencms.ade.containerpage.client.ui.I_CmsDropContainer#updatePositionInfo() 554 */ 555 public void updatePositionInfo() { 556 557 m_ownPosition = CmsPositionBean.getBoundingClientRect(getElement()); 558 } 559}