diff --git a/main/reportbuilder/java/com/sun/star/report/pentaho/model/OfficeMasterPage.java b/main/reportbuilder/java/com/sun/star/report/pentaho/model/OfficeMasterPage.java index 8e486c5255..3035db6ee1 100644 --- a/main/reportbuilder/java/com/sun/star/report/pentaho/model/OfficeMasterPage.java +++ b/main/reportbuilder/java/com/sun/star/report/pentaho/model/OfficeMasterPage.java @@ -59,4 +59,14 @@ public void setPageLayout(final String name) { setAttribute(OfficeNamespaces.STYLE_NS, "page-layout-name", name); } + + public void setNextMasterPage(final String name) + { + setAttribute(OfficeNamespaces.STYLE_NS, "next-style-name", name); + } + + public String getNextMasterPage() + { + return (String) getAttribute(OfficeNamespaces.STYLE_NS, "next-style-name"); + } } diff --git a/main/reportbuilder/java/com/sun/star/report/pentaho/output/OfficeDocumentReportTarget.java b/main/reportbuilder/java/com/sun/star/report/pentaho/output/OfficeDocumentReportTarget.java index 9d417319b5..9034227fbb 100644 --- a/main/reportbuilder/java/com/sun/star/report/pentaho/output/OfficeDocumentReportTarget.java +++ b/main/reportbuilder/java/com/sun/star/report/pentaho/output/OfficeDocumentReportTarget.java @@ -741,10 +741,22 @@ protected GroupContext getGroupContext() return groupContext; } + protected void performStyleProcessingAll(final AttributeMap attrs) + throws ReportProcessingException + { + performStyleProcessingOne(attrs, globalStylesCollection); + performStyleProcessingOne(attrs, contentStylesCollection); + } + protected void performStyleProcessing(final AttributeMap attrs) throws ReportProcessingException { final OfficeStylesCollection stylesCollection = getStylesCollection(); + performStyleProcessingOne(attrs, stylesCollection); + } + protected void performStyleProcessingOne(final AttributeMap attrs, final OfficeStylesCollection stylesCollection) + throws ReportProcessingException + { final OfficeStylesCollection predefCollection = getPredefinedStylesCollection(); final OfficeStylesCollection globalStylesCollection = getGlobalStylesCollection(); diff --git a/main/reportbuilder/java/com/sun/star/report/pentaho/output/text/PageContext.java b/main/reportbuilder/java/com/sun/star/report/pentaho/output/text/PageContext.java index 255bf6cde7..043e105f04 100644 --- a/main/reportbuilder/java/com/sun/star/report/pentaho/output/text/PageContext.java +++ b/main/reportbuilder/java/com/sun/star/report/pentaho/output/text/PageContext.java @@ -88,6 +88,9 @@ public Integer getColumnCount() public String getHeader() { + if(header==null) { + return ""; + } return header; } @@ -99,6 +102,9 @@ public void setHeader(final String header, final CSSNumericValue height) public String getFooter() { + if(footer==null) { + return ""; + } return footer; } diff --git a/main/reportbuilder/java/com/sun/star/report/pentaho/output/text/TextRawReportTarget.java b/main/reportbuilder/java/com/sun/star/report/pentaho/output/text/TextRawReportTarget.java index c44724a20e..fdfe9f8123 100644 --- a/main/reportbuilder/java/com/sun/star/report/pentaho/output/text/TextRawReportTarget.java +++ b/main/reportbuilder/java/com/sun/star/report/pentaho/output/text/TextRawReportTarget.java @@ -90,6 +90,7 @@ public class TextRawReportTarget extends OfficeDocumentReportTarget private static final String NORMAL = "normal"; private static final String PARAGRAPH_PROPERTIES = "paragraph-properties"; private static final String STANDARD = "Standard"; + private static final String FOLLOWING_STANDARD = "FollowingStandard"; private static final String TABLE_PROPERTIES = "table-properties"; private static final String VARIABLES_HIDDEN_STYLE_WITH_KEEPWNEXT = "variables_paragraph_with_next"; private static final String VARIABLES_HIDDEN_STYLE_WITHOUT_KEEPWNEXT = "variables_paragraph_without_next"; @@ -115,7 +116,9 @@ public class TextRawReportTarget extends OfficeDocumentReportTarget private boolean pageHeaderOnReportHeader; private int contentProcessingState; private OfficeMasterPage currentMasterPage; + private OfficeMasterPage nextMasterPage; private final FastStack activePageContext; + private final FastStack nextPageContext; private MasterPageFactory masterPageFactory; private LengthCalculator sectionHeight; private String variables; @@ -141,6 +144,7 @@ public TextRawReportTarget(final ReportJob reportJob, { super(reportJob, resourceManager, baseResource, inputRepository, outputRepository, target, imageService, datasourcefactory); activePageContext = new FastStack(); + nextPageContext = new FastStack(); this.sectionNames = new AttributeNameGenerator(); this.tableLayoutConfig = TABLE_LAYOUT_SINGLE_DETAIL_TABLE; @@ -213,6 +217,10 @@ private PageContext getCurrentContext() { return (PageContext) activePageContext.peek(); } + private PageContext getNextContext() + { + return (PageContext) nextPageContext.peek(); + } private String createMasterPage(final boolean printHeader, final boolean printFooter) @@ -226,6 +234,7 @@ private String createMasterPage(final boolean printHeader, final String activePageFooter; // Check, whether the report header can have a page-header final PageContext context = getCurrentContext(); + final PageContext nextContext = getNextContext(); if (printFooter) { activePageFooter = context.getPageFooterContent(); @@ -235,14 +244,17 @@ private String createMasterPage(final boolean printHeader, activePageFooter = null; } final String activePageHeader; + final String nextPageHeader; if (printHeader) { // we have to insert a manual pagebreak after the report header. activePageHeader = context.getPageHeaderContent(); + nextPageHeader = nextContext.getPageHeaderContent(); } else { activePageHeader = null; + nextPageHeader = null; } final String masterPageName; @@ -251,9 +263,11 @@ private String createMasterPage(final boolean printHeader, final CSSNumericValue headerSize = context.getAllHeaderSize(); final CSSNumericValue footerSize = context.getAllFooterSize(); + final CSSNumericValue nextHeaderSize = nextContext.getAllHeaderSize(); currentMasterPage = masterPageFactory.createMasterPage(STANDARD, activePageHeader, activePageFooter); + nextMasterPage = masterPageFactory.createMasterPage(FOLLOWING_STANDARD, nextPageHeader, activePageFooter); // LOGGER.debug("Created a new master-page: " + currentMasterPage.getStyleName()); @@ -269,22 +283,66 @@ private String createMasterPage(final boolean printHeader, { // there is no pagelayout. Create one .. final String derivedLayout = masterPageFactory.createPageStyle(getGlobalStylesCollection().getAutomaticStyles(), headerSize, footerSize); + final String derivedLayoutNext = masterPageFactory.createPageStyle(getGlobalStylesCollection().getAutomaticStyles(), nextHeaderSize, footerSize); currentMasterPage.setPageLayout(derivedLayout); + nextMasterPage.setPageLayout(derivedLayoutNext); } else { final String derivedLayout = masterPageFactory.derivePageStyle(pageLayoutTemplate, getPredefinedStylesCollection().getAutomaticStyles(), getGlobalStylesCollection().getAutomaticStyles(), headerSize, footerSize); + final String derivedLayoutNext = masterPageFactory.derivePageStyle(pageLayoutTemplate, + getPredefinedStylesCollection().getAutomaticStyles(), + getGlobalStylesCollection().getAutomaticStyles(), nextHeaderSize, footerSize); currentMasterPage.setPageLayout(derivedLayout); + nextMasterPage.setPageLayout(derivedLayoutNext); } + officeMasterStyles.addMasterPage(nextMasterPage); + currentMasterPage.setNextMasterPage(nextMasterPage.getStyleName()); officeMasterStyles.addMasterPage(currentMasterPage); masterPageName = currentMasterPage.getStyleName(); } + else if(!masterPageFactory.containsMasterPage(FOLLOWING_STANDARD, nextPageHeader, activePageFooter)) + { + final CSSNumericValue nextHeaderSize = nextContext.getAllHeaderSize(); + final CSSNumericValue footerSize = context.getAllFooterSize(); + final OfficeMasterPage masterPage = masterPageFactory.getMasterPage(STANDARD, activePageHeader, activePageFooter); + nextMasterPage = masterPageFactory.createMasterPage(FOLLOWING_STANDARD, nextPageHeader, activePageFooter); + + final OfficeStylesCollection officeStylesCollection = getGlobalStylesCollection(); + final OfficeMasterStyles officeMasterStyles = officeStylesCollection.getMasterStyles(); + final String pageLayoutTemplate = currentMasterPage.getPageLayout(); + if (ObjectUtilities.equal(masterPage.getStyleName(), currentMasterPage.getStyleName())) + { + masterPageName = null; + } + else + { + currentMasterPage = masterPage; + masterPageName = currentMasterPage.getStyleName(); + } + if (pageLayoutTemplate == null) + { + final String derivedLayoutNext = masterPageFactory.createPageStyle(getGlobalStylesCollection().getAutomaticStyles(), nextHeaderSize, footerSize); + nextMasterPage.setPageLayout(derivedLayoutNext); + } + else + { + final String derivedLayoutNext = masterPageFactory.derivePageStyle(pageLayoutTemplate, + getPredefinedStylesCollection().getAutomaticStyles(), + getGlobalStylesCollection().getAutomaticStyles(), nextHeaderSize, footerSize); + nextMasterPage.setPageLayout(derivedLayoutNext); + } + officeMasterStyles.addMasterPage(nextMasterPage); + currentMasterPage.setNextMasterPage(nextMasterPage.getStyleName()); + + } else { // retrieve the master-page. final OfficeMasterPage masterPage = masterPageFactory.getMasterPage(STANDARD, activePageHeader, activePageFooter); + final OfficeMasterPage nextMasterPage = masterPageFactory.getMasterPage(FOLLOWING_STANDARD, nextPageHeader, activePageFooter); if (ObjectUtilities.equal(masterPage.getStyleName(), currentMasterPage.getStyleName())) { // They are the same, @@ -447,6 +505,8 @@ public void startReport(final ReportStructureRoot report) activePageContext.clear(); activePageContext.push(new PageContext()); + nextPageContext.clear(); + nextPageContext.push(new PageContext()); final OfficeStylesCollection predefStyles = getPredefinedStylesCollection(); masterPageFactory = new MasterPageFactory(predefStyles.getMasterStyles()); @@ -528,7 +588,9 @@ protected void startContent(final AttributeMap attrs) if (colCount != null) { final PageContext pageContext = getCurrentContext(); + final PageContext nPageContext = getNextContext(); pageContext.setColumnCount(colCount); + nPageContext.setColumnCount(colCount); } } @@ -701,9 +763,14 @@ TextRawReportTarget.VARIABLES_HIDDEN_STYLE_WITH_KEEPWNEXT, getStylesCollection() // attrs.setAttribute(OfficeNamespaces.DRAWING_NS, OfficeToken.STYLE_NAME, predefAutoStyle.getStyleName()); } } - // process the styles as usual - performStyleProcessing(attrs); + final int currentRole = getCurrentRole(); + if(currentRole == OfficeDocumentReportTarget.ROLE_REPEATING_GROUP_HEADER) { + performStyleProcessingAll(attrs); + } + else { + performStyleProcessing(attrs); + } final XmlWriter xmlWriter = getXmlWriter(); final AttributeList attrList = buildAttributeList(attrs); xmlWriter.writeTag(namespace, elementType, attrList, XmlWriterSupport.OPEN); @@ -798,7 +865,7 @@ else if (currentRole == OfficeDocumentReportTarget.ROLE_REPORT_FOOTER) // But we skip this (and therefore the resulting pagebreak) if there is no manual break // and no other condition that would force an break. } - else if (currentRole == OfficeDocumentReportTarget.ROLE_REPEATING_GROUP_HEADER || currentRole == OfficeDocumentReportTarget.ROLE_REPEATING_GROUP_FOOTER) + else if (currentRole == OfficeDocumentReportTarget.ROLE_REPEATING_GROUP_FOOTER) { breakDefinition = null; // no pagebreaks .. @@ -806,6 +873,7 @@ else if (currentRole == OfficeDocumentReportTarget.ROLE_REPEATING_GROUP_HEADER | else if (currentMasterPage == null || isPagebreakPending()) { // Must be the first table, as we have no master-page yet. + boolean isbreaking = isPagebreakPending(); masterPageName = createMasterPage(true, true); setPagebreakDefinition(null); if (masterPageName == null) @@ -813,14 +881,23 @@ else if (currentMasterPage == null || isPagebreakPending()) // we should always have a master-page ... masterPageName = currentMasterPage.getStyleName(); } - breakDefinition = new PageBreakDefinition(isResetPageNumber()); + if(isbreaking) { + breakDefinition = new PageBreakDefinition(isResetPageNumber()); + } + else { + breakDefinition = null; + } } else { + if(currentRole == OfficeDocumentReportTarget.ROLE_DETAIL) //Only to update next page header that changed at end of repeating group header + { + createMasterPage(true, true); + } breakDefinition = null; } } - else if (isPagebreakPending() && currentRole != OfficeDocumentReportTarget.ROLE_REPEATING_GROUP_HEADER && currentRole != OfficeDocumentReportTarget.ROLE_REPEATING_GROUP_FOOTER) + else if (isPagebreakPending() && currentRole != OfficeDocumentReportTarget.ROLE_REPEATING_GROUP_FOOTER) { // Derive an automatic style for the pagebreak. // LOGGER.debug("Manual pagebreak (within the section): " + getCurrentRole()); @@ -858,7 +935,7 @@ else if (isPagebreakPending() && currentRole != OfficeDocumentReportTarget.ROLE_ final OfficeStyle style = deriveStyle(OfficeToken.PARAGRAPH, TextRawReportTarget.VARIABLES_HIDDEN_STYLE_WITH_KEEPWNEXT); style.setAttribute(OfficeNamespaces.STYLE_NS, "master-page-name", masterPageName); - if (breakDefinition.isResetPageNumber()) + if (breakDefinition != null && breakDefinition.isResetPageNumber()) { final Element paragraphProps = produceFirstChild(style, OfficeNamespaces.STYLE_NS, PARAGRAPH_PROPERTIES); paragraphProps.setAttribute(OfficeNamespaces.STYLE_NS, "page-number", "1"); @@ -918,7 +995,7 @@ TextRawReportTarget.VARIABLES_HIDDEN_STYLE_WITH_KEEPWNEXT, getStylesCollection() // Patch the current styles. // This usually only happens on Table-Styles or Paragraph-Styles style.setAttribute(OfficeNamespaces.STYLE_NS, "master-page-name", masterPageName); - if (breakDefinition.isResetPageNumber()) + if (breakDefinition != null && breakDefinition.isResetPageNumber()) { final Element paragraphProps = produceFirstChild(style, OfficeNamespaces.STYLE_NS, PARAGRAPH_PROPERTIES); paragraphProps.setAttribute(OfficeNamespaces.STYLE_NS, "page-number", "1"); @@ -1009,7 +1086,12 @@ else if (detailBandProcessingState == DETAIL_SECTION_FIRST_PRINTED) } // process the styles as usual - performStyleProcessing(attrs); + if(currentRole == OfficeDocumentReportTarget.ROLE_REPEATING_GROUP_HEADER) { + performStyleProcessingAll(attrs); + } + else { + performStyleProcessing(attrs); + } } final String namespace = ReportTargetUtil.getNamespaceFromAttribute(attrs); @@ -1121,6 +1203,11 @@ protected void startGroup(final AttributeMap attrs) super.startGroup(attrs); final PageContext pageContext = new PageContext(getCurrentContext()); activePageContext.push(pageContext); + if(getGroupContext().isGroupWithRepeatingSection()) + { + final PageContext nPageContext = new PageContext(getNextContext()); + nextPageContext.push(nPageContext); + } final Object resetPageNumber = attrs.getAttribute(OfficeNamespaces.OOREPORT_NS, "reset-page-number"); if (OfficeToken.TRUE.equals(resetPageNumber)) @@ -1155,10 +1242,6 @@ else if ("with-first-detail".equals(keepTogether) && pageContext.getKeepTogether protected void startGroupInstance(final AttributeMap attrs) throws IOException, DataSourceException, ReportProcessingException { - if (getGroupContext().isGroupWithRepeatingSection()) - { - setPagebreakDefinition(new PageBreakDefinition(isResetPageNumber())); - } } protected void endGroup(final AttributeMap attrs) @@ -1166,7 +1249,7 @@ protected void endGroup(final AttributeMap attrs) { if (getGroupContext().isGroupWithRepeatingSection()) { - setPagebreakDefinition(new PageBreakDefinition(isResetPageNumber())); + nextPageContext.pop(); } super.endGroup(attrs); @@ -1179,6 +1262,7 @@ private void finishSection() throws ReportProcessingException { final PageContext pageContext = getCurrentContext(); + final PageContext nPageContext = getNextContext(); if (pageContext.isSectionOpen()) { pageContext.setSectionOpen(false); @@ -1191,6 +1275,18 @@ private void finishSection() throw new ReportProcessingException("IOError", e); } } + if (nPageContext.isSectionOpen()) + { + nPageContext.setSectionOpen(false); + try + { + getXmlWriter().writeCloseTag(); + } + catch (IOException e) + { + throw new ReportProcessingException("IOError", e); + } + } } protected void endReportSection(final AttributeMap attrs, final int role) @@ -1206,22 +1302,34 @@ protected void endReportSection(final AttributeMap attrs, final int role) if (role == OfficeDocumentReportTarget.ROLE_PAGE_HEADER) { final PageContext pageContext = getCurrentContext(); - pageContext.setHeader(applyColumnsToPageBand(finishBuffering(), pageContext.getActiveColumns()).getXmlBuffer(), result); + final PageContext nextContext = getNextContext(); + final BufferState bstate = finishBuffering(); + nextContext.setHeader(applyColumnsToPageBand(bstate, nextContext.getActiveColumns()).getXmlBuffer(), result); + pageContext.setHeader(applyColumnsToPageBand(bstate, pageContext.getActiveColumns()).getXmlBuffer(), result); } else if (role == OfficeDocumentReportTarget.ROLE_PAGE_FOOTER) { final PageContext pageContext = getCurrentContext(); - pageContext.setFooter(applyColumnsToPageBand(finishBuffering(), pageContext.getActiveColumns()).getXmlBuffer(), result); + final PageContext nextContext = getNextContext(); + final BufferState bstate = finishBuffering(); + nextContext.setFooter(applyColumnsToPageBand(bstate, nextContext.getActiveColumns()).getXmlBuffer(), result); + pageContext.setFooter(applyColumnsToPageBand(bstate, pageContext.getActiveColumns()).getXmlBuffer(), result); } else if (role == OfficeDocumentReportTarget.ROLE_REPEATING_GROUP_HEADER) { - final PageContext pageContext = getCurrentContext(); - pageContext.setHeader(applyColumnsToPageBand(finishBuffering(), pageContext.getActiveColumns()).getXmlBuffer(), result); + final PageContext nextContext = getNextContext(); + final BufferState bstate = finishBuffering(); + nextContext.setHeader(applyColumnsToPageBand(bstate, nextContext.getActiveColumns()).getXmlBuffer(), result); + final String headerText = bstate.getXmlBuffer(); + getXmlWriter().writeText(headerText); } else if (role == OfficeDocumentReportTarget.ROLE_REPEATING_GROUP_FOOTER) { final PageContext pageContext = getCurrentContext(); - pageContext.setFooter(applyColumnsToPageBand(finishBuffering(), pageContext.getActiveColumns()).getXmlBuffer(), result); + final PageContext nextContext = getNextContext(); + final BufferState bstate = finishBuffering(); + nextContext.setFooter(applyColumnsToPageBand(bstate, nextContext.getActiveColumns()).getXmlBuffer(), result); + pageContext.setFooter(applyColumnsToPageBand(bstate, pageContext.getActiveColumns()).getXmlBuffer(), result); } else if (role == OfficeDocumentReportTarget.ROLE_VARIABLES) {