All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.hcl.domino.richtext.records.CDFrame Maven / Gradle / Ivy

There is a newer version: 1.41.0
Show newest version
/*
 * ==========================================================================
 * Copyright (C) 2019-2022 HCL America, Inc. ( http://www.hcl.com/ )
 *                            All rights reserved.
 * ==========================================================================
 * Licensed under the  Apache License, Version 2.0  (the "License").  You may
 * not use this file except in compliance with the License.  You may obtain a
 * copy of the License at .
 *
 * Unless  required  by applicable  law or  agreed  to  in writing,  software
 * distributed under the License is distributed on an  "AS IS" BASIS, WITHOUT
 * WARRANTIES OR  CONDITIONS OF ANY KIND, either express or implied.  See the
 * License for the  specific language  governing permissions  and limitations
 * under the License.
 * ==========================================================================
 */
package com.hcl.domino.richtext.records;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Collection;
import java.util.Optional;
import java.util.Set;

import com.hcl.domino.data.NativeItemCoder;
import com.hcl.domino.design.DesignColorsAndFonts;
import com.hcl.domino.design.DesignConstants;
import com.hcl.domino.design.frameset.FrameScrollStyle;
import com.hcl.domino.formula.FormulaCompiler;
import com.hcl.domino.misc.INumberEnum;
import com.hcl.domino.misc.StructureSupport;
import com.hcl.domino.richtext.annotation.StructureDefinition;
import com.hcl.domino.richtext.annotation.StructureGetter;
import com.hcl.domino.richtext.annotation.StructureMember;
import com.hcl.domino.richtext.annotation.StructureSetter;
import com.hcl.domino.richtext.structures.CDFrameVariableData;
import com.hcl.domino.richtext.structures.ColorValue;
import com.hcl.domino.richtext.structures.FontStyle;
import com.hcl.domino.richtext.structures.MemoryStructureWrapperService;
import com.hcl.domino.richtext.structures.WSIG;

/**
 * @author Jesse Gallagher
 * @since 1.0.34
 */
@StructureDefinition(
  name = "CDFRAME",
  members = {
    @StructureMember(name = "Header", type = WSIG.class),
    @StructureMember(name = "Flags", type = CDFrame.Flag.class, bitfield = true),
    @StructureMember(name = "DataFlags", type = CDFrame.DataFlag.class, bitfield = true),
    @StructureMember(name = "BorderEnable", type = byte.class),
    @StructureMember(name = "NoResize", type = byte.class),
    @StructureMember(name = "ScrollBarStyle", type = FrameScrollStyle.class),
    @StructureMember(name = "MarginWidth", type = short.class, unsigned = true),
    @StructureMember(name = "MarginHeight", type = short.class, unsigned = true),
    @StructureMember(name = "dwReserved", type = int.class),
    @StructureMember(name = "FrameNameLength", type = short.class, unsigned = true),
    @StructureMember(name = "Reserved1", type = short.class),
    @StructureMember(name = "FrameTargetLength", type = short.class, unsigned = true),
    @StructureMember(name = "FrameBorderColor", type = ColorValue.class),
    @StructureMember(name = "wReserved", type = short.class, unsigned = true),
  }
)
public interface CDFrame extends RichTextRecord {
  enum Flag implements INumberEnum {
    /**  Set if BorderEnable is specified  */
    BorderEnable(DesignConstants.fFRBorderEnable),
    /**  Set if MarginWidth is specified  */
    MarginWidth(DesignConstants.fFRMarginWidth),
    /**  Set if MarginHeight is specified  */
    MarginHeight(DesignConstants.fFRMarginHeight),
    /**  Set if FrameBorderColor is specified  */
    FrameBorderColor(DesignConstants.fFRFrameBorderColor),
    /**  Set if ScrollBarStyle is specified  */
    Scrolling(DesignConstants.fFRScrolling),
    /**  Set if this frame has a notes only border (a border with caption text =>"Caption Only") */
    NotesOnlyBorder(DesignConstants.fFRNotesOnlyBorder),
    /**  Set if this frame wants arrows shown in Notes (a border with arrows =>"Arrows Only") */
    NotesOnlyArrows(DesignConstants.fFRNotesOnlyArrows),
    /**  Open value specified for Border caption is in percent. */
    NotesOpenPercent(DesignConstants.fFRNotesOpenPercent),
    /**  if set, set initial focus to this frame  */
    NotesInitialFocus(DesignConstants.fFRNotesInitialFocus),
    /**  Set if this frame caption reading order is Right-To-Left */
    NotesReadingOrder(DesignConstants.fFRNotesReadingOrder);
    private final int value;
    private Flag(int value) {
      this.value = value;
    }

    @Override
    public long getLongValue() {
      return value;
    }

    @Override
    public Integer getValue() {
      return value;
    }
  }
  enum DataFlag implements INumberEnum {
    NotesBorder(DesignConstants.fFRNotesBorder),
    NotesBorderFontAndColor(DesignConstants.fFRNotesBorderFontAndColor),
    NotesBorderCaption(DesignConstants.fFRNotesBorderCaption),
    NotesCaptionFontName(DesignConstants.fFRNotesCaptionFontName),
    /**  set this if frame has a sequence set other than the default 0  */
    Sequence(DesignConstants.fFRSequence);
    private final short value;
    private DataFlag(short value) {
      this.value = value;
    }

    @Override
    public long getLongValue() {
      return value;
    }

    @Override
    public Short getValue() {
      return value;
    }
  }
  enum BorderAlignment implements INumberEnum {
    Top((short) 0),
    Bottom((short) 1),
    Left((short) 2),
    Right((short) 3);
    private final short value;
    private BorderAlignment(short value) {
      this.value = value;
    }
    
    @Override
    public long getLongValue() {
      return value;
    }

    @Override
    public Short getValue() {
      return value;
    }
  }
  enum TextAlignment implements INumberEnum {
    Left((short)0),
    Right((short)1),
    Center((short)2);
    private final short value;
    private TextAlignment(short value) {
      this.value = value;
    }
    
    @Override
    public long getLongValue() {
      return value;
    }

    @Override
    public Short getValue() {
      return value;
    }
  }
  
  @StructureGetter("Header")
  @Override
  WSIG getHeader();
  
  @StructureGetter("Flags")
  Set getFlags();
  
  @StructureSetter("Flags")
  CDFrame setFlags(Collection flags);
  
  @StructureGetter("DataFlags")
  Set getDataFlags();
  
  @StructureSetter("DataFlags")
  CDFrame setDataFlags(Collection flags);
  
  @StructureGetter("BorderEnable")
  byte getBorderEnable();
  
  @StructureSetter("BorderEnable")
  CDFrame setBorderEnable(byte borderEnable);
  
  /**
   * Specifies the NORESIZE attribute for this Frame element
   * 
   * @return noresize flag (0 = false, 1=true)
   */
  @StructureGetter("NoResize")
  byte getNoResize();
  
  /**
   * Specifies the NORESIZE attribute for this Frame element
   * 
   * @param noResize noresize flag (0 = false, 1=true)
   * @return this frame
   */
  @StructureSetter("NoResize")
  CDFrame setNoResize(byte noResize);
  
  @StructureGetter("ScrollBarStyle")
  Optional getScrollBarStyle();
  
  /**
   * Retrieves the scroll-bar style as a raw {@code short}.
   * 
   * @return the scroll-bar style as a {@code short}
   * @since 1.24.0
   */
  @StructureGetter("ScrollBarStyle")
  short getScrollBarStyleRaw();
  
  @StructureSetter("ScrollBarStyle")
  CDFrame setScrollBarStyle(FrameScrollStyle style);
  
  /**
   * Sets the scroll-bar style as a raw {@code short}.
   * 
   * @param style the value to set
   * @return this structure
   * @since 1.24.0
   */
  @StructureSetter("ScrollBarStyle")
  CDFrame setScrollBarStyleRaw(short style);
  
  @StructureGetter("MarginWidth")
  int getMarginWidth();
  
  @StructureSetter("MarginWidth")
  CDFrame setMarginWidth(int width);
  
  @StructureGetter("MarginHeight")
  int getMarginHeight();
  
  @StructureSetter("MarginHeight")
  CDFrame setMarginHeight(int height);

  @StructureGetter("FrameNameLength")
  int getFrameNameLength();
  
  @StructureSetter("FrameNameLength")
  CDFrame setFrameNameLength(int len);

  @StructureGetter("FrameTargetLength")
  int getFrameTargetLength();
  
  @StructureSetter("FrameTargetLength")
  CDFrame setFrameTargetLength(int len);
  
  @StructureGetter("FrameBorderColor")
  ColorValue getFrameBorderColor();
  
  default String getFrameName() {
    return StructureSupport.extractStringValue(
      this,
      0,
      getFrameNameLength()
    );
  }
  
  default CDFrame setFrameName(String name) {
    return StructureSupport.writeStringValue(
      this,
      0,
      getFrameNameLength(),
      name,
      this::setFrameNameLength
    );
  }
  
  default String getFrameTarget() {
    return StructureSupport.extractStringValue(
      this,
      getFrameNameLength(),
      getFrameTargetLength()
    );
  }
  
  default CDFrame setFrameTarget(String target) {
    return StructureSupport.writeStringValue(
      this,
      getFrameNameLength(),
      getFrameTargetLength(),
      target,
      this::setFrameTargetLength
    );
  }
  
  default CDFrame writeVariableFrameData(CDFrameVariableData varData) {
	  //allocate a buffer that is large enough for the content
	  byte[] bufArr = new byte[5000];
	  ByteBuffer buf = ByteBuffer.wrap(bufArr).order(ByteOrder.nativeOrder());
	  
	  Set dataFlags = getDataFlags();
	  
	  if (dataFlags.contains(DataFlag.NotesBorder)) {
		  //TODO find out if this can be enabled in Designer UI
	  }
	  
	  if (dataFlags.contains(DataFlag.NotesBorderFontAndColor)) {
		  //TODO find out if this can be disabled in Designer UI
	  }

	  if (dataFlags.contains(DataFlag.NotesBorderCaption)) {
		  Optional captionFormula = varData.getCaptionFormula();
		  if (captionFormula.isPresent()) {
			  byte[] compiledCaptionFormula = FormulaCompiler.get().compile(captionFormula.get());
			  buf.putShort((short) (compiledCaptionFormula.length & 0xffff));
			  buf.put(compiledCaptionFormula);
		  }
		  else {
			  buf.putShort((short) 0);
		  }
		  
		  Optional borderAlignment = varData.getBorderAlignment();
		  short borderAlignmentShort = borderAlignment.map((align) -> { return align.getValue(); }).orElse((short) 0);
		  buf.putShort(borderAlignmentShort);
		  
		  Optional textAlignment = varData.getTextAlignment();
      short textAlignmentShort = textAlignment.map((align) -> { return align.getValue(); }).orElse((short) 0);
		  buf.putShort((short) (textAlignmentShort & 0xffff));
		  
		  int open = varData.getOpen();
		  buf.putShort((short) (open & 0xffff));
	  }
	  
	  ColorValue backgroundColor = varData.getBackgroundColor().orElse(DesignColorsAndFonts.whiteColor());
	  buf.put(backgroundColor.getData());
	  
	  FontStyle fontId = varData.getFontStyle().orElse(DesignColorsAndFonts.defaultFont());
	  buf.put(fontId.getData());
	  
	  ColorValue textColor = varData.getTextColor().orElse(DesignColorsAndFonts.blackColor());
	  buf.put(textColor.getData());

	  if (dataFlags.contains(DataFlag.NotesCaptionFontName)) {
		  String fontName = varData.getFontName().get();
		  byte[] fontNameArr = fontName.getBytes(NativeItemCoder.get().getLmbcsCharset());
		  buf.putShort((short) (fontNameArr.length & 0xffff));
		  buf.put(fontNameArr);
	  }
	  
	  if (dataFlags.contains(DataFlag.Sequence)) {
		  int sequenceNo = varData.getSequenceNo();
		  buf.putShort((short) (sequenceNo & 0xffff));
	  }

	  int additionalVarDataLength = buf.position();
	  buf.limit(additionalVarDataLength).position(0);
	  
	  int frameNameLength = getFrameNameLength();
	  int frameTargetLength = getFrameTargetLength();
	  
	  resizeVariableData(frameNameLength + frameTargetLength + additionalVarDataLength);
	  ByteBuffer resizedVarDataBuffer = getVariableData();
	  resizedVarDataBuffer.position(frameNameLength + frameTargetLength);
	  
	  resizedVarDataBuffer.put(buf);
	  return this;
  }
  
  default Optional getCaptionFormula() {
	  return readVariableFrameData().getCaptionFormula();
  }
  
  default CDFrame setCaptionFormula(String formula) {
	  CDFrameVariableData varData = readVariableFrameData();
	  varData.setCaptionFormula(formula);
	  writeVariableFrameData(varData);
	  return this;
  }
  
  /**
   * Returns the text alignment
   * 
   * @return alignment
   */
  default Optional getTextAlignment() {
	  return readVariableFrameData().getTextAlignment();
  }
  
	/**
	 * Sets the text alignment
	 * 
	 * @param align new alignment
	 * @return this record
	 */
  default CDFrame setTextAlignment(TextAlignment align) {
	  CDFrameVariableData varData = readVariableFrameData();
	  varData.setTextAlignment(align);
	  writeVariableFrameData(varData);
	  return this;
  }
  
  default Optional getBorderAlignment() {
    return readVariableFrameData().getBorderAlignment();
  }
  
  default CDFrame setBorderAlignment(BorderAlignment align) {
    CDFrameVariableData varData = readVariableFrameData();
    varData.setBorderAlignment(align);
    writeVariableFrameData(varData);
    return this;
  }
  
  default int getOpen() {
	  return readVariableFrameData().getOpen();
  }
  
  default CDFrame setOpen(int open) {
	  CDFrameVariableData varData = readVariableFrameData();
	  varData.setOpen(open);
	  writeVariableFrameData(varData);
	  return this;
  }
  
  default Optional getBackgroundColor() {
	  return readVariableFrameData().getBackgroundColor();
  }

  default CDFrame setBackgroundColor(ColorValue color) {
	  CDFrameVariableData varData = readVariableFrameData();
	  varData.setBackgroundColor(color);
	  writeVariableFrameData(varData);
	  return this;
  }

  default Optional getFontStyle() {
	  return readVariableFrameData().getFontStyle();  
  }

  default CDFrame setFontStyle(FontStyle style) {
	  CDFrameVariableData varData = readVariableFrameData();
	  varData.setFontStyle(style);
	  writeVariableFrameData(varData);
	  return this;
  }

  default Optional getTextColor() {
	  return readVariableFrameData().getTextColor();  
  }

  default CDFrame setTextColor(ColorValue color) {
	  CDFrameVariableData varData = readVariableFrameData();
	  varData.setTextColor(color);
	  writeVariableFrameData(varData);
	  return this;
  }

  default Optional getFontName() {
	  return readVariableFrameData().getFontName();  
  }
  
  default CDFrame setFontName(String fontName) {
	  CDFrameVariableData varData = readVariableFrameData();
	  varData.setFontName(fontName);
	  writeVariableFrameData(varData);
	  return this;
  }
  
  default int getSequenceNo() {
	  return readVariableFrameData().getSequenceNo(); 
  }
  
  default CDFrame setSequenceNo(int seq) {
	  CDFrameVariableData varData = readVariableFrameData();
	  varData.setSequenceNo(seq);
	  writeVariableFrameData(varData);
	  return this;
  }
  
  default CDFrameVariableData readVariableFrameData() {
	  CDFrameVariableData varData = new CDFrameVariableData(this);
	  
	  final ByteBuffer buf = getVariableData();
	  
	  Set dataFlags = getDataFlags();
	  
	  if (dataFlags.contains(DataFlag.NotesBorder)) {
		  //TODO find out if this can be enabled in Designer UI
	  }
	  
	  if (dataFlags.contains(DataFlag.NotesBorderFontAndColor)) {
		  //TODO find out if this can be disabled in Designer UI
	  }

	  if (dataFlags.contains(DataFlag.NotesBorderCaption)) {
		  int frameNameLength = getFrameNameLength();
		  int frameTargetLength = getFrameTargetLength();
		  int preLen = frameNameLength + frameTargetLength;
		  
		  //WORD with caption formula length
		  buf.position(preLen);
		  short captionFormulaLength = buf.getShort();
		  int captionFormulaLengthUnsigned = Short.toUnsignedInt(captionFormulaLength);
		  
		  if (captionFormulaLengthUnsigned > 0) {
			  byte[] captionFormulaArr = new byte[captionFormulaLengthUnsigned];
			  buf.get(captionFormulaArr);
			  String captionFormula = FormulaCompiler.get().decompile(captionFormulaArr);
			  varData.setCaptionFormula(captionFormula);
		  }
		  
		  short borderAlignmentShort = buf.getShort();
		  BorderAlignment borderAlignment = BorderAlignment.Top; // use 0x0000 by default
		  for (BorderAlignment currAlignment : BorderAlignment.values()) {
		    if (borderAlignmentShort == currAlignment.getValue()) {
		      borderAlignment = currAlignment;
		      break;
		    }
		  }
		  
		  varData.setBorderAlignment(borderAlignment);
		  
		  short textAlignShort = buf.getShort();
		  for (TextAlignment currAlign : TextAlignment.values()) {
		    if (textAlignShort == currAlign.getValue()) {
		      varData.setTextAlignment(currAlign);
		      break;
		    }
		  }
		  
		  short open = buf.getShort();
		  varData.setOpen(Short.toUnsignedInt(open));
	  }
	  
	  byte[] backgroundColorArr = new byte[6]; // WORD FLAGS + 4 byte for component
	  buf.get(backgroundColorArr);
	  ColorValue backgroundColor = MemoryStructureWrapperService.get().wrapStructure(ColorValue.class, ByteBuffer.wrap(backgroundColorArr));
	  varData.setBackgroundColor(backgroundColor);
	  
	  byte[] fontIdArr = new byte[4];
	  buf.get(fontIdArr);
	  FontStyle fontId = MemoryStructureWrapperService.get().wrapStructure(FontStyle.class, ByteBuffer.wrap(fontIdArr));
	  varData.setFontStyle(fontId);
	  
	  byte[] textColorArr = new byte[6]; // WORD FLAGS + 4 byte for component
	  buf.get(textColorArr);
	  ColorValue textColor = MemoryStructureWrapperService.get().wrapStructure(ColorValue.class, ByteBuffer.wrap(textColorArr));
	  varData.setTextColor(textColor);
	  
	  if (dataFlags.contains(DataFlag.NotesCaptionFontName)) {
		  short fontNameLength = buf.getShort();
		  int fontNameLengthUnsigned = Short.toUnsignedInt(fontNameLength);
		  byte[] fontNameArr = new byte[fontNameLengthUnsigned];
		  buf.get(fontNameArr);
		  String fontName = StructureSupport.readLmbcsValue(fontNameArr);
		  varData.setFontName(fontName);
	  }
	  
	  if (dataFlags.contains(DataFlag.Sequence)) {
		  short sequenceNo = buf.getShort();
		  varData.setSequenceNo(Short.toUnsignedInt(sequenceNo));
	  }
	  
	  return varData;
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy