OpenConcerto

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

svn://code.openconcerto.org/openconcerto

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
137 ilm 1
package org.jopencalendar.print;
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.event.ActionEvent;
8
import java.awt.event.ActionListener;
9
import java.awt.image.BufferedImage;
10
import java.awt.print.PageFormat;
11
import java.awt.print.Pageable;
12
import java.awt.print.Printable;
13
import java.awt.print.PrinterException;
14
import java.awt.print.PrinterJob;
15
import java.text.DateFormat;
16
import java.util.ArrayList;
17
import java.util.Calendar;
18
import java.util.List;
19
 
20
import javax.print.attribute.HashPrintRequestAttributeSet;
21
import javax.print.attribute.PrintRequestAttributeSet;
22
import javax.print.attribute.standard.PrintQuality;
23
import javax.swing.JButton;
24
import javax.swing.JFrame;
25
import javax.swing.SwingUtilities;
26
import javax.swing.UIManager;
27
 
28
import org.jopencalendar.LayoutUtils;
29
import org.jopencalendar.model.Flag;
30
import org.jopencalendar.model.JCalendarItem;
31
 
32
public class CalendarItemPrinter implements Printable, Pageable {
33
 
34
    private List<JCalendarItem> items;
35
 
36
    private List<CalendarItemPage> pages = null;
37
 
38
    private String title;
39
 
40
    private boolean showDuration = true;
41
 
42
    private PageFormat pf;
43
 
44
    public CalendarItemPrinter(String title, List<JCalendarItem> items, PageFormat pf) {
45
        this.title = title;
46
        this.items = items;
47
        this.pf = pf;
48
    }
49
 
50
    public String getTitle() {
51
        return title;
52
    }
53
 
54
    public static final Font FONT_NORMAL = new Font("Arial", Font.PLAIN, 11);
55
    public static final Font FONT_BOLD = FONT_NORMAL.deriveFont(Font.BOLD);
56
 
57
    public int print(Graphics g, PageFormat pf, int pageIndex) throws PrinterException {
58
 
59
        if (pages == null) {
60
            computeLayout(g, pf);
61
        }
62
 
63
        if (pageIndex >= pages.size()) {
64
            return NO_SUCH_PAGE;
65
        }
66
 
67
        final Graphics2D g2d = (Graphics2D) g;
68
        g2d.translate(pf.getImageableX(), pf.getImageableY());
69
        final CalendarItemPage page = this.pages.get(pageIndex);
70
 
71
        printPage(g, pf, page);
72
 
73
        /* tell the caller that this page is part of the printed document */
74
        return PAGE_EXISTS;
75
    }
76
 
77
    public void printPage(Graphics g, PageFormat pf, final CalendarItemPage page) {
78
        final Graphics2D g2d = (Graphics2D) g;
79
        // Title
80
        g.setFont(getTitleFont());
81
        g.setColor(getTitleColor());
82
        final int xTitle = ((int) pf.getImageableWidth() - (int) g2d.getFontMetrics().getStringBounds(getTitle(), g2d).getWidth()) / 2;
83
        g.drawString(getTitle(), xTitle, g2d.getFontMetrics().getHeight());
84
        // Page number
85
        g.setFont(getPageNumberFont());
86
        g.setColor(getPageNumberColor());
87
        int y = getTitleHeight();
88
        final DateFormat df = DateFormat.getDateInstance(DateFormat.FULL);
89
        final int size = page.getItems().size();
90
        final String strPages = (page.getPageIndex() + 1) + " / " + pages.size();
91
        int xStrPages = (int) pf.getImageableWidth() - (int) g2d.getFontMetrics().getStringBounds(strPages, g2d).getWidth();
92
        g.drawString(strPages, xStrPages, g2d.getFontMetrics().getHeight());
93
 
94
        final double hourColumnWidth = getHourColumnWidth();
95
        for (int i = 0; i < size; i++) {
96
            final JCalendarItem item = page.getItems().get(i);
97
            final double lineHeight = page.getHeights().get(i);
98
            int lY = y;
99
            drawBackground(0, lY, (int) pf.getImageableWidth(), (int) lineHeight);
100
            if (page.getShowDates().get(i)) {
101
                g2d.setColor(getHourColor(item));
102
                g.setFont(getHourFont(item));
103
                int dateHeight = g2d.getFontMetrics().getHeight();
104
                lY += dateHeight;
105
                final String format = getDate(df, item);
106
                g2d.drawString(format, 2, lY);
107
            }
108
            // Vertical bar
109
            g2d.setColor(getVerticalBarColor(item));
110
            g2d.drawLine((int) hourColumnWidth - 5, lY + 6, (int) hourColumnWidth - 5, (int) (y + lineHeight));
111
 
112
            final Calendar dtStart = item.getDtStart();
113
            final Calendar dtEnd = item.getDtEnd();
114
            // Hour
115
            g.setColor(getHourColor(item));
116
            g.setFont(getHourFont(item));
117
            final int hourY = lY + g2d.getFontMetrics().getHeight();
118
            g2d.drawString(formatTime(dtStart) + " - " + formatTime(dtEnd), 3, hourY);
119
            // Duration
120
            if (this.showDuration) {
121
                g.setColor(getDurationColor(item));
122
                g.setFont(getDurationFont(item));
123
                final int durationY = hourY + g2d.getFontMetrics().getHeight();
124
                g2d.drawString(formatDuration(dtStart, dtEnd), 3, durationY);
125
            }
126
 
127
            final double maxWidth = pf.getImageableWidth() - hourColumnWidth;
128
            // Summary
129
            g.setFont(getLine1Font(item));
130
 
131
            final List<String> l1 = LayoutUtils.wrap(getLine1Text(item), g.getFontMetrics(), (int) maxWidth);
132
            if (item.hasFlag(Flag.getFlag("warning"))) {
133
                g2d.setColor(new Color(255, 249, 144));
134
                g2d.fillRect((int) hourColumnWidth - 1, lY + 3, (int) maxWidth, (int) g2d.getFontMetrics().getHeight() * l1.size());
135
            }
136
            g.setColor(getLine1Color(item));
137
            for (String string : l1) {
138
                lY += g2d.getFontMetrics().getHeight();
139
                g2d.drawString(string, (int) hourColumnWidth, lY);
140
            }
141
            // Description
142
            g.setFont(getLine2Font(item));
143
            g.setColor(getLine2Color(item));
144
            final List<String> l2 = LayoutUtils.wrap(getLine2Text(item), g.getFontMetrics(), (int) maxWidth);
145
            for (String string : l2) {
146
                lY += g2d.getFontMetrics().getHeight();
147
                g2d.drawString(string, (int) hourColumnWidth, lY);
148
            }
149
            //
150
            y += lineHeight;
151
        }
152
    }
153
 
154
    public String getDate(final DateFormat df, final JCalendarItem item) {
155
        return LayoutUtils.firstUp(df.format(item.getDtStart().getTime()));
156
    }
157
 
158
    public String formatDuration(Calendar dtStart, Calendar dtEnd) {
159
        long t2 = dtEnd.getTimeInMillis();
160
        long t1 = dtStart.getTimeInMillis();
161
        long seconds = (t2 - t1) / 1000;
162
 
163
        final long minutes = seconds / 60;
164
 
165
        String l = String.valueOf(minutes % 60);
166
        if (l.length() < 2) {
167
            l = "0" + l;
168
        }
169
        return "(" + minutes / 60 + "h" + l + ")";
170
    }
171
 
172
    public void drawBackground(int x, int y, int w, int h) {
173
        // for subclass to add some background
174
    }
175
 
176
    public Color getPageNumberColor() {
177
        return Color.BLACK;
178
    }
179
 
180
    public Font getPageNumberFont() {
181
        return FONT_NORMAL;
182
    }
183
 
184
    // Title
185
    public Color getTitleColor() {
186
        return Color.BLACK;
187
    }
188
 
189
    public Font getTitleFont() {
190
        return FONT_NORMAL;
191
    }
192
 
193
    // Hour
194
    public Color getHourColor(JCalendarItem item) {
195
        return Color.BLACK;
196
    }
197
 
198
    public Font getHourFont(JCalendarItem item) {
199
        return FONT_BOLD;
200
    }
201
 
202
    // Duration
203
    public Color getDurationColor(JCalendarItem item) {
204
        return Color.BLACK;
205
    }
206
 
207
    public Font getDurationFont(JCalendarItem item) {
208
        return FONT_NORMAL;
209
    }
210
 
211
    // Line 1
212
    public Color getLine1Color(final JCalendarItem item) {
213
        return Color.BLACK;
214
    }
215
 
216
    public String getLine1Text(final JCalendarItem item) {
217
        return item.getSummary();
218
    }
219
 
220
    public Font getLine1Font(final JCalendarItem item) {
221
        return FONT_NORMAL;
222
    }
223
 
224
    // Line 2
225
    public Color getLine2Color(final JCalendarItem item) {
226
        return Color.BLACK;
227
    }
228
 
229
    public String getLine2Text(final JCalendarItem item) {
230
        return item.getDescription();
231
    }
232
 
233
    public Font getLine2Font(final JCalendarItem item) {
234
        return FONT_NORMAL;
235
    }
236
 
237
    public Color getVerticalBarColor(final JCalendarItem item) {
238
        return new Color(0, 68, 128);
239
    }
240
 
241
    public void setShowDuration(boolean showDuration) {
242
        this.showDuration = showDuration;
243
    }
244
 
245
    public String formatTime(final Calendar dtStart) {
246
        String h = String.valueOf(dtStart.get(Calendar.HOUR_OF_DAY));
247
        String m = String.valueOf(dtStart.get(Calendar.MINUTE));
248
        if (h.length() < 2) {
249
            h = " " + h;
250
        }
251
        if (m.length() < 2) {
252
            m = "0" + m;
253
        }
254
        return h + ":" + m;
255
    }
256
 
257
    private void computeLayout(Graphics g, PageFormat pf) {
258
        pages = new ArrayList<CalendarItemPage>();
259
        CalendarItemPage page = new CalendarItemPage();
260
        this.pages.add(page);
261
        if (items.isEmpty()) {
262
            return;
263
        }
264
        double remainingHeight = pf.getImageableHeight() - getTitleHeight();
265
        boolean showDate = true;
266
        Calendar c = Calendar.getInstance();
267
        c.setTimeInMillis(this.items.get(0).getDtStart().getTimeInMillis());
268
        for (int i = 0; i < this.items.size(); i++) {
269
            JCalendarItem item = this.items.get(i);
270
            if (i > 0) {
271
                showDate = (item.getDtStart().get(Calendar.YEAR) != c.get(Calendar.YEAR) || item.getDtStart().get(Calendar.DAY_OF_YEAR) != c.get(Calendar.DAY_OF_YEAR));
272
            }
273
            c = item.getDtStart();
274
            double h = getPrintHeight(g, pf, item);
275
            double secureMargin = 20D;
276
            if (remainingHeight < h + secureMargin) {
277
                page = new CalendarItemPage();
278
                showDate = true;
279
                remainingHeight = pf.getImageableHeight() - getTitleHeight();
280
                this.pages.add(page);
281
            }
282
            if (showDate) {
283
                g.setFont(getHourFont(item));
284
                h += g.getFontMetrics().getHeight();
285
            }
286
            remainingHeight -= h;
287
 
288
            page.add(item);
289
            page.addHeight(Double.valueOf(h));
290
            page.addShowDate(showDate);
291
        }
292
 
293
    }
294
 
295
    public int getHourColumnWidth() {
296
        return 90;
297
    }
298
 
299
    public int getTitleHeight() {
300
        return 40;
301
    }
302
 
303
    private double getPrintHeight(Graphics g, PageFormat pf, JCalendarItem item) {
304
        double maxWidth = pf.getImageableWidth() - getHourColumnWidth();
305
        g.setFont(this.getLine1Font(item));
306
        int l1 = LayoutUtils.wrap(getLine1Text(item), g.getFontMetrics(), (int) maxWidth).size();
307
        g.setFont(this.getLine2Font(item));
308
        int l2 = LayoutUtils.wrap(getLine2Text(item), g.getFontMetrics(), (int) maxWidth).size();
309
        return (l1 + l2) * g.getFontMetrics().getHeight();
310
    }
311
 
312
    public List<CalendarItemPage> getPages() {
313
        return pages;
314
    }
315
 
316
    public static void main(String args[]) {
317
        SwingUtilities.invokeLater(new Runnable() {
318
 
319
            @Override
320
            public void run() {
321
                try {
322
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
323
                } catch (Exception ex) {
324
                    ex.printStackTrace();
325
                }
326
                final JFrame f = new JFrame("Printing Pagination Example");
327
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
328
                final JButton printButton = new JButton("Print test pages");
329
                printButton.addActionListener(new ActionListener() {
330
 
331
                    @Override
332
                    public void actionPerformed(ActionEvent e) {
333
                        PrinterJob job = PrinterJob.getPrinterJob();
334
                        List<JCalendarItem> items = new ArrayList<JCalendarItem>();
335
                        Calendar c = Calendar.getInstance();
336
                        Flag.register(new Flag("warning", null, "Warning", "A default warning"));
337
                        for (int i = 0; i < 50; i++) {
338
                            JCalendarItem item = new JCalendarItem();
339
                            item.setSummary("Item " + i);
340
                            StringBuilder d = new StringBuilder();
341
                            d.append("Description");
342
                            for (int j = 0; j < i; j++) {
343
                                if (i % 2 == 0)
344
                                    d.append(" Hello");
345
                                else
346
                                    d.append(" World");
347
                            }
348
                            d.append("END");
349
                            if (i % 6 == 0) {
350
                                item.addFlag(Flag.getFlag("warning"));
351
                            }
352
                            item.setDescription(d.toString());
353
                            item.setDtStart(c);
354
                            c.add(Calendar.HOUR_OF_DAY, 1);
355
                            item.setDtEnd(c);
356
                            c.add(Calendar.HOUR_OF_DAY, 1);
357
                            items.add(item);
358
                        }
359
                        final PrintRequestAttributeSet printAttributes = new HashPrintRequestAttributeSet();
360
                        printAttributes.add(PrintQuality.HIGH);
361
                        job.setPrintable(new CalendarItemPrinter("OpenConcerto", items, job.getPageFormat(printAttributes)));
362
                        boolean ok = job.printDialog();
363
                        if (ok) {
364
                            try {
365
                                job.print();
366
                            } catch (PrinterException ex) {
367
                                /* The job did not successfully complete */
368
                                ex.printStackTrace();
369
                            }
370
                        }
371
 
372
                    }
373
                });
374
                f.add("Center", printButton);
375
                f.pack();
376
                f.setLocationRelativeTo(null);
377
                f.setVisible(true);
378
            }
379
        });
380
    }
381
 
382
    public List<JCalendarItem> getItems() {
383
        return this.items;
384
    }
385
 
386
    @Override
387
    public int getNumberOfPages() {
388
        if (this.pages == null) {
389
            BufferedImage off_Image = new BufferedImage((int) pf.getHeight(), (int) pf.getWidth(), BufferedImage.TYPE_INT_ARGB);
390
            Graphics2D g2 = off_Image.createGraphics();
391
            computeLayout(g2, pf);
392
        }
393
        return this.pages.size();
394
    }
395
 
396
    @Override
397
    public PageFormat getPageFormat(int pageIndex) throws IndexOutOfBoundsException {
398
        return this.pf;
399
    }
400
 
401
    @Override
402
    public Printable getPrintable(int pageIndex) throws IndexOutOfBoundsException {
403
        final CalendarItemPage page = this.pages.get(pageIndex);
404
        return new Printable() {
405
 
406
            @Override
407
            public int print(Graphics graphics, PageFormat pageFormat, int i) throws PrinterException {
408
                final Graphics2D g2d = (Graphics2D) graphics;
409
                g2d.translate(pf.getImageableX(), pf.getImageableY());
410
                printPage(graphics, pageFormat, page);
411
                return PAGE_EXISTS;
412
            }
413
        };
414
    }
415
}