/* This file belongs to the Servoy development and deployment environment, Copyright (C) 1997-2010 Servoy BV This program is free software; you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, see http://www.gnu.org/licenses or write to the Free Software Foundation,Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 */ package com.servoy.j2db.persistence; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; import com.servoy.base.persistence.IBasePart; import com.servoy.base.persistence.constants.IPartConstants; import com.servoy.base.scripting.annotations.ServoyClientSupport; import com.servoy.j2db.documentation.ServoyDocumented; import com.servoy.j2db.util.PersistHelper; import com.servoy.j2db.util.UUID; /** * A part is a section from a Form, which can be used in reporting to aggregate data * * @author jblok */ @ServoyDocumented(category = ServoyDocumented.DESIGNTIME, typeCode = IRepository.PARTS) @ServoyClientSupport(mc = false, wc = true, sc = true) public class Part extends AbstractBase implements ISupportSize, IPersistCloneable, ICloneable, ISupportExtendsID, IBasePart { private static final long serialVersionUID = 1L; public static final int TITLE_HEADER = IPartConstants.TITLE_HEADER; public static final int HEADER = IPartConstants.HEADER; public static final int LEADING_GRAND_SUMMARY = IPartConstants.LEADING_GRAND_SUMMARY; public static final int LEADING_SUBSUMMARY = IPartConstants.LEADING_SUBSUMMARY; public static final int BODY = IPartConstants.BODY; public static final int TRAILING_SUBSUMMARY = IPartConstants.TRAILING_SUBSUMMARY; public static final int TRAILING_GRAND_SUMMARY = IPartConstants.TRAILING_GRAND_SUMMARY; public static final int FOOTER = IPartConstants.FOOTER; public static final int TITLE_FOOTER = IPartConstants.TITLE_FOOTER; public static final int PART_ARRAY_SIZE = IPartConstants.PART_ARRAY_SIZE; public static boolean rendersOnlyInPrint(int partType) { return partType == Part.TITLE_FOOTER || partType == Part.LEADING_SUBSUMMARY || partType == Part.TRAILING_SUBSUMMARY; } /** * Constructor I */ Part(ISupportChilds parent, int element_id, UUID uuid) { super(IRepository.PARTS, parent, element_id, uuid); } /* * _____________________________________________________________ Property Methods */ /** * Set the absolute height (from top of Form). * * @param arg the height */ public void setHeight(int arg) { setTypedProperty(StaticContentSpecLoader.PROPERTY_HEIGHT, arg); } /** * The height of a selected part; specified in pixels. * * This height property is the lowerbound as its ending Y value (0 == top of the form). */ public int getHeight() { return getTypedProperty(StaticContentSpecLoader.PROPERTY_HEIGHT).intValue(); } /** * Set the partType * * @param arg the partType */ public void setPartType(int arg) { setTypedProperty(StaticContentSpecLoader.PROPERTY_PARTTYPE, arg); } /** * The type of this part. */ public int getPartType() { return getTypedProperty(StaticContentSpecLoader.PROPERTY_PARTTYPE).intValue(); } /** * Set the background * * @param arg the background */ public void setBackground(java.awt.Color arg) { setTypedProperty(StaticContentSpecLoader.PROPERTY_BACKGROUND, arg); } /** * The background color of the form part. * * NOTE: When no background color has been set, the default background * color will be determined by the Look and Feel (LAF) that has been selected * in Application Preferences. */ public java.awt.Color getBackground() { return getTypedProperty(StaticContentSpecLoader.PROPERTY_BACKGROUND); } /** * Set the sequence * * @param arg the sequence */ public void setSequence(int arg) { setTypedProperty(StaticContentSpecLoader.PROPERTY_SEQUENCE, arg); } /** * Get the sequence * * @return the sequence */ public int getSequence() { return getTypedProperty(StaticContentSpecLoader.PROPERTY_SEQUENCE).intValue(); } //Size methods only for ISupportSize /** * Set the size * * @param arg the size */ public void setSize(java.awt.Dimension arg) { setHeight(arg.height); width = arg.width; } private int width; /** * Get the size * * @return the size */ public java.awt.Dimension getSize() { return new java.awt.Dimension(width, getHeight()); } /** * When set, the remainder of a selected part that does not fit on the page currently * being printed, will not be transported to the next page - it will break where the page * ends and continue on the next page. * * NOTE: Make sure to set this option when you are printing more than one page per record. */ public boolean getAllowBreakAcrossPageBounds() { return getTypedProperty(StaticContentSpecLoader.PROPERTY_ALLOWBREAKACROSSPAGEBOUNDS).booleanValue(); } /** * Set the allowBreakAcrossPageBounds * * @param b the allowBreakAcrossPageBounds */ public void setAllowBreakAcrossPageBounds(boolean b) { setTypedProperty(StaticContentSpecLoader.PROPERTY_ALLOWBREAKACROSSPAGEBOUNDS, b); } /** * When set, the remainder of a selected part that is broken due to the page * ending will not be printed on the next page - it will be discarded. */ public boolean getDiscardRemainderAfterBreak() { return getTypedProperty(StaticContentSpecLoader.PROPERTY_DISCARDREMAINDERAFTERBREAK).booleanValue(); } /** * Set the discardRemainderAfterBreak * * @param b the discardRemainderAfterBreak */ public void setDiscardRemainderAfterBreak(boolean b) { setTypedProperty(StaticContentSpecLoader.PROPERTY_DISCARDREMAINDERAFTERBREAK, b); } /** * For Leading Subsummary or Trailing Subsummary parts, one or more * dataproviders can be added as Break (GroupBy) dataproviders. The * Leading/Trailing Subsummary parts will be displayed once for each * resulted group of data. */ public String getGroupbyDataProviderIDs() { return getTypedProperty(StaticContentSpecLoader.PROPERTY_GROUPBYDATAPROVIDERIDS); } /** * Set the groupbyDataProviderIDs * * @param arg the groupbyDataProviderIDs */ public void setGroupbyDataProviderIDs(String arg) { setTypedProperty(StaticContentSpecLoader.PROPERTY_GROUPBYDATAPROVIDERIDS, arg); } /** * When set, a page break will be inserted before each occurrence of a selected part. */ public boolean getPageBreakBefore() { return getTypedProperty(StaticContentSpecLoader.PROPERTY_PAGEBREAKBEFORE).booleanValue(); } /** * Set the pageBreakBefore * * @param b the pageBreakBefore */ public void setPageBreakBefore(boolean b) { setTypedProperty(StaticContentSpecLoader.PROPERTY_PAGEBREAKBEFORE, b); } /** * A page break will be inserted after a specified number of occurences of a selected part. */ public int getPageBreakAfterOccurrence() { return getTypedProperty(StaticContentSpecLoader.PROPERTY_PAGEBREAKAFTEROCCURRENCE).intValue(); } /** * Set the pageBreakAfterOccurrence * * @param i the pageBreakAfterOccurrence */ public void setPageBreakAfterOccurrence(int i) { setTypedProperty(StaticContentSpecLoader.PROPERTY_PAGEBREAKAFTEROCCURRENCE, i); } /** * When set, page numbering will be restarted after each occurrence of a selected part. */ public boolean getRestartPageNumber() { return getTypedProperty(StaticContentSpecLoader.PROPERTY_RESTARTPAGENUMBER).booleanValue(); } /** * Set the restartPageNumber * * @param b the restartPageNumber */ public void setRestartPageNumber(boolean b) { setTypedProperty(StaticContentSpecLoader.PROPERTY_RESTARTPAGENUMBER, b); } /** * When set, the last part on a page (such as a Trailing Grand Summary part) will * "sink" to the lowest part of the page when there is free space. */ public boolean getSinkWhenLast() { return getTypedProperty(StaticContentSpecLoader.PROPERTY_SINKWHENLAST).booleanValue(); } /** * Set the sinkWhenLast * * @param b the sinkWhenLast */ public void setSinkWhenLast(boolean b) { setTypedProperty(StaticContentSpecLoader.PROPERTY_SINKWHENLAST, b); } /* * _____________________________________________________________ Methods from this class */ public static String getDisplayName(int type) { switch (type) { case TITLE_HEADER : return "Title Header"; //$NON-NLS-1$ case HEADER : return "Header"; //$NON-NLS-1$ case LEADING_GRAND_SUMMARY : return "Leading Grand Summary"; //$NON-NLS-1$ case LEADING_SUBSUMMARY : return "Leading Subsummary"; //$NON-NLS-1$ case BODY : return "Body"; //$NON-NLS-1$ case TRAILING_SUBSUMMARY : return "Trailing Subsummary"; //$NON-NLS-1$ case TRAILING_GRAND_SUMMARY : return "Trailing Grand Summary"; //$NON-NLS-1$ case FOOTER : return "Footer"; //$NON-NLS-1$ case TITLE_FOOTER : return "Title Footer"; //$NON-NLS-1$ default : return "<not Init>"; //$NON-NLS-1$ } } public static String getCSSSelector(int type) { switch (type) { case TITLE_HEADER : return "title_header"; //$NON-NLS-1$ case HEADER : return "header"; //$NON-NLS-1$ case BODY : return "body"; //$NON-NLS-1$ case FOOTER : return "footer"; //$NON-NLS-1$ case TITLE_FOOTER : return "title_footer"; //$NON-NLS-1$ default : return null; } } @Override public String toString() { return getDisplayName(getPartType()); } public String getEditorName() { String s = getDisplayName(getPartType()); boolean b = (getPartType() == Part.LEADING_SUBSUMMARY || getPartType() == Part.TRAILING_SUBSUMMARY); if (b) { s += " ON " + getGroupbyDataProviderIDs(); //$NON-NLS-1$ } return s; } public boolean canBeMoved() { return canBeMoved(getPartType()); } public static boolean canBeMoved(int partType) { return (partType == Part.LEADING_SUBSUMMARY || partType == Part.TRAILING_SUBSUMMARY); } public Part getPreviousPart() throws RepositoryException { Part prevPart = null; Iterator<Part> parts = getParent().getObjects(IRepository.PARTS); while (parts.hasNext()) { Part part = parts.next(); if (part.getHeight() < getHeight() && (prevPart == null || part.getHeight() > prevPart.getHeight())) { prevPart = part; } } return prevPart; } /** * Helper method to get all form elements inside of the part, note they all have the part Y offset in there location! * @return list of all elements in the part */ public List<IFormElement> getFormElementsSortedByYX() { List<IFormElement> retval = new ArrayList<IFormElement>(); Form f = (Form)getParent(); int top = f.getPartStartYPos(getID()); int bottom = f.getPartStartYPos(getID()); Iterator<IPersist> le = f.getAllObjects(PositionComparator.YX_PERSIST_COMPARATOR); while (le.hasNext()) { IPersist p = le.next(); if (p instanceof IFormElement && ((IFormElement)p).getLocation().y >= top && ((IFormElement)p).getLocation().y < bottom) { retval.add((IFormElement)p); } } return retval; } public int getExtendsID() { return getTypedProperty(StaticContentSpecLoader.PROPERTY_EXTENDSID).intValue(); } public void setExtendsID(int arg) { setTypedProperty(StaticContentSpecLoader.PROPERTY_EXTENDSID, arg); } @ServoyClientSupport(mc = true, wc = true, sc = true) public String getStyleClass() { return getTypedProperty(StaticContentSpecLoader.PROPERTY_STYLECLASS); } public void setStyleClass(String arg) { setTypedProperty(StaticContentSpecLoader.PROPERTY_STYLECLASS, arg); } @Override public Map<String, Object> getFlattenedPropertiesMap() { return PersistHelper.getFlattenedPropertiesMap(this); } }