001package jmri.jmrit.roster; 002 003import java.awt.Frame; 004import java.awt.event.ActionEvent; 005import java.io.IOException; 006import java.util.Arrays; 007import java.util.List; 008import javax.swing.ImageIcon; 009import javax.swing.JLabel; 010import jmri.beans.BeanUtil; 011import jmri.jmrit.roster.rostergroup.RosterGroupSelector; 012import jmri.jmrit.roster.swing.RosterFrame; 013import jmri.util.FileUtil; 014import jmri.util.StringUtil; 015import jmri.util.davidflanagan.HardcopyWriter; 016import org.slf4j.Logger; 017import org.slf4j.LoggerFactory; 018 019/** 020 * Action to print a very compact summary listing of the Roster contents. 021 * <p> 022 * This uses the older style printing, for compatibility with Java 1.1.8 in 023 * Macintosh MRJ 024 * 025 * @author Bob Jacobsen Copyright (C) 2003 026 * @author Dennis Miller Copyright (C) 2005 027 * @author Egbert Broerse Copyright (C) 2018 028 */ 029public class PrintListAction extends jmri.util.swing.JmriAbstractAction { 030 031 public PrintListAction(String s, jmri.util.swing.WindowInterface wi) { 032 super(s, wi); 033 isPreview = true; 034 } 035 036 public PrintListAction(String s, javax.swing.Icon i, jmri.util.swing.WindowInterface wi) { 037 super(s, i, wi); 038 isPreview = true; 039 } 040 041 public PrintListAction(String actionName, Frame frame, boolean preview) { 042 super(actionName); 043 mFrame = frame; 044 isPreview = preview; 045 } 046 047 public void setPreview(boolean preview) { 048 isPreview = preview; 049 } 050 051 /** 052 * Frame hosting the printing. 053 */ 054 Frame mFrame = new Frame(); 055 056 /** 057 * Variable to set whether this is to be printed or previewed. 058 */ 059 boolean isPreview; 060 061 @Override 062 public void actionPerformed(ActionEvent e) { 063 // obtain a HardcopyWriter to do this 064 Roster r = Roster.getDefault(); 065 String title = Bundle.getMessage("TitleDecoderProRoster"); 066 String rosterGroup = r.getDefaultRosterGroup(); 067 // rosterGroup may legitimately be null 068 // but getProperty returns null if the property cannot be found, so 069 // we test that the property exists before attempting to get its value 070 if (BeanUtil.hasProperty(wi, RosterGroupSelector.SELECTED_ROSTER_GROUP)) { 071 rosterGroup = (String) BeanUtil.getProperty(wi, RosterGroupSelector.SELECTED_ROSTER_GROUP); 072 } 073 if (rosterGroup == null) { 074 title = title + " " + Bundle.getMessage("ALLENTRIES"); 075 } else { 076 title = title + " " + Bundle.getMessage("TitleGroup") + " " + Bundle.getMessage("TitleEntries", rosterGroup); 077 } 078 try ( HardcopyWriter writer = new HardcopyWriter(mFrame, title, 10, .5, .5, .5, .5, isPreview); ) { 079 080 // add the image 081 ImageIcon icon = new ImageIcon(FileUtil.findURL("resources/decoderpro.gif", FileUtil.Location.INSTALLED)); 082 // we use an ImageIcon because it's guaranteed to have been loaded when ctor is complete 083 writer.write(icon.getImage(), new JLabel(icon)); 084 // add a number of blank lines, so that the roster entry starts below the decoderpro logo 085 int height = icon.getImage().getHeight(null); 086 int blanks = (height - writer.getLineAscent()) / writer.getLineHeight(); 087 088 try { 089 for (int i = 0; i < blanks; i++) { 090 String s = "\n"; 091 writer.write(s, 0, s.length()); 092 } 093 } catch (IOException ex) { 094 log.warn("error during printing", ex); 095 } 096 097 // Loop through the Roster, printing a 1 line list entry as needed 098 List<RosterEntry> l; 099 100 if ( BeanUtil.hasProperty(wi, "allRosterEntries")) { 101 l = Arrays.asList(((RosterFrame)wi).getAllRosterEntries()); 102 } else { 103 l = r.matchingList(null, null, null, null, null, null, null); // take all 104 } 105 log.debug("Roster list size: {}", l.size()); 106 107 // print table column headers, match column order + widths with RosterEntry#PrintEntryLine 108 // fields copied from RosterTableModel#getColumnName(int) 109 String headerText = ""; 110 // IDCOL (= Filename) 111 headerText += StringUtil.padString(Bundle.getMessage("FieldID"), 15); 112 // ADDRESSCOL: 113 headerText += StringUtil.padString(Bundle.getMessage("FieldDCCAddress"), 6); 114 // ROADNAMECOL: 115 headerText += StringUtil.padString(Bundle.getMessage("FieldRoadName"), 6); 116 // ROADNUMBERCOL: 117 headerText += StringUtil.padString(Bundle.getMessage("FieldRoadNumber"), 6); 118 // MFGCOL: 119 headerText += StringUtil.padString(Bundle.getMessage("FieldManufacturer"), 6); 120 // MODELCOL: 121 headerText += StringUtil.padString(Bundle.getMessage("FieldModel"), 10); 122 // DECODERCOL: 123 headerText += StringUtil.padString(Bundle.getMessage("FieldDecoderModel"), 10); 124 // PROTOCOL: 125 headerText += StringUtil.padString(Bundle.getMessage("FieldProtocol"), 12); 126 // OWNERCOL: 127 headerText += StringUtil.padString(Bundle.getMessage("FieldOwner"), 6); 128 // DATEUPDATECOL: 129 headerText += StringUtil.padString(Bundle.getMessage("FieldDateUpdated"), 10); 130 131 try { 132 // start a new line 133 writer.write("\n", 0, 1); 134 writer.write(headerText); 135 } catch (IOException ex) { 136 log.warn("error during printing", ex); 137 } 138 139 for (RosterEntry re : l) { 140 if (rosterGroup != null) { 141 if (re.getAttribute(Roster.getRosterGroupProperty(rosterGroup)) != null 142 && re.getAttribute(Roster.getRosterGroupProperty(rosterGroup)).equals("yes")) { 143 re.printEntryLine(writer); 144 } 145 } else { 146 re.printEntryLine(writer); 147 } 148 } 149 150 // and force completion of the printing 151 // writer.close(); not needed when using try / catch 152 } catch (HardcopyWriter.PrintCanceledException ex) { 153 log.debug("Print cancelled"); 154 } 155 } 156 157 // never invoked, because we overrode actionPerformed above 158 @Override 159 public jmri.util.swing.JmriPanel makePanel() { 160 throw new IllegalArgumentException("Should not be invoked"); 161 } 162 163 @Override 164 public void setParameter(String parameter, String value) { 165 parameter = parameter.toLowerCase(); 166 value = value.toLowerCase(); 167 if (parameter.equals("ispreview")) { 168 isPreview = value.equals("true"); 169 } 170 } 171 172 private final static Logger log = LoggerFactory.getLogger(PrintListAction.class); 173 174}