Esempio n. 1
0
  private static SdtBlock createSdt(String tagVal, RPr rPr) {

    // .. so create content control!
    SdtBlock sdtBlock = Context.getWmlObjectFactory().createSdtBlock();

    SdtPr sdtPr = Context.getWmlObjectFactory().createSdtPr();
    sdtBlock.setSdtPr(sdtPr);

    SdtContentBlock sdtContent = Context.getWmlObjectFactory().createSdtContentBlock();
    sdtBlock.setSdtContent(sdtContent);

    // For borders/shading, we'll use the values in this first paragraph.
    // We'll use a tag, so the XSLT can detect that its supposed to do something special.
    Tag tag = Context.getWmlObjectFactory().createTag();
    tag.setVal(tagVal);

    sdtPr.setTag(tag);
    if (rPr != null) {
      sdtPr.getRPrOrAliasOrLock().add((RPr) XmlUtils.deepCopy(rPr));
      /*
       * ECMA-376 says "specifies the set of run properties which shall be applied to
       *  the text entered into the parent structured document tag in replacement of
       *  placeholder text. When placeholder text is present in a structured document
       *  tag, its formatting is often different than the desired underlying formatting,
       *  and this element specifies the formatting which shall be used for non-placeholder
       *  text contents when they are initially added to the control. "
       *
       * Note that docx2fo.xslt is co-opting this to do something else.
       */
    }
    return sdtBlock;
  }
Esempio n. 2
0
  private static void appendRun(SdtBlock currentBlock, List<Object> resultElts) {

    List<Object> blkElements = null;
    R run = null;
    RPr blockRPr = null;
    if (currentBlock != null) {
      blkElements = currentBlock.getSdtContent().getContent();
      if (blkElements.size() == 1) {
        // If there is only one element, there is no need to use a sdtBlock
        resultElts.add(blkElements.get(0));
      } else {
        resultElts.add(currentBlock);
        // Remove the borders of the child elements
        // (and the shading if it is the same as that of the container)
        blockRPr = findBlockRPr(currentBlock);
        for (Object elem : blkElements) {
          if (elem instanceof R) {
            run = (R) elem;
            if (run.getRPr() != null) {
              run.getRPr().setBdr(null);
              if (!shadingChanged(blockRPr.getShd(), run.getRPr().getShd())) {
                run.getRPr().setShd(null);
              }
            }
          }
        }
      }
    }
  }
Esempio n. 3
0
 private static RPr findBlockRPr(SdtBlock currentBlock) {
   for (Object obj : currentBlock.getSdtPr().getRPrOrAliasOrLock()) {
     if (obj instanceof RPr) {
       return (RPr) obj;
     }
   }
   return null;
 }
Esempio n. 4
0
  private static List<Object> groupRuns(List<Object> paragraphElts) {

    List<Object> resultElts = new ArrayList<Object>();
    SdtBlock currentBlock = null;
    CTBorder lastBorder = null;
    CTBorder currentBorder = null;
    R run = null;

    //			java.util.Stack stack = new java.util.Stack();
    //			stack.push(newList);

    for (Object o : paragraphElts) {
      if (o instanceof R) {
        run = (R) o;
        currentBorder = null;
        if (run.getRPr() != null) {
          currentBorder = run.getRPr().getBdr();
        }

        if (borderChanged(currentBorder, lastBorder)) {
          appendRun(currentBlock, resultElts);
          currentBlock = null;
          // could mean null to borders; borders to null; or bordersA to bordersB
          if (currentBorder != null) {
            currentBlock = createSdt(TAG_RPR, run.getRPr());
          }
        }
      }
      if (currentBlock != null) {
        currentBlock.getSdtContent().getContent().add(o);
      } else {
        resultElts.add(o);
      }

      // setup for next loop
      lastBorder = currentBorder;
    }
    appendRun(currentBlock, resultElts);
    return resultElts;
  }
Esempio n. 5
0
  private static List<Object> groupBodyContent(List<Object> bodyElts) {

    List<Object> resultElts = new ArrayList<Object>();
    List<Object> paragraphElts = null;
    SdtBlock sdtBorders = null;
    SdtBlock sdtShading = null;
    PBdr lastBorders = null;
    PBdr currentBorders = null;
    CTShd lastShading = null;
    CTShd currentShading = null;
    P paragraph = null;

    for (Object o : bodyElts) {
      if (o instanceof JAXBElement) {
        o = ((JAXBElement) o).getValue();
      }
      if (o instanceof P) {
        paragraph = (P) o;
        paragraphElts = groupRuns(paragraph.getContent());
        paragraph.getContent().clear();
        if (paragraphElts != null) {
          paragraph.getContent().addAll(paragraphElts);
        }

        currentBorders = null;
        currentShading = null;
        if (paragraph.getPPr() != null) {
          // TODO: use effective ppr properties!
          // ie take styles into account
          currentBorders = paragraph.getPPr().getPBdr();
          currentShading = paragraph.getPPr().getShd();
        }

        if (bordersChanged(currentBorders, lastBorders)) {
          // could mean null to borders; borders to null; or bordersA to bordersB
          if (currentBorders == null) {
            sdtBorders = null;
          } else {
            sdtBorders = createSdt(TAG_BORDERS);
            resultElts.add(sdtBorders);
          }
        }

        if (shadingChanged(currentShading, lastShading)) {
          // handle change to shading before addElement
          if (currentShading == null) {
            sdtShading = null;
          } else {
            sdtShading = createSdt(TAG_SHADING);

            // need to set margins, so there isn't a white strip
            // between paragraphs.  hmm, model.properties.paragraph
            // won't translate this.  so do it at the fo level
            if (sdtBorders != null) {
              sdtBorders.getSdtContent().getContent().add(sdtShading);
            } else {
              resultElts.add(sdtShading);
            }
          }
        }
      } else if (o instanceof Tbl) {
        groupTable((Tbl) o);
      }
      if (sdtShading != null) {
        sdtShading.getSdtContent().getContent().add(o);
      } else if (sdtBorders != null) {
        sdtBorders.getSdtContent().getContent().add(o);
      } else {
        resultElts.add(o);
      }

      // setup for next loop
      lastBorders = currentBorders;
      lastShading = currentShading;
    }
    return resultElts;
  }
  protected static List<ConversionSectionWrapper> processComplete(
      WordprocessingMLPackage wmlPackage,
      Document document,
      RelationshipsPart rels,
      BooleanDefaultTrue evenAndOddHeaders,
      boolean dummyPageNumbering) {
    List<ConversionSectionWrapper> conversionSections = new ArrayList<ConversionSectionWrapper>();
    List<Object> sectionContent = new ArrayList<Object>();
    ConversionSectionWrapper currentSectionWrapper = null;
    HeaderFooterPolicy previousHF = null;
    int conversionSectionIndex = 0;

    // According to the ECMA-376 2ed, if type is not specified, read it as next page
    // However Word 2007 sometimes treats it as continuous, and sometimes doesn't??
    // 20130216 Review above comment: !  In the Word UI, the Word "continuous" is shown where it is
    // effective.
    // In the XML, it is stored in the next following sectPr.

    // First, remove content controls,
    // since the P could be in a content control.
    // (It is easier to remove content controls, than
    //  to make the code below TraversalUtil based)
    // RemovalHandler is an XSLT-based way of doing this,
    // but here we avoid introducing a dependency on
    // XSLT (Xalan) for PDF output.
    SdtBlockFinder sbr = new SdtBlockFinder();
    new TraversalUtil(document.getContent(), sbr);
    for (int i = sbr.sdtBlocks.size() - 1; i >= 0; i--) {
      // Have to process in reverse order
      // so that parentList is correct for nested sdt

      SdtBlock sdtBlock = sbr.sdtBlocks.get(i);
      List<Object> parentList = null;
      if (sdtBlock.getParent() instanceof ArrayList) {
        parentList = (ArrayList) sdtBlock.getParent();
      } else {
        log.error("Handle " + sdtBlock.getParent().getClass().getName());
      }
      int index = parentList.indexOf(sdtBlock);
      parentList.remove(index);
      parentList.addAll(index, sdtBlock.getSdtContent().getContent());
    }

    //		if (log.isDebugEnabled()) {
    //			log.debug(XmlUtils.marshaltoString(document, true, true));
    //		}

    // Make a list, so it is easy to look at the following sectPr,
    // which we need to do to handle continuous sections properly
    List<SectPr> sectPrs = new ArrayList<SectPr>();
    for (Object o : document.getBody().getContent()) {

      if (o instanceof org.docx4j.wml.P) {
        if (((org.docx4j.wml.P) o).getPPr() != null) {
          org.docx4j.wml.PPr ppr = ((org.docx4j.wml.P) o).getPPr();
          if (ppr.getSectPr() != null) {
            sectPrs.add(ppr.getSectPr());
          }
        }
      }
    }

    if (document.getBody().getSectPr() != null) {
      // usual case
      sectPrs.add(document.getBody().getSectPr());

    } else {
      log.debug("No body level sectPr in document");

      // OK if the last object is w:p and it contains a sectPr.
      List<Object> all = document.getBody().getContent();
      Object last = all.get(all.size() - 1);
      if (last instanceof P
          && ((P) last).getPPr() != null
          && ((P) last).getPPr().getSectPr() != null) {
        // ok
        log.debug(
            ".. but last p contains sectPr .. move it"); // so our assumption later about there
                                                         // being a following section is correct

        SectPr thisSectPr = ((P) last).getPPr().getSectPr();
        document.getBody().setSectPr(thisSectPr);
        ((P) last).getPPr().setSectPr(null);
        sectPrs.remove(thisSectPr);

      } else {
        document.getBody().setSectPr(Context.getWmlObjectFactory().createSectPr());
        sectPrs.add(document.getBody().getSectPr());
      }
    }

    int sectPrIndex = 0; // includes continuous ones
    for (Object o : document.getBody().getContent()) {

      if (o instanceof org.docx4j.wml.P) {

        if (((org.docx4j.wml.P) o).getPPr() != null) {

          org.docx4j.wml.PPr ppr = ((org.docx4j.wml.P) o).getPPr();
          if (ppr.getSectPr() != null) {

            // If the *following* section is continuous, don't add *this* section
            boolean ignoreThisSection = false;
            SectPr followingSectPr = sectPrs.get(++sectPrIndex);
            if (followingSectPr.getType() != null
                && followingSectPr.getType().getVal().equals("continuous")) {

              ignoreThisSection = true;

              // If the w:pgSz on the two sections differs,
              // then Word inserts a page break (ie doesn't treat it as continuous).
              // If no w:pgSz element is present, then Word defaults
              // (presumably to Legal? TODO CHECK. There is no default setting in the docx).
              // Word always inserts a w:pgSz element?

              PgSz pgSzThis = ppr.getSectPr().getPgSz();
              PgSz pgSzNext = followingSectPr.getPgSz();

              if (pgSzThis != null && pgSzNext != null) {

                if (pgSzThis.getH().compareTo(pgSzNext.getH()) != 0) {
                  ignoreThisSection = false;
                }
                if (pgSzThis.getW().compareTo(pgSzNext.getW()) != 0) {
                  ignoreThisSection = false;
                }

                // Orientation:default is portrait
                boolean portraitThis = true;
                if (pgSzThis.getOrient() != null) {
                  portraitThis = pgSzThis.getOrient().equals(STPageOrientation.PORTRAIT);
                }
                boolean portraitNext = true;
                if (pgSzNext.getOrient() != null) {
                  portraitNext = pgSzNext.getOrient().equals(STPageOrientation.PORTRAIT);
                }
                if (portraitThis != portraitNext) {
                  ignoreThisSection = false;
                }
              }
              // TODO: handle cases where one or both pgSz elements are missing,
              // or H or W is missing.
              // Treat pgSz element missing as Legal size?
            }

            if (ignoreThisSection) {
              // In case there are some headers/footers that get inherited by the next section
              previousHF =
                  new HeaderFooterPolicy(ppr.getSectPr(), previousHF, rels, evenAndOddHeaders);

            } else {
              currentSectionWrapper =
                  createSectionWrapper(
                      ppr.getSectPr(),
                      previousHF,
                      rels,
                      evenAndOddHeaders,
                      ++conversionSectionIndex,
                      sectionContent,
                      dummyPageNumbering);
              conversionSections.add(currentSectionWrapper);
              previousHF = currentSectionWrapper.getHeaderFooterPolicy();
              sectionContent = new ArrayList<Object>();
            }
          }
        }
      }
      sectionContent.add(o);
      //			System.out.println(XmlUtils.marshaltoString(o, true));
    }

    currentSectionWrapper =
        createSectionWrapper(
            document.getBody().getSectPr(),
            previousHF,
            rels,
            evenAndOddHeaders,
            ++conversionSectionIndex,
            sectionContent,
            dummyPageNumbering);
    conversionSections.add(currentSectionWrapper);
    return conversionSections;
  }