Package net.geco.control

Source Code of net.geco.control.SingleSplitPrinter

/**
* Copyright (c) 2010 Simon Denier
* Released under the MIT License (see LICENSE file)
*/
package net.geco.control;

import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.print.PrinterJob;
import java.util.Properties;
import java.util.Vector;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.Media;
import javax.print.attribute.standard.MediaSize;
import javax.print.attribute.standard.MediaSizeName;
import javax.swing.JFrame;
import javax.swing.JTextPane;

import net.geco.basics.Html;
import net.geco.basics.Announcer.CardListener;
import net.geco.basics.Announcer.StageListener;
import net.geco.control.ResultBuilder.SplitTime;
import net.geco.model.Messages;
import net.geco.model.RunnerRaceData;
import net.geco.model.Stage;


/**
* @author Simon Denier
* @since Nov 25, 2010
*
*/
public class SingleSplitPrinter extends Control implements StageListener, CardListener {
 
  public static enum SplitFormat { MultiColumns, Ticket }

  private static final boolean DEBUGMODE = false;
 
  private PrintService splitPrinter;
  private boolean autoPrint;
  private SplitFormat splitFormat = SplitFormat.MultiColumns;
  private MediaSizeName[] splitMedia;
 
  private final ResultBuilder builder;
  private final SplitExporter exporter;
 
  public SingleSplitPrinter(GecoControl gecoControl) {
    super(SingleSplitPrinter.class, gecoControl);
    builder = getService(ResultBuilder.class);
    exporter = getService(SplitExporter.class);
    geco().announcer().registerStageListener(this);
    geco().announcer().registerCardListener(this);
    changed(null, stage());
  }
 
  public String printSingleSplits(RunnerRaceData data) {
    if( getSplitPrinter()!=null ) {
      Html html = new Html();
      if( splitFormat==SplitFormat.Ticket ) {
        exporter.includeHeader(html, "ticket.css"); //$NON-NLS-1$
        printSingleSplitsInLine(data, html);
      } else {
        exporter.includeHeader(html, "result.css"); //$NON-NLS-1$
        printSingleSplitsInColumns(data, html);
      }
   
      final JTextPane ticket = new JTextPane();
      ticket.setContentType("text/html"); //$NON-NLS-1$
      String content = html.close();
      ticket.setText(content);
     
      final PrintRequestAttributeSet attributes = new HashPrintRequestAttributeSet();
      if( splitFormat==SplitFormat.Ticket ) {
        computeMediaForTicket(ticket, attributes);
      }
     
      Callable<Boolean> callable = new Callable<Boolean>() {
        @Override
        public Boolean call() throws Exception {
          return ticket.print(null, null, false, getSplitPrinter(), attributes, false);
        }
      };
     
      if( ! DEBUGMODE ) {
        ExecutorService pool = Executors.newCachedThreadPool();
        pool.submit(callable);
      } else {
        JFrame jFrame = new JFrame();
        jFrame.add(ticket);
        jFrame.pack();
        jFrame.setVisible(true);
      }
     
//      try {
//        ticket.print(null, null, false, getSplitPrinter(), attributes, true);
//      } catch (PrinterException e) {
//        geco().debug(e.getLocalizedMessage());
//      }
      return content;
    }
    return ""; //$NON-NLS-1$
  }


  private void printSingleSplitsInColumns(RunnerRaceData data, Html html) {
    html.b(data.getRunner().getName() + " - " //$NON-NLS-1$
        + geco().stage().getName() + " - " //$NON-NLS-1$
        + data.getCourse().getName() + " - " //$NON-NLS-1$
        + data.getResult().shortFormat());
    html.open("table"); //$NON-NLS-1$
    exporter.appendHtmlSplitsInColumns(
        builder.buildNormalSplits(data, null),
        new SplitTime[0],
        exporter.nbColumns(),
        html);
    html.close("table"); //$NON-NLS-1$
    html.tag("div", //$NON-NLS-1$
        "align=\"center\"", //$NON-NLS-1$
        "Geco for orienteering - http://geco.webou.net"); //$NON-NLS-1$
  }


  private void printSingleSplitsInLine(RunnerRaceData data, Html html) {
  //    char[] chars = Character.toChars(0x2B15); // control flag char :)
  //    html.contents(new String(chars));
      html.open("div", "align=\"center\""); //$NON-NLS-1$ //$NON-NLS-2$
      html.contents(geco().stage().getName()).br();
      html.b(data.getRunner().getName()).br();
      html.br();
      html.b(data.getCourse().getName() + " - " //$NON-NLS-1$
          + data.getResult().shortFormat());
      html.close("div"); // don't center table, it wastes too much space for some formats. //$NON-NLS-1$
      html.open("table", "width=\"75%\""); //$NON-NLS-1$ //$NON-NLS-2$
      exporter.appendHtmlSplitsInLine(builder.buildLinearSplits(data), html);
      html.close("table").br(); //$NON-NLS-1$
      html.contents(Messages.getString("SingleSplitPrinter.SplitBottomLine1")).br(); //$NON-NLS-1$
      html.contents(Messages.getString("SingleSplitPrinter.SplitBottomLine2")); //$NON-NLS-1$
    }


  private void computeMediaForTicket(final JTextPane ticket,
      final PrintRequestAttributeSet attributes) {
    Dimension preferredSize = ticket.getPreferredSize();
    int dpi = Toolkit.getDefaultToolkit().getScreenResolution();
    float height = ((float) preferredSize.height) / dpi;
    float width = ((float) preferredSize.width) / dpi;
//    float width = 2.76f;

    if( DEBUGMODE ){
      System.out.print("Request: "); //$NON-NLS-1$
      System.out.print(height * 25.4);
      System.out.print("x"); //$NON-NLS-1$
      System.out.print(width * 25.4);
      System.out.println(" mm"); //$NON-NLS-1$
    }

    MediaSizeName bestMedia = null;
    float bestFit = Float.MAX_VALUE;
    for (MediaSizeName media : getSplitMedia()) {
      MediaSize mediaSize = MediaSize.getMediaSizeForName(media);
      if( mediaSize!=null ){
        if( DEBUGMODE ){
          System.out.print(mediaSize.toString(MediaSize.MM, "mm")); //$NON-NLS-1$
          System.out.println(" - " + media); //$NON-NLS-1$
        }
        float dy = mediaSize.getY(MediaSize.INCH) - height;
        float dx = mediaSize.getY(MediaSize.INCH) - width;
        float fit = dy + dx;
        if( dy >= 0 && dx >= 0 && fit <= bestFit ){
          bestFit = fit;
          bestMedia = media;
        }
      }
    }
    if( bestMedia==null ){
      bestMedia = MediaSize.findMedia(width, height, MediaSize.INCH);
      geco().debug(Messages.getString("SingleSplitPrinter.SmallTicketSizeWarning")); //$NON-NLS-1$
      if( DEBUGMODE ){
        System.out.print("Found: "); //$NON-NLS-1$
      }     
    } else {
      if( DEBUGMODE ){
        System.out.print("Chosen: "); //$NON-NLS-1$
      }     
    }
    if( bestMedia!=null ){
      attributes.add(bestMedia);
      MediaSize fitSize = MediaSize.getMediaSizeForName(bestMedia);
      if( DEBUGMODE ){
        System.out.println(fitSize.toString(MediaSize.MM, "mm")); //$NON-NLS-1$
      }
    } else {
      geco().log(Messages.getString("SingleSplitPrinter.NoMatchingTicketSizeWarning")); //$NON-NLS-1$
    }
  }


  private MediaSizeName[] getSplitMedia() {
    if( splitMedia==null ) {
      Vector<MediaSizeName> mediaSizenames = new Vector<MediaSizeName>();
      Media[] media = (Media[]) getSplitPrinter().getSupportedAttributeValues(Media.class, null, null);
      for (Media m : media) {
        if( m!=null && m instanceof MediaSizeName ){
          mediaSizenames.add((MediaSizeName) m);
        }
      }
      splitMedia = mediaSizenames.toArray(new MediaSizeName[0]);
    }
    return splitMedia;
  }

  public Vector<String> listPrinterNames() {
    Vector<String> printerNames = new Vector<String>();
    for (PrintService printer : PrinterJob.lookupPrintServices()) {
      printerNames.add(printer.getName());
    }
    return printerNames;
  }
 
  protected PrintService getSplitPrinter() {
    if( splitPrinter==null ) {
      splitPrinter = PrintServiceLookup.lookupDefaultPrintService();
    }
    return splitPrinter;
  }
 
  public String getSplitPrinterName() {
    return ( getSplitPrinter()==null ) ? "" : getSplitPrinter().getName(); //$NON-NLS-1$
  }
 
  public String getDefaultPrinterName() {
    PrintService defaultService = PrintServiceLookup.lookupDefaultPrintService();
    return ( defaultService==null ) ? "" : defaultService.getName(); //$NON-NLS-1$
  }
 
  public boolean setSplitPrinterName(String name) {
    splitMedia = null; // reset cache
    for (PrintService printer : PrinterJob.lookupPrintServices()) {
      if( printer.getName().equals(name) ) {
        splitPrinter = printer;
        return true;
      }
    }
    splitPrinter = null;
    return false;
  }

 
  public void enableAutoprint() {
    this.autoPrint = true;
  }
 
  public void disableAutoprint() {
    this.autoPrint = false;
  }
 
  public SplitFormat getSplitFormat() {
    return this.splitFormat;
  }
 
  public void setSplitFormat(SplitFormat format) {
    this.splitFormat = format;
  }


  @Override
  public void cardRead(String chip) {
    if( autoPrint ) {
      printSingleSplits(registry().findRunnerData(chip));
    }
  }
  @Override
  public void unknownCardRead(String chip) {  }
  @Override
  public void cardReadAgain(String chip) {  }
  @Override
  public void rentedCard(String siIdent) {  }


  @Override
  public void changed(Stage previous, Stage current) {
    Properties props = stage().getProperties();
    setSplitPrinterName(props.getProperty(splitPrinterProperty()));
    String format = props.getProperty(splitFormatProperty());
    if( format!=null ) {
      setSplitFormat(SplitFormat.valueOf(format));
    }
  }
  @Override
  public void saving(Stage stage, Properties properties) {
    properties.setProperty(splitPrinterProperty(), getSplitPrinterName());
    properties.setProperty(splitFormatProperty(), getSplitFormat().name());
  }
  @Override
  public void closing(Stage stage) {  }

  public static String splitPrinterProperty() {
    return "SplitPrinter"; //$NON-NLS-1$
  }
  public static String splitFormatProperty() {
    return "SplitFormat"; //$NON-NLS-1$
  }
 
}
TOP

Related Classes of net.geco.control.SingleSplitPrinter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.