Statistics
| Revision:

svn-document-layout / trunk / org.gvsig.app.document.layout2.app / org.gvsig.app.document.layout2.app.mainplugin / src / main / java / org / gvsig / app / project / documents / layout / fframes / FFrameText.java @ 1654

History | View | Annotate | Download (26.9 KB)

1
/* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
4
 * of the Valencian Government (CIT)
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 */
22
package org.gvsig.app.project.documents.layout.fframes;
23

    
24
import java.awt.BasicStroke;
25
import java.awt.Color;
26
import java.awt.Font;
27
import java.awt.Graphics2D;
28
import java.awt.Rectangle;
29
import java.awt.font.FontRenderContext;
30
import java.awt.font.TextLayout;
31
import java.awt.geom.AffineTransform;
32
import java.awt.geom.Rectangle2D;
33
import java.awt.image.BufferedImage;
34
import java.util.ArrayList;
35
import java.util.Arrays;
36
import java.util.List;
37
import org.apache.commons.collections4.CollectionUtils;
38
import org.apache.commons.collections4.ListUtils;
39
import org.apache.commons.lang3.StringUtils;
40

    
41
import org.gvsig.andami.PluginServices;
42
import org.gvsig.app.project.documents.Document;
43
import org.gvsig.app.project.documents.layout.FLayoutUtilities;
44
import org.gvsig.app.project.documents.layout.report.LayoutReportActionImpl;
45
import org.gvsig.compat.print.PrintAttributes;
46
import org.gvsig.expressionevaluator.ExpressionEvaluatorLocator;
47
import org.gvsig.expressionevaluator.ExpressionEvaluatorManager;
48
import org.gvsig.expressionevaluator.MutableSymbolTable;
49
import org.gvsig.expressionevaluator.SymbolTable;
50
import org.gvsig.fmap.geom.Geometry;
51
import org.gvsig.tools.ToolsLocator;
52
import org.gvsig.tools.dynobject.DynStruct;
53
import org.gvsig.tools.future.FutureUtils;
54
import org.gvsig.tools.persistence.PersistenceManager;
55
import org.gvsig.tools.persistence.PersistentState;
56
import org.gvsig.tools.persistence.exception.PersistenceException;
57

    
58
/**
59
 * FFrame para introducir un texto en el Layout.
60
 * 
61
 * @author Vicente Caballero Navarro
62
 */
63
public class FFrameText extends FFrame {
64

    
65
    public static final String PERSISTENCE_DEFINITION_NAME = "FFrameText";
66

    
67
    private static final String TEXT_FIELD = "text";
68
    private static final String S_FIELD = "s";
69
    private static final String ISFIXED_FIELD = "isFixed";
70
    private static final String FONT_FIELD = "font";
71
    private static final String POS_FIELD = "pos";
72
    private static final String TEXTCOLOR_FIELD = "textColor";
73
    private static final String TRANSITIONPIXELSMILIMETERS_FIELD =
74
        "transicionPixelsMilimetros";
75
    private static final String CELLPADDING_FIELD = "cellPadding";
76
    private static final String FONTSIZE_FIELD = "fontSize";
77
    private static final String FIXEDFONTSIZE_FIELD = "fixedFontSize";
78
    private static final String SURROUNDED_FIELD = "surrounded";
79
    private static final String HASTITLE_FIELD = "hasTitle";
80
    private static final String TITLE_FIELD = "title";
81
    private static final String TITLESIZE_FIELD = "titleSize";
82
    private static final String FRAMEBORDERSIZE_FIELD = "frameBorderSize";
83
    private static final String FRAMECOLOR_FIELD = "frameColor";
84
    private static final String TITLECOLOR_FIELD = "titleColor";
85

    
86
    /** Localizaci?n del texto. */
87
    public static final int LEFT = 0;
88
    public static final int CENTER = 1;
89
    public static final int RIGTH = 2;
90
    private List<String> m_text = new ArrayList();
91
    private boolean m_isFixed = false;
92
    private int m_pos = LEFT;
93
    private Color textColor = Color.BLACK;
94

    
95
    // jaume
96
    private boolean surrounded = false; // The text field is surrounded by a
97
                                        // rectangle
98
    private double cellPadding = 0; // The gap between the the text field and
99
                                    // the surrounding rectangle
100
    private boolean fixedFontSize = false; // The text field font size is
101
                                           // constant fixed to the folio's size
102
    private int fontSize; // Text field's font size
103
    private boolean hasTitle; // The text field has title
104
    private String title; // The text for the title
105
    private int titleSize; // The title's font size
106
    private double frameBorderSize = 0; // The surrounding rectangle's border
107
                                        // size
108
    private Color frameColor = Color.BLACK; // The surrounding rectangle's color
109
    private Color titleColor = Color.BLACK; // The title's color
110
    private Font m_f = null;
111
    private boolean transicionPixelsMilimetros = true;
112

    
113
    /**
114
     * Crea un nuevo FFrameText.
115
     */
116
    public FFrameText() {
117
        m_f = new Font("SansSerif", Font.PLAIN, 9);
118
    }
119

    
120
    /**
121
     * Inserta la fuente del texto.
122
     * 
123
     * @param f
124
     *            Fuente del texto.
125
     */
126
    public void setFont(Font f) {
127
        m_f = f;
128
    }
129

    
130
    /**
131
     * Devuelve el color del texto del FFrameText.
132
     * 
133
     * @return Color del texto.
134
     */
135
    public Color getTextColor() {
136
        return textColor;
137
    }
138

    
139
    /**
140
     * Obtiene el fixedFontSize
141
     * 
142
     * @return boolean
143
     */
144
    public boolean isFontSizeFixed() {
145
        return fixedFontSize;
146
    }
147

    
148
    /**
149
     * Establece fixedFontSize
150
     * 
151
     * @param fixedFontSize
152
     */
153
    public void setFixedFontSize(boolean fixedFontSize) {
154
        this.fixedFontSize = fixedFontSize;
155
    }
156

    
157
    /**
158
     * Obtiene el fontSize
159
     * 
160
     * @return int
161
     */
162
    public int getFontSize() {
163
        return fontSize;
164
    }
165

    
166
    /**
167
     * Establece fontSize
168
     * 
169
     * @param fontSize
170
     */
171
    public void setFontSize(int fontSize) {
172
        this.fontSize = fontSize;
173
    }
174

    
175
    /**
176
     * Obtiene el cellPadding
177
     * 
178
     * @return int
179
     */
180
    public double getCellPadding() {
181
        return cellPadding;
182
    }
183

    
184
    /**
185
     * Inserta el color del texto a escribir.
186
     * 
187
     * @param color
188
     *            Color del texto.
189
     */
190
    public void setTextColor(Color color) {
191
        textColor = color;
192
    }
193

    
194
    /**
195
     * Devuelve la fuente del texto.
196
     * 
197
     * @return Fuente del texto.
198
     */
199
    public Font getFont() {
200
        return new Font(m_f.getFontName(), m_f.getStyle(), 9);
201
    }
202

    
203
    /**
204
     * Devuelve la posici?n izquierda, centro o derecha del texto.
205
     * 
206
     * @return Posici?n del texto.
207
     */
208
    public int getPos() {
209
        return m_pos;
210
    }
211

    
212
    /**
213
     * Pone la posici?n izquierda, centro o derecha del texto.
214
     * 
215
     * @param p
216
     *            0=LEFT,1=CENTER,2=RIGTH.
217
     */
218
    public void setPos(int p) {
219
        m_pos = p;
220
    }
221

    
222
    /**
223
     * M?todo que dibuja sobre el graphics que se le pasa como par?metro, seg?n
224
     * la transformada afin que se debe de aplicar y el rect?ngulo que se debe
225
     * de dibujar.
226
     * 
227
     * @param g
228
     *            Graphics
229
     * @param at
230
     *            Transformada af?n.
231
     * @param rv
232
     *            rect?ngulo sobre el que hacer un clip.
233
     * @param imgBase
234
     *            Imagen para acelerar el dibujado.
235
     */
236
    public void draw(Graphics2D g, AffineTransform at, Rectangle2D rv,
237
        BufferedImage imgBase) {
238
        g.setColor(Color.BLACK);
239

    
240
        Rectangle2D.Double rec = getBoundingBox(at);
241
        Rectangle2D.Double raux = (Rectangle2D.Double) rec.clone();
242
        g.rotate(Math.toRadians(getRotation()), raux.x + (raux.width / 2),
243
            raux.y + (raux.height / 2));
244

    
245
        int longmax = 1;
246

    
247
        if (intersects(rv, raux)) { // comprueba que no cae fuera de la pantalla
248
            List<String> texts = this.getExpandedTexts();
249
            
250
            if ( CollectionUtils.isEmpty(texts) ) {
251
                drawEmpty(g);
252
            } else {
253
                for (String text : texts) {
254
                    if( text == null) {
255
                        text = "<NULL>";
256
                    }
257
                    if (text.length() > longmax) {
258
                        longmax = text.length();
259
                    }
260
                }
261

    
262
                FontRenderContext frc = g.getFontRenderContext();
263
                int scaledFontSize;
264

    
265
                // TODO myScale es la escala sobre la que se extraen todos los
266
                // escalados. Esto
267
                // funciona bien tal cual est? si la ratio de aspecto
268
                // (alto/ancho) del folio es constante
269
                // porque se toma como medidas el ancho del folio real y el
270
                // ancho del folio en pantalla.
271
                // No se que pasar? si la ratio cambia, por ejemplo si se usan
272
                // USLetter en lugar de DIN A4
273
                double myScale = at.getScaleX() * 0.0234; // FLayoutUtilities.fromSheetDistance(folio.getAncho(),at)/rv.getWidth();
274

    
275
                // Distinguish when the font has fixed size or not
276
                if (isFontSizeFixed()) {
277
                    scaledFontSize = (int) (myScale * fontSize);
278
                } else {
279
                    scaledFontSize = ((int) (raux.width)) / longmax;
280

    
281
                    if (scaledFontSize > (int) ((raux.height) / texts.size())) {
282
                        scaledFontSize = (int) ((raux.height) / texts.size());
283
                    }
284
                }
285

    
286
                if (m_f != null) {
287
                    // Aqu? se ajusta a partir de las caracter?sticas de la
288
                    // fuente, una nueva fuente con el tama?o ajustado.
289
                    m_f =
290
                        new Font(m_f.getFontName(), m_f.getStyle(),
291
                            scaledFontSize);
292
                } else {
293
                    // Aqu? pasa cuando se abre el di?logo para seleccionar un
294
                    // tipo de fuente y se cierra sin haber seleccionado
295
                    // ninguna.
296
                    m_f = new Font("SansSerif", Font.PLAIN, scaledFontSize);
297
                }
298

    
299
                // Draw the text title if it exists
300
                if (hasTitle()) {
301
                    int scaledTitleFontSize = (int) (myScale * titleSize);
302
                    int gap = 3;
303

    
304
                    if (isSurrounded()) {
305
                        // Para evitar que el marco se pinte sobre el t?tulo
306
                        gap +=
307
                            (int) (FLayoutUtilities.fromSheetDistance(
308
                                frameBorderSize, at) * myScale);
309
                    }
310

    
311
                    g.setColor(titleColor);
312

    
313
                    Font titleFont =
314
                        new Font(m_f.getFontName(), m_f.getStyle(),
315
                            scaledTitleFontSize);
316

    
317
                    if (!getTitle().equals("")) {
318
                        TextLayout titleTextLayout =
319
                            new TextLayout(getTitle(), titleFont, frc);
320
                        titleTextLayout.draw(g, (float) raux.getX(),
321
                            (float) (raux.getY() - (gap * myScale)));
322
                    }
323
                }
324

    
325
                // Draw the frame involving the text if it exists
326
                if (isSurrounded()) {
327
                    g.setColor(frameColor);
328
                    // g.drawRect((int) raux.x, (int) raux.y, (int) raux.width,
329
                    // (int) raux.height);
330

    
331
                    double scaledCellPadding =
332
                        FLayoutUtilities.fromSheetDistance(cellPadding, at);
333
                    double sizeBorder =
334
                        FLayoutUtilities.fromSheetDistance(frameBorderSize, at);
335

    
336
                    // if (sizeBorder > 1) {
337
                    int bordermm = (int) (sizeBorder * 10);
338
                    int scaledCellPaddingmm = (int) (scaledCellPadding * 10);
339
                    // System.out.println("borderSize = " + bordermm);
340
                    g.setStroke(new BasicStroke(bordermm));
341
                    // int scaledBorderSize = (int) (sizeBorder * myScale);
342

    
343
                    // for (int i = scaledBorderSize - 1; i > 0; i--)
344
                    // g.drawRect((int) raux.x - i, (int) raux.y - i,
345
                    // (int) raux.width + (2 * i),
346
                    // (int) raux.height + (2 * i));
347
                    g.drawRect((int) (raux.x + bordermm / 2 - 1), (int) (raux.y
348
                        + bordermm / 2 - 1), (int) (raux.width - bordermm + 2),
349
                        (int) (raux.height - bordermm + 2));
350
                    g.setStroke(new BasicStroke(0));
351
                    // }
352

    
353
                    // Recalibro el rectangulo para establecer el ?rea donde se
354
                    // dibujan las fuentes
355
                    // al ?rea marcada con el rat?n menos la distancia al marco
356
                    // especificada
357
                    raux.setRect(raux.getX() + scaledCellPaddingmm + bordermm,
358
                        raux.getY() + scaledCellPaddingmm + bordermm,
359
                        raux.getWidth() - (scaledCellPaddingmm * 2) - bordermm
360
                            * 2, raux.getHeight() - (scaledCellPaddingmm * 2)
361
                            - bordermm * 2);
362

    
363
                    if (raux.getWidth() <= 0 || raux.getHeight() <= 0) {
364
                        // JOptionPane.showMessageDialog((Component)PluginServices.getMainFrame(),PluginServices.getText(this,"too_large_border")+": "+bordermm+
365
                        // " + "+scaledCellPaddingmm);
366
                        g.setColor(Color.red);
367
                        drawError(getBoundingBox(at), 15, g,
368
                            PluginServices.getText(this, "too_large_border")
369
                                + ": " + frameBorderSize + "cm + "
370
                                + cellPadding + "cm");
371
                        // g.rotate(Math.toRadians(-getRotation()),
372
                        // raux.x + (raux.width / 2), raux.y + (raux.height /
373
                        // 2));
374
                        return;
375
                    }
376
                }
377

    
378
                g.setColor(textColor);
379

    
380
                drawText(raux, scaledFontSize, g);
381
                g.rotate(Math.toRadians(-getRotation()), raux.x
382
                    + (raux.width / 2), raux.y + (raux.height / 2));
383
            }
384
        }
385

    
386
        raux = null;
387
    }
388

    
389
    private void drawError(Rectangle2D r, int sfs, Graphics2D g, String error) {
390
        FontRenderContext frc = g.getFontRenderContext();
391
        TextLayout textLayout = null;
392
        m_f = new Font(m_f.getFontName(), m_f.getStyle(), sfs);
393
        textLayout = new TextLayout(error, m_f, frc);
394
        textLayout.draw(g, (float) r.getCenterX(), (float) (r.getCenterY()));
395

    
396
    }
397

    
398
    /**
399
     * Dibuja el texto sobre el graphics con el tama?o adecuado.
400
     * 
401
     * @param r
402
     *            Rect?ngulo sobre el que dibujar.
403
     * @param sfs
404
     *            Tama?o aproximado del texto.
405
     * @param g
406
     *            Graphics sobre el que dibujar el texto.
407
     */
408
    private void drawText(Rectangle2D r, int sfs, Graphics2D g) {
409
        int minSFS = Integer.MAX_VALUE;
410
        FontRenderContext frc = g.getFontRenderContext();
411
        List<String> texts = this.getExpandedTexts();
412
        
413
        int ht = (int) (r.getHeight() / texts.size());
414

    
415
        if (isFontSizeFixed()) {
416
            minSFS = sfs;
417
        } else {
418
            for (int i = 0; i < texts.size(); i++) {
419
                if (!texts.get(i).equals("") && !texts.get(i).equals("\n")) {
420
                    TextLayout textaux = new TextLayout(texts.get(i), m_f, frc);
421
                    Rectangle2D txtBound = textaux.getBounds();
422
                    double difW = txtBound.getWidth() / r.getWidth();
423
                    double difH = (txtBound.getHeight() * texts.size()) / (r.getHeight());
424
                    if (difW > difH) {
425
                        if (minSFS > sfs) {
426
                            minSFS = (int) (sfs / difW);
427
                        }
428
                    } else {
429
                        if (minSFS > sfs) {
430
                            minSFS = (int) (sfs / difH);
431
                        }
432
                    }
433
                }
434
            }
435
        }
436

    
437
        TextLayout textLayout = null;
438

    
439
        for (int i = 0; i < texts.size(); i++) {
440
            if (!texts.get(i).equals("")) {
441
                m_f = new Font(m_f.getFontName(), m_f.getStyle(), minSFS);
442

    
443
                textLayout = new TextLayout(texts.get(i), m_f, frc);
444

    
445
                Rectangle2D txtBound = textLayout.getBounds();
446
                float difW = (float) (r.getWidth() - txtBound.getWidth());
447

    
448
                switch (m_pos) {
449
                case (LEFT):
450
                    textLayout.draw(g, (float) r.getX(),
451
                        (float) (r.getY() + (ht * (i + 0.8))));
452

    
453
                    break;
454

    
455
                case (CENTER):
456
                    textLayout.draw(g, (float) r.getX() + (difW / 2),
457
                        (float) (r.getY() + (ht * (i + 0.8))));
458

    
459
                    break;
460

    
461
                case (RIGTH):
462
                    textLayout.draw(g, (float) r.getX() + difW,
463
                        (float) (r.getY() + (ht * (i + 0.8)))); // - (ht /
464
                                                                // 2))));
465

    
466
                    break;
467
                }
468
            }
469
        }
470
    }
471

    
472
    /*
473
     * @see
474
     * com.iver.cit.gvsig.project.documents.layout.fframes.IFFrame#print(java
475
     * .awt.Graphics2D,
476
     * java.awt.geom.AffineTransform)
477
     */
478
    public void print(Graphics2D g, AffineTransform at, Geometry geom,
479
        PrintAttributes properties) {
480
        draw(g, at, null, null);
481
    }
482

    
483
    /**
484
     * Rellenar el texto que se quiere a?adir al Layout.
485
     * 
486
     * @param s
487
     *            String a a?adir.
488
     */
489
    public void addText(String s) {
490
        m_text.add(s);
491
    }
492

    
493
    /**
494
     * Devuelve el ArrayList que contiene las l?neas de texto.
495
     * 
496
     * @return ArrayList.
497
     */
498
    public List<String> getText() {
499
        return m_text;
500
    }
501

    
502
    /**
503
     * Seleccionar si se quiere un tama?o fijo o adecuado a la escala.
504
     * 
505
     * @param b
506
     *            true si se quiere tama?o fijo.
507
     */
508
    public void setSizeFixed(boolean b) {
509
        m_isFixed = b;
510
    }
511

    
512
    /**
513
     * Devuelve si est? fijado el tama?o.
514
     * 
515
     * @return True si est? fijado el tama?o.
516
     */
517
    public boolean isSizeFixed() {
518
        return m_isFixed;
519
    }
520

    
521
    /**
522
     * @see org.gvsig.app.project.documents.layout.fframes.IFFrame#getNameFFrame()
523
     */
524
    public String getNameFFrame() {
525
        return PluginServices.getText(this, "texto") + num;
526
    }
527

    
528
    public String getName() {
529
        return PERSISTENCE_DEFINITION_NAME;
530
    }
531

    
532
    /**
533
     * Sets FFrameText to draw an involving rectangle
534
     * 
535
     * @param b
536
     */
537
    public void setSurrounded(boolean b) {
538
        surrounded = b;
539
    }
540

    
541
    /**
542
     * True if the FFrameText is set to draw an involving rectangle, or false
543
     * if not.
544
     * 
545
     * @return boolean
546
     */
547
    public boolean isSurrounded() {
548
        return surrounded;
549
    }
550

    
551
    /**
552
     * Sets the gap between the involving rectangle and the text
553
     * 
554
     * @param i
555
     */
556
    public void setCellPadding(double i) {
557
        cellPadding = i;
558
    }
559

    
560
    /**
561
     * Devuelve true si tiene un t?tulo.
562
     * 
563
     * @return
564
     */
565
    public boolean hasTitle() {
566
        return hasTitle;
567
    }
568

    
569
    /**
570
     * Devuelve un string con el t?tulo.
571
     * 
572
     * @return
573
     */
574
    public String getTitle() {
575
        return title;
576
    }
577

    
578
    /**
579
     * Inserta true si tiene t?tulo
580
     * 
581
     * @param b
582
     */
583
    public void setHasTitle(boolean b) {
584
        hasTitle = b;
585
    }
586

    
587
    /**
588
     * Inserta un string con el t?tulo.
589
     * 
590
     * @param text
591
     */
592
    public void setTitle(String text) {
593
        title = text;
594
    }
595

    
596
    /**
597
     * Devuelve el tama?o del t?tulo.
598
     * 
599
     * @return
600
     */
601
    public int getTitleSize() {
602
        return titleSize;
603
    }
604

    
605
    /**
606
     * Inserta el tama?o del t?tulo.
607
     * 
608
     * @param size
609
     *            DOCUMENT ME!
610
     */
611
    public void setTitleSize(int size) {
612
        titleSize = size;
613
    }
614

    
615
    /**
616
     * Inserta el tama?o del borde.
617
     * 
618
     * @param size
619
     */
620
    public void setFrameBorderSize(double size) {
621
        frameBorderSize = size;
622
    }
623

    
624
    /**
625
     * Devuelve el tama?o del borde.
626
     * 
627
     * @return
628
     */
629
    public double getFrameBorderSize() {
630
        return frameBorderSize;
631
    }
632

    
633
    /**
634
     * DOCUMENT ME!
635
     * 
636
     * @param frameColor
637
     */
638
    public void setFrameColor(Color frameColor) {
639
        this.frameColor = frameColor;
640
    }
641

    
642
    /**
643
     * DOCUMENT ME!
644
     * 
645
     * @param titleColor
646
     *            DOCUMENT ME!
647
     */
648
    public void setTitleColor(Color titleColor) {
649
        this.titleColor = titleColor;
650
    }
651

    
652
    /**
653
     * DOCUMENT ME!
654
     * 
655
     * @return DOCUMENT ME!
656
     */
657
    public Color getFrameColor() {
658
        return frameColor;
659
    }
660

    
661
    /**
662
     * DOCUMENT ME!
663
     * 
664
     * @return DOCUMENT ME!
665
     */
666
    public Color getTitleColor() {
667
        return titleColor;
668
    }
669

    
670
    /**
671
     * Use this method if you want the text in the FFrameText to be removed.
672
     */
673
    public void clearText() {
674
        m_text.clear();
675
    }
676

    
677
    public void initialize() {
678
        // TODO Auto-generated method stub
679

    
680
    }
681

    
682
    public static void registerPersistent() {
683
        PersistenceManager manager = ToolsLocator.getPersistenceManager();
684
        if (manager.getDefinition(PERSISTENCE_DEFINITION_NAME) == null) {
685
            DynStruct definition =
686
                manager.addDefinition(FFrameText.class,
687
                    PERSISTENCE_DEFINITION_NAME,
688
                    "FFrameText persistence definition", null, null);
689

    
690
            definition.extend(manager
691
                .getDefinition(FFrame.PERSISTENCE_DEFINITION_NAME));
692

    
693
            /*
694
             * field 's' is Rectangle but stored as Rectangle2D
695
             */
696
            definition.addDynFieldObject(S_FIELD)
697
                .setClassOfValue(Rectangle2D.class).setMandatory(true);
698
            definition.addDynFieldList(TEXT_FIELD)
699
                  .setClassOfItems(String.class).setMandatory(true);
700
            definition.addDynFieldBoolean(ISFIXED_FIELD).setMandatory(true);
701
            definition.addDynFieldObject(FONT_FIELD)
702
                .setClassOfValue(Font.class).setMandatory(true);
703
            definition.addDynFieldInt(POS_FIELD).setMandatory(true);
704
            definition.addDynFieldObject(TEXTCOLOR_FIELD)
705
                .setClassOfValue(Color.class).setMandatory(false);
706
            definition.addDynFieldBoolean(TRANSITIONPIXELSMILIMETERS_FIELD)
707
                .setMandatory(true);
708
            definition.addDynFieldDouble(CELLPADDING_FIELD).setMandatory(false);
709
            definition.addDynFieldInt(FONTSIZE_FIELD).setMandatory(false);
710
            definition.addDynFieldBoolean(FIXEDFONTSIZE_FIELD).setMandatory(
711
                false);
712
            definition.addDynFieldBoolean(SURROUNDED_FIELD).setMandatory(false);
713
            definition.addDynFieldBoolean(HASTITLE_FIELD).setMandatory(false);
714
            definition.addDynFieldString(TITLE_FIELD).setMandatory(false);
715
            definition.addDynFieldInt(TITLESIZE_FIELD).setMandatory(false);
716
            definition.addDynFieldDouble(FRAMEBORDERSIZE_FIELD).setMandatory(
717
                false);
718
            definition.addDynFieldObject(FRAMECOLOR_FIELD)
719
                .setClassOfValue(Color.class).setMandatory(false);
720
            definition.addDynFieldObject(TITLECOLOR_FIELD)
721
                .setClassOfValue(Color.class).setMandatory(false);
722
        }
723
    }
724

    
725
    @Override
726
    public void loadFromState(PersistentState state)
727
        throws PersistenceException {
728
        super.loadFromState(state);
729
        
730
        /*
731
         * field 's' is Rectangle but stored as Rectangle2D
732
         */
733
        Rectangle2D s_2d = (Rectangle2D) state.get(S_FIELD);
734
        s = new Rectangle(
735
            (int) s_2d.getX(),
736
            (int) s_2d.getY(),
737
            (int) s_2d.getWidth(),
738
            (int) s_2d.getHeight());
739
        
740
        /*
741
         * the text is an arraylist of strings
742
         */
743
        List<String> text_list = state.getList(TEXT_FIELD);
744
        for (int i=0; i<text_list.size(); i++) {
745
            m_text.add(text_list.get(i));
746
        }
747

    
748
        m_isFixed = state.getBoolean(ISFIXED_FIELD);
749
        m_f = (Font) state.get(FONT_FIELD);
750
        m_pos = state.getInt(POS_FIELD);
751
        textColor = (Color) state.get(TEXTCOLOR_FIELD);
752
        transicionPixelsMilimetros =
753
            state.getBoolean(TRANSITIONPIXELSMILIMETERS_FIELD);
754
        cellPadding = state.getDouble(CELLPADDING_FIELD);
755
        fontSize = state.getInt(FONTSIZE_FIELD);
756
        fixedFontSize = state.getBoolean(FIXEDFONTSIZE_FIELD);
757
        surrounded = state.getBoolean(SURROUNDED_FIELD);
758
        hasTitle = state.getBoolean(HASTITLE_FIELD);
759
        title = state.getString(TITLE_FIELD);
760
        titleSize = state.getInt(TITLESIZE_FIELD);
761
        frameBorderSize = state.getDouble(FRAMEBORDERSIZE_FIELD);
762
        frameColor = (Color) state.get(FRAMECOLOR_FIELD);
763
        titleColor = (Color) state.get(TITLECOLOR_FIELD);
764
    }
765

    
766
    @Override
767
    public void saveToState(PersistentState state) throws PersistenceException {
768
        super.saveToState(state);
769

    
770
        /*
771
         * field 's' is Rectangle but stored as Rectangle2D
772
         */
773
        Rectangle2D s_2d = new Rectangle2D.Double(
774
            s.x, s.y, s.width, s.height);
775
        state.set(S_FIELD, s_2d);
776
        
777
        state.set(TEXT_FIELD, m_text);
778
        state.set(ISFIXED_FIELD, m_isFixed);
779
        state.set(FONT_FIELD, m_f);
780
        state.set(POS_FIELD, m_pos);
781
        state.set(TEXTCOLOR_FIELD, textColor);
782
        state.set(TRANSITIONPIXELSMILIMETERS_FIELD, transicionPixelsMilimetros);
783
        state.set(CELLPADDING_FIELD, cellPadding);
784
        state.set(FONTSIZE_FIELD, fontSize);
785
        state.set(FIXEDFONTSIZE_FIELD, fixedFontSize);
786
        state.set(SURROUNDED_FIELD, surrounded);
787
        state.set(HASTITLE_FIELD, hasTitle);
788
        state.set(TITLE_FIELD, title);
789
        state.set(TITLESIZE_FIELD, titleSize);
790
        state.set(FRAMEBORDERSIZE_FIELD, frameBorderSize);
791
        state.set(FRAMECOLOR_FIELD, frameColor);
792
        state.set(TITLECOLOR_FIELD, titleColor);
793
    }
794
    
795
    @Override
796
    public Object clone() throws CloneNotSupportedException {
797
            FFrameText frame = (FFrameText) super.clone();
798
            frame.m_text = new ArrayList<>(this.m_text);
799
            return frame;
800
    }
801

    
802
    private List<String> getExpandedTexts() {
803
        try {
804
            ExpressionEvaluatorManager expressionManager = ExpressionEvaluatorLocator.getExpressionEvaluatorManager();
805
            String ss1 = StringUtils.join(this.m_text, "\n");
806
            if( !expressionManager.isDynamicText(ss1) ) {
807
                return this.m_text;
808
            }
809

    
810
            Document doc = this.getDocument();
811
            LayoutReportActionImpl report = (LayoutReportActionImpl) doc.getProperty("$REPORT");
812
            if( report == null ) {
813
                report = LayoutReportActionImpl.createFakeLayoutReportAction(doc);
814
            }
815
            String ss2 = report.evaluateDynamicText(ss1);
816
            List<String> texts = Arrays.asList(StringUtils.split(ss2, '\n'));
817
            return texts;
818
        } catch(Throwable t) {
819
            return this.m_text;
820
        }
821
    }
822
}