Dépôt officiel du code source de l'ERP OpenConcerto
/trunk/OpenConcerto/src/org/openconcerto/openoffice/XMLVersion.java |
---|
33,7 → 33,6 |
this.putMandatory(OFFICE_1, STYLE_1, TEXT_1, TABLE_1); |
this.put("number", NUMBER_1); |
this.put("draw", DRAW_1); |
this.put("number", NUMBER_1); |
this.put("fo", FO_1); |
this.put("form", "http://openoffice.org/2000/form"); |
this.put("xlink", "http://www.w3.org/1999/xlink"); |
49,7 → 48,6 |
this.putMandatory(OFFICE_2, STYLE_2, TEXT_2, TABLE_2); |
this.put("number", NUMBER_2); |
this.put("draw", DRAW_2); |
this.put("number", NUMBER_2); |
this.put("fo", FO_2); |
this.put("form", "urn:oasis:names:tc:opendocument:xmlns:form:1.0"); |
this.put("xlink", "http://www.w3.org/1999/xlink"); |
/trunk/OpenConcerto/src/org/openconcerto/openoffice/generation/ReportGeneration.java |
---|
161,7 → 161,7 |
*/ |
@SuppressWarnings("unchecked") |
protected C createCommon(String name) { |
return (C) new GenerationCommon<ReportGeneration>(this); |
return (C) new GenerationCommon<ReportGeneration<?>>(this); |
} |
/** |
/trunk/OpenConcerto/src/org/openconcerto/openoffice/StyleProperties.java |
---|
23,6 → 23,18 |
public static final Color TRANSPARENT = new Color(0, 0, 0, 0); |
public static final String TRANSPARENT_NAME = "transparent"; |
static public final boolean parseBoolean(final String s, boolean def) { |
return s == null ? def : Boolean.parseBoolean(s); |
} |
static public final int parseInt(final String s, int def) { |
return s == null ? def : Integer.parseInt(s); |
} |
static public final Integer parseInteger(final String s) { |
return s == null ? null : Integer.valueOf(s); |
} |
private final Style parentStyle; |
private final String propPrefix; |
36,13 → 48,36 |
} |
public final Element getElement() { |
return this.getParentStyle().getFormattingProperties(this.propPrefix); |
return getElement(this.getParentStyle(), true); |
} |
protected final boolean parseBoolean(final String s, boolean def) { |
return s == null ? def : Boolean.parseBoolean(s); |
protected final Element getElement(final Style s, final boolean create) { |
return s.getFormattingProperties(this.propPrefix, create); |
} |
private final String getAttributeValue(final Style s, final String attrName, final Namespace attrNS) { |
// e.g. no default style defined |
if (s == null) |
return null; |
final Element elem = this.getElement(s, false); |
if (elem == null) |
return null; |
return elem.getAttributeValue(attrName, attrNS); |
} |
// if a formatting property is not defined locally, the default style should be searched |
protected final String getAttributeValue(final String attrName, final Namespace attrNS) { |
final String localRes = getAttributeValue(this.getParentStyle(), attrName, attrNS); |
if (localRes != null) |
return localRes; |
if (this.getParentStyle() instanceof StyleStyle) { |
final StyleStyle defaultStyle = ((StyleStyle) this.getParentStyle()).getDefaultStyle(); |
return getAttributeValue(defaultStyle, attrName, attrNS); |
} else { |
return null; |
} |
} |
protected final Namespace getNS(final String prefix) { |
return this.getParentStyle().getNS().getNS(prefix); |
} |
53,7 → 88,7 |
// <style:table-properties>, <style:table-row-properties> and <style:text-properties> |
public final String getRawBackgroundColor() { |
return this.getElement().getAttributeValue("background-color", this.getNS("fo")); |
return this.getAttributeValue("background-color", this.getNS("fo")); |
} |
public final Color getBackgroundColor() { |
/trunk/OpenConcerto/src/org/openconcerto/openoffice/ODFrame.java |
---|
34,22 → 34,16 |
* @return the length, eg 15.3. |
*/ |
public static final float parseLength(final String l, final LengthUnit to) { |
return parseLengthDecimal(l, to).floatValue(); |
return LengthUnit.parseLength(l, to).floatValue(); |
} |
public static final BigDecimal parseLengthDecimal(final String l, final LengthUnit to) { |
if (l == null) |
return null; |
return LengthUnit.parseLength(l, to).stripTrailingZeros(); |
} |
// BigDecimal are exact and they can be null (eg optional attribute) |
private final BigDecimal width, height; |
public ODFrame(D parent, Element frame) { |
super(parent, frame, GraphicStyle.class); |
this.width = parseLengthDecimal(this.getSVGAttr("width"), getUnit()); |
this.height = parseLengthDecimal(this.getSVGAttr("height"), getUnit()); |
this.width = LengthUnit.parseLength(this.getSVGAttr("width"), getUnit()); |
this.height = LengthUnit.parseLength(this.getSVGAttr("height"), getUnit()); |
} |
public final BigDecimal getWidth() { |
95,11 → 89,11 |
} |
public final BigDecimal getX() { |
return parseLengthDecimal(this.getSVGAttr("x"), getUnit()); |
return LengthUnit.parseLength(this.getSVGAttr("x"), getUnit()); |
} |
public final BigDecimal getY() { |
return parseLengthDecimal(this.getSVGAttr("y"), getUnit()); |
return LengthUnit.parseLength(this.getSVGAttr("y"), getUnit()); |
} |
/** |
/trunk/OpenConcerto/src/org/openconcerto/openoffice/style/data/PercentStyle.java |
---|
New file |
0,0 → 1,57 |
/* |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
* |
* Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved. |
* |
* The contents of this file are subject to the terms of the GNU General Public License Version 3 |
* only ("GPL"). You may not use this file except in compliance with the License. You can obtain a |
* copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific |
* language governing permissions and limitations under the License. |
* |
* When distributing the software, include this License Header Notice in each file. |
*/ |
package org.openconcerto.openoffice.style.data; |
import org.openconcerto.openoffice.ODPackage; |
import org.openconcerto.openoffice.XMLVersion; |
import org.openconcerto.openoffice.spreadsheet.CellStyle; |
import java.util.List; |
import org.jdom.Element; |
import org.jdom.Namespace; |
// from section 16.27.9 in v1.2-cs01-part1 |
public class PercentStyle extends DataStyle { |
public static final DataStyleDesc<PercentStyle> DESC = new DataStyleDesc<PercentStyle>(PercentStyle.class, XMLVersion.OD, "percentage-style", "N") { |
@Override |
public PercentStyle create(ODPackage pkg, Element e) { |
return new PercentStyle(pkg, e); |
} |
}; |
public PercentStyle(final ODPackage pkg, Element elem) { |
super(pkg, elem, Number.class); |
} |
@Override |
public String format(Object o, CellStyle defaultStyle, boolean lenient) { |
final Number n = (Number) o; |
final Namespace numberNS = this.getElement().getNamespace(); |
final StringBuilder sb = new StringBuilder(); |
@SuppressWarnings("unchecked") |
final List<Element> children = this.getElement().getChildren(); |
for (final Element elem : children) { |
if (elem.getNamespace().equals(numberNS)) { |
if (elem.getName().equals("text")) { |
sb.append(elem.getText()); |
} else if (elem.getName().equals("number")) { |
sb.append(formatNumberOrScientificNumber(elem, n, 100, defaultStyle)); |
} |
} |
} |
return sb.toString(); |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/openoffice/style/data/TextStyle.java |
---|
New file |
0,0 → 1,56 |
/* |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
* |
* Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved. |
* |
* The contents of this file are subject to the terms of the GNU General Public License Version 3 |
* only ("GPL"). You may not use this file except in compliance with the License. You can obtain a |
* copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific |
* language governing permissions and limitations under the License. |
* |
* When distributing the software, include this License Header Notice in each file. |
*/ |
package org.openconcerto.openoffice.style.data; |
import org.openconcerto.openoffice.ODPackage; |
import org.openconcerto.openoffice.XMLVersion; |
import org.openconcerto.openoffice.spreadsheet.CellStyle; |
import java.util.List; |
import org.jdom.Element; |
import org.jdom.Namespace; |
// from section 16.27.25 in v1.2-cs01-part1 |
public class TextStyle extends DataStyle { |
public static final DataStyleDesc<TextStyle> DESC = new DataStyleDesc<TextStyle>(TextStyle.class, XMLVersion.OD, "text-style", "N") { |
@Override |
public TextStyle create(ODPackage pkg, Element e) { |
return new TextStyle(pkg, e); |
} |
}; |
public TextStyle(final ODPackage pkg, Element elem) { |
super(pkg, elem, Object.class); |
} |
@Override |
public String format(Object o, CellStyle defaultStyle, boolean lenient) { |
final Namespace numberNS = this.getElement().getNamespace(); |
final StringBuilder sb = new StringBuilder(); |
@SuppressWarnings("unchecked") |
final List<Element> children = this.getElement().getChildren(); |
for (final Element elem : children) { |
if (elem.getNamespace().equals(numberNS)) { |
if (elem.getName().equals("text")) { |
sb.append(elem.getText()); |
} else if (elem.getName().equals("text-content")) { |
sb.append(o.toString()); |
} |
} |
} |
return sb.toString(); |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/openoffice/style/data/NumberStyle.java |
---|
New file |
0,0 → 1,62 |
/* |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
* |
* Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved. |
* |
* The contents of this file are subject to the terms of the GNU General Public License Version 3 |
* only ("GPL"). You may not use this file except in compliance with the License. You can obtain a |
* copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific |
* language governing permissions and limitations under the License. |
* |
* When distributing the software, include this License Header Notice in each file. |
*/ |
package org.openconcerto.openoffice.style.data; |
import org.openconcerto.openoffice.ODPackage; |
import org.openconcerto.openoffice.XMLVersion; |
import org.openconcerto.openoffice.spreadsheet.CellStyle; |
import org.openconcerto.openoffice.spreadsheet.MutableCell; |
import java.util.List; |
import org.jdom.Element; |
import org.jdom.Namespace; |
// from section 16.27.2 in v1.2-cs01-part1 |
public class NumberStyle extends DataStyle { |
public static final DataStyleDesc<NumberStyle> DESC = new DataStyleDesc<NumberStyle>(NumberStyle.class, XMLVersion.OD, "number-style", "N") { |
@Override |
public NumberStyle create(ODPackage pkg, Element e) { |
return new NumberStyle(pkg, e); |
} |
}; |
public NumberStyle(final ODPackage pkg, Element elem) { |
super(pkg, elem, Number.class); |
} |
@Override |
public String format(Object o, CellStyle defaultStyle, boolean lenient) { |
final Number n = (Number) o; |
final Namespace numberNS = this.getElement().getNamespace(); |
final StringBuilder sb = new StringBuilder(); |
@SuppressWarnings("unchecked") |
final List<Element> children = this.getElement().getChildren(); |
for (final Element elem : children) { |
if (elem.getNamespace().equals(numberNS)) { |
if (elem.getName().equals("text")) { |
sb.append(elem.getText()); |
} else if (elem.getName().equals("number") || elem.getName().equals("scientific-number")) { |
sb.append(formatNumberOrScientificNumber(elem, n, defaultStyle)); |
} else if (elem.getName().equals("fraction")) { |
// TODO fractions |
reportError("Fractions not supported", lenient); |
sb.append(MutableCell.formatNumber(n, defaultStyle)); |
} |
} |
} |
return sb.toString(); |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/openoffice/style/data/DataStyle.java |
---|
New file |
0,0 → 1,207 |
/* |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
* |
* Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved. |
* |
* The contents of this file are subject to the terms of the GNU General Public License Version 3 |
* only ("GPL"). You may not use this file except in compliance with the License. You can obtain a |
* copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific |
* language governing permissions and limitations under the License. |
* |
* When distributing the software, include this License Header Notice in each file. |
*/ |
package org.openconcerto.openoffice.style.data; |
import org.openconcerto.openoffice.Log; |
import org.openconcerto.openoffice.ODPackage; |
import org.openconcerto.openoffice.Style; |
import org.openconcerto.openoffice.StyleDesc; |
import org.openconcerto.openoffice.StyleProperties; |
import org.openconcerto.openoffice.XMLVersion; |
import org.openconcerto.openoffice.spreadsheet.CellStyle; |
import org.openconcerto.openoffice.text.TextStyle.StyleTextProperties; |
import org.openconcerto.utils.NumberUtils; |
import java.math.RoundingMode; |
import java.text.DecimalFormat; |
import java.util.Arrays; |
import java.util.Collections; |
import java.util.List; |
import java.util.Map.Entry; |
import java.util.SortedMap; |
import java.util.TreeMap; |
import java.util.regex.Matcher; |
import java.util.regex.Pattern; |
import org.jdom.Attribute; |
import org.jdom.Element; |
import org.jdom.Namespace; |
// from section 16.27 in v1.2-cs01-part1 |
public abstract class DataStyle extends Style { |
private static final int DEFAULT_GROUPING_SIZE = new DecimalFormat().getGroupingSize(); |
private static final int DEFAULT_DECIMAL_PLACES = 2; |
private static final Pattern QUOTE_PATRN = Pattern.compile("'", Pattern.LITERAL); |
private static final Pattern EXP_PATTERN = Pattern.compile("E(\\d+)$"); |
public static int getDecimalPlaces(final CellStyle defaultStyle) { |
final int res; |
if (defaultStyle != null && defaultStyle.getTableCellProperties().getDecimalPlaces() != null) |
res = defaultStyle.getTableCellProperties().getDecimalPlaces().intValue(); |
else |
res = DEFAULT_DECIMAL_PLACES; |
return res; |
} |
public static void addStringLiteral(final StringBuilder formatSB, final String s) { |
formatSB.append('\''); |
formatSB.append(QUOTE_PATRN.matcher(s).replaceAll("''")); |
formatSB.append('\''); |
} |
public static final DataStyleDesc<?>[] DATA_STYLES_DESCS = new DataStyleDesc<?>[] { NumberStyle.DESC, PercentStyle.DESC, TextStyle.DESC, CurrencyStyle.DESC, DateStyle.DESC, TimeStyle.DESC, |
BooleanStyle.DESC }; |
public static abstract class DataStyleDesc<S extends DataStyle> extends StyleDesc<S> { |
protected DataStyleDesc(Class<S> clazz, XMLVersion version, String elemName, String baseName) { |
super(clazz, version, elemName, baseName); |
this.setElementNS(getVersion().getNS("number")); |
// from 19.469 in v1.2-cs01-part1 |
this.getRefElementsMap().putAll( |
"style:data-style-name", |
Arrays.asList("presentation:date-time-decl", "style:style", "text:creation-date", "text:creation-time", "text:database-display", "text:date", "text:editing-duration", |
"text:expression", "text:meta-field", "text:modification-date", "text:modification-time", "text:print-date", "text:print-time", "text:table-formula", "text:time", |
"text:user-defined", "text:user-field-get", "text:user-field-input", "text:variable-get", "text:variable-input", "text:variable-set")); |
} |
} |
// type accepted by #format() |
private final Class<?> type; |
private StyleTextProperties textProps; |
protected DataStyle(final ODPackage pkg, Element elem, final Class<?> type) { |
super(pkg, elem); |
this.type = type; |
} |
protected final Class<?> getDataType() { |
return this.type; |
} |
public final boolean canFormat(Class<?> toFormat) { |
return this.getDataType().isAssignableFrom(toFormat); |
} |
public final String getTitle() { |
return this.getElement().getAttributeValue("title", getElement().getNamespace()); |
} |
public final StyleTextProperties getTextProperties() { |
if (this.textProps == null) |
this.textProps = new StyleTextProperties(this); |
return this.textProps; |
} |
public abstract String format(final Object o, final CellStyle defaultStyle, boolean lenient) throws UnsupportedOperationException; |
protected final void reportError(String msg, boolean lenient) throws UnsupportedOperationException { |
if (lenient) |
Log.get().warning(msg); |
else |
throw new UnsupportedOperationException(msg); |
} |
protected final String formatNumberOrScientificNumber(final Element elem, final Number n, CellStyle defaultStyle) { |
return this.formatNumberOrScientificNumber(elem, n, 1, defaultStyle); |
} |
protected final String formatNumberOrScientificNumber(final Element elem, final Number n, final int multiplier, CellStyle defaultStyle) { |
final Namespace numberNS = this.getElement().getNamespace(); |
final StringBuilder numberSB = new StringBuilder(); |
final List<?> embeddedTexts = elem.getChildren("embedded-text", numberNS); |
final SortedMap<Integer, String> embeddedTextByPosition = new TreeMap<Integer, String>(Collections.reverseOrder()); |
for (final Object o : embeddedTexts) { |
final Element embeddedText = (Element) o; |
embeddedTextByPosition.put(Integer.valueOf(embeddedText.getAttributeValue("position", numberNS)), embeddedText.getText()); |
} |
final Attribute factorAttr = elem.getAttribute("display-factor", numberNS); |
final double factor = (factorAttr != null ? Double.valueOf(factorAttr.getValue()) : 1) / multiplier; |
// default value from 19.348 |
final boolean grouping = StyleProperties.parseBoolean(elem.getAttributeValue("grouping", numberNS), false); |
final String minIntDigitsAttr = elem.getAttributeValue("min-integer-digits", numberNS); |
final int minIntDig = minIntDigitsAttr == null ? 0 : Integer.parseInt(minIntDigitsAttr); |
if (minIntDig == 0) { |
numberSB.append('#'); |
} else { |
for (int i = 0; i < minIntDig; i++) |
numberSB.append('0'); |
} |
// e.g. if it's "--", 12,3 is displayed "12,3" and 12 is displayed "12,--" |
final String decReplacement = elem.getAttributeValue("decimal-replacement", numberNS); |
final boolean decSeparatorAlwaysShown; |
if (decReplacement != null && !NumberUtils.hasFractionalPart(n)) { |
decSeparatorAlwaysShown = true; |
numberSB.append('.'); |
// escape quote in replacement |
addStringLiteral(numberSB, decReplacement); |
} else { |
decSeparatorAlwaysShown = false; |
// see 19.343.2 |
final Attribute decPlacesAttr = elem.getAttribute("decimal-places", numberNS); |
final int decPlaces; |
if (decPlacesAttr != null) |
decPlaces = Integer.parseInt(decPlacesAttr.getValue()); |
else |
decPlaces = getDecimalPlaces(defaultStyle); |
if (decPlaces > 0) { |
numberSB.append('.'); |
for (int i = 0; i < decPlaces; i++) |
numberSB.append('0'); |
} |
} |
final Attribute minExpAttr = elem.getAttribute("min-exponent-digits", numberNS); |
if (minExpAttr != null) { |
numberSB.append('E'); |
for (int i = 0; i < Integer.parseInt(minExpAttr.getValue()); i++) |
numberSB.append('0'); |
} |
final DecimalFormat decFormat = new DecimalFormat(numberSB.toString()); |
// Java always use HALF_EVEN |
decFormat.setRoundingMode(RoundingMode.HALF_UP); |
decFormat.setGroupingUsed(grouping); |
// needed since the default size is overwritten by the pattern |
decFormat.setGroupingSize(DEFAULT_GROUPING_SIZE); |
decFormat.setDecimalSeparatorAlwaysShown(decSeparatorAlwaysShown); |
String res = decFormat.format(NumberUtils.divide(n, factor)); |
// java only puts the minus sign, OO also puts the plus sign |
if (minExpAttr != null) { |
final Matcher m = EXP_PATTERN.matcher(res); |
if (m.find()) |
res = res.substring(0, m.start()) + "E+" + m.group(1); |
} |
if (embeddedTextByPosition.size() > 0) { |
final int intDigits = Math.max(minIntDig, NumberUtils.intDigits(n)); |
// each time we insert text the decimal point moves |
int offset = 0; |
// sorted descending to avoid overwriting |
for (Entry<Integer, String> e : embeddedTextByPosition.entrySet()) { |
final String embeddedText = e.getValue(); |
// the text will be before this index |
final int index = Math.max(0, offset + intDigits - e.getKey().intValue()); |
res = res.substring(0, index) + embeddedText + res.substring(index); |
offset += embeddedText.length(); |
} |
} |
return res; |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/openoffice/style/data/CurrencyStyle.java |
---|
New file |
0,0 → 1,67 |
/* |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
* |
* Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved. |
* |
* The contents of this file are subject to the terms of the GNU General Public License Version 3 |
* only ("GPL"). You may not use this file except in compliance with the License. You can obtain a |
* copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific |
* language governing permissions and limitations under the License. |
* |
* When distributing the software, include this License Header Notice in each file. |
*/ |
package org.openconcerto.openoffice.style.data; |
import org.openconcerto.openoffice.ODPackage; |
import org.openconcerto.openoffice.XMLVersion; |
import org.openconcerto.openoffice.spreadsheet.CellStyle; |
import java.text.DecimalFormatSymbols; |
import java.util.List; |
import org.jdom.Element; |
import org.jdom.Namespace; |
// from section 16.27.7 in v1.2-cs01-part1 |
public class CurrencyStyle extends DataStyle { |
public static final DataStyleDesc<CurrencyStyle> DESC = new DataStyleDesc<CurrencyStyle>(CurrencyStyle.class, XMLVersion.OD, "currency-style", "N") { |
@Override |
public CurrencyStyle create(ODPackage pkg, Element e) { |
return new CurrencyStyle(pkg, e); |
} |
}; |
public CurrencyStyle(final ODPackage pkg, Element elem) { |
super(pkg, elem, Number.class); |
} |
@Override |
public String format(Object o, CellStyle defaultStyle, boolean lenient) { |
final Number n = (Number) o; |
final Namespace numberNS = this.getElement().getNamespace(); |
final StringBuilder sb = new StringBuilder(); |
@SuppressWarnings("unchecked") |
final List<Element> children = this.getElement().getChildren(); |
for (final Element elem : children) { |
if (elem.getNamespace().equals(numberNS)) { |
if (elem.getName().equals("text")) { |
sb.append(elem.getText()); |
} else if (elem.getName().equals("number")) { |
// ATTN OpenOffice Fix (it generates <text>-</text>, so we have to use the |
// absolute value) |
final int multiplier = n.doubleValue() > 0 ? 1 : -1; |
sb.append(formatNumberOrScientificNumber(elem, n, multiplier, defaultStyle)); |
} else if (elem.getName().equals("currency-symbol")) { |
if (elem.getTextTrim().length() > 0) { |
sb.append(elem.getText()); |
} else { |
sb.append(new DecimalFormatSymbols(DateStyle.getLocale(elem)).getCurrencySymbol()); |
} |
} |
} |
} |
return sb.toString(); |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/openoffice/style/data/DateStyle.java |
---|
New file |
0,0 → 1,179 |
/* |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
* |
* Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved. |
* |
* The contents of this file are subject to the terms of the GNU General Public License Version 3 |
* only ("GPL"). You may not use this file except in compliance with the License. You can obtain a |
* copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific |
* language governing permissions and limitations under the License. |
* |
* When distributing the software, include this License Header Notice in each file. |
*/ |
package org.openconcerto.openoffice.style.data; |
import org.openconcerto.openoffice.ODPackage; |
import org.openconcerto.openoffice.StyleProperties; |
import org.openconcerto.openoffice.XMLVersion; |
import org.openconcerto.openoffice.spreadsheet.CellStyle; |
import java.math.BigDecimal; |
import java.text.DecimalFormat; |
import java.text.DecimalFormatSymbols; |
import java.text.SimpleDateFormat; |
import java.util.Calendar; |
import java.util.Date; |
import java.util.List; |
import java.util.Locale; |
import org.jdom.Attribute; |
import org.jdom.Element; |
import org.jdom.Namespace; |
// from section 16.27.10 in v1.2-cs01-part1 |
public class DateStyle extends DataStyle { |
// see http://download.oracle.com/javase/6/docs/technotes/guides/intl/calendar.doc.html |
private static final Locale BUDDHIST_LOCALE = new Locale("th", "TH"); |
private static final Locale JAPANESE_LOCALE = new Locale("ja", "JP", "JP"); |
private static final Locale GREGORIAN_LOCALE = new Locale("fr", "FR"); |
public static final DataStyleDesc<DateStyle> DESC = new DataStyleDesc<DateStyle>(DateStyle.class, XMLVersion.OD, "date-style", "N") { |
@Override |
public DateStyle create(ODPackage pkg, Element e) { |
return new DateStyle(pkg, e); |
} |
}; |
private static final boolean isShort(final Element elem) { |
return "short".equals(elem.getAttributeValue("style", elem.getNamespace("number"))); |
} |
public static final Locale getLocale(final Element elem) { |
final Locale res; |
final String country = elem.getAttributeValue("country", elem.getNamespace()); |
final String lang = elem.getAttributeValue("language", elem.getNamespace()); |
if (lang != null) { |
res = new Locale(lang, country == null ? "" : country); |
} else { |
res = Locale.getDefault(); |
} |
return res; |
} |
private static final Locale getCalendarLocale(final Element elem, Locale defaultLocale) { |
final Locale res; |
final String cal = elem.getAttributeValue("calendar", elem.getNamespace()); |
if (cal == null) { |
res = defaultLocale; |
} else if ("buddhist".equals(cal)) { |
res = BUDDHIST_LOCALE; |
} else if ("gengou".equals(cal)) { |
res = JAPANESE_LOCALE; |
} else if ("gregorian".equals(cal)) { |
res = GREGORIAN_LOCALE; |
} else { |
throw new IllegalArgumentException("Unsupported calendar : " + cal); |
} |
return res; |
} |
private static final Locale getCalendarLocale(final Locale locale) { |
final Locale res; |
if (locale.equals(BUDDHIST_LOCALE) || locale.equals(JAPANESE_LOCALE)) { |
res = locale; |
} else { |
res = GREGORIAN_LOCALE; |
} |
return res; |
} |
public DateStyle(final ODPackage pkg, Element elem) { |
super(pkg, elem, Date.class); |
} |
@Override |
public String format(Object o, CellStyle defaultStyle, boolean lenient) { |
final Date d = o instanceof Calendar ? ((Calendar) o).getTime() : (Date) o; |
final Namespace numberNS = this.getElement().getNamespace(); |
final Locale styleLocale = getLocale(getElement()); |
final Locale styleCalendarLocale = getCalendarLocale(styleLocale); |
final StringBuilder res = new StringBuilder(); |
Locale currentCalendarLocale = styleCalendarLocale; |
final StringBuilder sb = new StringBuilder(); |
@SuppressWarnings("unchecked") |
final List<Element> children = this.getElement().getChildren(); |
for (final Element elem : children) { |
if (elem.getNamespace().equals(numberNS)) { |
final Locale calendarLocaleElem = getCalendarLocale(elem, styleCalendarLocale); |
if (!calendarLocaleElem.equals(currentCalendarLocale)) { |
if (sb.length() > 0) { |
res.append(new SimpleDateFormat(sb.toString(), currentCalendarLocale).format(d)); |
sb.setLength(0); |
} |
currentCalendarLocale = calendarLocaleElem; |
} |
if (elem.getName().equals("text")) { |
DataStyle.addStringLiteral(sb, elem.getText()); |
} else if (elem.getName().equals("era")) { |
sb.append(isShort(elem) ? "G" : "GGGG"); |
} else if (elem.getName().equals("year")) { |
sb.append(isShort(elem) ? "yy" : "yyyy"); |
} else if (elem.getName().equals("quarter")) { |
final int quarter = Calendar.getInstance(GREGORIAN_LOCALE).get(Calendar.MONTH) / 3 + 1; |
// TODO localize and honor short/long style |
reportError("Quarters are not localized", lenient); |
DataStyle.addStringLiteral(sb, isShort(elem) ? "Q" + quarter : "Q" + quarter); |
} else if (elem.getName().equals("month")) { |
final Attribute possessive = elem.getAttribute("possessive-form", numberNS); |
if (possessive != null) |
reportError("Ignoring " + possessive, lenient); |
if (!StyleProperties.parseBoolean(elem.getAttributeValue("textual", numberNS), false)) |
sb.append(isShort(elem) ? "M" : "MM"); |
else |
sb.append(isShort(elem) ? "MMM" : "MMMM"); |
} else if (elem.getName().equals("week-of-year")) { |
sb.append("w"); |
} else if (elem.getName().equals("day")) { |
sb.append(isShort(elem) ? "d" : "dd"); |
} else if (elem.getName().equals("day-of-week")) { |
sb.append(isShort(elem) ? "E" : "EEEE"); |
} else if (elem.getName().equals("am-pm")) { |
sb.append("a"); |
} else if (elem.getName().equals("hours")) { |
// see 16.27.22 : If a <number:am-pm> element is contained in a date or time |
// style, hours are displayed using values from 1 to 12 only. |
if (getElement().getChild("am-pm", numberNS) == null) |
sb.append(isShort(elem) ? "H" : "HH"); |
else |
sb.append(isShort(elem) ? "h" : "hh"); |
} else if (elem.getName().equals("minutes")) { |
sb.append(isShort(elem) ? "m" : "mm"); |
} else if (elem.getName().equals("seconds")) { |
sb.append(isShort(elem) ? "s" : "ss"); |
final int decPlaces = StyleProperties.parseInt(elem.getAttributeValue("decimal-places", numberNS), 0); |
if (decPlaces > 0) { |
// use styleLocale since <seconds> hasn't @calendar |
final Calendar cal = Calendar.getInstance(styleLocale); |
cal.setTime(d); |
final DecimalFormat decFormat = new DecimalFormat(); |
decFormat.setDecimalFormatSymbols(new DecimalFormatSymbols(styleLocale)); |
decFormat.setMinimumIntegerDigits(0); |
decFormat.setMinimumFractionDigits(decPlaces); |
decFormat.setMaximumFractionDigits(decPlaces); |
final BigDecimal secondFractions = new BigDecimal(cal.get(Calendar.MILLISECOND)).movePointLeft(3); |
assert secondFractions.compareTo(BigDecimal.ONE) < 0; |
// .12 or .578 |
final String fractionPart = decFormat.format(secondFractions); |
DataStyle.addStringLiteral(sb, fractionPart); |
} |
} |
} |
} |
return new SimpleDateFormat(sb.toString(), currentCalendarLocale).format(d); |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/openoffice/style/data/TimeStyle.java |
---|
New file |
0,0 → 1,43 |
/* |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
* |
* Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved. |
* |
* The contents of this file are subject to the terms of the GNU General Public License Version 3 |
* only ("GPL"). You may not use this file except in compliance with the License. You can obtain a |
* copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific |
* language governing permissions and limitations under the License. |
* |
* When distributing the software, include this License Header Notice in each file. |
*/ |
package org.openconcerto.openoffice.style.data; |
import org.openconcerto.openoffice.ODPackage; |
import org.openconcerto.openoffice.XMLVersion; |
import org.openconcerto.openoffice.spreadsheet.CellStyle; |
import javax.xml.datatype.Duration; |
import org.jdom.Element; |
// from section 16.27.18 in v1.2-cs01-part1 |
public class TimeStyle extends DataStyle { |
public static final DataStyleDesc<TimeStyle> DESC = new DataStyleDesc<TimeStyle>(TimeStyle.class, XMLVersion.OD, "time-style", "N") { |
@Override |
public TimeStyle create(ODPackage pkg, Element e) { |
return new TimeStyle(pkg, e); |
} |
}; |
public TimeStyle(final ODPackage pkg, Element elem) { |
super(pkg, elem, Duration.class); |
} |
@Override |
public String format(Object o, CellStyle defaultStyle, boolean lenient) { |
// TODO time |
throw new UnsupportedOperationException(DESC.getElementName() + " unsupported"); |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/openoffice/style/data/BooleanStyle.java |
---|
New file |
0,0 → 1,58 |
/* |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
* |
* Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved. |
* |
* The contents of this file are subject to the terms of the GNU General Public License Version 3 |
* only ("GPL"). You may not use this file except in compliance with the License. You can obtain a |
* copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific |
* language governing permissions and limitations under the License. |
* |
* When distributing the software, include this License Header Notice in each file. |
*/ |
package org.openconcerto.openoffice.style.data; |
import org.openconcerto.openoffice.ODPackage; |
import org.openconcerto.openoffice.XMLVersion; |
import org.openconcerto.openoffice.spreadsheet.CellStyle; |
import java.util.List; |
import org.jdom.Element; |
import org.jdom.Namespace; |
// from section 16.27.23 in v1.2-cs01-part1 |
public class BooleanStyle extends DataStyle { |
public static final DataStyleDesc<BooleanStyle> DESC = new DataStyleDesc<BooleanStyle>(BooleanStyle.class, XMLVersion.OD, "boolean-style", "N") { |
@Override |
public BooleanStyle create(ODPackage pkg, Element e) { |
return new BooleanStyle(pkg, e); |
} |
}; |
public BooleanStyle(final ODPackage pkg, Element elem) { |
super(pkg, elem, Boolean.class); |
} |
@Override |
public String format(Object o, CellStyle defaultStyle, boolean lenient) { |
final Namespace numberNS = this.getElement().getNamespace(); |
final StringBuilder sb = new StringBuilder(); |
@SuppressWarnings("unchecked") |
final List<Element> children = this.getElement().getChildren(); |
for (final Element elem : children) { |
if (elem.getNamespace().equals(numberNS)) { |
if (elem.getName().equals("text")) { |
sb.append(elem.getText()); |
} else if (elem.getName().equals("boolean")) { |
// TODO localize |
reportError("Boolean not localized", lenient); |
sb.append(o.toString()); |
} |
} |
} |
return sb.toString(); |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/openoffice/style/PageLayoutStyle.java |
---|
99,7 → 99,7 |
} |
private final BigDecimal getLengthAttr(final String attrName, final String attrNS, final LengthUnit in) { |
return LengthUnit.parseLength(getElement().getAttributeValue(attrName, this.getNS(attrNS)), in); |
return LengthUnit.parseLength(getAttributeValue(attrName, this.getNS(attrNS)), in); |
} |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/openoffice/style/SideStyleProperties.java |
---|
69,12 → 69,12 |
} |
protected final String getSideAttribute(final Side s, final String attrName, final Namespace ns) { |
final String allBorder = getElement().getAttributeValue(attrName, ns); |
final String allBorder = getAttributeValue(attrName, ns); |
final String res; |
if (allBorder != null) |
res = allBorder; |
else |
res = getElement().getAttributeValue(attrName + "-" + s.name().toLowerCase(), ns); |
res = getAttributeValue(attrName + "-" + s.name().toLowerCase(), ns); |
return res; |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/openoffice/OOXML.java |
---|
254,7 → 254,7 |
return new Element("span", getVersion().getTEXT()).setContent(encodeWSasList(s)); |
} |
private final List<Content> encodeWSasList(final String s) { |
public final List<Content> encodeWSasList(final String s) { |
final List<Content> res = new ArrayList<Content>(); |
final Matcher m = Pattern.compile("\n|\t| {2,}").matcher(s); |
int last = 0; |
/trunk/OpenConcerto/src/org/openconcerto/openoffice/StyleDesc.java |
---|
75,6 → 75,7 |
// need version since each one might have different attributes and elements (plus we need it |
// anyway for the XPath, otherwise it fails when searching for an inexistant namespace) |
private final XMLVersion version; |
private Namespace elemNS; |
private final String elemName, baseName; |
// { attribute -> element } |
private final CollectionMap<String, String> refElements; |
90,6 → 91,7 |
super(); |
this.clazz = clazz; |
this.version = version; |
this.elemNS = version.getSTYLE(); |
this.elemName = elemName; |
this.baseName = baseName; |
this.refElements = new CollectionMap<String, String>(); |
108,6 → 110,14 |
return this.version; |
} |
protected final void setElementNS(Namespace elemNS) { |
this.elemNS = elemNS; |
} |
public final Namespace getElementNS() { |
return this.elemNS; |
} |
/** |
* The name of the XML element for this type of style. |
* |
163,11 → 173,14 |
} |
// e.g. { "text:style-name" -> ["text:h", "text:p"] } |
// if a property of the style is changed it will affect only the referent element |
protected final CollectionMap<String, String> getRefElementsMap() { |
return this.refElements; |
} |
// e.g. { "table:default-cell-style-name" -> ["table:table-column", "table:table-row"] } |
// if a property of the style is changed it will affect multiple cells even if only one element |
// (e.g. a column) references the style |
protected final CollectionMap<String, String> getMultiRefElementsMap() { |
return this.multiRefElements; |
} |
/trunk/OpenConcerto/src/org/openconcerto/openoffice/Style.java |
---|
20,6 → 20,7 |
import org.openconcerto.openoffice.spreadsheet.RowStyle; |
import org.openconcerto.openoffice.spreadsheet.TableStyle; |
import org.openconcerto.openoffice.style.PageLayoutStyle; |
import org.openconcerto.openoffice.style.data.DataStyle; |
import org.openconcerto.openoffice.text.ParagraphStyle; |
import org.openconcerto.openoffice.text.TextStyle; |
import org.openconcerto.utils.CollectionMap; |
48,18 → 49,20 |
private static final Map<XMLVersion, Map<String, StyleDesc<?>>> elemName2Desc; |
private static final Map<XMLVersion, Map<Class<? extends Style>, StyleDesc<?>>> class2Desc; |
private static boolean descsLoaded = false; |
private static final Map<XMLVersion, Map<Tuple2<String, String>, StyleDesc<?>>> attribute2Desc; |
// need a CollectionMap e.g. [ "style:style", "style:data-style-name" ] -> |
// DataStyle.DATA_STYLES_DESCS |
private static final Map<XMLVersion, CollectionMap<Tuple2<String, String>, StyleDesc<?>>> attribute2Desc; |
static { |
final int versionsCount = XMLVersion.values().length; |
family2Desc = new HashMap<XMLVersion, Map<String, StyleDesc<?>>>(versionsCount); |
elemName2Desc = new HashMap<XMLVersion, Map<String, StyleDesc<?>>>(versionsCount); |
class2Desc = new HashMap<XMLVersion, Map<Class<? extends Style>, StyleDesc<?>>>(versionsCount); |
attribute2Desc = new HashMap<XMLVersion, Map<Tuple2<String, String>, StyleDesc<?>>>(versionsCount); |
attribute2Desc = new HashMap<XMLVersion, CollectionMap<Tuple2<String, String>, StyleDesc<?>>>(versionsCount); |
for (final XMLVersion v : XMLVersion.values()) { |
family2Desc.put(v, new HashMap<String, StyleDesc<?>>()); |
elemName2Desc.put(v, new HashMap<String, StyleDesc<?>>()); |
class2Desc.put(v, new HashMap<Class<? extends Style>, StyleDesc<?>>()); |
attribute2Desc.put(v, new HashMap<Tuple2<String, String>, StyleDesc<?>>(128)); |
attribute2Desc.put(v, new CollectionMap<Tuple2<String, String>, StyleDesc<?>>(128)); |
} |
} |
73,6 → 76,8 |
registerAllVersions(TableStyle.DESC); |
registerAllVersions(TextStyle.DESC); |
registerAllVersions(ParagraphStyle.DESC); |
for (final StyleDesc<?> d : DataStyle.DATA_STYLES_DESCS) |
registerAllVersions(d); |
register(GraphicStyle.DESC); |
register(GraphicStyle.DESC_OO); |
register(PageLayoutStyle.DESC); |
128,8 → 133,8 |
* @param version the version. |
* @return the mapping from attribute to description. |
*/ |
private static Map<Tuple2<String, String>, StyleDesc<?>> getAttr2Desc(final XMLVersion version) { |
final Map<Tuple2<String, String>, StyleDesc<?>> map = attribute2Desc.get(version); |
private static CollectionMap<Tuple2<String, String>, StyleDesc<?>> getAttr2Desc(final XMLVersion version) { |
final CollectionMap<Tuple2<String, String>, StyleDesc<?>> map = attribute2Desc.get(version); |
if (map.isEmpty()) { |
for (final StyleDesc<?> desc : getDesc(version)) { |
fillMap(map, desc, desc.getRefElementsMap()); |
140,13 → 145,11 |
return map; |
} |
private static void fillMap(final Map<Tuple2<String, String>, StyleDesc<?>> map, final StyleDesc<?> desc, final CollectionMap<String, String> elemsByAttrs) { |
private static void fillMap(final CollectionMap<Tuple2<String, String>, StyleDesc<?>> map, final StyleDesc<?> desc, final CollectionMap<String, String> elemsByAttrs) { |
for (final Entry<String, Collection<String>> e : elemsByAttrs.entrySet()) { |
for (final String elementName : e.getValue()) { |
final Tuple2<String, String> key = Tuple2.create(elementName, e.getKey()); |
final StyleDesc<?> previous = map.put(key, desc); |
if (previous != null) |
throw new IllegalStateException("Duplicate desc for " + key + " : " + previous + " and " + desc); |
map.put(key, desc); |
} |
} |
} |
195,12 → 198,24 |
* <code><style:page-layout style:name="pm1"></code>. |
*/ |
public static Element getReferencedStyleElement(final ODPackage pkg, final Attribute styleAttr) { |
final Style res = getReferencedStyle(pkg, styleAttr); |
if (res != null) |
return res.getElement(); |
else |
return null; |
} |
public static Style getReferencedStyle(final ODPackage pkg, final Attribute styleAttr) { |
if (styleAttr == null) |
return null; |
assert styleAttr.getDocument() == pkg.getDocument(RootElement.CONTENT.getZipEntry()) || styleAttr.getDocument() == pkg.getDocument(RootElement.STYLES.getZipEntry()) : "attribute not defined in either the content or the styles of " |
+ pkg; |
final StyleDesc<?> desc = getAttr2Desc(pkg.getVersion()).get(Tuple2.create(styleAttr.getParent().getQualifiedName(), styleAttr.getQualifiedName())); |
if (desc != null) { |
return pkg.getStyle(styleAttr.getDocument(), desc, styleAttr.getValue()); |
} else |
final Collection<StyleDesc<?>> descs = getAttr2Desc(pkg.getVersion()).getNonNull(Tuple2.create(styleAttr.getParent().getQualifiedName(), styleAttr.getQualifiedName())); |
for (final StyleDesc<?> desc : descs) { |
final Element res = pkg.getStyle(styleAttr.getDocument(), desc, styleAttr.getValue()); |
if (res != null) |
return desc.create(pkg, res); |
} |
return null; |
} |
208,6 → 223,10 |
return getStyleDesc(clazz, version, true); |
} |
public static <S extends StyleStyle> StyleStyleDesc<S> getStyleStyleDesc(Class<S> clazz, final XMLVersion version) { |
return (StyleStyleDesc<S>) getStyleDesc(clazz, version); |
} |
@SuppressWarnings("unchecked") |
private static <S extends Style> StyleDesc<S> getStyleDesc(Class<S> clazz, final XMLVersion version, final boolean mustExist) { |
loadDescs(); |
257,13 → 276,21 |
this.name = this.getElement().getAttributeValue("name", this.getSTYLE()); |
this.ns = this.pkg.getFormatVersion(); |
this.desc = getNonNullStyleDesc(this.getClass(), this.ns.getXMLVersion(), styleElem, getName()); |
if (!this.desc.getElementName().equals(this.getElement().getName())) |
throw new IllegalArgumentException("expected " + this.desc.getElementName() + " but got " + this.getElement().getName() + " for " + styleElem); |
checkElemName(); |
// assert that styleElem is in pkg (and thus have the same version) |
assert this.pkg.getXMLFile(getElement().getDocument()) != null; |
assert this.pkg.getFormatVersion().equals(XMLFormatVersion.get(getElement().getDocument())); |
} |
protected void checkElemName() { |
if (!this.desc.getElementName().equals(this.getElement().getName())) |
throw new IllegalArgumentException("expected " + this.desc.getElementName() + " but got " + this.getElement().getName() + " for " + getElement()); |
} |
protected final ODPackage getPackage() { |
return this.pkg; |
} |
protected final Namespace getSTYLE() { |
return this.getElement().getNamespace("style"); |
} |
291,9 → 318,13 |
* @return the matching properties, eg <text-properties>. |
*/ |
public final Element getFormattingProperties(final String family) { |
return getFormattingProperties(family, true); |
} |
public final Element getFormattingProperties(final String family, final boolean create) { |
final Element elem = this.ns.getXML().createFormattingProperties(family); |
Element res = this.getElement().getChild(elem.getName(), elem.getNamespace()); |
if (res == null) { |
if (res == null && create) { |
res = elem; |
this.getElement().addContent(res); |
} |
352,6 → 383,8 |
final ODXMLDocument xmlFile = this.pkg.getXMLFile(this.getElement().getDocument()); |
final String unusedName = xmlFile.findUnusedName(this.desc, this.desc.getBaseName()); |
final Element clone = (Element) this.getElement().clone(); |
// needed if this is a default-style |
clone.setName(this.desc.getElementName()); |
clone.setAttribute("name", unusedName, this.getSTYLE()); |
JDOMUtils.insertAfter(this.getElement(), singleton(clone)); |
return this.desc.create(this.pkg, clone); |
/trunk/OpenConcerto/src/org/openconcerto/openoffice/text/TextStyle.java |
---|
16,6 → 16,7 |
import static java.util.Arrays.asList; |
import org.openconcerto.openoffice.ODPackage; |
import org.openconcerto.openoffice.OOUtils; |
import org.openconcerto.openoffice.Style; |
import org.openconcerto.openoffice.StyleProperties; |
import org.openconcerto.openoffice.StyleStyle; |
import org.openconcerto.openoffice.StyleStyleDesc; |
64,12 → 65,12 |
// cf style-text-properties-content-strict in the relaxNG |
public static class StyleTextProperties extends StyleProperties { |
public StyleTextProperties(StyleStyle style) { |
public StyleTextProperties(Style style) { |
super(style, DESC.getFamily()); |
} |
public final Color getColor() { |
return OOUtils.decodeRGB(this.getElement().getAttributeValue("color", this.getNS("fo"))); |
return OOUtils.decodeRGB(this.getAttributeValue("color", this.getNS("fo"))); |
} |
public final void setColor(Color color) { |
77,19 → 78,19 |
} |
public final String getFontName() { |
return this.getElement().getAttributeValue("font-name", this.getElement().getNamespace("style")); |
return this.getAttributeValue("font-name", this.getElement().getNamespace("style")); |
} |
public final String getLanguage() { |
return this.getElement().getAttributeValue("language", this.getNS("fo")); |
return this.getAttributeValue("language", this.getNS("fo")); |
} |
public final String getCountry() { |
return this.getElement().getAttributeValue("country", this.getNS("fo")); |
return this.getAttributeValue("country", this.getNS("fo")); |
} |
public final String getWeight() { |
return this.getElement().getAttributeValue("font-weight", this.getNS("fo")); |
return this.getAttributeValue("font-weight", this.getNS("fo")); |
} |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/openoffice/text/ParagraphStyle.java |
---|
78,7 → 78,7 |
} |
public final String getAlignment() { |
return getElement().getAttributeValue("text-align", this.getNS("fo")); |
return getAttributeValue("text-align", this.getNS("fo")); |
} |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/openoffice/text/Heading.java |
---|
13,6 → 13,7 |
package org.openconcerto.openoffice.text; |
import org.openconcerto.openoffice.StyleProperties; |
import org.openconcerto.openoffice.XMLVersion; |
import org.jdom.Element; |
39,7 → 40,7 |
public final int getLevel() { |
final String attr = this.getElement().getAttributeValue("outline-level", this.getElement().getNamespace()); |
// see 4.1.1 |
return attr == null ? 1 : Integer.parseInt(attr); |
return StyleProperties.parseInt(attr, 1); |
} |
public final void setLevel(int level) { |
/trunk/OpenConcerto/src/org/openconcerto/openoffice/ODPackage.java |
---|
360,6 → 360,21 |
return null; |
} |
/** |
* The XML document where are located the common styles. |
* |
* @return the document where are located styles. |
*/ |
public final ODXMLDocument getStyles() { |
final ODXMLDocument res; |
if (this.isSingle()) |
res = this.getContent(); |
else { |
res = this.getXMLFile(STYLES.getZipEntry()); |
} |
return res; |
} |
public final ODXMLDocument getContent() { |
return this.getXMLFile(CONTENT.getZipEntry()); |
} |
427,6 → 442,11 |
return res; |
} |
public final Element getDefaultStyle(final StyleStyleDesc<?> desc) { |
// from 16.4 of OpenDocument-v1.2-cs01-part1, default-style only usable in office:styles |
return getStyles().getDefaultStyle(desc); |
} |
// *** setter |
public void putFile(String entry, Object data) { |
/trunk/OpenConcerto/src/org/openconcerto/openoffice/StyleStyleDesc.java |
---|
28,9 → 28,10 |
public abstract class StyleStyleDesc<S extends StyleStyle> extends StyleDesc<S> { |
static final String ELEMENT_NAME = "style"; |
static final String ELEMENT_DEFAULT_NAME = "default-style"; |
static String getFamily(final Element styleElem) { |
assert styleElem.getName().equals(ELEMENT_NAME); |
assert styleElem.getName().equals(ELEMENT_NAME) || styleElem.getName().equals(ELEMENT_DEFAULT_NAME); |
return styleElem.getAttributeValue("family", styleElem.getNamespace("style")); |
} |
71,4 → 72,9 |
super.initStyle(elem); |
elem.setAttribute("family", this.getFamily(), elem.getNamespace()); |
} |
public final S findDefaultStyle(final ODPackage pkg) { |
final Element styleElem = pkg.getDefaultStyle(this); |
return styleElem == null ? null : this.create(pkg, styleElem); |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/openoffice/StyleStyle.java |
---|
32,6 → 32,13 |
} |
@Override |
protected void checkElemName() { |
// allow use of default styles |
if (!StyleStyleDesc.ELEMENT_DEFAULT_NAME.equals(this.getElement().getName()) && !this.getDesc().getElementName().equals(this.getElement().getName())) |
throw new IllegalArgumentException("expected a default style (" + StyleStyleDesc.ELEMENT_DEFAULT_NAME + ") or " + this.getDesc().getElementName() + " but got " + getElement()); |
} |
@Override |
protected StyleStyleDesc<?> getDesc() { |
return (StyleStyleDesc<?>) super.getDesc(); |
} |
44,6 → 51,10 |
return this.getFormattingProperties(this.getFamily()); |
} |
public final StyleStyle getDefaultStyle() { |
return this.getDesc().findDefaultStyle(getPackage()); |
} |
@Override |
public final boolean equals(Object obj) { |
if (!(obj instanceof StyleStyle) || !super.equals(obj)) |
/trunk/OpenConcerto/src/org/openconcerto/openoffice/ODXMLDocument.java |
---|
218,12 → 218,12 |
// " | ./office:master-styles/style:master-page/" + stylePath); |
final Element root = this.getDocument().getRootElement(); |
final Namespace office = getVersion().getOFFICE(); |
Element res = this.findStyleChild(root.getChild("styles", office), styleDesc.getElementName(), family, name); |
Element res = this.findStyleChild(root.getChild("styles", office), styleDesc.getElementNS(), styleDesc.getElementName(), family, name); |
if (res != null) { |
return res; |
} |
res = this.findStyleChild(root.getChild("automatic-styles", office), styleDesc.getElementName(), family, name); |
res = this.findStyleChild(root.getChild("automatic-styles", office), styleDesc.getElementNS(), styleDesc.getElementName(), family, name); |
if (res != null) { |
return res; |
} |
230,7 → 230,7 |
final Element masterStyles = root.getChild("master-styles", office); |
if (masterStyles != null) { |
res = this.findStyleChild(root.getChild("master-page", getVersion().getSTYLE()), styleDesc.getElementName(), family, name); |
res = this.findStyleChild(root.getChild("master-page", getVersion().getSTYLE()), styleDesc.getElementNS(), styleDesc.getElementName(), family, name); |
if (res != null) { |
return res; |
} |
239,16 → 239,22 |
return null; |
} |
private final Element findStyleChild(final Element styles, final String elemName, final String family, final String name) { |
public final Element getDefaultStyle(final StyleStyleDesc<?> styleDesc) { |
final Element root = this.getDocument().getRootElement(); |
final Namespace office = getVersion().getOFFICE(); |
return this.findStyleChild(root.getChild("styles", office), styleDesc.getElementNS(), StyleStyleDesc.ELEMENT_DEFAULT_NAME, styleDesc.getFamily(), null); |
} |
private final Element findStyleChild(final Element styles, final Namespace elemNS, final String elemName, final String family, final String name) { |
if (styles == null) |
return null; |
final Namespace styleNS = getVersion().getSTYLE(); |
// from JDOM : traversal through the List is best done with a Iterator |
for (final Object o : styles.getChildren(elemName, styleNS)) { |
for (final Object o : styles.getChildren(elemName, elemNS)) { |
final Element styleElem = (Element) o; |
// name first since it is more specific (and often includes family, eg "co2") |
if (name.equals(styleElem.getAttributeValue("name", styleNS)) && (family == null || family.equals(StyleStyleDesc.getFamily(styleElem)))) { |
if ((name == null || name.equals(styleElem.getAttributeValue("name", styleNS))) && (family == null || family.equals(StyleStyleDesc.getFamily(styleElem)))) { |
return styleElem; |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/openoffice/spreadsheet/ColumnStyle.java |
---|
13,12 → 13,16 |
package org.openconcerto.openoffice.spreadsheet; |
import org.openconcerto.openoffice.LengthUnit; |
import org.openconcerto.openoffice.ODFrame; |
import org.openconcerto.openoffice.ODPackage; |
import org.openconcerto.openoffice.StyleProperties; |
import org.openconcerto.openoffice.StyleStyle; |
import org.openconcerto.openoffice.StyleStyleDesc; |
import org.openconcerto.openoffice.XMLVersion; |
import java.math.BigDecimal; |
import org.jdom.Element; |
public class ColumnStyle extends StyleStyle { |
31,17 → 35,21 |
} |
}; |
private StyleTableColumnProperties colProps; |
public ColumnStyle(final ODPackage pkg, Element tableColElem) { |
super(pkg, tableColElem); |
} |
public final Float getWidth() { |
final String attr = getFormattingProperties().getAttributeValue("column-width", this.getSTYLE()); |
return attr == null ? null : ODFrame.parseLength(attr, TableStyle.DEFAULT_UNIT); |
public final StyleTableColumnProperties getTableColumnProperties() { |
if (this.colProps == null) |
this.colProps = new StyleTableColumnProperties(this); |
return this.colProps; |
} |
public final String getBreakBefore() { |
return getFormattingProperties().getAttributeValue("break-before", this.getNS().getNS("fo")); |
public final Float getWidth() { |
final BigDecimal res = this.getTableColumnProperties().getWidth(TableStyle.DEFAULT_UNIT); |
return res == null ? null : res.floatValue(); |
} |
void setWidth(float f) { |
53,4 → 61,24 |
void rmRelWidth() { |
getFormattingProperties().removeAttribute("rel-column-width", this.getSTYLE()); |
} |
// see 17.16 of v1.2-cs01-part1 |
public static class StyleTableColumnProperties extends StyleProperties { |
public StyleTableColumnProperties(StyleStyle style) { |
super(style, style.getFamily()); |
} |
public final BigDecimal getWidth(final LengthUnit in) { |
return LengthUnit.parseLength(getAttributeValue("column-width", this.getNS("style")), in); |
} |
public final String getBreakBefore() { |
return getAttributeValue("break-before", this.getNS("fo")); |
} |
public final String getBreakAfter() { |
return getAttributeValue("break-after", this.getNS("fo")); |
} |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/openoffice/spreadsheet/Cell.java |
---|
18,9 → 18,11 |
import org.openconcerto.openoffice.ODDocument; |
import org.openconcerto.openoffice.ODValueType; |
import org.openconcerto.openoffice.OOXML; |
import org.openconcerto.openoffice.XMLFormatVersion; |
import org.openconcerto.openoffice.XMLVersion; |
import org.openconcerto.utils.CollectionUtils; |
import org.openconcerto.xml.JDOMUtils; |
import java.util.ArrayList; |
import java.util.Arrays; |
168,10 → 170,13 |
private String getStringValue(final Element pElem, final boolean ooMode) { |
final StringBuilder sb = new StringBuilder(); |
final Namespace textNS = pElem.getNamespace(); |
final OOXML xml = OOXML.get(getODDocument().getFormatVersion()); |
final Element tabElem = xml.getTab(); |
final Element newLineElem = xml.getLineBreak(); |
// true if the string ends with a space that wasn't expanded from an XML element (e.g. |
// <tab/> or <text:s/>) |
boolean spaceSuffix = false; |
final Iterator iter = pElem.getDescendants(); |
final Iterator<?> iter = pElem.getDescendants(); |
while (iter.hasNext()) { |
final Object o = iter.next(); |
if (o instanceof Text) { |
184,9 → 189,9 |
spaceSuffix = text.endsWith(" "); |
} else if (o instanceof Element) { |
final Element elem = (Element) o; |
if (elem.getName().equals("tab") && elem.getNamespace().equals(textNS)) { |
if (JDOMUtils.equals(elem, tabElem)) { |
sb.append("\t"); |
} else if (elem.getName().equals("line-break") && elem.getNamespace().equals(textNS)) { |
} else if (JDOMUtils.equals(elem, newLineElem)) { |
sb.append("\n"); |
} else if (elem.getName().equals("s") && elem.getNamespace().equals(textNS)) { |
final int count = Integer.valueOf(elem.getAttributeValue("c", textNS, "1")); |
/trunk/OpenConcerto/src/org/openconcerto/openoffice/spreadsheet/CellStyle.java |
---|
14,10 → 14,12 |
package org.openconcerto.openoffice.spreadsheet; |
import org.openconcerto.openoffice.ODPackage; |
import org.openconcerto.openoffice.Style; |
import org.openconcerto.openoffice.StyleStyle; |
import org.openconcerto.openoffice.StyleStyleDesc; |
import org.openconcerto.openoffice.XMLVersion; |
import org.openconcerto.openoffice.style.SideStyleProperties; |
import org.openconcerto.openoffice.style.data.DataStyle; |
import org.openconcerto.openoffice.text.ParagraphStyle.StyleParagraphProperties; |
import org.openconcerto.openoffice.text.TextStyle.StyleTextProperties; |
50,6 → 52,10 |
super(pkg, tableColElem); |
} |
public final DataStyle getDataStyle() { |
return (DataStyle) Style.getReferencedStyle(getPackage(), getElement().getAttribute("data-style-name", getSTYLE())); |
} |
public final Color getBackgroundColor() { |
return getTableCellProperties().getBackgroundColor(); |
} |
84,21 → 90,25 |
} |
public final int getRotationAngle() { |
final String s = this.getElement().getAttributeValue("rotation-angle", this.getElement().getNamespace("style")); |
return s == null ? 0 : Integer.parseInt(s); |
final String s = this.getAttributeValue("rotation-angle", this.getElement().getNamespace("style")); |
return parseInt(s, 0); |
} |
public final boolean isContentPrinted() { |
return parseBoolean(this.getElement().getAttributeValue("print-content", this.getElement().getNamespace("style")), true); |
return parseBoolean(this.getAttributeValue("print-content", this.getElement().getNamespace("style")), true); |
} |
public final boolean isContentRepeated() { |
return parseBoolean(this.getElement().getAttributeValue("repeat-content", this.getElement().getNamespace("style")), false); |
return parseBoolean(this.getAttributeValue("repeat-content", this.getElement().getNamespace("style")), false); |
} |
public final boolean isShrinkToFit() { |
return parseBoolean(this.getElement().getAttributeValue("shrink-to-fit", this.getElement().getNamespace("style")), false); |
return parseBoolean(this.getAttributeValue("shrink-to-fit", this.getElement().getNamespace("style")), false); |
} |
public final Integer getDecimalPlaces() { |
return parseInteger(this.getAttributeValue("decimal-places", this.getElement().getNamespace("style"))); |
} |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/openoffice/spreadsheet/Table.java |
---|
14,6 → 14,8 |
package org.openconcerto.openoffice.spreadsheet; |
import org.openconcerto.openoffice.ODDocument; |
import org.openconcerto.openoffice.Style; |
import org.openconcerto.openoffice.StyleStyleDesc; |
import org.openconcerto.openoffice.XMLVersion; |
import org.openconcerto.openoffice.spreadsheet.SheetTableModel.MutableTableModel; |
import org.openconcerto.utils.CollectionUtils; |
346,9 → 348,17 |
} |
public final CellStyle getStyleAt(int column, int row) { |
return CellStyle.DESC.findStyle(this.getODDocument().getPackage(), this.getElement().getDocument(), this.getStyleNameAt(column, row)); |
return getCellStyleDesc().findStyle(this.getODDocument().getPackage(), this.getElement().getDocument(), this.getStyleNameAt(column, row)); |
} |
protected StyleStyleDesc<CellStyle> getCellStyleDesc() { |
return Style.getStyleStyleDesc(CellStyle.class, getODDocument().getVersion()); |
} |
public final CellStyle getDefaultCellStyle() { |
return getCellStyleDesc().findDefaultStyle(this.getODDocument().getPackage()); |
} |
/** |
* Return the coordinates of cells using the passed style. |
* |
/trunk/OpenConcerto/src/org/openconcerto/openoffice/spreadsheet/RowStyle.java |
---|
13,12 → 13,15 |
package org.openconcerto.openoffice.spreadsheet; |
import org.openconcerto.openoffice.ODFrame; |
import org.openconcerto.openoffice.LengthUnit; |
import org.openconcerto.openoffice.ODPackage; |
import org.openconcerto.openoffice.StyleProperties; |
import org.openconcerto.openoffice.StyleStyle; |
import org.openconcerto.openoffice.StyleStyleDesc; |
import org.openconcerto.openoffice.XMLVersion; |
import java.math.BigDecimal; |
import org.jdom.Element; |
public class RowStyle extends StyleStyle { |
31,12 → 34,35 |
} |
}; |
private StyleTableRowProperties rowProps; |
public RowStyle(final ODPackage pkg, Element tableColElem) { |
super(pkg, tableColElem); |
} |
public final float getHeight() { |
return ODFrame.parseLength(getFormattingProperties().getAttributeValue("row-height", this.getSTYLE()), TableStyle.DEFAULT_UNIT); |
public final StyleTableRowProperties getTableRowProperties() { |
if (this.rowProps == null) |
this.rowProps = new StyleTableRowProperties(this); |
return this.rowProps; |
} |
// see 17.17 of v1.2-cs01-part1 |
public static class StyleTableRowProperties extends StyleProperties { |
public StyleTableRowProperties(StyleStyle style) { |
super(style, style.getFamily()); |
} |
public final BigDecimal getHeight(final LengthUnit in) { |
return LengthUnit.parseLength(getAttributeValue("row-height", this.getNS("style")), in); |
} |
public final String getBreakBefore() { |
return getAttributeValue("break-before", this.getNS("fo")); |
} |
public final String getBreakAfter() { |
return getAttributeValue("break-after", this.getNS("fo")); |
} |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/openoffice/spreadsheet/TableStyle.java |
---|
14,12 → 14,13 |
package org.openconcerto.openoffice.spreadsheet; |
import org.openconcerto.openoffice.LengthUnit; |
import org.openconcerto.openoffice.ODFrame; |
import org.openconcerto.openoffice.ODPackage; |
import org.openconcerto.openoffice.StyleStyle; |
import org.openconcerto.openoffice.StyleStyleDesc; |
import org.openconcerto.openoffice.StyleStyle; |
import org.openconcerto.openoffice.XMLVersion; |
import org.openconcerto.openoffice.style.SideStyleProperties; |
import java.math.BigDecimal; |
import java.util.Arrays; |
import org.jdom.Element; |
35,13 → 36,21 |
} |
}; |
private StyleTableProperties tableProps; |
public TableStyle(final ODPackage pkg, Element tableColElem) { |
super(pkg, tableColElem); |
} |
public final StyleTableProperties getTableProperties() { |
if (this.tableProps == null) |
this.tableProps = new StyleTableProperties(this); |
return this.tableProps; |
} |
public final Float getWidth() { |
final String width = getFormattingProperties().getAttributeValue("width", this.getSTYLE()); |
return width == null ? null : ODFrame.parseLength(width, TableStyle.DEFAULT_UNIT); |
final BigDecimal width = getTableProperties().getWidth(TableStyle.DEFAULT_UNIT); |
return width == null ? null : width.floatValue(); |
} |
void setWidth(float f) { |
48,4 → 57,30 |
getFormattingProperties().setAttribute("width", f + DEFAULT_UNIT.getSymbol(), this.getSTYLE()); |
} |
// see 17.15 of v1.2-cs01-part1 |
public static class StyleTableProperties extends SideStyleProperties { |
public StyleTableProperties(StyleStyle style) { |
super(style, style.getFamily()); |
} |
public final String getRawMargin(final Side s) { |
return getSideAttribute(s, "margin", this.getNS("fo")); |
} |
/** |
* Get the margin of one of the side. |
* |
* @param s which side. |
* @param in the desired unit. |
* @return the margin. |
*/ |
public final BigDecimal getMargin(final Side s, final LengthUnit in) { |
return LengthUnit.parseLength(getRawMargin(s), in); |
} |
public final BigDecimal getWidth(final LengthUnit in) { |
return LengthUnit.parseLength(getAttributeValue("width", this.getNS("style")), in); |
} |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/openoffice/spreadsheet/MutableCell.java |
---|
13,11 → 13,15 |
package org.openconcerto.openoffice.spreadsheet; |
import org.openconcerto.openoffice.Log; |
import org.openconcerto.openoffice.ODDocument; |
import org.openconcerto.openoffice.ODFrame; |
import org.openconcerto.openoffice.ODValueType; |
import org.openconcerto.openoffice.OOXML; |
import org.openconcerto.openoffice.spreadsheet.BytesProducer.ByteArrayProducer; |
import org.openconcerto.openoffice.spreadsheet.BytesProducer.ImageProducer; |
import org.openconcerto.openoffice.style.data.DataStyle; |
import org.openconcerto.utils.ExceptionUtils; |
import org.openconcerto.utils.FileUtils; |
import java.awt.Color; |
27,7 → 31,7 |
import java.text.DateFormat; |
import java.text.DecimalFormat; |
import java.text.NumberFormat; |
import java.text.SimpleDateFormat; |
import java.util.Calendar; |
import java.util.Date; |
import java.util.List; |
44,9 → 48,33 |
*/ |
public class MutableCell<D extends ODDocument> extends Cell<D> { |
static private final DateFormat TextPDateFormat = new SimpleDateFormat("dd/MM/yyyy"); |
static private final NumberFormat TextPFloatFormat = new DecimalFormat(",##0.00"); |
static private final DateFormat TextPDateFormat = DateFormat.getDateInstance(); |
static private final DateFormat TextPTimeFormat = DateFormat.getTimeInstance(); |
static private final NumberFormat TextPFloatFormat = DecimalFormat.getNumberInstance(); |
static private final NumberFormat TextPPercentFormat = DecimalFormat.getPercentInstance(); |
static private final NumberFormat TextPCurrencyFormat = DecimalFormat.getCurrencyInstance(); |
static public String formatNumber(Number n, final CellStyle defaultStyle) { |
return formatNumber(TextPFloatFormat, n, defaultStyle, false); |
} |
static public String formatPercent(Number n, final CellStyle defaultStyle) { |
return formatNumber(TextPPercentFormat, n, defaultStyle, true); |
} |
static public String formatCurrency(Number n, final CellStyle defaultStyle) { |
return formatNumber(TextPCurrencyFormat, n, defaultStyle, true); |
} |
static private String formatNumber(NumberFormat format, Number n, final CellStyle defaultStyle, boolean forceFraction) { |
synchronized (format) { |
final int decPlaces = DataStyle.getDecimalPlaces(defaultStyle); |
format.setMinimumFractionDigits(forceFraction ? decPlaces : 0); |
format.setMaximumFractionDigits(decPlaces); |
return format.format(n); |
} |
} |
MutableCell(Row<D> parent, Element elem) { |
super(parent, elem); |
} |
86,7 → 114,7 |
// try to reuse the first text:p to keep style |
final Element child = this.getElement().getChild("p", getNS().getTEXT()); |
final Element t = child != null ? child : new Element("p", getNS().getTEXT()); |
t.setContent(new Text(value)); |
t.setContent(OOXML.get(this.getODDocument().getFormatVersion()).encodeWSasList(value)); |
this.getElement().setContent(t); |
} |
102,30 → 130,99 |
} |
public void setValue(Object obj) { |
// FIXME use arbitrary textP format, should use the cell format |
// TODO handle all type of objects as in ODUserDefinedMeta |
// setValue(Object o, final ODValueType vt) |
if (obj instanceof Number) |
// 5.2 |
// FIXME voir avec Sylvain : probleme avec le viewer si Integer ou Long le textp ne doit |
// avoir de décimal |
if (obj instanceof Integer || obj instanceof Long) { |
this.setValue(ODValueType.FLOAT, obj, (obj == null) ? "" : obj.toString()); |
final ODValueType type; |
final ODValueType currentType = getValueType(); |
// try to keep current type, since for example a Number can work with FLOAT, PERCENTAGE |
// and CURRENCY |
if (currentType != null && currentType.canFormat(obj.getClass())) { |
type = currentType; |
} else if (obj instanceof Number) { |
type = ODValueType.FLOAT; |
} else if (obj instanceof Date || obj instanceof Calendar) { |
type = ODValueType.DATE; |
} else if (obj instanceof Boolean) { |
type = ODValueType.BOOLEAN; |
} else if (obj instanceof String) { |
type = ODValueType.STRING; |
} else { |
this.setValue(ODValueType.FLOAT, obj, TextPFloatFormat.format(obj)); |
throw new IllegalArgumentException("Couldn't infer type of " + obj); |
} |
else if (obj instanceof Date) |
this.setValue(ODValueType.DATE, obj, TextPDateFormat.format(obj)); |
this.setValue(obj, type, true); |
} |
/** |
* Change the value of this cell. |
* |
* @param obj the new cell value. |
* @param vt the value type. |
* @param lenient <code>false</code> to throw an exception if we can't format according to the |
* ODF, <code>true</code> to try best-effort. |
* @throws UnsupportedOperationException if <code>obj</code> couldn't be formatted. |
*/ |
public void setValue(final Object obj, final ODValueType vt, final boolean lenient) throws UnsupportedOperationException { |
final String text; |
final String formatted = format(obj, lenient); |
if (formatted != null) { |
text = formatted; |
} else { |
// either there were no format or formatting failed |
if (vt == ODValueType.FLOAT) { |
text = formatNumber((Number) obj, getDefaultStyle()); |
} else if (vt == ODValueType.PERCENTAGE) { |
text = formatPercent((Number) obj, getDefaultStyle()); |
} else if (vt == ODValueType.CURRENCY) { |
text = formatCurrency((Number) obj, getDefaultStyle()); |
} else if (vt == ODValueType.DATE) { |
text = TextPDateFormat.format(obj); |
} else if (vt == ODValueType.TIME) { |
text = TextPTimeFormat.format(obj); |
} else if (vt == ODValueType.BOOLEAN) { |
if (lenient) |
text = obj.toString(); |
else |
this.setValue(null, null, obj.toString()); |
throw new UnsupportedOperationException(vt + " not supported"); |
} else if (vt == ODValueType.STRING) { |
text = obj.toString(); |
} else { |
throw new IllegalStateException(vt + " unknown"); |
} |
} |
this.setValue(vt, obj, text); |
} |
// return null if no data style exists, or if one exists but we couldn't use it |
private String format(Object obj, boolean lenient) { |
try { |
final DataStyle ds = getDataStyle(); |
// act like OO, that is if we set a String to a Date cell, change the value and |
// value-type but leave the data-style untouched |
if (ds != null && ds.canFormat(obj.getClass())) |
return ds.format(obj, getDefaultStyle(), lenient); |
} catch (UnsupportedOperationException e) { |
if (lenient) |
Log.get().warning(ExceptionUtils.getStackTrace(e)); |
else |
throw e; |
} |
return null; |
} |
public final DataStyle getDataStyle() { |
final CellStyle s = this.getStyle(); |
return s != null ? getStyle().getDataStyle() : null; |
} |
protected final CellStyle getDefaultStyle() { |
return this.getRow().getSheet().getDefaultCellStyle(); |
} |
public void replaceBy(String oldValue, String newValue) { |
replaceContentBy(this.getElement(), oldValue, newValue); |
} |
private void replaceContentBy(Element l, String oldValue, String newValue) { |
final List content = l.getContent(); |
final List<?> content = l.getContent(); |
for (int i = 0; i < content.size(); i++) { |
final Object obj = content.get(i); |
if (obj instanceof Text) { |
/trunk/OpenConcerto/src/org/openconcerto/openoffice/GraphicStyle.java |
---|
95,19 → 95,19 |
} |
public final String getHorizontalPosition() { |
return this.getElement().getAttributeValue("horizontal-pos", this.getElement().getNamespace("style")); |
return this.getAttributeValue("horizontal-pos", this.getElement().getNamespace("style")); |
} |
public final String getHorizontalRelation() { |
return this.getElement().getAttributeValue("horizontal-rel", this.getElement().getNamespace("style")); |
return this.getAttributeValue("horizontal-rel", this.getElement().getNamespace("style")); |
} |
public final String getVerticalPosition() { |
return this.getElement().getAttributeValue("vertical-pos", this.getElement().getNamespace("style")); |
return this.getAttributeValue("vertical-pos", this.getElement().getNamespace("style")); |
} |
public final String getVerticalRelation() { |
return this.getElement().getAttributeValue("vertical-rel", this.getElement().getNamespace("style")); |
return this.getAttributeValue("vertical-rel", this.getElement().getNamespace("style")); |
} |
/** |
116,7 → 116,7 |
* @return a list that consists of any of the values content, position, or size. |
*/ |
public final List<String> getProtected() { |
final String val = this.getElement().getAttributeValue("protect", this.getElement().getNamespace("style")); |
final String val = this.getAttributeValue("protect", this.getElement().getNamespace("style")); |
if (val == null || "none".equals(val)) |
return Collections.emptyList(); |
else |
124,7 → 124,7 |
} |
public final boolean isContentPrinted() { |
return parseBoolean(this.getElement().getAttributeValue("print-content", this.getElement().getNamespace("style")), true); |
return parseBoolean(this.getAttributeValue("print-content", this.getElement().getNamespace("style")), true); |
} |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/ui/AutoHideTabbedPane.java |
---|
New file |
0,0 → 1,157 |
/* |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
* |
* Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved. |
* |
* The contents of this file are subject to the terms of the GNU General Public License Version 3 |
* only ("GPL"). You may not use this file except in compliance with the License. You can obtain a |
* copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific |
* language governing permissions and limitations under the License. |
* |
* When distributing the software, include this License Header Notice in each file. |
*/ |
package org.openconcerto.ui; |
import org.openconcerto.utils.Tuple2; |
import org.openconcerto.utils.cc.IClosure; |
import java.awt.Component; |
import java.awt.Container; |
import java.awt.GridLayout; |
import java.util.Arrays; |
import java.util.IdentityHashMap; |
import java.util.Map; |
import javax.swing.Icon; |
import javax.swing.JComponent; |
import javax.swing.JPanel; |
import javax.swing.JTabbedPane; |
/** |
* A component like {@link JTabbedPane} but hiding the tab bar when there's only one tab. |
* |
* @author Sylvain CUAZ |
*/ |
public class AutoHideTabbedPane extends JPanel { |
private static final String TITLE_PROP = AutoHideTabbedPane.class.getName() + " title prop"; |
private static final String ICON_PROP = AutoHideTabbedPane.class.getName() + " icon prop"; |
private static final String TOOLTIP_PROP = AutoHideTabbedPane.class.getName() + " tooltip prop"; |
private final JTabbedPane tabbedPane; |
// can't use putClientProperty() since we can't retrieve it from JTabbedPane |
private final Map<JComponent, IClosure<Tuple2<JTabbedPane, Integer>>> customizers; |
public AutoHideTabbedPane() { |
this(new JTabbedPane()); |
} |
public AutoHideTabbedPane(final JTabbedPane tabbedPane) { |
this.tabbedPane = tabbedPane; |
this.customizers = new IdentityHashMap<JComponent, IClosure<Tuple2<JTabbedPane, Integer>>>(); |
this.setLayout(new GridLayout(1, 1)); |
} |
public final void addTab(final String title, final JComponent comp) { |
insertTab(title, null, comp, null, -1); |
} |
/** |
* Insert a tab at the specified index. |
* |
* @param title the title to be displayed in this tab. |
* @param icon the icon to be displayed in this tab, can be <code>null</code>. |
* @param component the component to be displayed when this tab is clicked. |
* @param tip the tooltip to be displayed for this tab, can be <code>null</code>. |
* @param index the position to insert this new tab, -1 meaning at the end. |
*/ |
public final void insertTab(String title, Icon icon, JComponent comp, String tip, final int index) { |
this.insertTab(title, icon, comp, tip, index, null); |
} |
public final void insertTab(String title, Icon icon, JComponent comp, String tip, final int index, final IClosure<Tuple2<JTabbedPane, Integer>> customize) { |
this.customizers.put(comp, customize); |
if (getComponentCount() == 0) { |
putClientProps(title, icon, comp, tip); |
this.add(comp); |
} else { |
JTabbedPane tabbedPane = this.getDisplayedTabbedPane(); |
// if there was no tabbedPane move the current component to it |
if (tabbedPane == null) { |
final JComponent onlyComp = (JComponent) this.getComponent(0); |
this.remove(0); |
tabbedPane = this.tabbedPane; |
tabbedPane.addTab((String) onlyComp.getClientProperty(TITLE_PROP), (Icon) onlyComp.getClientProperty(ICON_PROP), onlyComp, (String) onlyComp.getClientProperty(TOOLTIP_PROP)); |
final IClosure<Tuple2<JTabbedPane, Integer>> closure = this.customizers.get(onlyComp); |
if (closure != null) |
closure.executeChecked(Tuple2.create(tabbedPane, 0)); |
this.add(tabbedPane); |
assert tabbedPane == this.getDisplayedTabbedPane(); |
} |
final int realIndex = index < 0 ? tabbedPane.getTabCount() : index; |
tabbedPane.insertTab(title, icon, comp, tip, realIndex); |
if (customize != null) |
customize.executeChecked(Tuple2.create(tabbedPane, realIndex)); |
} |
assert this.customizers.size() == getTabContainer().getComponentCount(); |
this.revalidate(); |
this.repaint(); |
} |
private final void putClientProps(String title, Icon icon, JComponent comp, String tip) { |
comp.putClientProperty(TITLE_PROP, title); |
comp.putClientProperty(ICON_PROP, icon); |
comp.putClientProperty(TOOLTIP_PROP, tip); |
} |
public final int removeTab(final JComponent comp) { |
if (comp == null) |
throw new NullPointerException("Null component"); |
final int index = Arrays.asList(getTabContainer().getComponents()).indexOf(comp); |
if (index >= 0) |
this.removeTabAt(index); |
return index; |
} |
public final JComponent removeTabAt(final int index) { |
final JComponent res; |
final JTabbedPane tabbedPane = this.getDisplayedTabbedPane(); |
if (tabbedPane == null) { |
res = (JComponent) this.getComponent(index); |
this.remove(index); |
this.customizers.clear(); |
} else { |
res = (JComponent) tabbedPane.getComponentAt(index); |
this.customizers.remove(res); |
tabbedPane.removeTabAt(index); |
// remove the tabbedPane if there's only one tab |
if (tabbedPane.getTabCount() == 1) { |
final JComponent onlyComp = (JComponent) tabbedPane.getComponentAt(0); |
// store tab properties, so that it can be recreated later |
putClientProps(tabbedPane.getTitleAt(0), tabbedPane.getIconAt(0), onlyComp, tabbedPane.getToolTipTextAt(0)); |
tabbedPane.removeTabAt(0); |
this.remove(0); |
this.add(onlyComp); |
} |
} |
assert this.customizers.size() == getTabContainer().getComponentCount(); |
this.revalidate(); |
this.repaint(); |
return res; |
} |
// Allow to access the {@link JTabbedPane}. Note: if you use the result to add a tab, some of |
// its properties might get lost, and if you remove a tab this instance will leak memory |
protected final JTabbedPane getDisplayedTabbedPane() { |
if (this.getComponentCount() == 0) |
return null; |
final Component res = this.getComponent(0); |
return res instanceof JTabbedPane ? (JTabbedPane) res : null; |
} |
private final Container getTabContainer() { |
final JTabbedPane tabbedPane = this.getDisplayedTabbedPane(); |
return tabbedPane == null ? this : tabbedPane; |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/ui/preferences/AbstractProps.java |
---|
99,14 → 99,13 |
return ""; |
} |
public int getIntProperty(String name) { |
public final int getIntProperty(String name) { |
return getIntProperty(name, getDefautIntValue()); |
} |
public final int getIntProperty(String name, int defaultVal) { |
final String property = this.getProperty(name); |
int result; |
if (property == null) |
result = getDefautIntValue(); |
else |
result = Integer.valueOf(property).intValue(); |
return result; |
return property == null ? defaultVal : Integer.valueOf(property).intValue(); |
} |
protected int getDefautIntValue() { |
/trunk/OpenConcerto/src/org/openconcerto/ui/JTime.java |
---|
15,9 → 15,11 |
import org.openconcerto.ui.component.text.TextComponent; |
import org.openconcerto.ui.valuewrapper.ValueWrapper; |
import org.openconcerto.utils.checks.ValidChangeSupport; |
import org.openconcerto.utils.checks.ValidListener; |
import java.awt.BorderLayout; |
import java.beans.PropertyChangeEvent; |
import java.beans.PropertyChangeListener; |
import java.text.SimpleDateFormat; |
import java.util.Calendar; |
64,6 → 66,7 |
private final boolean fillWithCurrentTime; |
private final JFormattedTextField text; |
private final ValidChangeSupport validSupp; |
/** |
* Create the component, empty. |
79,10 → 82,14 |
* else empty. |
*/ |
public JTime(final boolean fillWithCurrentTime) { |
this(fillWithCurrentTime, false); |
} |
public JTime(final boolean fillWithCurrentTime, final boolean withSeconds) { |
super(new BorderLayout()); |
this.fillWithCurrentTime = fillWithCurrentTime; |
final DateFormatter formatter = new DateFormatter(new SimpleDateFormat("HH:mm")); |
final DateFormatter formatter = new DateFormatter(new SimpleDateFormat(withSeconds ? "HH:mm:ss" : "HH:mm")); |
formatter.setOverwriteMode(true); |
// don't setAllowsInvalid(false) otherwise we can't replace 07:00 by 21:00 |
formatter.setMaximum(dateFromTimeInMillis(DAY_LENGTH - 1)); |
90,6 → 97,15 |
this.text = new JFormattedTextField(formatter); |
this.add(this.text, BorderLayout.CENTER); |
this.text.addPropertyChangeListener("editValid", new PropertyChangeListener() { |
@Override |
public void propertyChange(PropertyChangeEvent evt) { |
setValidated((Boolean) evt.getNewValue()); |
} |
}); |
// initial value |
this.validSupp = new ValidChangeSupport(this, this.text.isEditValid()); |
this.resetValue(); |
} |
158,19 → 174,23 |
return this; |
} |
protected final void setValidated(boolean newValue) { |
this.validSupp.fireValidChange(newValue); |
} |
@Override |
public boolean isValidated() { |
return true; |
return this.validSupp.getValidState(); |
} |
@Override |
public void addValidListener(ValidListener l) { |
// nothing to do |
this.validSupp.addValidListener(l); |
} |
@Override |
public void removeValidListener(ValidListener l) { |
// nothing to do |
this.validSupp.removeValidListener(l); |
} |
@Override |
/trunk/OpenConcerto/src/org/openconcerto/sql/request/BaseFillSQLRequest.java |
---|
37,6 → 37,13 |
*/ |
public static final boolean lockSelect = !Boolean.getBoolean("org.openconcerto.sql.noSelectLock"); |
static public void setupForeign(final SQLRowValuesListFetcher fetcher) { |
// include rows having NULL (not undefined ID) foreign keys |
fetcher.setFullOnly(false); |
// treat the same way tables with or without undefined ID |
fetcher.setIncludeForeignUndef(false); |
} |
private final SQLTable primaryTable; |
private Where where; |
private ITransformer<SQLSelect, SQLSelect> selTransf; |
117,10 → 124,7 |
protected final SQLRowValuesListFetcher getFetcher(final Where w) { |
final String tableName = getPrimaryTable().getName(); |
final SQLRowValuesListFetcher fetcher = new SQLRowValuesListFetcher(getGraphToFetch(), true); |
// include rows having NULL (not undefined ID) foreign keys |
fetcher.setFullOnly(false); |
// treat the same way tables with or without undefined ID |
fetcher.setIncludeForeignUndef(false); |
setupForeign(fetcher); |
fetcher.setSelTransf(new ITransformer<SQLSelect, SQLSelect>() { |
@Override |
public SQLSelect transformChecked(SQLSelect sel) { |
/trunk/OpenConcerto/src/org/openconcerto/sql/utils/DropTable.java |
---|
67,4 → 67,9 |
throw new UnsupportedOperationException(); |
} |
@Override |
protected String getConstraintPrefix() { |
// FIXME make a superclass w/o it |
throw new UnsupportedOperationException(); |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/sql/utils/AlterTable.java |
---|
51,6 → 51,11 |
this.t = null; |
} |
@Override |
protected String getConstraintPrefix() { |
return "ADD "; |
} |
public final AlterTable addColumn(String name, String definition) { |
// column keyword is not accepted by H2 |
return this.addClause("ADD " + SQLBase.quoteIdentifier(name) + " " + definition, ClauseType.ADD_COL); |
/trunk/OpenConcerto/src/org/openconcerto/sql/utils/SQLCreateTableBase.java |
---|
21,6 → 21,7 |
import java.util.ArrayList; |
import java.util.Arrays; |
import java.util.Collections; |
import java.util.EnumSet; |
import java.util.List; |
import java.util.Set; |
33,7 → 34,7 |
*/ |
public abstract class SQLCreateTableBase<T extends SQLCreateTableBase<T>> extends ChangeTable<T> { |
private String pk; |
private List<String> pk; |
private boolean tmp; |
public SQLCreateTableBase(final SQLSyntax syntax, final String name) { |
44,10 → 45,15 |
@Override |
public void reset() { |
super.reset(); |
this.pk = null; |
this.pk = Collections.emptyList(); |
this.tmp = false; |
} |
@Override |
protected String getConstraintPrefix() { |
return ""; |
} |
public final T addColumn(String name, String definition) { |
return this.addClause(SQLBase.quoteIdentifier(name) + " " + definition, ClauseType.ADD_COL); |
} |
62,18 → 68,14 |
public final T setPrimaryKey(List<String> fields) { |
this.checkPK(); |
if (fields.size() > 0) { |
this.pk = "PRIMARY KEY (" + CollectionUtils.join(fields, ",", new ITransformer<String, String>() { |
@Override |
public String transformChecked(String input) { |
return SQLBase.quoteIdentifier(input); |
} |
}) + ")"; |
} else |
this.pk = null; |
this.pk = Collections.unmodifiableList(new ArrayList<String>(fields)); |
return thisAsT(); |
} |
public List<String> getPrimaryKey() { |
return this.pk; |
} |
protected void checkPK() { |
} |
111,8 → 113,13 |
final List<String> genClauses = new ArrayList<String>(this.getClauses(tableName, types)); |
this.modifyClauses(genClauses); |
if (this.pk != null && types.contains(ClauseType.ADD_COL)) |
genClauses.add(this.pk); |
if (this.pk.size() > 0 && types.contains(ClauseType.ADD_COL)) |
genClauses.add("PRIMARY KEY (" + CollectionUtils.join(this.pk, ",", new ITransformer<String, String>() { |
@Override |
public String transformChecked(String input) { |
return SQLBase.quoteIdentifier(input); |
} |
}) + ")"); |
if (types.contains(ClauseType.ADD_CONSTRAINT)) { |
genClauses.addAll(this.getForeignConstraints(rootName)); |
} |
/trunk/OpenConcerto/src/org/openconcerto/sql/utils/SQLCreateTable.java |
---|
21,6 → 21,7 |
import org.openconcerto.sql.model.SQLTable; |
import org.openconcerto.sql.model.graph.SQLKey; |
import java.util.Collections; |
import java.util.List; |
/** |
65,9 → 66,16 |
public SQLCreateTable addForeignColumn(String foreignTableN, String suffix) { |
final String fk = SQLKey.PREFIX + foreignTableN + (suffix.length() == 0 ? "" : "_" + suffix); |
final SQLTable foreignTable = this.b.getTable(foreignTableN); |
if (foreignTable == null) |
throw new IllegalArgumentException("Unknown table in " + this.b + " : " + foreignTableN); |
return this.addForeignColumn(fk, foreignTable, true); |
} |
@Override |
public List<String> getPrimaryKey() { |
return this.plain ? super.getPrimaryKey() : Collections.singletonList(SQLSyntax.ID_NAME); |
} |
protected void checkPK() { |
if (!this.plain) |
throw new IllegalStateException("can only set primary key in plain mode, otherwise it is automatically added"); |
/trunk/OpenConcerto/src/org/openconcerto/sql/utils/ChangeTable.java |
---|
23,6 → 23,7 |
import org.openconcerto.sql.model.SQLTable; |
import org.openconcerto.sql.model.SQLTable.Index; |
import org.openconcerto.sql.model.graph.Link; |
import org.openconcerto.sql.model.graph.SQLKey; |
import org.openconcerto.utils.CollectionMap; |
import org.openconcerto.utils.CollectionUtils; |
import org.openconcerto.utils.ReflectUtils; |
202,6 → 203,29 |
return this.addColumn(name, getSyntax().getDateAndTimeType()); |
} |
/** |
* Adds a non-null integer column. |
* |
* @param name the name of the column. |
* @param defaultVal the default value of the column. |
* @return this. |
*/ |
public final T addIntegerColumn(String name, int defaultVal) { |
return this.addIntegerColumn(name, defaultVal, false); |
} |
/** |
* Adds an integer column. |
* |
* @param name the name of the column. |
* @param defaultVal the default value of the column, can be <code>null</code>. |
* @param nullable whether the column accepts NULL. |
* @return this. |
*/ |
public final T addIntegerColumn(String name, Integer defaultVal, boolean nullable) { |
return this.addColumn(name, "integer " + getSyntax().getDefaultClause(defaultVal == null ? null : defaultVal.toString()) + " " + getSyntax().getNullableClause(nullable)); |
} |
public abstract T addColumn(String name, String definition); |
public final T addColumn(SQLField f) { |
255,7 → 279,42 |
// * addForeignColumn = addColumn + addForeignConstraint |
public T addForeignColumn(SQLCreateTableBase<?> createTable) { |
return this.addForeignColumnWithSuffix("", createTable); |
} |
/** |
* Add a foreign column to a table not yet created. |
* |
* @param suffix the suffix of the column, used to tell apart multiple columns pointing to the |
* same table, e.g. "" or "2". |
* @param createTable the table the new column must point to. |
* @return this. |
* @see #addForeignColumn(String, SQLCreateTableBase) |
*/ |
public T addForeignColumnWithSuffix(String suffix, SQLCreateTableBase<?> createTable) { |
final String fk = SQLKey.PREFIX + createTable.getName() + (suffix.length() == 0 ? "" : "_" + suffix); |
return this.addForeignColumn(fk, createTable); |
} |
/** |
* Add a foreign column to a table not yet created. Note: this method assumes that the foreign |
* table will be created in the same root as this table, like with |
* {@link ChangeTable#cat(List, String)}. |
* |
* @param fk the field name, e.g. "ID_BAT". |
* @param createTable the table the new column must point to. |
* @return this. |
* @see #addForeignColumn(String, SQLName, String, String) |
*/ |
public T addForeignColumn(String fk, SQLCreateTableBase<?> createTable) { |
final List<String> primaryKey = createTable.getPrimaryKey(); |
if (primaryKey.size() != 1) |
throw new IllegalArgumentException("Not exactly one field in the foreign primary key : " + primaryKey); |
return this.addForeignColumn(fk, new SQLName(createTable.getName()), primaryKey.get(0), null); |
} |
/** |
* Add a column and its foreign constraint. If <code>table</code> is of length 1 it will be |
* prepended the root name of this table. |
* |
306,9 → 365,7 |
}); |
} |
private final String getConstraintPrefix() { |
return this instanceof AlterTable ? "ADD " : ""; |
} |
protected abstract String getConstraintPrefix(); |
/** |
* Add a clause inside the "CREATE TABLE". |
/trunk/OpenConcerto/src/org/openconcerto/sql/model/SQLType.java |
---|
23,6 → 23,7 |
import java.sql.Blob; |
import java.sql.Clob; |
import java.sql.Date; |
import java.sql.Time; |
import java.sql.Timestamp; |
import java.sql.Types; |
import java.util.Arrays; |
66,6 → 67,8 |
return Timestamp.class; |
case Types.DATE: |
return java.util.Date.class; |
case Types.TIME: |
return java.sql.Time.class; |
case Types.INTEGER: |
case Types.SMALLINT: |
case Types.TINYINT: |
121,6 → 124,8 |
res = new BooleanType(type, size, typeName, clazz); |
else if (Number.class.isAssignableFrom(clazz)) |
res = new NumberType(type, size, decDigits, typeName, clazz); |
else if (Time.class.isAssignableFrom(clazz)) |
res = new TimeType(type, size, decDigits, typeName, clazz); |
else if (Timestamp.class.isAssignableFrom(clazz)) |
res = new TimestampType(type, size, decDigits, typeName, clazz); |
// Date en dernier surclasse des autres |
469,6 → 474,22 |
} |
} |
private static class TimeType extends DateOrTimeType { |
public TimeType(int type, int size, Integer decDigits, String typeName, Class clazz) { |
super(type, size, decDigits, typeName, clazz); |
} |
@Override |
protected String toStringRaw(Object o) { |
final Time ts; |
if (o instanceof Time) |
ts = (Time) o; |
else |
ts = new Time(getTime(o)); |
return "'" + ts.toString() + "'"; |
} |
} |
private static class StringType extends SQLType { |
public StringType(int type, int size, String typeName, Class clazz) { |
super(type, size, null, typeName, clazz); |
/trunk/OpenConcerto/src/org/openconcerto/sql/model/SQLBase.java |
---|
63,6 → 63,11 |
*/ |
public static final String ALLOW_OBJECT_REMOVAL = "org.openconcerto.sql.identifier.allowRemoval"; |
static public final void logCacheError(final DBItemFileCache dir, Exception e) { |
Log.get().info("invalid files in " + dir + "\n" + e.getMessage()); |
Log.get().config("invalid files in " + dir + "\n" + ExceptionUtils.getStackTrace(e)); |
} |
// null is a valid name (MySQL doesn't support schemas) |
private final Map<String, SQLSchema> schemas; |
private int[] dbVersion; |
140,7 → 145,7 |
final long t2 = System.currentTimeMillis(); |
Log.get().config("XML took " + (t2 - t1) + "ms for mapping " + this.getName() + "." + xmlStructSrc.getSchemas()); |
} catch (Exception e) { |
Log.get().info("invalid files in " + dir + "\n" + ExceptionUtils.getStackTrace(e)); |
logCacheError(dir, e); |
// delete all files not just structure, since every information about obsolete |
// schemas is obsolete |
// delete all schemas, otherwise if afterwards we load one file it might be valid |
/trunk/OpenConcerto/src/org/openconcerto/sql/model/graph/DatabaseGraph.java |
---|
24,6 → 24,7 |
import org.openconcerto.sql.model.DBItemFileCache; |
import org.openconcerto.sql.model.DBRoot; |
import org.openconcerto.sql.model.DBSystemRoot; |
import org.openconcerto.sql.model.SQLBase; |
import org.openconcerto.sql.model.SQLDataSource; |
import org.openconcerto.sql.model.SQLField; |
import org.openconcerto.sql.model.SQLSchema; |
142,7 → 143,7 |
Log.get().config("XML took " + (t2 - t1) + "ms for mapping the graph of " + this.base.getName() + "." + res); |
} |
} catch (Exception e) { |
Log.get().info("invalid files in " + dir + "\n" + ExceptionUtils.getStackTrace(e)); |
SQLBase.logCacheError(dir, e); |
this.deleteGraphFiles(); |
} |
if (!childrenToFetch.isEmpty()) { |
/trunk/OpenConcerto/src/org/openconcerto/sql/model/SQLSyntax.java |
---|
338,7 → 338,7 |
return !Boolean.FALSE.equals(f.isNullable()); |
} |
protected final String getNullableClause(boolean nullable) { |
public final String getNullableClause(boolean nullable) { |
return nullable ? " " : " NOT NULL "; |
} |
404,7 → 404,7 |
* @param def the default, e.g. "0". |
* @return the default clause, e.g. "DEFAULT 0". |
*/ |
protected final String getDefaultClause(final String def) { |
public final String getDefaultClause(final String def) { |
if (def == null) |
return " "; |
else |
/trunk/OpenConcerto/src/org/openconcerto/sql/preferences/UserProps.java |
---|
14,6 → 14,7 |
package org.openconcerto.sql.preferences; |
import org.openconcerto.sql.Configuration; |
import org.openconcerto.sql.model.SQLRow; |
import org.openconcerto.ui.preferences.AbstractProps; |
import java.io.File; |
42,7 → 43,7 |
} |
public int getLastSocieteID() { |
return getIntProperty(UserProps.LAST_SOCIETE); |
return getIntProperty(UserProps.LAST_SOCIETE, SQLRow.NONEXISTANT_ID); |
} |
public void setLastSocieteID(int id) { |
/trunk/OpenConcerto/src/org/openconcerto/sql/view/list/search/SearchQueue.java |
---|
15,8 → 15,8 |
import org.openconcerto.sql.model.SQLRow; |
import org.openconcerto.sql.model.SQLRowValues; |
import org.openconcerto.sql.model.SQLRowValuesCluster.State; |
import org.openconcerto.sql.model.SQLTable; |
import org.openconcerto.sql.model.SQLRowValuesCluster.State; |
import org.openconcerto.sql.model.graph.Path; |
import org.openconcerto.sql.view.list.ITableModel; |
import org.openconcerto.sql.view.list.LineListener; |
124,7 → 124,7 |
if (id < SQLRow.MIN_VALID_ID) |
throw new IllegalArgumentException("invalid ID: " + id); |
if (!this.fullList.isEmpty()) { |
final SQLRowValues proto = this.fullList.get(0).getRow(); |
final SQLRowValues proto = this.getModel().getLinesSource().getParent().getMaxGraph(); |
final List<Path> pathsToT = new ArrayList<Path>(); |
proto.walkGraph(pathsToT, new ITransformer<State<List<Path>>, List<Path>>() { |
@Override |
137,9 → 137,9 |
}); |
for (final Path p : pathsToT) { |
for (final ListSQLLine line : this.fullList) { |
final SQLRowValues current = line.getRow().assurePath(p); |
final SQLRowValues current = line.getRow().followPath(p); |
// works for rowValues w/o any ID |
if (current.getID() == id) { |
if (current != null && current.getID() == id) { |
// add to the list of paths that have been refreshed |
if (byLine) |
res.put(line, p); |
/trunk/OpenConcerto/src/org/openconcerto/sql/view/list/SQLTableModelSource.java |
---|
191,6 → 191,13 |
protected abstract SQLTableModelLinesSource _createLinesSource(ITableModel model); |
/** |
* The maximum graph of the lines returned by {@link #createLinesSource(ITableModel)}. |
* |
* @return the maximum graph of our lines. |
*/ |
public abstract SQLRowValues getMaxGraph(); |
// * columns |
/** |
/trunk/OpenConcerto/src/org/openconcerto/sql/view/list/SQLTableModelSourceOffline.java |
---|
14,6 → 14,7 |
package org.openconcerto.sql.view.list; |
import org.openconcerto.sql.element.SQLElement; |
import org.openconcerto.sql.model.SQLRowValues; |
import org.openconcerto.sql.model.SQLRowValuesListFetcher; |
/** |
46,4 → 47,9 |
protected SQLTableModelLinesSourceOffline _createLinesSource(final ITableModel model) { |
return new SQLTableModelLinesSourceOffline(this, model); |
} |
@Override |
public SQLRowValues getMaxGraph() { |
return this.getFetcher().getGraph(); |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/sql/view/list/IListe.java |
---|
73,6 → 73,7 |
import java.io.File; |
import java.io.IOException; |
import java.sql.Clob; |
import java.sql.Time; |
import java.text.DateFormat; |
import java.text.SimpleDateFormat; |
import java.util.ArrayList; |
125,10 → 126,13 |
private static boolean FORCE_ALT_CELL_RENDERER = false; |
private static final DateFormat MODIF_DATE_FORMAT = new SimpleDateFormat("'le' dd MMMM yyyy 'à' HH:mm:ss"); |
static final String SEP = " ► "; |
private static final DateFormat TIME_FORMAT = DateFormat.getTimeInstance(DateFormat.SHORT); |
private static final Map<Class<?>, FormatGroup> FORMATS; |
static { |
FORMATS = new HashMap<Class<?>, FormatGroup>(); |
FORMATS.put(Date.class, new FormatGroup(DateFormat.getDateInstance(DateFormat.SHORT), DateFormat.getDateInstance(DateFormat.MEDIUM), DateFormat.getDateInstance(DateFormat.LONG))); |
// longer first otherwise seconds are not displayed by the cell editor and will be lost |
FORMATS.put(Time.class, new FormatGroup(DateFormat.getTimeInstance(DateFormat.MEDIUM), DateFormat.getTimeInstance(DateFormat.SHORT))); |
} |
public static final void remove(InputMap m, KeyStroke key) { |
556,6 → 560,13 |
return super.getTableCellRendererComponent(table, StringClobConvertor.INSTANCE.unconvert((Clob) value), isSelected, hasFocus, row, column); |
} |
}); |
this.jTable.setDefaultRenderer(Time.class, new DefaultTableCellRenderer() { |
@Override |
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { |
final String val = value == null ? "" : TIME_FORMAT.format((Time) value); |
return super.getTableCellRendererComponent(table, val, isSelected, hasFocus, row, column); |
} |
}); |
for (final Map.Entry<Class<?>, FormatGroup> e : this.getFormats().entrySet()) |
this.jTable.setDefaultEditor(e.getKey(), new FormatEditor(e.getValue())); |
this.sorter.setTableHeader(this.jTable.getTableHeader()); |
/trunk/OpenConcerto/src/org/openconcerto/sql/view/list/AbstractUpdateOneRunnable.java |
---|
21,6 → 21,7 |
import org.openconcerto.sql.model.SQLTable; |
import org.openconcerto.sql.model.Where; |
import org.openconcerto.sql.model.graph.Path; |
import org.openconcerto.sql.request.BaseFillSQLRequest; |
import org.openconcerto.sql.request.ListSQLRequest; |
import org.openconcerto.utils.CollectionMap; |
import org.openconcerto.utils.cc.ITransformer; |
50,19 → 51,18 |
if (!lines.isEmpty()) { |
// deepCopy() instead of new SQLRowValues() otherwise the used line's graph will be |
// modified (eg the new instance would be linked to it) |
final SQLRowValues proto = lines.get(0).getRow().followPath(p).deepCopy(); |
final SQLRowValues proto = getModel().getLinesSource().getParent().getMaxGraph().followPath(p).deepCopy(); |
// keep only what has changed, eg CONTACT.NOM |
proto.retainAll(getModifedFields()); |
// fetch the changed rowValues |
// ATTN this doesn't use the original fetcher that was used in the updateAll |
// MAYBE add a slower but accurate mode using the updateAll fetcher (and thus |
// reloading rows from the primary table and not just the changed rows) |
final SQLRowValuesListFetcher fetcher = new SQLRowValuesListFetcher(proto); |
// the result should have the same graph as proto |
fetcher.setFullOnly(true); |
BaseFillSQLRequest.setupForeign(fetcher); |
final ITransformer<SQLSelect, SQLSelect> transf = new ITransformer<SQLSelect, SQLSelect>() { |
@Override |
public SQLSelect transformChecked(SQLSelect input) { |
// don't exclude undef, eg either RECEPTEUR pointing to undef OBS |
// or even refreshing that undef OBS |
input.setExcludeUndefined(false); |
if (ListSQLRequest.lockSelect) |
input.addWaitPreviousWriteTXTable(getTable().getName()); |
return input.setWhere(new Where(getTable().getKey(), "=", getID())); |
/trunk/OpenConcerto/src/org/openconcerto/sql/view/list/SQLTableModelSourceOnline.java |
---|
59,4 → 59,9 |
protected SQLTableModelLinesSourceOnline _createLinesSource(final ITableModel model) { |
return new SQLTableModelLinesSourceOnline(this, model); |
} |
@Override |
public SQLRowValues getMaxGraph() { |
return this.getReq().getGraphToFetch(); |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/utils/convertor/DateToTimeConvertor.java |
---|
New file |
0,0 → 1,29 |
/* |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
* |
* Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved. |
* |
* The contents of this file are subject to the terms of the GNU General Public License Version 3 |
* only ("GPL"). You may not use this file except in compliance with the License. You can obtain a |
* copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific |
* language governing permissions and limitations under the License. |
* |
* When distributing the software, include this License Header Notice in each file. |
*/ |
package org.openconcerto.utils.convertor; |
import java.sql.Time; |
import java.util.Date; |
public class DateToTimeConvertor extends NullIsNullConvertor<Date, Time> { |
@Override |
protected Time convertNonNull(Date o) { |
return new Time(o.getTime()); |
} |
@Override |
protected Date unconvertNonNull(Time o) { |
return o; |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/utils/convertor/ValueConvertorFactory.java |
---|
24,6 → 24,7 |
static { |
convs = new ArrayList<ValueConvertor<?, ?>>(); |
convs.add(new DateTSConvertor()); |
convs.add(new DateToTimeConvertor()); |
convs.add(StringClobConvertor.INSTANCE); |
} |
/trunk/OpenConcerto/src/org/openconcerto/utils/NumberUtils.java |
---|
New file |
0,0 → 1,98 |
/* |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
* |
* Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved. |
* |
* The contents of this file are subject to the terms of the GNU General Public License Version 3 |
* only ("GPL"). You may not use this file except in compliance with the License. You can obtain a |
* copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific |
* language governing permissions and limitations under the License. |
* |
* When distributing the software, include this License Header Notice in each file. |
*/ |
package org.openconcerto.utils; |
import java.math.BigDecimal; |
import java.math.BigInteger; |
import java.util.concurrent.atomic.AtomicInteger; |
import java.util.concurrent.atomic.AtomicLong; |
public class NumberUtils { |
/** |
* Whether <code>n</code> has a non-zero fractional part. |
* |
* @param n a number. |
* @return <code>true</code> if there is a non-zero fractional part, e.g. <code>true</code> for |
* 1.3d and <code>false</code> for <code>new BigDecimal("1.00")</code>. |
*/ |
static public final boolean hasFractionalPart(Number n) { |
if (n instanceof Integer || n instanceof Long || n instanceof Short || n instanceof Byte || n instanceof BigInteger || n instanceof AtomicLong || n instanceof AtomicInteger) |
return false; |
final BigDecimal bd; |
if (n instanceof BigDecimal) |
bd = (BigDecimal) n; |
else if (n instanceof Double || n instanceof Float) |
bd = new BigDecimal(n.doubleValue()); |
else |
bd = new BigDecimal(n.toString()); |
return DecimalUtils.decimalDigits(bd) > 0; |
} |
static final int MAX_LONG_LENGTH = String.valueOf(Long.MAX_VALUE).length(); |
static public final int intDigits(final long l) { |
final long x = Math.abs(l); |
long p = 10; |
int i = 1; |
while (x >= p && i < MAX_LONG_LENGTH) { |
p = 10 * p; |
i++; |
} |
return i; |
} |
/** |
* The number of digits of the integer part in decimal representation. |
* |
* @param n a number, e.g. 123.45. |
* @return the number of digits of the integer part, e.g. 3. |
*/ |
static public final int intDigits(Number n) { |
if (n instanceof Integer || n instanceof Long || n instanceof Short || n instanceof Byte || n instanceof AtomicLong || n instanceof AtomicInteger) |
return intDigits(n.longValue()); |
final BigDecimal bd; |
if (n instanceof BigDecimal) |
bd = (BigDecimal) n; |
else if (n instanceof BigInteger) |
bd = new BigDecimal((BigInteger) n); |
else if (n instanceof Double || n instanceof Float) |
bd = new BigDecimal(n.doubleValue()); |
else |
bd = new BigDecimal(n.toString()); |
return DecimalUtils.intDigits(bd); |
} |
/** |
* High precision divide. |
* |
* @param n the dividend. |
* @param d the divisor. |
* @return <code>n / d</code>. |
* @see DecimalUtils#HIGH_PRECISION |
*/ |
static public Number divide(Number n, double d) { |
if (d == 1) |
return n; |
if (n instanceof BigDecimal) { |
return ((BigDecimal) n).divide(new BigDecimal(d), DecimalUtils.HIGH_PRECISION); |
} else if (n instanceof BigInteger) { |
return new BigDecimal((BigInteger) n).divide(new BigDecimal(d), DecimalUtils.HIGH_PRECISION); |
} else { |
return n.doubleValue() / d; |
} |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/utils/CompareUtils.java |
---|
18,6 → 18,7 |
import org.openconcerto.utils.cc.ITransformer; |
import java.math.BigDecimal; |
import java.util.Comparator; |
import java.util.List; |
88,6 → 89,7 |
* @param o1 the first object, can be <code>null</code>. |
* @param o2 the second object, can be <code>null</code>. |
* @return <code>true</code> if both are <code>null</code> or if o1.equals(o2). |
* @see Object#equals(Object) |
*/ |
static public final boolean equals(Object o1, Object o2) { |
if (o1 == null && o2 == null) |
97,6 → 99,24 |
return o1.equals(o2); |
} |
/** |
* Compare 2 objets pouvant être <code>null</code> avec compareTo(). Useful since for some |
* classes equals() is more specific than compareTo()==0, e.g. {@link BigDecimal#equals(Object)} |
* doesn't compare the numeric value but instance variables (1E2 is not equal to 100 or 100.00). |
* |
* @param o1 the first object, can be <code>null</code>. |
* @param o2 the second object, can be <code>null</code>. |
* @return <code>true</code> if both are <code>null</code> or if o1.compareTo(o2) == 0. |
* @see Comparable#compareTo(Object) |
*/ |
static public final <T> boolean equalsWithCompareTo(Comparable<T> o1, T o2) { |
if (o1 == null && o2 == null) |
return true; |
if (o1 == null || o2 == null) |
return false; |
return o1.compareTo(o2) == 0; |
} |
static public interface Equalizer<T> { |
public boolean equals(T o1, T o2); |
} |
/trunk/OpenConcerto/src/org/openconcerto/utils/checks/ValidChangeSupport.java |
---|
36,6 → 36,10 |
this.validState = initialState; |
} |
public final Boolean getValidState() { |
return this.validState; |
} |
public final void fireValidChange(final Boolean newValue) { |
if (!newValue.equals(this.validState)) { |
this.validState = newValue; |
/trunk/OpenConcerto/src/org/openconcerto/xml/JDOMUtils.java |
---|
13,6 → 13,8 |
package org.openconcerto.xml; |
import org.openconcerto.utils.cc.IPredicate; |
import java.io.ByteArrayInputStream; |
import java.io.IOException; |
import java.io.StringReader; |
151,6 → 153,25 |
return OUTPUTTER.outputString(xml); |
} |
public static Element getAncestor(Element element, final String name, final Namespace ns) { |
return getAncestor(element, new IPredicate<Element>() { |
@Override |
public boolean evaluateChecked(Element elem) { |
return elem.getName().equals(name) && elem.getNamespace().equals(ns); |
} |
}); |
} |
public static Element getAncestor(Element element, final IPredicate<Element> pred) { |
Element current = element; |
while (current != null) { |
if (pred.evaluateChecked(current)) |
return current; |
current = current.getParentElement(); |
} |
return null; |
} |
/** |
* Add namespace declaration to <code>elem</code> if needed. Necessary since JDOM uses a simple |
* list. |
228,6 → 249,23 |
parentElement.addContent(after ? index + 1 : index, toAdd); |
} |
/** |
* Test if two elements have the same namespace and name. |
* |
* @param elem1 an element, can be <code>null</code>. |
* @param elem2 an element, can be <code>null</code>. |
* @return <code>true</code> if both elements have the same name and namespace, or if both are |
* <code>null</code>. |
*/ |
public static boolean equals(Element elem1, Element elem2) { |
if (elem1 == null && elem2 == null) |
return true; |
else if (elem1 == null || elem2 == null) |
return false; |
else |
return elem1.getName().equals(elem2.getName()) && elem1.getNamespace().equals(elem2.getNamespace()); |
} |
// @return SAXException If a SAX error occurs during parsing of doc. |
static SAXException validate(final Document doc, final Schema schema, final ErrorHandler errorHandler) { |
ByteArrayInputStream ins; |
/trunk/OpenConcerto/src/org/openconcerto/xml/SimpleXMLPath.java |
---|
57,6 → 57,30 |
return create(Arrays.<Step<?>> asList(first, second), lastStep); |
} |
/** |
* Create a path searching for all descendant attributes with the passed name and namespace. |
* I.e. in XPath this would be ".//@ns:name". |
* |
* @param name the name of attributes. |
* @param ns the namespace of attributes. |
* @return a path searching attributes in all {@link Axis#descendantOrSelf} elements. |
*/ |
public static SimpleXMLPath<Attribute> allAttributes(final String name, final String ns) { |
return create(Step.createElementStep(Axis.descendantOrSelf, null), Step.createAttributeStep(name, ns)); |
} |
/** |
* Create a path searching for all descendant elements with the passed name and namespace. I.e. |
* in XPath this would be ".//ns:name". |
* |
* @param name the name of elements. |
* @param ns the namespace of elements. |
* @return a path searching all {@link Axis#descendantOrSelf} elements. |
*/ |
public static SimpleXMLPath<Element> allElements(final String name, final String ns) { |
return create(Step.createElementStep(Axis.descendantOrSelf, name, ns)); |
} |
private final List<Step<?>> items; |
private final Step<T> lastItem; |
65,11 → 89,11 |
this.items = new ArrayList<Step<?>>(); |
} |
public final SimpleXMLPath add(final String name) { |
public final SimpleXMLPath<T> add(final String name) { |
return this.add(Step.createElementStep(name, null, null)); |
} |
public final SimpleXMLPath add(Step<?> step) { |
public final SimpleXMLPath<T> add(Step<?> step) { |
this.items.add(step); |
return this; |
} |
183,7 → 207,7 |
if (axis == Axis.ancestor) { |
step.add(node.getParent(), res); |
} else if (axis == Axis.attribute) { |
final List attributes = node.getAttributes(); |
final List<?> attributes = node.getAttributes(); |
final int stop = attributes.size(); |
for (int i = 0; i < stop; i++) { |
step.add(attributes.get(i), res); |
/trunk/OpenConcerto/src/org/openconcerto/task/config/ComptaBasePropsConfiguration.java |
---|
163,7 → 163,7 |
} |
public final DBRoot getRootSociete() { |
if (this.baseSociete == null) |
if (this.baseSociete == null && this.rowSociete != null) |
this.baseSociete = this.createSQLBaseSociete(); |
return this.baseSociete; |
} |
/trunk/OpenConcerto/src/org/openconcerto/erp/config/ComptaPropsConfiguration.java |
---|
444,13 → 444,9 |
dir.addSQLElement(new SaisieKmItemSQLElement()); |
dir.addSQLElement(new EcritureSQLElement()); |
dir.addSQLElement(new SharedSQLElement("ACCES_SOCIETE")); |
dir.addSQLElement(new SharedSQLElement("PREFS_COMPTE")); |
dir.addSQLElement(new SharedSQLElement("EMPLOYEUR_MULTIPLE")); |
dir.addSQLElement(new SharedSQLElement("REPARTITION_ANALYTIQUE_ELEMENT")); |
dir.addSQLElement(PosteAnalytiqueSQLElement.class); |
dir.addSQLElement(new SharedSQLElement("CLASSE_COMPTE")); |
dir.addSQLElement(new SharedSQLElement("PREFERENCES")); |
dir.addSQLElement(new CaisseCotisationSQLElement()); |
dir.addSQLElement(CaisseTicketSQLElement.class); |
/trunk/OpenConcerto/src/org/openconcerto/erp/config/MainFrame.java |
---|
115,8 → 115,10 |
import org.openconcerto.sql.users.rights.UserRights; |
import org.openconcerto.task.TodoListPanel; |
import org.openconcerto.task.config.ComptaBasePropsConfiguration; |
import org.openconcerto.ui.AutoHideTabbedPane; |
import org.openconcerto.ui.MenuUtils; |
import org.openconcerto.ui.SwingThreadUtils; |
import org.openconcerto.ui.state.WindowStateManager; |
import org.openconcerto.utils.JImage; |
import org.openconcerto.utils.OSXAdapter; |
128,6 → 130,7 |
import java.awt.event.ActionEvent; |
import java.awt.event.WindowAdapter; |
import java.awt.event.WindowEvent; |
import java.io.File; |
import java.util.ArrayList; |
import java.util.Arrays; |
import java.util.List; |
153,6 → 156,7 |
public static final String LIST_MENU = "Gestion"; |
public static final String CREATE_MENU = "Saisie"; |
public static final String FILE_MENU = "Fichier"; |
private static final String HELP_MENU = "Aide"; |
static private final List<Runnable> runnables = new ArrayList<Runnable>(); |
static private MainFrame instance = null; |
192,7 → 196,8 |
}); |
} |
private TodoListPanel todoPanel = new TodoListPanel(); |
private final AutoHideTabbedPane tabContainer; |
private TodoListPanel todoPanel; |
private JImage image; |
public TodoListPanel getTodoPanel() { |
203,7 → 208,7 |
super(); |
this.setIconImage(new ImageIcon(this.getClass().getResource("frameicon.png")).getImage()); |
this.setJMenuBar(createMenu()); |
this.setJMenuBar(Gestion.isMinimalMode() ? createMinimalMenu() : createMenu()); |
Container co = this.getContentPane(); |
co.setLayout(new GridBagLayout()); |
GridBagConstraints c = new GridBagConstraints(); |
213,10 → 218,10 |
// // co.add(new RangeSlider(2005), c); |
c.weightx = 1; |
c.weighty = 0; |
image = new JImage(ComptaBasePropsConfiguration.class.getResource("logo.png")); |
image.setBackground(Color.WHITE); |
image.check(); |
co.add(image, c); |
this.image = new JImage(ComptaBasePropsConfiguration.class.getResource("logo.png")); |
this.image.setBackground(Color.WHITE); |
this.image.check(); |
co.add(this.image, c); |
c.weighty = 0; |
c.gridy++; |
c.fill = GridBagConstraints.BOTH; |
223,15 → 228,37 |
co.add(new JSeparator(JSeparator.HORIZONTAL), c); |
c.gridy++; |
c.weighty = 1; |
co.add(this.todoPanel, c); |
this.tabContainer = new AutoHideTabbedPane(); |
co.add(this.tabContainer, c); |
Dimension minSize; |
final String confSuffix; |
if (!Gestion.isMinimalMode()) { |
this.todoPanel = new TodoListPanel(); |
this.getTabbedPane().addTab("Tâches", this.todoPanel); |
minSize = new Dimension(800, 600); |
confSuffix = ""; |
} else { |
minSize = null; |
confSuffix = "-minimal"; |
} |
c.weighty = 0; |
c.gridy++; |
c.fill = GridBagConstraints.HORIZONTAL; |
co.add(StatusPanel.getInstance(), c); |
if (minSize == null) { |
this.pack(); |
minSize = new Dimension(this.getSize()); |
} |
this.setMinimumSize(minSize); |
final File confFile = new File(Configuration.getInstance().getConfDir(), "Configuration" + File.separator + "Frame" + File.separator + "mainFrame" + confSuffix + ".xml"); |
new WindowStateManager(this, confFile).loadState(); |
registerForMacOSXEvents(); |
this.addWindowListener(new WindowAdapter() { |
@Override |
public void windowClosing(WindowEvent arg0) { |
quit(); |
} |
238,10 → 265,38 |
}); |
setInstance(this); |
new NewsUpdater(image); |
new NewsUpdater(this.image); |
} |
public JMenuBar createMenu() { |
private final JMenuBar createMinimalMenu() { |
final JMenuBar res = new JMenuBar(); |
final JMenu fileMenu = new JMenu(FILE_MENU); |
fileMenu.add(new SauvegardeBaseAction()); |
if (!Gestion.MAC_OS_X) { |
fileMenu.add(new JMenuItem(new AbstractAction("Quitter") { |
@Override |
public void actionPerformed(ActionEvent e) { |
quit(); |
} |
})); |
} |
res.add(fileMenu); |
final UserRights rights = UserManager.getInstance().getCurrentUser().getRights(); |
if (rights.haveRight(LockAdminUserRight.LOCK_MENU_ADMIN)) { |
final JMenu structMenu = new JMenu(STRUCTURE_MENU); |
structMenu.add(new JMenuItem(new ListeDesUsersCommonAction())); |
res.add(structMenu); |
} |
final JMenu helpMenu = new JMenu(HELP_MENU); |
helpMenu.add(new JMenuItem(AboutAction.getInstance())); |
res.add(helpMenu); |
return res; |
} |
private final JMenuBar createMenu() { |
JMenuBar result = new JMenuBar(); |
JMenu menu; |
284,6 → 339,7 |
if (!Gestion.MAC_OS_X) { |
menu.add(new JMenuItem(new PreferencesAction())); |
menu.add(new JMenuItem(new AbstractAction("Quitter") { |
@Override |
public void actionPerformed(ActionEvent e) { |
quit(); |
} |
494,7 → 550,7 |
result.add(menu); |
} |
// Aide |
menu = new JMenu("Aide"); |
menu = new JMenu(HELP_MENU); |
menu.add(new JMenuItem(AboutAction.getInstance())); |
menu.add(new JMenuItem(new AstuceAction())); |
529,7 → 585,8 |
final JMenu res; |
if (existing == null) { |
res = new JMenu(name); |
this.getJMenuBar().add(res); |
// insert before the help menu |
this.getJMenuBar().add(res, this.getJMenuBar().getComponentCount() - 1); |
} else { |
res = existing; |
} |
578,8 → 635,13 |
} |
public boolean quit() { |
if (this.getTodoPanel() != null) |
this.getTodoPanel().stopUpdate(); |
Gestion.askForExit(); |
return false; |
} |
public final AutoHideTabbedPane getTabbedPane() { |
return this.tabContainer; |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/erp/config/Gestion.java |
---|
71,6 → 71,12 |
public class Gestion { |
/** |
* When this system property is set to <code>true</code>, Gestion will hide most of its normal |
* UI. E.g. no SOCIETE selection in the login panel, minimalist menu bar, etc. |
*/ |
public static final String MINIMAL_PROP = "org.openconcerto.erp.minimal"; |
private static List<Image> frameIcon; |
// Check that we are on Mac OS X. This is crucial to loading and using the OSXAdapter class. |
static final boolean MAC_OS_X = System.getProperty("os.name").toLowerCase().startsWith("mac os x"); |
104,6 → 110,10 |
} |
} |
public static final boolean isMinimalMode() { |
return Boolean.getBoolean(MINIMAL_PROP); |
} |
/** |
* @param args |
*/ |
/trunk/OpenConcerto/src/org/openconcerto/erp/config/InstallationPanel.java |
---|
20,6 → 20,7 |
import org.openconcerto.sql.model.DBSystemRoot; |
import org.openconcerto.sql.model.SQLBase; |
import org.openconcerto.sql.model.SQLDataSource; |
import org.openconcerto.sql.model.SQLField; |
import org.openconcerto.sql.model.SQLField.Properties; |
import org.openconcerto.sql.model.SQLName; |
import org.openconcerto.sql.model.SQLRow; |
49,6 → 50,7 |
import java.awt.event.ActionEvent; |
import java.awt.event.ActionListener; |
import java.sql.SQLException; |
import java.sql.Types; |
import java.util.ArrayList; |
import java.util.EnumSet; |
import java.util.List; |
180,6 → 182,7 |
SQLUtils.executeAtomic(ds, new SQLUtils.SQLFactory<Object>() { |
@Override |
public Object create() throws SQLException { |
fixUnboundedVarchar(root); |
updateSocieteSchema(root); |
updateToV1Dot2(root); |
return null; |
403,6 → 406,36 |
this.add(comp, c); |
} |
private void fixUnboundedVarchar(DBRoot root) throws SQLException { |
final Set<String> namesSet = CollectionUtils.createSet("NOM", "PRENOM", "SURNOM", "LOGIN", "PASSWORD"); |
final List<AlterTable> alters = new ArrayList<AlterTable>(); |
for (final SQLTable t : root.getTables()) { |
final AlterTable alter = new AlterTable(t); |
for (final SQLField f : t.getFields()) { |
if (f.getType().getType() == Types.VARCHAR && f.getType().getSize() == Integer.MAX_VALUE) { |
final String fName = f.getName(); |
final int size; |
if (namesSet.contains(fName)) |
size = 64; |
else if (fName.equals("TEL") || fName.startsWith("TEL_")) |
size = 16; |
else |
size = 128; |
alter.alterColumn(fName, EnumSet.allOf(Properties.class), "varchar(" + size + ")", "''", false); |
} |
} |
if (!alter.isEmpty()) |
alters.add(alter); |
} |
if (alters.size() > 0) { |
final SQLDataSource ds = root.getDBSystemRoot().getDataSource(); |
for (final String sql : ChangeTable.cat(alters, root.getName())) { |
ds.execute(sql); |
} |
root.refetch(); |
} |
} |
private void updateToV1Dot2(final DBRoot root) throws SQLException { |
final SQLTable tableDevis = root.getTable("DEVIS"); |
final SQLDataSource ds = root.getDBSystemRoot().getDataSource(); |
/trunk/OpenConcerto/src/org/openconcerto/erp/modules/AlterTableRestricted.java |
---|
19,6 → 19,7 |
import org.openconcerto.sql.model.SQLSyntax; |
import org.openconcerto.sql.model.SQLTable; |
import org.openconcerto.sql.utils.AlterTable; |
import org.openconcerto.sql.utils.SQLCreateTableBase; |
import org.openconcerto.utils.CollectionUtils; |
import java.util.HashSet; |
97,15 → 98,20 |
return this.alter.addDateAndTimeColumn(name); |
} |
public final AlterTable addIntegerColumn(String name, int defaultVal) { |
addCol(name); |
return this.alter.addIntegerColumn(name, defaultVal); |
} |
public AlterTable addForeignColumn(String fk, String table) { |
return this.addForeignColumn(fk, new SQLName(table)); |
} |
public AlterTable addForeignColumn(String fk, SQLName tableName) { |
if (tableName.getItemCount() == 1 && this.ctxt.getAddedTables().contains(tableName.getFirst())) { |
SQLCreateTableBase<?> createTable; |
if (tableName.getItemCount() == 1 && (createTable = this.ctxt.getCreateTables().get(tableName.getFirst())) != null) { |
addCol(fk); |
// see DBContext.execute() |
return this.alter.addForeignColumn(fk, tableName, SQLSyntax.ID_NAME, "NULL"); |
return this.alter.addForeignColumn(fk, createTable); |
} else { |
return this.addForeignColumn(fk, this.table.getDesc(tableName, SQLTable.class)); |
} |
/trunk/OpenConcerto/src/org/openconcerto/erp/modules/ModuleManager.java |
---|
60,8 → 60,8 |
import java.util.LinkedHashSet; |
import java.util.List; |
import java.util.Map; |
import java.util.Set; |
import java.util.Map.Entry; |
import java.util.Set; |
import java.util.logging.Logger; |
import java.util.prefs.BackingStoreException; |
import java.util.prefs.Preferences; |
915,7 → 915,9 |
final SQLField f = root.getDesc(field, SQLField.class); |
// dropped by DROP TABLE |
if (!tableNames.contains(f.getTable().getName())) { |
l.add(new AlterTable(f.getTable()).dropColumn(f.getName())); |
// cascade needed since the module might have created constraints |
// (e.g. on H2 a foreign column cannot be dropped) |
l.add(new AlterTable(f.getTable()).dropColumnCascade(f.getName())); |
} |
} |
for (final String table : tableNames) { |
/trunk/OpenConcerto/src/org/openconcerto/erp/modules/ModulePackager.java |
---|
25,7 → 25,9 |
import java.io.InputStream; |
import java.util.ArrayList; |
import java.util.Enumeration; |
import java.util.HashSet; |
import java.util.List; |
import java.util.Set; |
import java.util.jar.JarEntry; |
import java.util.jar.JarFile; |
import java.util.jar.JarOutputStream; |
42,13 → 44,26 |
private final List<File> classesDirs; |
private final List<File> jars = new ArrayList<File>(); |
private final File propsFile; |
private final Set<String> dirEntries, fileEntries; |
private boolean skipDuplicateFiles; |
public ModulePackager(final File propsFile, final File classes) { |
this.propsFile = propsFile; |
this.classesDirs = new ArrayList<File>(8); |
this.classesDirs.add(classes); |
this.dirEntries = new HashSet<String>(); |
this.fileEntries = new HashSet<String>(); |
this.setSkipDuplicateFiles(false); |
} |
public final void setSkipDuplicateFiles(boolean skipDuplicateFiles) { |
this.skipDuplicateFiles = skipDuplicateFiles; |
} |
public final boolean getSkipDuplicateFiles() { |
return this.skipDuplicateFiles; |
} |
public final void addDir(final File classesDir) { |
this.classesDirs.add(classesDir); |
} |
90,6 → 105,8 |
final RuntimeModuleFactory f = new RuntimeModuleFactory(this.propsFile); |
final File jarFile = new File(dir, f.getID() + "-" + f.getMajorVersion() + "." + f.getMinorVersion() + ".jar"); |
final JarOutputStream jarStream = new JarOutputStream(new BufferedOutputStream(new FileOutputStream(jarFile))); |
this.dirEntries.clear(); |
this.fileEntries.clear(); |
try { |
if (!this.zipExistingFile(jarStream, this.propsFile, MODULE_PROPERTIES_PATH)) |
throw new IllegalStateException("Missing properties file : " + this.propsFile); |
101,6 → 118,8 |
} |
} finally { |
jarStream.close(); |
this.dirEntries.clear(); |
this.fileEntries.clear(); |
} |
return jarFile; |
} |
172,6 → 191,13 |
} |
private void zip(JarOutputStream jarStream, final JarEntry entry, InputStream in) throws IOException { |
// ignore duplicate directories |
final boolean isDir = entry.isDirectory(); |
if (isDir && !this.dirEntries.add(entry.getName())) |
return; |
if (!isDir && this.getSkipDuplicateFiles() && !this.fileEntries.add(entry.getName())) |
return; |
jarStream.putNextEntry(entry); |
if (in != null) { |
StreamUtils.copy(in, jarStream); |
/trunk/OpenConcerto/src/org/openconcerto/erp/modules/ComponentsContext.java |
---|
18,7 → 18,6 |
import org.openconcerto.sql.element.SQLElementDirectory; |
import org.openconcerto.sql.model.DBRoot; |
import org.openconcerto.sql.model.SQLName; |
import org.openconcerto.sql.model.SQLTable; |
import org.openconcerto.sql.sqlobject.SQLTextCombo; |
import org.openconcerto.sql.view.DropManager; |
import org.openconcerto.sql.view.FileDropHandler; |
25,6 → 24,7 |
import org.openconcerto.sql.view.SQLMenuItemHelper; |
import org.openconcerto.sql.view.SQLMenuItemHelper.SQLMenuItemAction; |
import org.openconcerto.sql.view.list.RowAction; |
import org.openconcerto.sql.view.list.RowActionFactory; |
import org.openconcerto.utils.CollectionMap; |
import java.util.ArrayList; |
37,8 → 37,6 |
import javax.swing.JMenuItem; |
import javax.swing.text.JTextComponent; |
import org.openconcerto.sql.view.list.RowActionFactory; |
/** |
* Allow a module to add JComponent to edit fields. |
* |
174,7 → 172,7 |
return this.menuItems; |
} |
public final void addFileDropHandler(SQLTable table, FileDropHandler handler) { |
DropManager.getInstance().add(table, handler); |
public final void addFileDropHandler(final String tableName, FileDropHandler handler) { |
DropManager.getInstance().add(this.getRoot().getTable(tableName), handler); |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/erp/modules/DBContext.java |
---|
27,7 → 27,9 |
import java.util.ArrayList; |
import java.util.Collections; |
import java.util.HashSet; |
import java.util.LinkedHashMap; |
import java.util.List; |
import java.util.Map; |
import java.util.Set; |
/** |
121,10 → 123,14 |
// getter |
final List<String> getAddedTables() { |
final List<String> res = new ArrayList<String>(); |
return new ArrayList<String>(getCreateTables().keySet()); |
} |
final Map<String, SQLCreateTableBase<?>> getCreateTables() { |
final Map<String, SQLCreateTableBase<?>> res = new LinkedHashMap<String, SQLCreateTableBase<?>>(); |
for (final ChangeTable<?> a : this.changeTables) { |
if (a instanceof SQLCreateTableBase<?>) { |
res.add(a.getName()); |
res.put(a.getName(), (SQLCreateTableBase<?>) a); |
} |
} |
return res; |
/trunk/OpenConcerto/src/org/openconcerto/erp/action/NouvelleConnexionAction.java |
---|
15,6 → 15,7 |
import static org.openconcerto.task.config.ComptaBasePropsConfiguration.getStreamStatic; |
import org.openconcerto.erp.config.ComptaPropsConfiguration; |
import org.openconcerto.erp.config.Gestion; |
import org.openconcerto.erp.config.MainFrame; |
import org.openconcerto.erp.core.common.ui.PanelFrame; |
import org.openconcerto.erp.core.common.ui.StatusPanel; |
36,6 → 37,7 |
import org.openconcerto.sql.model.UndefinedRowValuesCache; |
import org.openconcerto.sql.model.Where; |
import org.openconcerto.sql.preferences.UserProps; |
import org.openconcerto.sql.sqlobject.IComboSelectionItem; |
import org.openconcerto.sql.ui.ConnexionPanel; |
import org.openconcerto.sql.users.User; |
import org.openconcerto.sql.users.UserManager; |
45,17 → 47,13 |
import org.openconcerto.task.config.ComptaBasePropsConfiguration; |
import org.openconcerto.ui.DefaultGridBagConstraints; |
import org.openconcerto.ui.FrameUtil; |
import org.openconcerto.ui.state.WindowStateManager; |
import org.openconcerto.utils.ExceptionHandler; |
import org.openconcerto.utils.ExceptionUtils; |
import org.openconcerto.utils.JImage; |
import java.awt.Color; |
import java.awt.Dimension; |
import java.awt.GridBagConstraints; |
import java.awt.GridBagLayout; |
import java.awt.Insets; |
import java.io.File; |
import java.io.InputStream; |
import java.sql.SQLException; |
import java.util.ArrayList; |
99,8 → 97,20 |
} |
}); |
} |
final int selectedSociete = NouvelleConnexionAction.this.connexionPanel == null ? UserProps.getInstance().getLastSocieteID() : NouvelleConnexionAction.this.connexionPanel |
.getSelectedSociete(); |
int selectedSociete; |
if (NouvelleConnexionAction.this.connexionPanel != null && !Gestion.isMinimalMode()) { |
selectedSociete = NouvelleConnexionAction.this.connexionPanel.getSelectedSociete(); |
} else { |
selectedSociete = UserProps.getInstance().getLastSocieteID(); |
if (selectedSociete < SQLRow.MIN_VALID_ID) { |
final SQLElement elem = comptaPropsConfiguration.getDirectory().getElement(comptaPropsConfiguration.getRoot().getTable("SOCIETE_COMMON")); |
final List<IComboSelectionItem> comboItems = elem.getComboRequest().getComboItems(); |
if (comboItems.size() > 0) |
selectedSociete = comboItems.get(0).getId(); |
else |
throw new IllegalStateException("No " + elem + " found"); |
} |
} |
comptaPropsConfiguration.setUpSocieteDataBaseConnexion(selectedSociete); |
112,14 → 122,10 |
StatusPanel.getInstance().fireStatusChanged(); |
final JFrame f = new MainFrame(); |
final File f2 = new File(Configuration.getInstance().getConfDir(), "Configuration" + File.separator + "Frame" + File.separator + "mainFrame.xml"); |
WindowStateManager manager = new WindowStateManager(f, f2); |
String version = comptaPropsConfiguration.getVersion(); |
f.setTitle(comptaPropsConfiguration.getAppName() + " " + version + ", " + " [Société " + comptaPropsConfiguration.getRowSociete().getString("NOM") + "]"); |
f.setMinimumSize(new Dimension(800, 600)); |
// f.setResizable(false); |
final String socTitle = comptaPropsConfiguration.getRowSociete() == null ? "" : ", [Société " + comptaPropsConfiguration.getRowSociete().getString("NOM") + "]"; |
f.setTitle(comptaPropsConfiguration.getAppName() + " " + version + socTitle); |
f.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); |
manager.loadState(); |
FrameUtil.show(f); |
} |
173,7 → 179,7 |
c.insets = new Insets(0, 0, 0, 0); |
c.fill = GridBagConstraints.BOTH; |
this.connexionPanel = ConnexionPanel.create(r, image, true); |
this.connexionPanel = ConnexionPanel.create(r, image, !Gestion.isMinimalMode()); |
if (this.connexionPanel == null) |
return null; |
/trunk/OpenConcerto/src/org/openconcerto/erp/panel/ChargementCreationSocietePanel.java |
---|
23,6 → 23,7 |
import org.openconcerto.sql.model.SQLTable; |
import org.openconcerto.sql.model.Where; |
import org.openconcerto.ui.JLabelBold; |
import org.openconcerto.utils.ExceptionHandler; |
import java.awt.GridBagConstraints; |
import java.awt.GridBagLayout; |
71,8 → 72,9 |
this.add(this.progressBar, c); |
this.progressBar.setIndeterminate(true); |
new Thread() { |
new Thread("Creation de societe") { |
public void run() { |
try { |
creationBase(idSoc); |
statusChanged("Importation du plan comptable"); |
86,11 → 88,14 |
((JFrame) SwingUtilities.getRoot(ChargementCreationSocietePanel.this)).dispose(); |
} |
}); |
} catch (Throwable e) { |
ExceptionHandler.handle("Erreur pendant la création de la base!", e); |
} |
} |
}.start(); |
} |
private void creationBase(int id) { |
private void creationBase(int id) throws SQLException { |
System.err.println("Création de la base"); |
99,13 → 104,10 |
statusChanged("Mise à jour des sociétés"); |
SQLRowValues rowVals = new SQLRowValues(Configuration.getInstance().getBase().getTable("SOCIETE_COMMON")); |
rowVals.put("DATABASE_NAME", "OpenConcerto" + id); |
try { |
rowVals.update(id); |
} catch (SQLException e) { |
e.printStackTrace(); |
} |
} |
private void importationPlanComptable(int id, int typePCG) { |
/trunk/OpenConcerto/src/org/openconcerto/erp/utils/ActionDB.java |
---|
116,7 → 116,7 |
log(l, "Duplication terminée"); |
} catch (SQLException e) { |
} catch (Throwable e) { |
e.printStackTrace(); |
ExceptionHandler.handle("Erreur pendant la création de la base!", e); |
log(l, "Erreur pendant la duplication"); |
/trunk/OpenConcerto/src/org/openconcerto/erp/importer/DataImporter.java |
---|
35,7 → 35,6 |
import java.nio.charset.Charset; |
import java.sql.SQLException; |
import java.util.ArrayList; |
import java.util.Collection; |
import java.util.Collections; |
import java.util.HashMap; |
import java.util.Iterator; |
/trunk/OpenConcerto/src/org/openconcerto/erp/importer/EqualsConstraint.java |
---|
New file |
0,0 → 1,35 |
/* |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
* |
* Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved. |
* |
* The contents of this file are subject to the terms of the GNU General Public License Version 3 |
* only ("GPL"). You may not use this file except in compliance with the License. You can obtain a |
* copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific |
* language governing permissions and limitations under the License. |
* |
* When distributing the software, include this License Header Notice in each file. |
*/ |
package org.openconcerto.erp.importer; |
public class EqualsConstraint implements Constraint { |
private String value; |
public EqualsConstraint(String string) { |
this.value = string; |
} |
@Override |
public boolean isValid(Object obj) { |
if (obj == null) { |
return (value == null); |
} |
if (obj instanceof String) { |
return value.equals((String) obj); |
} |
return value.equals(obj.toString()); |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/erp/importer/CentsValueConverter.java |
---|
New file |
0,0 → 1,45 |
/* |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
* |
* Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved. |
* |
* The contents of this file are subject to the terms of the GNU General Public License Version 3 |
* only ("GPL"). You may not use this file except in compliance with the License. You can obtain a |
* copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific |
* language governing permissions and limitations under the License. |
* |
* When distributing the software, include this License Header Notice in each file. |
*/ |
package org.openconcerto.erp.importer; |
import org.openconcerto.sql.model.SQLField; |
public class CentsValueConverter extends ValueConverter { |
public CentsValueConverter(SQLField f) { |
super(f); |
} |
public Object convertFrom(Object obj) { |
long result = 0; |
if (obj != null) { |
try { |
String string = obj.toString(); |
int index = string.indexOf("."); |
if (index >= 0) { |
string = string.substring(0, index) + string.substring(index + 1, string.length()); |
} else { |
index = string.indexOf(","); |
if (index >= 0) { |
string = string.substring(0, index) + string.substring(index + 1, string.length()); |
} |
} |
result = Integer.parseInt(string); |
} catch (Exception e) { |
e.printStackTrace(); |
} |
} |
return result; |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/erp/importer/RowValuesNavigatorPanel.java |
---|
New file |
0,0 → 1,145 |
/* |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
* |
* Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved. |
* |
* The contents of this file are subject to the terms of the GNU General Public License Version 3 |
* only ("GPL"). You may not use this file except in compliance with the License. You can obtain a |
* copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific |
* language governing permissions and limitations under the License. |
* |
* When distributing the software, include this License Header Notice in each file. |
*/ |
package org.openconcerto.erp.importer; |
import org.openconcerto.sql.model.SQLRowValues; |
import org.openconcerto.ui.DefaultGridBagConstraints; |
import java.awt.Dimension; |
import java.awt.GridBagConstraints; |
import java.awt.GridBagLayout; |
import java.awt.event.ActionEvent; |
import java.awt.event.ActionListener; |
import java.util.Collections; |
import java.util.List; |
import javax.swing.JButton; |
import javax.swing.JLabel; |
import javax.swing.JOptionPane; |
import javax.swing.JPanel; |
import javax.swing.JProgressBar; |
import javax.swing.JTabbedPane; |
import javax.swing.SwingUtilities; |
public class RowValuesNavigatorPanel extends JPanel implements ActionListener { |
private JTabbedPane tabbedPane; |
private List<SQLRowValues> updateList = Collections.EMPTY_LIST; |
private List<SQLRowValues> insertList = Collections.EMPTY_LIST;; |
private JProgressBar pBar; |
private JButton bImport; |
private JLabel pLabel = new JLabel("Prêt à importer"); |
final JLabel lNothing = new JLabel(" Pas de données à importer"); |
public RowValuesNavigatorPanel() { |
this.setLayout(new GridBagLayout()); |
GridBagConstraints c = new DefaultGridBagConstraints(); |
c.weightx = 1; |
c.weighty = 1; |
c.gridwidth = 3; |
c.fill = GridBagConstraints.BOTH; |
tabbedPane = new JTabbedPane(); |
tabbedPane.setMinimumSize(new Dimension(480, 640)); |
tabbedPane.setPreferredSize(new Dimension(480, 640)); |
tabbedPane.add("Données à importer", lNothing); |
this.add(tabbedPane, c); |
// Line 2 |
c.gridwidth = 1; |
c.gridy++; |
pBar = new JProgressBar(); |
c.weighty = 0; |
c.fill = GridBagConstraints.HORIZONTAL; |
this.add(pBar, c); |
c.gridx++; |
c.fill = GridBagConstraints.NONE; |
c.weightx = 0; |
pLabel.setMinimumSize(pLabel.getPreferredSize()); |
this.add(pLabel, c); |
c.gridx++; |
bImport = new JButton("Importer les données"); |
bImport.addActionListener(this); |
this.add(bImport, c); |
} |
public void setRowValuesToUpdate(List<SQLRowValues> list) { |
this.updateList = list; |
if (list.size() > 0) { |
tabbedPane.remove(lNothing); |
tabbedPane.add("Lignes à modifier", new RowValuesNavigatorMainPanel(list)); |
} |
} |
public void setRowValuesToInsert(List<SQLRowValues> list) { |
this.insertList = list; |
if (list.size() > 0) { |
tabbedPane.remove(lNothing); |
tabbedPane.add("Lignes à ajouter", new RowValuesNavigatorMainPanel(list)); |
} |
} |
int c = 0; |
@Override |
public void actionPerformed(ActionEvent e) { |
pBar.setMinimum(0); |
final int size = this.insertList.size() + this.updateList.size(); |
pBar.setMaximum(size); |
bImport.setEnabled(false); |
Thread t = new Thread("Importer") { |
public void run() { |
c = 0; |
try { |
for (SQLRowValues row : insertList) { |
row.insert(); |
updateBar(); |
} |
for (SQLRowValues row : updateList) { |
row.update(); |
updateBar(); |
} |
SwingUtilities.invokeLater(new Runnable() { |
@Override |
public void run() { |
pBar.setValue(pBar.getMaximum()); |
pLabel.setText("Import terminé"); |
} |
}); |
JOptionPane.showMessageDialog(RowValuesNavigatorPanel.this, "Import terminé"); |
} catch (Exception e) { |
e.printStackTrace(); |
JOptionPane.showMessageDialog(RowValuesNavigatorPanel.this, "Erreur pendant l'importation"); |
} |
} |
private void updateBar() { |
c++; |
if (c % 5 == 0) { |
SwingUtilities.invokeLater(new Runnable() { |
@Override |
public void run() { |
pBar.setValue(c); |
pLabel.setText((c + 1) + "/" + size); |
} |
}); |
} |
}; |
}; |
t.start(); |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/erp/importer/DoubleAsLongValueConverter.java |
---|
New file |
0,0 → 1,33 |
/* |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
* |
* Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved. |
* |
* The contents of this file are subject to the terms of the GNU General Public License Version 3 |
* only ("GPL"). You may not use this file except in compliance with the License. You can obtain a |
* copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific |
* language governing permissions and limitations under the License. |
* |
* When distributing the software, include this License Header Notice in each file. |
*/ |
package org.openconcerto.erp.importer; |
import org.openconcerto.sql.model.SQLField; |
public class DoubleAsLongValueConverter extends ValueConverter { |
public DoubleAsLongValueConverter(SQLField f) { |
super(f); |
} |
@Override |
public Object convertFrom(Object obj) { |
if (obj instanceof Double) { |
Long l = Math.round((Double) obj); |
return super.convertFrom(l); |
} |
return super.convertFrom(obj); |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/erp/importer/RowValuesNavigatorPanel2.java |
---|
New file |
0,0 → 1,131 |
/* |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
* |
* Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved. |
* |
* The contents of this file are subject to the terms of the GNU General Public License Version 3 |
* only ("GPL"). You may not use this file except in compliance with the License. You can obtain a |
* copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific |
* language governing permissions and limitations under the License. |
* |
* When distributing the software, include this License Header Notice in each file. |
*/ |
package org.openconcerto.erp.importer; |
import org.openconcerto.sql.model.SQLRowValues; |
import org.openconcerto.ui.DefaultGridBagConstraints; |
import java.awt.FlowLayout; |
import java.awt.GridBagConstraints; |
import java.awt.GridBagLayout; |
import java.awt.event.ActionEvent; |
import java.awt.event.ActionListener; |
import java.util.List; |
import javax.swing.JButton; |
import javax.swing.JLabel; |
import javax.swing.JPanel; |
import javax.swing.JTextField; |
public class RowValuesNavigatorPanel2 extends JPanel implements ActionListener { |
private List<SQLRowValues> list; |
private int currentIndex = -1; |
private GridBagConstraints pConstraint; |
JPanel currentPanel; |
JButton bFirst = new JButton("<<"); |
JButton bPrevious = new JButton("<"); |
JButton bNext = new JButton(">"); |
JButton bLast = new JButton(">>"); |
private JTextField indexText; |
public RowValuesNavigatorPanel2(List<SQLRowValues> list) { |
this.setOpaque(false); |
this.list = list; |
this.setLayout(new GridBagLayout()); |
GridBagConstraints c = new DefaultGridBagConstraints(); |
c.fill = GridBagConstraints.NONE; |
final JPanel buttons = new JPanel(); |
buttons.setOpaque(false); |
buttons.setLayout(new FlowLayout()); |
buttons.add(bFirst); |
buttons.add(bPrevious); |
buttons.add(bNext); |
buttons.add(bLast); |
indexText = new JTextField(6); |
indexText.setText("1"); |
buttons.add(indexText); |
buttons.add(new JLabel(" / " + list.size())); |
this.add(buttons, c); |
c.fill = GridBagConstraints.BOTH; |
c.weightx = 1; |
c.weighty = 0; |
c.gridy++; |
pConstraint = (GridBagConstraints) c.clone(); |
currentPanel = new JPanel(); |
this.add(currentPanel, c); |
setCurrentIndex(0); |
JPanel spacer = new JPanel(); |
spacer.setOpaque(false); |
c.gridy++; |
c.weighty = 1; |
this.add(spacer, c); |
bFirst.setOpaque(false); |
bPrevious.setOpaque(false); |
bNext.setOpaque(false); |
bLast.setOpaque(false); |
bFirst.addActionListener(this); |
bPrevious.addActionListener(this); |
bNext.addActionListener(this); |
bLast.addActionListener(this); |
} |
private void setCurrentIndex(int i) { |
if (this.currentIndex == i) { |
return; |
} |
this.indexText.setText(String.valueOf(i + 1)); |
this.currentIndex = i; |
this.remove(currentPanel); |
RowValuesPanel p = new RowValuesPanel(this.list.get(i)); |
p.setOpaque(false); |
this.invalidate(); |
this.currentPanel = p; |
this.add(currentPanel, pConstraint); |
this.revalidate(); |
this.repaint(); |
this.bFirst.setEnabled(currentIndex > 0); |
this.bPrevious.setEnabled(currentIndex > 0); |
this.bNext.setEnabled(currentIndex < list.size() - 1); |
this.bLast.setEnabled(currentIndex < list.size() - 1); |
} |
@Override |
public void actionPerformed(ActionEvent e) { |
if (e.getSource().equals(bFirst)) { |
setCurrentIndex(0); |
} |
if (e.getSource().equals(bPrevious)) { |
setCurrentIndex(currentIndex - 1); |
} |
if (e.getSource().equals(bNext)) { |
setCurrentIndex(currentIndex + 1); |
} |
if (e.getSource().equals(bLast)) { |
setCurrentIndex(this.list.size() - 1); |
} |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/erp/importer/RowValuesNavigatorMainPanel.java |
---|
New file |
0,0 → 1,131 |
/* |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
* |
* Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved. |
* |
* The contents of this file are subject to the terms of the GNU General Public License Version 3 |
* only ("GPL"). You may not use this file except in compliance with the License. You can obtain a |
* copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific |
* language governing permissions and limitations under the License. |
* |
* When distributing the software, include this License Header Notice in each file. |
*/ |
package org.openconcerto.erp.importer; |
import org.openconcerto.sql.model.SQLRowValues; |
import org.openconcerto.ui.DefaultGridBagConstraints; |
import java.awt.FlowLayout; |
import java.awt.GridBagConstraints; |
import java.awt.GridBagLayout; |
import java.awt.event.ActionEvent; |
import java.awt.event.ActionListener; |
import java.util.List; |
import javax.swing.JButton; |
import javax.swing.JLabel; |
import javax.swing.JPanel; |
import javax.swing.JTextField; |
public class RowValuesNavigatorMainPanel extends JPanel implements ActionListener { |
private List<SQLRowValues> list; |
private int currentIndex = -1; |
private GridBagConstraints pConstraint; |
JPanel currentPanel; |
JButton bFirst = new JButton("<<"); |
JButton bPrevious = new JButton("<"); |
JButton bNext = new JButton(">"); |
JButton bLast = new JButton(">>"); |
private JTextField indexText; |
public RowValuesNavigatorMainPanel(List<SQLRowValues> list) { |
this.setOpaque(false); |
this.list = list; |
this.setLayout(new GridBagLayout()); |
GridBagConstraints c = new DefaultGridBagConstraints(); |
c.fill = GridBagConstraints.NONE; |
final JPanel buttons = new JPanel(); |
buttons.setOpaque(false); |
buttons.setLayout(new FlowLayout()); |
buttons.add(bFirst); |
buttons.add(bPrevious); |
buttons.add(bNext); |
buttons.add(bLast); |
indexText = new JTextField(6); |
indexText.setText("1"); |
buttons.add(indexText); |
buttons.add(new JLabel(" / " + list.size())); |
this.add(buttons, c); |
c.fill = GridBagConstraints.BOTH; |
c.weightx = 1; |
c.weighty = 0; |
c.gridy++; |
pConstraint = (GridBagConstraints) c.clone(); |
currentPanel = new JPanel(); |
this.add(currentPanel, c); |
setCurrentIndex(0); |
JPanel spacer = new JPanel(); |
spacer.setOpaque(false); |
c.gridy++; |
c.weighty = 1; |
this.add(spacer, c); |
bFirst.setOpaque(false); |
bPrevious.setOpaque(false); |
bNext.setOpaque(false); |
bLast.setOpaque(false); |
bFirst.addActionListener(this); |
bPrevious.addActionListener(this); |
bNext.addActionListener(this); |
bLast.addActionListener(this); |
} |
private void setCurrentIndex(int i) { |
if (this.currentIndex == i) { |
return; |
} |
this.indexText.setText(String.valueOf(i + 1)); |
this.currentIndex = i; |
this.remove(currentPanel); |
RowValuesPanel p = new RowValuesPanel(this.list.get(i)); |
p.setOpaque(false); |
this.invalidate(); |
this.currentPanel = p; |
this.add(currentPanel, pConstraint); |
this.revalidate(); |
this.repaint(); |
this.bFirst.setEnabled(currentIndex > 0); |
this.bPrevious.setEnabled(currentIndex > 0); |
this.bNext.setEnabled(currentIndex < list.size() - 1); |
this.bLast.setEnabled(currentIndex < list.size() - 1); |
} |
@Override |
public void actionPerformed(ActionEvent e) { |
if (e.getSource().equals(bFirst)) { |
setCurrentIndex(0); |
} |
if (e.getSource().equals(bPrevious)) { |
setCurrentIndex(currentIndex - 1); |
} |
if (e.getSource().equals(bNext)) { |
setCurrentIndex(currentIndex + 1); |
} |
if (e.getSource().equals(bLast)) { |
setCurrentIndex(this.list.size() - 1); |
} |
} |
} |
/trunk/OpenConcerto/src/org/openconcerto/erp/importer/RowValuesPanel.java |
---|
New file |
0,0 → 1,80 |
/* |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. |
* |
* Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved. |
* |
* The contents of this file are subject to the terms of the GNU General Public License Version 3 |
* only ("GPL"). You may not use this file except in compliance with the License. You can obtain a |
* copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific |
* language governing permissions and limitations under the License. |
* |
* When distributing the software, include this License Header Notice in each file. |
*/ |
package org.openconcerto.erp.importer; |
import org.openconcerto.sql.Configuration; |
import org.openconcerto.sql.model.SQLField; |
import org.openconcerto.sql.model.SQLRowValues; |
import org.openconcerto.ui.DefaultGridBagConstraints; |
import java.awt.GridBagConstraints; |
import java.awt.GridBagLayout; |
import java.util.Map; |
import javax.swing.JLabel; |
import javax.swing.JPanel; |
import javax.swing.JTextField; |
import javax.swing.SwingConstants; |
public class RowValuesPanel extends JPanel { |
public RowValuesPanel(SQLRowValues sqlRowValues) { |
this.setLayout(new GridBagLayout()); |
GridBagConstraints c = new DefaultGridBagConstraints(); |
Map<String, Object> m = sqlRowValues.getAbsolutelyAll(); |
String[] p = m.keySet().toArray(new String[0]); |
for (int i = 0; i < p.length; i++) { |
c.gridx = 0; |
c.weightx = 0; |
String key = p[i]; |
SQLField f = sqlRowValues.getTable().getField(key); |
String name = Configuration.getTranslator(f.getTable()).getDescFor(f.getTable(), f.getName()).getLabel(); |
if (name == null) { |
name = key; |
} |
String value = "null"; |
if (m.get(key) != null) { |
if (m.get(key) instanceof SQLRowValues) { |
SQLRowValues rv = (SQLRowValues) m.get(key); |
this.add(new JLabel(name, SwingConstants.RIGHT), c); |
c.gridx++; |
c.weightx = 1; |
final RowValuesPanel comp = new RowValuesPanel(rv); |
comp.setOpaque(false); |
this.add(comp, c); |
} else { |
c.gridwidth = 1; |
value = m.get(key).toString(); |
this.add(new JLabel(name, SwingConstants.RIGHT), c); |
c.gridx++; |
c.weightx = 1; |
final JTextField comp = new JTextField(20); |
comp.setText(value); |
comp.setEditable(false); |
this.add(comp, c); |
} |
} |
c.gridy++; |
} |
} |
} |