You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

HSLFTableCell.java 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400
  1. /* ====================================================================
  2. Licensed to the Apache Software Foundation (ASF) under one or more
  3. contributor license agreements. See the NOTICE file distributed with
  4. this work for additional information regarding copyright ownership.
  5. The ASF licenses this file to You under the Apache License, Version 2.0
  6. (the "License"); you may not use this file except in compliance with
  7. the License. You may obtain a copy of the License at
  8. http://www.apache.org/licenses/LICENSE-2.0
  9. Unless required by applicable law or agreed to in writing, software
  10. distributed under the License is distributed on an "AS IS" BASIS,
  11. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. See the License for the specific language governing permissions and
  13. limitations under the License.
  14. ==================================================================== */
  15. package org.apache.poi.hslf.usermodel;
  16. import java.awt.Color;
  17. import java.awt.geom.Rectangle2D;
  18. import org.apache.poi.ddf.AbstractEscherOptRecord;
  19. import org.apache.poi.ddf.EscherContainerRecord;
  20. import org.apache.poi.ddf.EscherProperties;
  21. import org.apache.poi.sl.draw.DrawPaint;
  22. import org.apache.poi.sl.usermodel.PaintStyle;
  23. import org.apache.poi.sl.usermodel.ShapeType;
  24. import org.apache.poi.sl.usermodel.StrokeStyle;
  25. import org.apache.poi.sl.usermodel.StrokeStyle.LineCompound;
  26. import org.apache.poi.sl.usermodel.StrokeStyle.LineDash;
  27. import org.apache.poi.sl.usermodel.TableCell;
  28. /**
  29. * Represents a cell in a ppt table
  30. *
  31. * @author Yegor Kozlov
  32. */
  33. public final class HSLFTableCell extends HSLFTextBox implements TableCell<HSLFShape,HSLFTextParagraph> {
  34. protected static final int DEFAULT_WIDTH = 100;
  35. protected static final int DEFAULT_HEIGHT = 40;
  36. /* package */ HSLFLine borderLeft;
  37. /* package */ HSLFLine borderRight;
  38. /* package */ HSLFLine borderTop;
  39. /* package */ HSLFLine borderBottom;
  40. /**
  41. * Create a TableCell object and initialize it from the supplied Record container.
  42. *
  43. * @param escherRecord EscherSpContainer which holds information about this shape
  44. * @param parent the parent of the shape
  45. */
  46. protected HSLFTableCell(EscherContainerRecord escherRecord, HSLFTable parent){
  47. super(escherRecord, parent);
  48. }
  49. /**
  50. * Create a new TableCell. This constructor is used when a new shape is created.
  51. *
  52. * @param parent the parent of this Shape. For example, if this text box is a cell
  53. * in a table then the parent is Table.
  54. */
  55. public HSLFTableCell(HSLFTable parent){
  56. super(parent);
  57. setShapeType(ShapeType.RECT);
  58. //_txtrun.setRunType(TextHeaderAtom.HALF_BODY_TYPE);
  59. //_txtrun.getRichTextRuns()[0].setFlag(false, 0, false);
  60. }
  61. protected EscherContainerRecord createSpContainer(boolean isChild){
  62. _escherContainer = super.createSpContainer(isChild);
  63. AbstractEscherOptRecord opt = getEscherOptRecord();
  64. setEscherProperty(opt, EscherProperties.TEXT__TEXTID, 0);
  65. setEscherProperty(opt, EscherProperties.TEXT__SIZE_TEXT_TO_FIT_SHAPE, 0x20000);
  66. setEscherProperty(opt, EscherProperties.FILL__NOFILLHITTEST, 0x150001);
  67. setEscherProperty(opt, EscherProperties.SHADOWSTYLE__SHADOWOBSURED, 0x20000);
  68. setEscherProperty(opt, EscherProperties.PROTECTION__LOCKAGAINSTGROUPING, 0x40000);
  69. return _escherContainer;
  70. }
  71. private void anchorBorder(BorderEdge edge, final HSLFLine line) {
  72. if (line == null) {
  73. return;
  74. }
  75. Rectangle2D cellAnchor = getAnchor();
  76. double x,y,w,h;
  77. switch(edge){
  78. case top:
  79. x = cellAnchor.getX();
  80. y = cellAnchor.getY();
  81. w = cellAnchor.getWidth();
  82. h = 0;
  83. break;
  84. case right:
  85. x = cellAnchor.getX() + cellAnchor.getWidth();
  86. y = cellAnchor.getY();
  87. w = 0;
  88. h = cellAnchor.getHeight();
  89. break;
  90. case bottom:
  91. x = cellAnchor.getX();
  92. y = cellAnchor.getY() + cellAnchor.getHeight();
  93. w = cellAnchor.getWidth();
  94. h = 0;
  95. break;
  96. case left:
  97. x = cellAnchor.getX();
  98. y = cellAnchor.getY();
  99. w = 0;
  100. h = cellAnchor.getHeight();
  101. break;
  102. default:
  103. throw new IllegalArgumentException();
  104. }
  105. line.setAnchor(new Rectangle2D.Double(x,y,w,h));
  106. }
  107. public void setAnchor(Rectangle2D anchor){
  108. super.setAnchor(anchor);
  109. anchorBorder(BorderEdge.top, borderTop);
  110. anchorBorder(BorderEdge.right, borderRight);
  111. anchorBorder(BorderEdge.bottom, borderBottom);
  112. anchorBorder(BorderEdge.left, borderLeft);
  113. }
  114. @Override
  115. public StrokeStyle getBorderStyle(final BorderEdge edge) {
  116. final Double width = getBorderWidth(edge);
  117. return (width == null) ? null : new StrokeStyle() {
  118. public PaintStyle getPaint() {
  119. return DrawPaint.createSolidPaint(getBorderColor(edge));
  120. }
  121. public LineCap getLineCap() {
  122. return null;
  123. }
  124. public LineDash getLineDash() {
  125. return getBorderDash(edge);
  126. }
  127. public LineCompound getLineCompound() {
  128. return getBorderCompound(edge);
  129. }
  130. public double getLineWidth() {
  131. return width;
  132. }
  133. };
  134. }
  135. @Override
  136. public void setBorderStyle(BorderEdge edge, StrokeStyle style) {
  137. if (style == null) {
  138. throw new IllegalArgumentException("StrokeStyle needs to be specified.");
  139. }
  140. // setting the line cap is not implemented, as the border lines aren't connected
  141. LineCompound compound = style.getLineCompound();
  142. if (compound != null) {
  143. setBorderCompound(edge, compound);
  144. }
  145. LineDash dash = style.getLineDash();
  146. if (dash != null) {
  147. setBorderDash(edge, dash);
  148. }
  149. double width = style.getLineWidth();
  150. setBorderWidth(edge, width);
  151. }
  152. public Double getBorderWidth(BorderEdge edge) {
  153. HSLFLine l;
  154. switch (edge) {
  155. case bottom: l = borderBottom; break;
  156. case top: l = borderTop; break;
  157. case right: l = borderRight; break;
  158. case left: l = borderLeft; break;
  159. default: throw new IllegalArgumentException();
  160. }
  161. return (l == null) ? null : l.getLineWidth();
  162. }
  163. @Override
  164. public void setBorderWidth(BorderEdge edge, double width) {
  165. HSLFLine l = addLine(edge);
  166. l.setLineWidth(width);
  167. }
  168. public Color getBorderColor(BorderEdge edge) {
  169. HSLFLine l;
  170. switch (edge) {
  171. case bottom: l = borderBottom; break;
  172. case top: l = borderTop; break;
  173. case right: l = borderRight; break;
  174. case left: l = borderLeft; break;
  175. default: throw new IllegalArgumentException();
  176. }
  177. return (l == null) ? null : l.getLineColor();
  178. }
  179. @Override
  180. public void setBorderColor(BorderEdge edge, Color color) {
  181. if (edge == null || color == null) {
  182. throw new IllegalArgumentException("BorderEdge and/or Color need to be specified.");
  183. }
  184. HSLFLine l = addLine(edge);
  185. l.setLineColor(color);
  186. }
  187. public LineDash getBorderDash(BorderEdge edge) {
  188. HSLFLine l;
  189. switch (edge) {
  190. case bottom: l = borderBottom; break;
  191. case top: l = borderTop; break;
  192. case right: l = borderRight; break;
  193. case left: l = borderLeft; break;
  194. default: throw new IllegalArgumentException();
  195. }
  196. return (l == null) ? null : l.getLineDash();
  197. }
  198. @Override
  199. public void setBorderDash(BorderEdge edge, LineDash dash) {
  200. if (edge == null || dash == null) {
  201. throw new IllegalArgumentException("BorderEdge and/or LineDash need to be specified.");
  202. }
  203. HSLFLine l = addLine(edge);
  204. l.setLineDash(dash);
  205. }
  206. public LineCompound getBorderCompound(BorderEdge edge) {
  207. HSLFLine l;
  208. switch (edge) {
  209. case bottom: l = borderBottom; break;
  210. case top: l = borderTop; break;
  211. case right: l = borderRight; break;
  212. case left: l = borderLeft; break;
  213. default: throw new IllegalArgumentException();
  214. }
  215. return (l == null) ? null : l.getLineCompound();
  216. }
  217. @Override
  218. public void setBorderCompound(BorderEdge edge, LineCompound compound) {
  219. if (edge == null || compound == null) {
  220. throw new IllegalArgumentException("BorderEdge and/or LineCompound need to be specified.");
  221. }
  222. HSLFLine l = addLine(edge);
  223. l.setLineCompound(compound);
  224. }
  225. protected HSLFLine addLine(BorderEdge edge) {
  226. switch (edge) {
  227. case bottom: {
  228. if (borderBottom == null) {
  229. borderBottom = createBorder(edge);
  230. HSLFTableCell c = getSiblingCell(1,0);
  231. if (c != null) {
  232. assert(c.borderTop == null);
  233. c.borderTop = borderBottom;
  234. }
  235. }
  236. return borderBottom;
  237. }
  238. case top: {
  239. if (borderTop == null) {
  240. borderTop = createBorder(edge);
  241. HSLFTableCell c = getSiblingCell(-1,0);
  242. if (c != null) {
  243. assert(c.borderBottom == null);
  244. c.borderBottom = borderTop;
  245. }
  246. }
  247. return borderTop;
  248. }
  249. case right: {
  250. if (borderRight == null) {
  251. borderRight = createBorder(edge);
  252. HSLFTableCell c = getSiblingCell(0,1);
  253. if (c != null) {
  254. assert(c.borderLeft == null);
  255. c.borderLeft = borderRight;
  256. }
  257. }
  258. return borderRight;
  259. }
  260. case left: {
  261. if (borderLeft == null) {
  262. borderLeft = createBorder(edge);
  263. HSLFTableCell c = getSiblingCell(0,-1);
  264. if (c != null) {
  265. assert(c.borderRight == null);
  266. c.borderRight = borderLeft;
  267. }
  268. }
  269. return borderLeft;
  270. }
  271. default:
  272. throw new IllegalArgumentException();
  273. }
  274. }
  275. @Override
  276. public void removeBorder(BorderEdge edge) {
  277. switch (edge) {
  278. case bottom: {
  279. if (borderBottom == null) break;
  280. getParent().removeShape(borderBottom);
  281. borderBottom = null;
  282. HSLFTableCell c = getSiblingCell(1,0);
  283. if (c != null) {
  284. c.borderTop = null;
  285. }
  286. break;
  287. }
  288. case top: {
  289. if (borderTop == null) break;
  290. getParent().removeShape(borderTop);
  291. borderTop = null;
  292. HSLFTableCell c = getSiblingCell(-1,0);
  293. if (c != null) {
  294. c.borderBottom = null;
  295. }
  296. break;
  297. }
  298. case right: {
  299. if (borderRight == null) break;
  300. getParent().removeShape(borderRight);
  301. borderRight = null;
  302. HSLFTableCell c = getSiblingCell(0,1);
  303. if (c != null) {
  304. c.borderLeft = null;
  305. }
  306. break;
  307. }
  308. case left: {
  309. if (borderLeft == null) break;
  310. getParent().removeShape(borderLeft);
  311. borderLeft = null;
  312. HSLFTableCell c = getSiblingCell(0,-1);
  313. if (c != null) {
  314. c.borderRight = null;
  315. }
  316. break;
  317. }
  318. default:
  319. throw new IllegalArgumentException();
  320. }
  321. }
  322. protected HSLFTableCell getSiblingCell(int row, int col) {
  323. return getParent().getRelativeCell(this, row, col);
  324. }
  325. /**
  326. * Create a border to format this table
  327. *
  328. * @return the created border
  329. */
  330. private HSLFLine createBorder(BorderEdge edge) {
  331. HSLFTable table = getParent();
  332. HSLFLine line = new HSLFLine(table);
  333. table.addShape(line);
  334. AbstractEscherOptRecord opt = getEscherOptRecord();
  335. setEscherProperty(opt, EscherProperties.GEOMETRY__SHAPEPATH, -1);
  336. setEscherProperty(opt, EscherProperties.GEOMETRY__FILLOK, -1);
  337. setEscherProperty(opt, EscherProperties.SHADOWSTYLE__SHADOWOBSURED, 0x20000);
  338. setEscherProperty(opt, EscherProperties.THREED__LIGHTFACE, 0x80000);
  339. anchorBorder(edge, line);
  340. return line;
  341. }
  342. protected void applyLineProperties(BorderEdge edge, HSLFLine other) {
  343. HSLFLine line = addLine(edge);
  344. line.setLineWidth(other.getLineWidth());
  345. line.setLineColor(other.getLineColor());
  346. // line.setLineCompound(other.getLineCompound());
  347. // line.setLineDashing(other.getLineDashing());
  348. }
  349. @Override
  350. public HSLFTable getParent() {
  351. return (HSLFTable)super.getParent();
  352. }
  353. }