LibreOffice Module xmerge (master)  1
CellStyle.java
Go to the documentation of this file.
1 /*
2  * This file is part of the LibreOffice project.
3  *
4  * This Source Code Form is subject to the terms of the Mozilla Public
5  * License, v. 2.0. If a copy of the MPL was not distributed with this
6  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7  *
8  * This file incorporates work covered by the following license notice:
9  *
10  * Licensed to the Apache Software Foundation (ASF) under one or more
11  * contributor license agreements. See the NOTICE file distributed
12  * with this work for additional information regarding copyright
13  * ownership. The ASF licenses this file to you under the Apache
14  * License, Version 2.0 (the "License"); you may not use this file
15  * except in compliance with the License. You may obtain a copy of
16  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
17  */
18 
19 package org.openoffice.xmerge.converter.xml.sxc;
20 
21 import java.awt.Color;
22 
23 import org.w3c.dom.NodeList;
24 import org.w3c.dom.Node;
25 import org.w3c.dom.NamedNodeMap;
26 import org.w3c.dom.Element;
27 
31 
35 public class CellStyle extends Style implements Cloneable {
36 
37  private Format fmt = new Format();
38 
48  public CellStyle(Node node, StyleCatalog sc) {
49  super(node, sc);
50 
51  // Run through the attributes of this node, saving
52  // the ones we're interested in.
53  NamedNodeMap attrNodes = node.getAttributes();
54  if (attrNodes != null) {
55  int len = attrNodes.getLength();
56  for (int i = 0; i < len; i++) {
57  Node attr = attrNodes.item(i);
58  handleAttribute(attr.getNodeName(), attr.getNodeValue());
59  }
60  }
61 
62  // Look for children. Only ones we care about are "style:properties"
63  // nodes. If any are found, recursively traverse them, passing
64  // along the style element to add properties to.
65  if (node.hasChildNodes()) {
66  NodeList children = node.getChildNodes();
67  int len = children.getLength();
68  for (int i = 0; i < len; i++) {
69  Node child = children.item(i);
70  String nodeName = child.getNodeName();
71  if (nodeName.equals("style:properties")) {
72  NamedNodeMap childAttrNodes = child.getAttributes();
73  if (childAttrNodes != null) {
74  int nChildAttrNodes = childAttrNodes.getLength();
75  for (int j = 0; j < nChildAttrNodes; j++) {
76  Node attr = childAttrNodes.item(j);
77  handleAttribute(attr.getNodeName(),
78  attr.getNodeValue());
79  }
80  }
81  }
82  }
83  }
84  }
85 
98  public CellStyle(String name, String family, String parent,Format fmt,
99  StyleCatalog sc) {
100  super(name, family, parent, sc);
101  this.fmt = fmt;
102  }
103 
109  public Format getFormat() {
110  return fmt;
111  }
112 
120  private Color parseColorString(String value) {
121  int red = 0;
122  int green = 0;
123  int blue = 0;
124  try {
125  // Assume color value is of form #rrggbb
126  red = Integer.parseInt(value.substring(1, 3), 16);
127  green = Integer.parseInt(value.substring(3, 5), 16);
128  blue = Integer.parseInt(value.substring(5, 7), 16);
129  } catch (NumberFormatException e) {
130  Debug.log(Debug.ERROR, "Problem parsing a color string", e);
131  } catch (IndexOutOfBoundsException e) {
132  Debug.log(Debug.ERROR, "Problem parsing a color string", e);
133  }
134  return new Color(red, green, blue, 0);
135  }
136 
143  private void handleAttribute(String attr, String value) {
144 
145  if (attr.equals("fo:font-weight")) {
146  fmt.setAttribute(Format.BOLD, value.equals("bold"));
147  }
148 
149  else if (attr.equals("fo:font-style")) {
150  if (value.equals("italic") || value.equals("oblique"))
151  fmt.setAttribute(Format.ITALIC, true);
152  else if (value.equals("normal"))
153  fmt.setAttribute(Format.ITALIC, false);
154  }
155 
156  else if (attr.equals("style:text-underline")) {
157  fmt.setAttribute(Format.UNDERLINE, !value.equals("none"));
158  }
159 
160  else if (attr.equals("style:text-crossing-out")) {
161  fmt.setAttribute(Format.STRIKETHRU, !value.equals("none"));
162  }
163 
164  else if (attr.equals("style:text-position")) {
165  if (value.startsWith("super "))
166  fmt.setAttribute(Format.SUPERSCRIPT, true);
167  else if (value.startsWith("sub "))
168  fmt.setAttribute(Format.SUBSCRIPT, true);
169  else if (value.startsWith("0% "))
171  else {
172  String firstPart = value.substring(0, value.indexOf(' '));
173  if (firstPart.endsWith("%")) {
174  firstPart = firstPart.substring(0, value.indexOf('%'));
175  int amount;
176  try {
177  amount = Integer.parseInt(firstPart);
178  } catch (NumberFormatException e) {
179  amount = 0;
180  Debug.log(Debug.ERROR, "Problem with style:text-position tag", e);
181  }
182  if (amount < 0) fmt.setAttribute(Format.SUBSCRIPT, true);
183  else if (amount > 0) fmt.setAttribute(Format.SUPERSCRIPT, false);
184  }
185  }
186  }
187 
188  else if (attr.equals("fo:font-size")) {
189  if (value.endsWith("pt")) {
190  String num = value.substring(0, value.length() - 2);
191  fmt.setFontSize(Integer.parseInt(num));
192  }
193  }
194 
195  else if (attr.equals("style:font-name"))
196  fmt.setFontName(value);
197 
198  else if (attr.equals("fo:color"))
199  fmt.setForeground(parseColorString(value));
200 
201  else if (attr.equals("fo:background-color"))
202  fmt.setBackground(parseColorString(value));
203 
204  else if (attr.equals("fo:text-align")) {
205  if(value.equals("center")) {
207  } else if(value.equals("end")) {
209  } else if(value.equals("start")) {
211  }
212  }
213 
214  else if (attr.equals("fo:vertical-align")) {
215  if(value.equals("top")) {
217  } else if(value.equals("middle")) {
219  } else if(value.equals("bottom")) {
221  }
222  }
223 
224  else if (attr.equals("fo:border")) {
225  fmt.setAttribute(Format.TOP_BORDER, !value.equals("none"));
226  fmt.setAttribute(Format.BOTTOM_BORDER, !value.equals("none"));
227  fmt.setAttribute(Format.LEFT_BORDER, !value.equals("none"));
228  fmt.setAttribute(Format.RIGHT_BORDER, !value.equals("none"));
229  }
230  else if (attr.equals("fo:border-top")) {
231  fmt.setAttribute(Format.TOP_BORDER, !value.equals("none"));
232  }
233  else if (attr.equals("fo:border-bottom")) {
234  fmt.setAttribute(Format.BOTTOM_BORDER, !value.equals("none"));
235  }
236  else if (attr.equals("fo:border-left")) {
237  fmt.setAttribute(Format.LEFT_BORDER, !value.equals("none"));
238  }
239  else if (attr.equals("fo:border-right")) {
240  fmt.setAttribute(Format.RIGHT_BORDER, !value.equals("none"));
241  }
242  else if (attr.equals("fo:wrap-option")) {
243  fmt.setAttribute(Format.WORD_WRAP, value.equals("wrap"));
244  }
245 
246  else if (isIgnored(attr)) {}
247 
248  else {
249  Debug.log(Debug.INFO, "CellStyle Unhandled: " + attr + "=" + value);
250  }
251  }
252 
262  @Override
263  public Style getResolved() {
264  // Create a new object to return, which is a clone of this one.
265  CellStyle resolved = null;
266  try {
267  resolved = (CellStyle)this.clone();
268  } catch (Exception e) {
269  Debug.log(Debug.ERROR, "Can't clone", e);
270  }
271 
272  // Look up the parentStyle. (If there is no style catalog
273  // specified, we can't do any lookups.)
274  CellStyle parentStyle = null;
275  if (sc != null) {
276  if (parent != null) {
277  parentStyle = (CellStyle)sc.lookup(parent, family, null,
278  this.getClass());
279  if (parentStyle == null)
280  Debug.log(Debug.ERROR, "parent style lookup of "
281  + parent + " failed!");
282  else
283  parentStyle = (CellStyle)parentStyle.getResolved();
284 
285  } else if (!name.equals("DEFAULT_STYLE")) {
286  parentStyle = (CellStyle)sc.lookup("DEFAULT_STYLE", null,
287  null, this.getClass());
288  }
289  }
290 
291  // If we found a parent, for any attributes which we don't have
292  // set, try to get the values from the parent.
293  if (parentStyle != null) {
294  parentStyle = (CellStyle)parentStyle.getResolved();
295  Format parentFormat = parentStyle.getFormat();
296  Format resolvedFormat = resolved.getFormat();
297 
298  if ((fmt.getAlign() == Format.LEFT_ALIGN) && (parentFormat.getAlign() != Format.LEFT_ALIGN))
299  resolvedFormat.setAlign(parentFormat.getAlign());
300  if ((fmt.getVertAlign() == Format.BOTTOM_ALIGN) && (parentFormat.getVertAlign() != Format.BOTTOM_ALIGN))
301  resolvedFormat.setVertAlign(parentFormat.getVertAlign());
302  if ((fmt.getFontSize() == 0) && (parentFormat.getFontSize() != 0))
303  resolvedFormat.setFontSize(parentFormat.getFontSize());
304  if ((fmt.getFontName() == null) && (parentFormat.getFontName() != null))
305  resolvedFormat.setFontName(parentFormat.getFontName());
306  if ((fmt.getForeground() == null) && (parentFormat.getForeground() != null))
307  resolvedFormat.setForeground(parentFormat.getForeground());
308  if ((fmt.getBackground() == null) && (parentFormat.getBackground() != null))
309  resolvedFormat.setBackground(parentFormat.getBackground());
310  for (int m = Format.BOLD; m <= Format.SUBSCRIPT; m = m << 1) {
311  if ((fmt.getAttribute(m)) && (parentFormat.getAttribute(m))) {
312  resolvedFormat.setAttribute(m, parentFormat.getAttribute(m));
313  }
314  }
315 
316  }
317  return resolved;
318  }
319 
330  @Override
331  public Node createNode(org.w3c.dom.Document parentDoc, String name) {
332  Element node = parentDoc.createElement(name);
333  writeAttributes(node);
334  return node;
335  }
336 
346  @Override
347  public boolean isSubset(Style style) {
348  if (style.getClass() != this.getClass())
349  return false;
350  CellStyle tStyle = (CellStyle)style;
351 
352  Format rhs = tStyle.getFormat();
353 
354  return fmt.isSubset(rhs);
355  }
356 
363  private void writeAttributes(Element node) {
364 
365  if (fmt.getAlign()==Format.RIGHT_ALIGN)
366  node.setAttribute("fo:text-align", "end");
367 
368  if (fmt.getAlign()==Format.LEFT_ALIGN)
369  node.setAttribute("fo:text-align", "start");
370 
371  if (fmt.getAlign()==Format.CENTER_ALIGN)
372  node.setAttribute("fo:text-align", "center");
373 
374  if (fmt.getVertAlign()==Format.TOP_ALIGN)
375  node.setAttribute("fo:vertical-align", "top");
376 
377  if (fmt.getVertAlign()==Format.MIDDLE_ALIGN)
378  node.setAttribute("fo:vertical-align", "middle");
379 
380  if (fmt.getVertAlign()==Format.BOTTOM_ALIGN)
381  node.setAttribute("fo:vertical-align", "bottom");
382 
383  if (fmt.getAttribute(Format.BOLD))
384  node.setAttribute("fo:font-weight", "bold");
385 
386  if (fmt.getAttribute(Format.ITALIC))
387  node.setAttribute("fo:font-style", "italic");
388 
389  if (fmt.getAttribute(Format.UNDERLINE))
390  node.setAttribute("style:text-underline", "single");
391 
392  if (fmt.getAttribute(Format.STRIKETHRU))
393  node.setAttribute("style:text-crossing-out", "single-line");
394 
396  node.setAttribute("style:text-position", "super 58%");
397 
398  if (fmt.getAttribute(Format.SUBSCRIPT))
399  node.setAttribute("style:text-position", "sub 58%");
400 
401  if (fmt.getFontSize() != 0) {
402  node.setAttribute("fo:font-size", Integer.toString(fmt.getFontSize()) + "pt");
403  }
404 
405  if (fmt.getFontName() != null)
406  node.setAttribute("style:font-name", fmt.getFontName());
407 
408  if (fmt.getForeground() != null)
409  node.setAttribute("fo:color", buildColorString(fmt.getForeground()));
410 
411  if (fmt.getBackground() != null)
412  node.setAttribute("fo:background-color",
414 
415  if (fmt.getAttribute(Format.TOP_BORDER))
416  node.setAttribute("fo:border-top", "0.0008inch solid #000000");
417 
419  node.setAttribute("fo:border-bottom", "0.0008inch solid #000000");
420 
422  node.setAttribute("fo:border-right", "0.0008inch solid #000000");
423 
425  node.setAttribute("fo:border-left", "0.0008inch solid #000000");
426 
427  if (fmt.getAttribute(Format.WORD_WRAP))
428  node.setAttribute("fo:wrap-option", "wrap");
429 
430  }
431 
439  private String buildColorString(Color c) {
440  return String.format("#%06X", c.getRGB() & 0x00FFFFFF);
441  }
442 
443  private static String[] ignored = {
444  "style:text-autospace", "style:text-underline-color",
445  "fo:margin-left", "fo:margin-right", "fo:text-indent",
446  "fo:margin-top", "fo:margin-bottom", "text:line-number",
447  "text:number-lines", "style:country-asian",
448  "style:font-size-asian", "style:font-name-complex",
449  "style:language-complex", "style:country-complex",
450  "style:font-size-complex", "style:punctuation-wrap",
451  "fo:language", "fo:country",
452  "style:font-name-asian", "style:language-asian",
453  "style:line-break", "fo:keep-with-next"
454  };
455 
464  private boolean isIgnored(String attribute) {
465  for (int i = 0; i < ignored.length; i++) {
466  if (ignored[i].equals(attribute))
467  return true;
468  }
469  return false;
470  }
471 }
static final int INFO
Informational messages.
Definition: Debug.java:42
Node createNode(org.w3c.dom.Document parentDoc, String name)
Create a new.
Definition: CellStyle.java:331
Color parseColorString(String value)
Parse a color specification of the form { #rrggbb}.
Definition: CellStyle.java:120
Provides general purpose utilities.
static void log(int flag, String msg)
Log message based on the flag type.
Definition: Debug.java:205
final static int BOLD
Indicates bold text.
Definition: Format.java:39
final static int SUPERSCRIPT
Indicates superscripted text.
Definition: Format.java:47
Color getBackground()
Get the Background.
Definition: Format.java:356
static final int ERROR
Error messages.
Definition: Debug.java:44
void setAttribute(int flags, boolean toggle)
Set one or more text attributes.
Definition: Format.java:146
void setFontName(String fontName)
Set the font used for this cell.
Definition: Format.java:255
int getAlign()
Get the alignment used for this cell.
Definition: Format.java:318
exports com.sun.star. java
final static int SUBSCRIPT
Indicates subscripted text.
Definition: Format.java:49
void handleAttribute(String attr, String value)
Set an attribute.
Definition: CellStyle.java:143
int i
This class specifies the format for a given spreadsheet cell.
Definition: Format.java:26
boolean getAttribute(int attribute)
Return.
Definition: Format.java:164
PyRef getClass(const OUString &name, const Runtime &runtime)
String getFontName()
Get the font used for this cell.
Definition: Format.java:264
void setBackground(Color c)
Set the Background.
Definition: Format.java:346
final static int TOP_ALIGN
Vertical Alignment Constants.
Definition: Format.java:34
void setVertAlign(int vertAlign)
Set the vertical alignment used for this cell.
Definition: Format.java:291
CellStyle(Node node, StyleCatalog sc)
Constructor for use when going from DOM to client device format.
Definition: CellStyle.java:48
int getFontSize()
Get the font size (in points) used for this cell.
Definition: Format.java:282
boolean isIgnored(String attribute)
This code checks whether an attribute is one that we intentionally ignore.
Definition: CellStyle.java:464
void setFontSize(int fontSize)
Set the font size (in points) used for this cell.
Definition: Format.java:273
void setAlign(int align)
Set the alignment used for this cell.
Definition: Format.java:309
boolean isSubset(Format rhs)
Return true if passed.
Definition: Format.java:402
T * clone(T *const other)
Color getForeground()
Get the Foreground.
Definition: Format.java:337
Provides interfaces for converting between two.
Definition: Convert.java:19
int getVertAlign()
Get the vertical alignment used for this cell.
Definition: Format.java:300
final static int UNDERLINE
Indicates underlined text.
Definition: Format.java:43
void setForeground(Color c)
Set the Foreground.
Definition: Format.java:327
This class is used for logging debug messages.
Definition: Debug.java:39
void writeAttributes(Element node)
Write this.
Definition: CellStyle.java:363
tuple m
CellStyle(String name, String family, String parent, Format fmt, StyleCatalog sc)
Constructor for use when going from client device format to DOM.
Definition: CellStyle.java:98
final static int STRIKETHRU
Indicates strike-through in the text.
Definition: Format.java:45
final static int RIGHT_ALIGN
Horizontal Alignment Constants.
Definition: Format.java:29
final static int ITALIC
Indicates italic text.
Definition: Format.java:41