OpenConcerto

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

svn://code.openconcerto.org/openconcerto

Rev

Rev 137 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
137 ilm 1
package org.jopencalendar.ui;
2
 
3
import java.awt.Color;
4
import java.awt.Font;
5
import java.awt.Graphics;
6
import java.awt.Graphics2D;
7
import java.awt.Rectangle;
8
import java.awt.RenderingHints;
9
import java.text.DateFormat;
10
import java.text.SimpleDateFormat;
11
import java.util.ArrayList;
12
import java.util.Calendar;
13
import java.util.List;
14
 
15
import javax.swing.Scrollable;
16
import javax.swing.SwingWorker;
17
 
18
import org.jopencalendar.model.JCalendarItem;
19
 
20
public class WeekView extends MultipleDayView implements Scrollable {
21
 
22
    private final JCalendarItemProvider manager;
23
 
24
    // Current week
25
    private int week;
26
    private int year;
27
    // Date of columns
28
    private int[] daysOfYear = new int[7];
29
    private int[] years = new int[7];
30
    private final SimpleDateFormat monthAndYearFormat = new SimpleDateFormat("MMMM yyyy");
31
 
32
    private boolean weekEndMinimised = true;
33
 
34
    public WeekView(JCalendarItemProvider manager) {
35
        if (manager == null) {
36
            throw new IllegalArgumentException("null manager");
37
        }
38
        this.manager = manager;
39
 
40
    }
41
 
42
    /**
43
     * Load week
44
     *
45
     * @param week the week number (1 - 52)
178 ilm 46
     */
137 ilm 47
    public void loadWeek(final int week, final int year, boolean forceReload) {
178 ilm 48
        if (!forceReload && week == this.week && year == this.year) {
49
            return;
137 ilm 50
        }
51
        this.week = week;
52
        this.year = year;
53
        Calendar c = getFirstDayCalendar();
54
        final int columnCount = this.getColumnCount();
55
        for (int i = 0; i < columnCount; i++) {
56
            this.daysOfYear[i] = c.get(Calendar.DAY_OF_YEAR);
57
            this.years[i] = c.get(Calendar.YEAR);
58
            c.add(Calendar.HOUR_OF_DAY, 24);
59
        }
60
 
61
        SwingWorker<List<JCalendarItem>, Object> w = new SwingWorker<List<JCalendarItem>, Object>() {
62
 
63
            @Override
64
            protected List<JCalendarItem> doInBackground() throws Exception {
178 ilm 65
                return WeekView.this.manager.getItemInWeek(week, year);
137 ilm 66
            }
67
 
178 ilm 68
            @Override
137 ilm 69
            protected void done() {
70
                try {
71
                    List<JCalendarItem> l = get();
178 ilm 72
                    List<List<JCalendarItem>> items = new ArrayList<>();
137 ilm 73
                    for (int i = 0; i < columnCount; i++) {
178 ilm 74
                        List<JCalendarItem> list = new ArrayList<>();
75
                        int d = WeekView.this.daysOfYear[i];
76
                        int y = WeekView.this.years[i];
137 ilm 77
                        for (JCalendarItem jCalendarItem : l) {
78
                            if (jCalendarItem.getDtStart().get(Calendar.DAY_OF_YEAR) == d && jCalendarItem.getDtStart().get(Calendar.YEAR) == y) {
79
                                list.add(jCalendarItem);
80
                            }
81
                        }
82
                        items.add(list);
83
                    }
84
                    setItems(items);
85
                } catch (Exception e) {
86
                    throw new IllegalStateException("error while getting items", e);
87
                }
88
 
178 ilm 89
            }
137 ilm 90
        };
91
        w.execute();
92
    }
93
 
94
    public void setWeekEndMinimised(boolean b) {
178 ilm 95
        this.weekEndMinimised = b;
137 ilm 96
        repaint();
97
    }
98
 
178 ilm 99
    @Override
137 ilm 100
    public void paintHeader(Graphics g) {
101
        g.setColor(Color.WHITE);
102
        g.fillRect(0, 0, this.getWidth() + 100, getHeaderHeight());
103
        g.setColor(Color.GRAY);
104
        // Vertical lines
105
        int columnCount = 7;
106
        int x = HOURS_LABEL_WIDTH;
107
 
108
        for (int i = 0; i < columnCount - 1; i++) {
109
            x += getColumnWidth(i);
110
            g.drawLine(x, YEAR_HEIGHT, x, this.getHeaderHeight());
111
        }
112
        g.setColor(Color.DARK_GRAY);
113
        // Text : month & year
114
        Graphics2D g2 = (Graphics2D) g;
115
        g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
116
        g.setFont(getFont().deriveFont(13f));
117
        int month = getMonth(this.daysOfYear[0], this.years[0]);
118
        int count = 1;
119
        for (int i = 1; i < columnCount; i++) {
120
            int m = getMonth(this.daysOfYear[i], this.years[i]);
121
            if (m == month) {
122
                count++;
123
            }
124
        }
125
        if (count == 7) {
126
            String str = getMonthName(this.daysOfYear[0], this.years[0]);
127
            Rectangle r = g.getFontMetrics().getStringBounds(str, g).getBounds();
128
            int w = 0;
129
            for (int i = 0; i < count; i++) {
130
                w += getColumnWidth(i);
131
            }
132
            g.drawString(str, (int) (HOURS_LABEL_WIDTH + (w - r.getWidth()) / 2), 15);
133
        } else {
134
            // draw left month
135
            String strLeft = getMonthName(this.daysOfYear[0], this.years[0]);
136
            Rectangle r1 = g.getFontMetrics().getStringBounds(strLeft, g).getBounds();
137
 
138
            int wLeft = 0;
139
            for (int i = 0; i < count; i++) {
140
                wLeft += getColumnWidth(i);
141
            }
142
            int wRight = 0;
143
            for (int i = count; i < columnCount; i++) {
144
                wRight += getColumnWidth(i);
145
            }
146
 
147
            final int xLeft = (int) (HOURS_LABEL_WIDTH + (wLeft - r1.getWidth()) / 2);
148
            g.drawString(strLeft, xLeft, 15);
149
 
150
            // draw right month
151
            String strRight = getMonthName(this.daysOfYear[columnCount - 1], this.years[columnCount - 1]);
152
            Rectangle r2 = g.getFontMetrics().getStringBounds(strRight, g).getBounds();
153
            final int xRight = (int) (HOURS_LABEL_WIDTH + wLeft + (wRight - r2.getWidth()) / 2);
154
            g.drawString(strRight, xRight, 15);
155
 
156
            // draw separator
157
            g.setColor(Color.GRAY);
158
            int xSep = HOURS_LABEL_WIDTH + wLeft;
159
            g.drawLine(xSep, 0, xSep, YEAR_HEIGHT);
160
        }
161
 
162
        // Text : day
163
        final Font font1 = getFont().deriveFont(12f);
164
        g.setFont(font1);
165
        x = HOURS_LABEL_WIDTH;
166
        Calendar today = Calendar.getInstance();
167
        int todayYear = today.get(Calendar.YEAR);
168
        int todayDay = today.get(Calendar.DAY_OF_YEAR);
169
 
170
        Calendar c = getFirstDayCalendar();
171
        final DateFormat df;
178 ilm 172
        if (!this.weekEndMinimised) {
137 ilm 173
            df = new SimpleDateFormat("EEEE d");
174
        } else {
175
            df = new SimpleDateFormat("E d");
176
        }
177
        for (int i = 0; i < columnCount; i++) {
178
            String str = df.format(c.getTime());
179
            str = str.substring(0, 1).toUpperCase() + str.substring(1);
180
            int columnWidth = getColumnWidth(i);
181
            Rectangle r = g.getFontMetrics().getStringBounds(str, g).getBounds();
182
            if (c.get(Calendar.YEAR) == todayYear && c.get(Calendar.DAY_OF_YEAR) == todayDay) {
183
                g.setColor(new Color(232, 242, 254));
184
                g.fillRect(x + 1, YEAR_HEIGHT, columnWidth - 1, (int) r.getHeight() + 4);
185
                g.setColor(Color.BLACK);
186
            } else {
187
                g.setColor(Color.DARK_GRAY);
188
            }
189
            g.drawString(str, (int) (x + (columnWidth - r.getWidth()) / 2), YEAR_HEIGHT + 15);
190
            x += columnWidth;
191
            c.add(Calendar.HOUR_OF_DAY, 24);
192
        }
193
        paintHeaderAlldays(g);
194
    }
195
 
196
    private int getMonth(int day, int year) {
197
        Calendar c = Calendar.getInstance();
198
        c.set(year, 1, 0, 0, 0, 0);
199
        c.set(Calendar.MILLISECOND, 0);
200
        c.set(Calendar.DAY_OF_YEAR, day);
201
        return c.get(Calendar.MONTH);
202
    }
203
 
204
    private String getMonthName(int day, int year) {
205
        Calendar c = Calendar.getInstance();
206
        c.set(year, 1, 0, 0, 0, 0);
207
        c.set(Calendar.MILLISECOND, 0);
208
        c.set(Calendar.DAY_OF_YEAR, day);
178 ilm 209
        return this.monthAndYearFormat.format(c.getTime()).toUpperCase();
137 ilm 210
    }
211
 
212
    private Calendar getFirstDayCalendar() {
213
        Calendar c = Calendar.getInstance();
214
        c.set(this.year, 1, 0, 0, 0, 0);
215
        c.set(Calendar.MILLISECOND, 0);
216
        c.set(Calendar.WEEK_OF_YEAR, this.week);
217
        c.set(Calendar.DAY_OF_WEEK, c.getFirstDayOfWeek());
218
        return c;
219
    }
220
 
221
    @Override
222
    public String getColumnTitle(int index) {
223
        final DateFormat df;
178 ilm 224
        if (!this.weekEndMinimised) {
137 ilm 225
            df = new SimpleDateFormat("EEEE d");
226
        } else {
227
            df = new SimpleDateFormat("E d");
228
        }
229
        Calendar c = getFirstDayCalendar();
230
        c.add(Calendar.DAY_OF_YEAR, index);
231
 
232
        String str = df.format(c.getTime());
233
        str = str.substring(0, 1).toUpperCase() + str.substring(1);
234
        return str;
235
    }
236
 
237
    @Override
238
    public void reload() {
239
        loadWeek(this.week, this.year, true);
240
    }
241
 
242
    @Override
243
    public int getColumnCount() {
244
        return 7;
245
    }
246
 
247
    @Override
248
    public int getColumnWidth(int column) {
249
        final int c;
178 ilm 250
        if (this.weekEndMinimised) {
137 ilm 251
            int minSize = 50;
252
            if (column == 5 || column == 6) {
253
                return minSize;
254
            } else {
255
                c = (this.getWidth() - HOURS_LABEL_WIDTH - 2 * minSize) / (getColumnCount() - 2);
256
            }
257
 
258
        } else {
259
            c = (this.getWidth() - HOURS_LABEL_WIDTH) / getColumnCount();
260
        }
261
        return c;
262
    }
263
}