001: /*
002: * Copyright 2006-2007 Pentaho Corporation. All rights reserved.
003: * This software was developed by Pentaho Corporation and is provided under the terms
004: * of the Mozilla Public License, Version 1.1, or any later version. You may not use
005: * this file except in compliance with the license. If you need a copy of the license,
006: * please go to http://www.mozilla.org/MPL/MPL-1.1.txt.
007: *
008: * Software distributed under the Mozilla Public License is distributed on an "AS IS"
009: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. Please refer to
010: * the license for the specific language governing your rights and limitations.
011: *
012: * Additional Contributor(s): Martin Schmid gridvision engineering GmbH
013: */
014: package org.pentaho.reportdesigner.crm.report.lineal;
015:
016: import org.jetbrains.annotations.NonNls;
017: import org.jetbrains.annotations.NotNull;
018: import org.jetbrains.annotations.Nullable;
019: import org.pentaho.reportdesigner.crm.report.ReportDialog;
020: import org.pentaho.reportdesigner.crm.report.Unit;
021: import org.pentaho.reportdesigner.crm.report.model.PageDefinition;
022: import org.pentaho.reportdesigner.crm.report.model.Report;
023: import org.pentaho.reportdesigner.crm.report.util.JOptionPaneHelper;
024: import org.pentaho.reportdesigner.lib.client.components.CenterPanelDialog;
025: import org.pentaho.reportdesigner.lib.client.i18n.TranslationManager;
026: import org.pentaho.reportdesigner.lib.client.util.MathUtils;
027:
028: import javax.swing.*;
029: import java.awt.*;
030: import java.awt.event.ActionEvent;
031: import java.awt.event.MouseAdapter;
032: import java.awt.event.MouseEvent;
033: import java.awt.event.MouseMotionListener;
034: import java.awt.geom.Rectangle2D;
035: import java.text.DecimalFormat;
036: import java.util.LinkedHashSet;
037: import java.util.logging.Level;
038: import java.util.logging.Logger;
039:
040: /**
041: * User: Martin
042: * Date: 26.01.2006
043: * Time: 09:02:38
044: */
045: public class HorizontalLinealComponent extends JComponent {
046: @NonNls
047: @NotNull
048: private static final Logger LOG = Logger
049: .getLogger(HorizontalLinealComponent.class.getName());
050:
051: @NotNull
052: public static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat(
053: "0.0##");
054:
055: @NotNull
056: public static final DecimalFormat DECIMAL_FORMAT_NUMBERS_ONE_DIGIT = new DecimalFormat(
057: "0.0");
058: @NotNull
059: public static final DecimalFormat DECIMAL_FORMAT_NUMBERS_INTEGER = new DecimalFormat(
060: "0");
061:
062: private double scaleFactor;
063: @NotNull
064: private ReportDialog reportDialog;
065: @NotNull
066: private LinealModel linealModel;
067:
068: @Nullable
069: private GuideLine activeGuidLine;
070:
071: private boolean showLeftBorder = true;
072:
073: @Nullable
074: private GuideLine draggedGuideLine;
075:
076: public HorizontalLinealComponent(@NotNull
077: final ReportDialog reportDialog, @NotNull
078: final LinealModel linealModel) {
079: this .reportDialog = reportDialog;
080: this .linealModel = linealModel;
081:
082: addMouseListener(new MouseAdapter() {
083: public void mouseClicked(@NotNull
084: MouseEvent e) {
085: double start = 0;
086: Report report = linealModel.getReport();
087: if (report != null) {
088: if (showLeftBorder) {
089: start = report.getPageDefinition()
090: .getLeftBorder();
091: }
092: if (e.getButton() == MouseEvent.BUTTON1
093: && getActiveGuide(e, linealModel) == null) {
094: linealModel.addGuidLine(new GuideLine(
095: MathUtils.truncate(
096: (e.getX() / scaleFactor)
097: - start, 0, report
098: .getPageDefinition()
099: .getInnerPageSize()
100: .getWidth()), true));
101: } else if (e.getButton() == MouseEvent.BUTTON2
102: && getActiveGuide(e, linealModel) == null) {
103: linealModel.addGuidLine(new GuideLine(
104: MathUtils.truncate(
105: (e.getX() / scaleFactor)
106: - start, 0, report
107: .getPageDefinition()
108: .getInnerPageSize()
109: .getWidth()), false));
110: }
111: }
112: }
113:
114: public void mousePressed(@NotNull
115: MouseEvent e) {
116: if (e.getButton() == MouseEvent.BUTTON1) {
117: draggedGuideLine = getActiveGuide(e, linealModel);
118: }
119: }
120:
121: public void mouseReleased(@NotNull
122: MouseEvent e) {
123: draggedGuideLine = null;
124: }
125: });
126:
127: linealModel.addLinealModelListener(new LinealModelListener() {
128: public void guidLineAdded(@NotNull
129: GuideLine guideLine) {
130: activeGuidLine = null;
131: repaint();
132: }
133:
134: public void guidLineRemoved(@NotNull
135: GuideLine guideLine) {
136: activeGuidLine = null;
137: repaint();
138: }
139:
140: public void activationChanged(@NotNull
141: GuideLine guideLine) {
142: activeGuidLine = null;
143: repaint();
144: }
145:
146: public void positionChanged(@NotNull
147: GuideLine guideLine, double oldPosition) {
148: activeGuidLine = null;
149: repaint();
150: }
151: });
152:
153: addMouseMotionListener(new MouseMotionListener() {
154: public void mouseDragged(@NotNull
155: MouseEvent e) {
156: GuideLine dragged = draggedGuideLine;
157: if (dragged != null) {
158: double start = 0;
159: Report report = linealModel.getReport();
160: if (report != null) {
161: if (showLeftBorder) {
162: start = report.getPageDefinition()
163: .getLeftBorder();
164: }
165: linealModel
166: .setPosition(
167: dragged,
168: MathUtils
169: .truncate(
170: (e.getX() / scaleFactor)
171: - start,
172: 0,
173: report
174: .getPageDefinition()
175: .getInnerPageSize()
176: .getWidth()));
177: }
178: }
179: }
180:
181: public void mouseMoved(@NotNull
182: MouseEvent e) {
183: GuideLine ag = getActiveGuide(e, linealModel);
184: //noinspection ObjectEquality
185: if (activeGuidLine != ag) {
186: activeGuidLine = ag;
187: repaint();
188: }
189: }
190: });
191:
192: addMouseListener(new MouseAdapter() {
193: public void mouseEntered(@NotNull
194: MouseEvent e) {
195: GuideLine ag = getActiveGuide(e, linealModel);
196: //noinspection ObjectEquality
197: if (activeGuidLine != ag) {
198: activeGuidLine = ag;
199: repaint();
200: }
201: }
202:
203: public void mouseExited(@NotNull
204: MouseEvent e) {
205: if (activeGuidLine != null) {
206: activeGuidLine = null;
207: repaint();
208: }
209: }
210:
211: public void mouseClicked(@NotNull
212: MouseEvent e) {
213: GuideLine ag = getActiveGuide(e, linealModel);
214: //noinspection ObjectEquality
215: if (activeGuidLine != ag) {
216: activeGuidLine = ag;
217: repaint();
218: }
219: popup(e);
220: }
221:
222: public void mousePressed(@NotNull
223: MouseEvent e) {
224: GuideLine ag = getActiveGuide(e, linealModel);
225: //noinspection ObjectEquality
226: if (activeGuidLine != ag) {
227: activeGuidLine = ag;
228: repaint();
229: }
230: popup(e);
231: }
232:
233: public void mouseReleased(@NotNull
234: MouseEvent e) {
235: GuideLine ag = getActiveGuide(e, linealModel);
236: //noinspection ObjectEquality
237: if (activeGuidLine != ag) {
238:
239: repaint();
240: }
241: popup(e);
242: }
243:
244: private void popup(@NotNull
245: final MouseEvent me) {
246: if (me.isPopupTrigger()) {
247: double start = 0;
248: final Report report = linealModel.getReport();
249: if (report != null) {
250: if (showLeftBorder) {
251: start = report.getPageDefinition()
252: .getLeftBorder();
253: }
254:
255: LinkedHashSet<GuideLine> guideLines = linealModel
256: .getGuideLines();
257: for (final GuideLine guideLine : guideLines) {
258: int x = (int) ((guideLine.getPosition() + start) * scaleFactor);
259:
260: if (x <= me.getX() + 2
261: && x >= me.getX() - 2) {
262: JPopupMenu popupMenu = new JPopupMenu();
263:
264: popupMenu
265: .add(new AbstractAction(
266: TranslationManager
267: .getInstance()
268: .getTranslation(
269: "R",
270: "LinealComponent.Properties")) {
271: public void actionPerformed(
272: @NotNull
273: ActionEvent e) {
274: double unitValue = reportDialog
275: .getApplicationSettings()
276: .getUnit()
277: .convertFromPoints(
278: guideLine
279: .getPosition());
280: String initialSelectionValue = DECIMAL_FORMAT
281: .format(unitValue);
282: String s = JOptionPaneHelper
283: .showInputDialog(
284: reportDialog,
285: TranslationManager
286: .getInstance()
287: .getTranslation(
288: "R",
289: "LinealComponent.Guide.Position"),
290: initialSelectionValue,
291: CenterPanelDialog.ModalityType.DOCUMENT_MODAL);
292: if (s != null) {
293: try {
294: double d = Double
295: .parseDouble(s);
296: double points = reportDialog
297: .getApplicationSettings()
298: .getUnit()
299: .convertToPoints(
300: d);
301: linealModel
302: .setPosition(
303: guideLine,
304: MathUtils
305: .truncate(
306: points,
307: 0,
308: report
309: .getPageDefinition()
310: .getInnerPageSize()
311: .getWidth()));
312: } catch (NumberFormatException e1) {
313: if (LOG
314: .isLoggable(Level.FINE))
315: LOG
316: .log(
317: Level.FINE,
318: "HorizontalLinealComponent.actionPerformed ",
319: e1);
320: //ok
321: }
322: }
323: }
324: });
325:
326: if (guideLine.isActive()) {
327: popupMenu
328: .add(new AbstractAction(
329: TranslationManager
330: .getInstance()
331: .getTranslation(
332: "R",
333: "LinealComponent.Deactivate")) {
334: public void actionPerformed(
335: @NotNull
336: ActionEvent e) {
337: linealModel
338: .setActive(
339: guideLine,
340: false);
341: }
342: });
343: } else {
344: popupMenu
345: .add(new AbstractAction(
346: TranslationManager
347: .getInstance()
348: .getTranslation(
349: "R",
350: "LinealComponent.Activate")) {
351: public void actionPerformed(
352: @NotNull
353: ActionEvent e) {
354: linealModel
355: .setActive(
356: guideLine,
357: true);
358: }
359: });
360: }
361:
362: popupMenu
363: .add(new AbstractAction(
364: TranslationManager
365: .getInstance()
366: .getTranslation(
367: "R",
368: "LinealComponent.Delete")) {
369: public void actionPerformed(
370: @NotNull
371: ActionEvent e) {
372: linealModel
373: .removeGuideLine(guideLine);
374: }
375: });
376:
377: popupMenu.show(
378: HorizontalLinealComponent.this ,
379: me.getX(), me.getY());
380:
381: break;
382: }
383: }
384: }
385: }
386: }
387: });
388: }
389:
390: @Nullable
391: private GuideLine getActiveGuide(@NotNull
392: MouseEvent e, @NotNull
393: LinealModel linealModel) {
394: Report report = linealModel.getReport();
395: if (report != null) {
396: for (GuideLine guideLine : linealModel.getGuideLines()) {
397: double start = 0;
398: if (showLeftBorder) {
399: start = report.getPageDefinition().getLeftBorder();
400: }
401: int x = (int) ((guideLine.getPosition() + start) * scaleFactor);
402: if (x <= e.getX() + 2 && x >= e.getX() - 2) {
403: double unitValue = reportDialog
404: .getApplicationSettings().getUnit()
405: .convertFromPoints(guideLine.getPosition());
406: setToolTipText(DECIMAL_FORMAT.format(unitValue));
407: return guideLine;
408: }
409: }
410: }
411:
412: setToolTipText(null);
413: return null;
414: }
415:
416: @NotNull
417: public Dimension getPreferredSize() {
418: Report report = linealModel.getReport();
419: if (report != null) {
420: PageDefinition pageDefinition = report.getPageDefinition();
421: double d = pageDefinition.getLeftBorder()
422: + pageDefinition.getInnerPageSize().getWidth()
423: + pageDefinition.getRightBorder();
424: return new Dimension((int) (d * scaleFactor), 15);
425: } else {
426: return new Dimension(0, 15);
427: }
428: }
429:
430: protected void paintComponent(@NotNull
431: Graphics g) {
432: Report report = linealModel.getReport();
433: if (report != null) {
434: double start = report.getPageDefinition().getLeftBorder();
435:
436: double end = report.getPageDefinition().getInnerPageSize()
437: .getWidth();
438: end += report.getPageDefinition().getLeftBorder();
439: end += report.getPageDefinition().getRightBorder();
440:
441: g.setColor(Color.WHITE);
442: g.fillRect((int) (start * scaleFactor), 0,
443: (int) ((end - start) * scaleFactor), getHeight());
444:
445: g.setColor(Color.LIGHT_GRAY);
446: g.drawRect(-1, -1, (int) (start * scaleFactor) + 1,
447: getHeight() - 1 + 1);
448: g.drawRect((int) (start * scaleFactor), -1,
449: (int) ((end - start) * scaleFactor),
450: getHeight() - 1 + 1);
451:
452: drawGuideLines(g, report);
453: drawDots(g, start, end);
454: drawNumbers(g, start, end);
455: }
456: }
457:
458: private void drawGuideLines(@NotNull
459: Graphics g, @NotNull
460: Report report) {
461: LinkedHashSet<GuideLine> guideLines = linealModel
462: .getGuideLines();
463: double startOffset = 0;
464: if (showLeftBorder) {
465: startOffset = report.getPageDefinition().getLeftBorder();
466: }
467: int so = (int) (startOffset * scaleFactor);
468:
469: for (GuideLine guideLine : guideLines) {
470: int x = (int) (guideLine.getPosition() * scaleFactor) + so;
471: if (guideLine.isActive()) {
472: g.setColor(new Color(240, 170, 170));
473: } else {
474: g.setColor(new Color(205, 205, 205));
475: }
476: g.fillRect(x - 2, 1, 4, 13);
477: if (guideLine.isActive()) {
478: g.setColor(new Color(231, 109, 109));
479: } else {
480: g.setColor(new Color(170, 170, 170));
481: }
482: g.drawRect(x - 2, 0, 4, 14);
483: }
484:
485: g.setColor(Color.RED);
486: GuideLine highlightGuideLine = activeGuidLine;
487: if (draggedGuideLine != null) {
488: highlightGuideLine = draggedGuideLine;
489: }
490:
491: if (highlightGuideLine != null) {
492: int x = (int) (highlightGuideLine.getPosition() * scaleFactor)
493: + so;
494: if (highlightGuideLine.isActive()) {
495: g.setColor(new Color(255, 128, 128));
496: } else {
497: g.setColor(new Color(170, 170, 170));
498: }
499: g.fillRect(x - 2, 1, 4, 13);
500: if (highlightGuideLine.isActive()) {
501: g.setColor(new Color(255, 34, 34));
502: } else {
503: g.setColor(new Color(100, 100, 100));
504: }
505: g.drawRect(x - 2, 0, 4, 14);
506: }
507: }
508:
509: private void drawDots(@NotNull
510: Graphics g, double start, double end) {
511: g.setColor(Color.GRAY);
512:
513: Unit unit = reportDialog.getApplicationSettings().getUnit();
514: double factorForUnitAndScale = NumberHelper
515: .getFactorForUnitAndScale(unit, scaleFactor);
516:
517: double increment = unit.getDotsPerUnit()
518: * factorForUnitAndScale;
519:
520: for (double i = start + increment / 2; i < end; i += increment) {
521: int x = (int) (i * scaleFactor);
522: g.drawLine(x, 7, x, 9);
523: }
524: }
525:
526: private void drawNumbers(@NotNull
527: Graphics g, double start, double end) {
528: Unit unit = reportDialog.getApplicationSettings().getUnit();
529: double factorForUnitAndScale = NumberHelper
530: .getFactorForUnitAndScale(unit, scaleFactor);
531:
532: double increment = unit.getDotsPerUnit()
533: * factorForUnitAndScale;
534: double numberIncrement = factorForUnitAndScale;
535:
536: DecimalFormat df = DECIMAL_FORMAT_NUMBERS_INTEGER;
537: if (numberIncrement < 1) {
538: df = DECIMAL_FORMAT_NUMBERS_ONE_DIGIT;
539: }
540:
541: g.setColor(Color.BLACK);
542: double number = 0;
543: for (double i = start; i < end - increment / 2; i += increment) {
544: int x = (int) (i * scaleFactor);
545:
546: if (number > 0) {
547: String s = df.format(number);
548: Rectangle2D sb = g.getFontMetrics().getStringBounds(s,
549: g);
550: g.drawString(s,
551: (int) ((sb.getX() - sb.getWidth() / 2) + x),
552: (int) -sb.getY());
553: }
554: number += numberIncrement;
555: }
556: }
557:
558: public void setScaleFactor(double sf) {
559: scaleFactor = sf;
560: }
561: }
|