OpenConcerto

Dépôt officiel du code source de l'ERP OpenConcerto
sonarqube

svn://code.openconcerto.org/openconcerto

Rev

Rev 73 | Rev 180 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
20 ilm 1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
5
 *
6
 * The contents of this file are subject to the terms of the GNU General Public License Version 3
7
 * only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
8
 * copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
9
 * language governing permissions and limitations under the License.
10
 *
11
 * When distributing the software, include this License Header Notice in each file.
12
 */
13
 
14
 package org.openconcerto.openoffice.style.data;
15
 
16
import org.openconcerto.openoffice.ODPackage;
25 ilm 17
import org.openconcerto.openoffice.ODValueType;
21 ilm 18
import org.openconcerto.openoffice.StyleProperties;
20 ilm 19
import org.openconcerto.openoffice.XMLVersion;
20
import org.openconcerto.openoffice.spreadsheet.CellStyle;
25 ilm 21
import org.openconcerto.utils.TimeUtils;
22
import org.openconcerto.utils.convertor.NumberConvertor;
20 ilm 23
 
21 ilm 24
import java.math.BigDecimal;
25
import java.text.DateFormatSymbols;
25 ilm 26
import java.util.Calendar;
21 ilm 27
import java.util.List;
28
import java.util.Locale;
29
 
20 ilm 30
import javax.xml.datatype.Duration;
31
 
32
import org.jdom.Element;
21 ilm 33
import org.jdom.Namespace;
20 ilm 34
 
35
// from section 16.27.18 in v1.2-cs01-part1
36
public class TimeStyle extends DataStyle {
37
 
65 ilm 38
    static final DataStyleDesc<TimeStyle> DESC = new DataStyleDesc<TimeStyle>(TimeStyle.class, XMLVersion.OD, "time-style", "N") {
20 ilm 39
        @Override
40
        public TimeStyle create(ODPackage pkg, Element e) {
41
            return new TimeStyle(pkg, e);
42
        }
43
    };
44
 
21 ilm 45
    private static final int DAY_LENGTH_IN_HOURS = 24;
46
    private static final int AM_LENGTH = DAY_LENGTH_IN_HOURS / 2;
47
 
48
    private static final String formatInt(int i, Element elem) {
49
        final String res = String.valueOf(i);
50
        return !DateStyle.isShort(elem) && res.length() < 2 ? '0' + res : res;
51
    }
52
 
20 ilm 53
    public TimeStyle(final ODPackage pkg, Element elem) {
25 ilm 54
        super(pkg, elem, ODValueType.TIME);
20 ilm 55
    }
56
 
57
    @Override
25 ilm 58
    protected Duration convertNonNull(Object o) {
59
        if (o instanceof Number) {
60
            return TimeUtils.timePartToDuration(getEpoch().getDate(NumberConvertor.toBigDecimal((Number) o)));
61
        } else {
62
            return null;
63
        }
64
    }
65
 
66
    @Override
20 ilm 67
    public String format(Object o, CellStyle defaultStyle, boolean lenient) {
25 ilm 68
        final Duration d = o instanceof Calendar ? TimeUtils.timePartToDuration((Calendar) o) : (Duration) o;
21 ilm 69
        final Namespace numberNS = this.getElement().getNamespace();
70
        final StringBuilder sb = new StringBuilder();
71
 
174 ilm 72
        final Locale styleLocale = this.getLocale();
21 ilm 73
        final boolean truncate = StyleProperties.parseBoolean(getElement().getAttributeValue("truncate-on-overflow", numberNS), true);
74
        @SuppressWarnings("unchecked")
75
        final List<Element> children = this.getElement().getChildren();
76
        for (final Element elem : children) {
77
            if (elem.getNamespace().equals(numberNS)) {
78
                if (elem.getName().equals("text")) {
79
                    sb.append(elem.getText());
80
                } else if (elem.getName().equals("hours")) {
81
                    int hours = d.getHours();
82
                    if (truncate)
83
                        hours = hours % DAY_LENGTH_IN_HOURS;
84
                    if (elem.getChild("am-pm", numberNS) != null) {
85
                        // Duration fields are never negative
86
                        hours = d.getHours() == 0 ? AM_LENGTH : (d.getHours() - 1) % AM_LENGTH + 1;
87
                        assert hours >= 1 && hours <= AM_LENGTH;
88
                    }
89
                    sb.append(formatInt(hours, elem));
90
                } else if (elem.getName().equals("am-pm")) {
91
                    final boolean am = d.getHours() % DAY_LENGTH_IN_HOURS < AM_LENGTH;
92
                    sb.append(new DateFormatSymbols(styleLocale).getAmPmStrings()[am ? 0 : 1]);
93
                } else if (elem.getName().equals("minutes")) {
94
                    final int minutes;
95
                    if (truncate && getElement().getChild("hours", numberNS) == null)
96
                        minutes = d.getMinutes() % 60;
97
                    else
98
                        minutes = d.getMinutes();
99
                    sb.append(formatInt(minutes, elem));
100
                } else if (elem.getName().equals("seconds")) {
73 ilm 101
                    final BigDecimal seconds = TimeUtils.getSeconds(d);
21 ilm 102
                    final int secondsIntPart;
103
                    if (truncate && getElement().getChild("hours", numberNS) == null && getElement().getChild("minutes", numberNS) == null)
104
                        secondsIntPart = seconds.intValue() % 60;
105
                    else
106
                        secondsIntPart = seconds.intValue();
107
                    sb.append(formatInt(secondsIntPart, elem));
108
 
109
                    final int decPlaces = StyleProperties.parseInt(elem.getAttributeValue("decimal-places", numberNS), 0);
110
                    sb.append(DateStyle.formatSecondFraction(styleLocale, seconds, decPlaces));
111
                }
112
            }
113
        }
114
 
115
        return sb.toString();
20 ilm 116
    }
117
}