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