001package jmri.jmrit.operations.locations.tools; 002 003import java.awt.*; 004import java.io.IOException; 005import java.text.MessageFormat; 006import java.util.List; 007 008import javax.swing.*; 009 010import org.slf4j.Logger; 011import org.slf4j.LoggerFactory; 012 013import jmri.InstanceManager; 014import jmri.jmrit.operations.OperationsFrame; 015import jmri.jmrit.operations.locations.*; 016import jmri.jmrit.operations.locations.schedules.*; 017import jmri.jmrit.operations.rollingstock.cars.*; 018import jmri.jmrit.operations.rollingstock.engines.EngineTypes; 019import jmri.jmrit.operations.routes.Route; 020import jmri.jmrit.operations.routes.RouteManager; 021import jmri.jmrit.operations.setup.Control; 022import jmri.jmrit.operations.setup.Setup; 023import jmri.jmrit.operations.trains.Train; 024import jmri.jmrit.operations.trains.TrainManager; 025import jmri.jmrit.operations.trains.trainbuilder.TrainCommon; 026import jmri.util.davidflanagan.HardcopyWriter; 027 028/** 029 * Frame to print a summary of the Location Roster contents 030 * <p> 031 * This uses the older style printing, for compatibility with Java 1.1.8 in 032 * Macintosh MRJ 033 * 034 * @author Bob Jacobsen Copyright (C) 2003 035 * @author Dennis Miller Copyright (C) 2005 036 * @author Daniel Boudreau Copyright (C) 2008, 2011, 2012, 2014, 2022, 2023 037 */ 038public class PrintLocationsFrame extends OperationsFrame { 039 040 static final String FORM_FEED = "\f"; // NOI18N 041 static final String TAB = "\t"; // NOI18N 042 static final int TAB_LENGTH = 10; 043 static final String SPACES_2 = " "; 044 static final String SPACES_3 = " "; 045 static final String SPACES_4 = " "; 046 047 static final int MAX_NAME_LENGTH = Control.max_len_string_location_name; 048 049 JCheckBox printLocations = new JCheckBox(Bundle.getMessage("PrintLocations")); 050 JCheckBox printSchedules = new JCheckBox(Bundle.getMessage("PrintSchedules")); 051 JCheckBox printComments = new JCheckBox(Bundle.getMessage("PrintComments")); 052 JCheckBox printDetails = new JCheckBox(Bundle.getMessage("PrintDetails")); 053 JCheckBox printAnalysis = new JCheckBox(Bundle.getMessage("PrintAnalysis")); 054 JCheckBox printErrorAnalysis = new JCheckBox(Bundle.getMessage("PrintErrorAnalysis")); 055 056 JButton okayButton = new JButton(Bundle.getMessage("ButtonOK")); 057 058 LocationManager lmanager = InstanceManager.getDefault(LocationManager.class); 059 CarTypes cts = InstanceManager.getDefault(CarTypes.class); 060 CarLoads cls = InstanceManager.getDefault(CarLoads.class); 061 CarRoads crs = InstanceManager.getDefault(CarRoads.class); 062 063 boolean _isPreview; 064 Location _location; 065 066 private int charactersPerLine = 70; 067 068 HardcopyWriter writer; 069 070 public PrintLocationsFrame(boolean isPreview, Location location) { 071 super(); 072 _isPreview = isPreview; 073 _location = location; 074 075 // create panel 076 JPanel pPanel = new JPanel(); 077 pPanel.setLayout(new GridBagLayout()); 078 pPanel.setBorder(BorderFactory.createTitledBorder(Bundle.getMessage("PrintOptions"))); 079 addItemLeft(pPanel, printLocations, 0, 0); 080 addItemLeft(pPanel, printSchedules, 0, 3); 081 addItemLeft(pPanel, printComments, 0, 5); 082 addItemLeft(pPanel, printDetails, 0, 7); 083 addItemLeft(pPanel, printAnalysis, 0, 9); 084 addItemLeft(pPanel, printErrorAnalysis, 0, 11); 085 086 // set defaults 087 printLocations.setSelected(true); 088 printSchedules.setSelected(false); 089 printComments.setSelected(false); 090 printDetails.setSelected(false); 091 printAnalysis.setSelected(false); 092 printErrorAnalysis.setSelected(false); 093 094 // add tool tips 095 JPanel pButtons = new JPanel(); 096 pButtons.setLayout(new GridBagLayout()); 097 pButtons.add(okayButton); 098 addButtonAction(okayButton); 099 100 getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS)); 101 getContentPane().add(pPanel); 102 getContentPane().add(pButtons); 103 setPreferredSize(null); 104 if (_isPreview) { 105 setTitle(Bundle.getMessage("MenuItemPreview")); 106 } else { 107 setTitle(Bundle.getMessage("MenuItemPrint")); 108 } 109 initMinimumSize(new Dimension(Control.panelWidth300, Control.panelHeight250)); 110 } 111 112 @Override 113 public void buttonActionPerformed(java.awt.event.ActionEvent ae) { 114 setVisible(false); 115 printLocations(); 116 } 117 118 private void printLocations() { 119 // prevent NPE on close 120 if (!printLocations.isSelected() && 121 !printSchedules.isSelected() && 122 !printComments.isSelected() && 123 !printDetails.isSelected() && 124 !printAnalysis.isSelected() && 125 !printErrorAnalysis.isSelected()) { 126 return; 127 } 128 // obtain a HardcopyWriter 129 String title = Bundle.getMessage("TitleLocationsTable"); 130 if (_location != null) { 131 title = _location.getName(); 132 } 133 try (HardcopyWriter writer = 134 new HardcopyWriter(new Frame(), title, Control.reportFontSize, .5, .5, .5, .5, _isPreview)) { 135 136 this.writer = writer; 137 138 charactersPerLine = writer.getCharactersPerLine(); 139 140 // print locations? 141 if (printLocations.isSelected()) { 142 printLocationsSelected(); 143 } 144 // print schedules? 145 if (printSchedules.isSelected()) { 146 printSchedulesSelected(); 147 } 148 if (printComments.isSelected()) { 149 printCommentsSelected(); 150 } 151 // print detailed report? 152 if (printDetails.isSelected()) { 153 printDetailsSelected(); 154 } 155 // print analysis? 156 if (printAnalysis.isSelected()) { 157 printAnalysisSelected(); 158 } 159 if (printErrorAnalysis.isSelected()) { 160 printErrorAnalysisSelected(); 161 } 162 } catch (HardcopyWriter.PrintCanceledException ex) { 163 log.debug("Print canceled"); 164 } catch (IOException we) { 165 log.error("Error printing PrintLocationAction: {}", we.getLocalizedMessage()); 166 } 167 } 168 169 // Loop through the Roster, printing as needed 170 private void printLocationsSelected() throws IOException { 171 List<Location> locations = lmanager.getLocationsByNameList(); 172 int totalLength = 0; 173 int usedLength = 0; 174 int numberRS = 0; 175 int numberCars = 0; 176 int numberEngines = 0; 177 // header 178 String s = Bundle.getMessage("Location") + 179 TAB + 180 TAB + 181 TAB + 182 Bundle.getMessage("Length") + 183 " " + 184 Bundle.getMessage("Used") + 185 TAB + 186 Bundle.getMessage("RS") + 187 TAB + 188 Bundle.getMessage("Cars") + 189 TAB + 190 Bundle.getMessage("Engines") + 191 TAB + 192 Bundle.getMessage("Pickups") + 193 " " + 194 Bundle.getMessage("Drop") + 195 NEW_LINE; 196 writer.write(s); 197 for (Location location : locations) { 198 if (_location != null && location != _location) { 199 continue; 200 } 201 // location name, track length, used, number of RS, scheduled pick 202 // ups and drops 203 s = padOutString(location.getName(), MAX_NAME_LENGTH) + 204 TAB + 205 " " + 206 Integer.toString(location.getLength()) + 207 TAB + 208 Integer.toString(location.getUsedLength()) + 209 TAB + 210 Integer.toString(location.getNumberRS()) + 211 TAB + 212 Integer.toString(location.getNumberCars()) + 213 TAB + 214 Integer.toString(location.getNumberEngines()) + 215 TAB + 216 Integer.toString(location.getPickupRS()) + 217 TAB + 218 Integer.toString(location.getDropRS()) + 219 NEW_LINE; 220 writer.write(s); 221 222 if (location.getDivision() != null) { 223 writer.write(SPACES_3 + Bundle.getMessage("Division") + ": " + location.getDivisionName() + NEW_LINE); 224 } 225 226 totalLength += location.getLength(); 227 usedLength += location.getUsedLength(); 228 numberRS += location.getNumberRS(); 229 230 List<Track> yards = location.getTracksByNameList(Track.YARD); 231 if (yards.size() > 0) { 232 // header 233 writer.write(SPACES_3 + Bundle.getMessage("YardName") + NEW_LINE); 234 for (Track yard : yards) { 235 writer.write(getTrackString(yard)); 236 numberCars += yard.getNumberCars(); 237 numberEngines += yard.getNumberEngines(); 238 } 239 } 240 241 List<Track> spurs = location.getTracksByNameList(Track.SPUR); 242 if (spurs.size() > 0) { 243 // header 244 writer.write(SPACES_3 + Bundle.getMessage("SpurName") + NEW_LINE); 245 for (Track spur : spurs) { 246 writer.write(getTrackString(spur)); 247 numberCars += spur.getNumberCars(); 248 numberEngines += spur.getNumberEngines(); 249 } 250 } 251 252 List<Track> interchanges = location.getTracksByNameList(Track.INTERCHANGE); 253 if (interchanges.size() > 0) { 254 // header 255 writer.write(SPACES_3 + Bundle.getMessage("InterchangeName") + NEW_LINE); 256 for (Track interchange : interchanges) { 257 writer.write(getTrackString(interchange)); 258 numberCars += interchange.getNumberCars(); 259 numberEngines += interchange.getNumberEngines(); 260 } 261 } 262 263 List<Track> stagingTracks = location.getTracksByNameList(Track.STAGING); 264 if (stagingTracks.size() > 0) { 265 // header 266 writer.write(SPACES_3 + Bundle.getMessage("StagingName") + NEW_LINE); 267 for (Track staging : stagingTracks) { 268 writer.write(getTrackString(staging)); 269 numberCars += staging.getNumberCars(); 270 numberEngines += staging.getNumberEngines(); 271 } 272 } 273 writer.write(NEW_LINE); 274 } 275 276 // summary 277 s = MessageFormat 278 .format(Bundle.getMessage("TotalLengthMsg"), 279 new Object[]{Integer.toString(totalLength), Integer.toString(usedLength), 280 totalLength > 0 ? Integer.toString(usedLength * 100 / totalLength) : 0}) + 281 NEW_LINE; 282 writer.write(s); 283 s = MessageFormat 284 .format(Bundle.getMessage("TotalRollingMsg"), 285 new Object[]{Integer.toString(numberRS), Integer.toString(numberCars), 286 Integer.toString(numberEngines)}) + 287 NEW_LINE; 288 writer.write(s); 289 // are there trains en route, then some cars and engines not counted! 290 if (numberRS != numberCars + numberEngines) { 291 s = Bundle.getMessage("NoteRSMsg", Integer.toString(numberRS - (numberCars + numberEngines))) + NEW_LINE; 292 writer.write(s); 293 } 294 if (printSchedules.isSelected() || 295 printComments.isSelected() || 296 printDetails.isSelected() || 297 printAnalysis.isSelected() || 298 printErrorAnalysis.isSelected()) { 299 writer.write(FORM_FEED); 300 } 301 } 302 303 private void printSchedulesSelected() throws IOException { 304 List<Location> locations = lmanager.getLocationsByNameList(); 305 String s = padOutString(Bundle.getMessage("Schedules"), MAX_NAME_LENGTH) + 306 " " + 307 Bundle.getMessage("Location") + 308 " - " + 309 Bundle.getMessage("SpurName") + 310 NEW_LINE; 311 writer.write(s); 312 List<Schedule> schedules = InstanceManager.getDefault(ScheduleManager.class).getSchedulesByNameList(); 313 for (Schedule schedule : schedules) { 314 for (Location location : locations) { 315 if (_location != null && location != _location) { 316 continue; 317 } 318 List<Track> spurs = location.getTracksByNameList(Track.SPUR); 319 for (Track spur : spurs) { 320 if (spur.getScheduleId().equals(schedule.getId())) { 321 // pad out schedule name 322 s = padOutString(schedule.getName(), 323 MAX_NAME_LENGTH) + " " + location.getName() + " - " + spur.getName(); 324 String status = spur.checkScheduleValid(); 325 if (!status.equals(Schedule.SCHEDULE_OKAY)) { 326 StringBuffer buf = new StringBuffer(s); 327 for (int m = s.length(); m < 63; m++) { 328 buf.append(" "); 329 } 330 s = buf.toString(); 331 if (s.length() > 63) { 332 s = s.substring(0, 63); 333 } 334 s = s + TAB + status; 335 } 336 s = s + NEW_LINE; 337 writer.write(s); 338 // show the schedule's mode 339 s = padOutString("", MAX_NAME_LENGTH) + 340 SPACES_3 + 341 Bundle.getMessage("ScheduleMode") + 342 ": " + 343 spur.getScheduleModeName() + 344 NEW_LINE; 345 writer.write(s); 346 // show alternate track if there's one 347 if (spur.getAlternateTrack() != null) { 348 s = padOutString("", MAX_NAME_LENGTH) + 349 SPACES_3 + 350 Bundle.getMessage("AlternateTrackName", spur.getAlternateTrack().getName()) + 351 NEW_LINE; 352 writer.write(s); 353 } 354 // show custom loads from staging if not 100% 355 if (spur.getReservationFactor() != 100) { 356 s = padOutString("", MAX_NAME_LENGTH) + 357 SPACES_3 + 358 Bundle.getMessage("PercentageStaging", 359 spur.getReservationFactor()) + 360 NEW_LINE; 361 writer.write(s); 362 } 363 } 364 } 365 } 366 } 367 // now show the contents of each schedule 368 for (Schedule schedule : schedules) { 369 writer.write(FORM_FEED); 370 s = schedule.getName() + NEW_LINE; 371 writer.write(s); 372 373 for (ScheduleItem si : schedule.getItemsBySequenceList()) { 374 s = padOutString(Bundle.getMessage("Type"), cts.getMaxNameLength() + 1) + 375 padOutString(Bundle.getMessage("Receive"), cls.getMaxNameLength() + 1) + 376 padOutString(Bundle.getMessage("Ship"), cls.getMaxNameLength() + 1) + 377 padOutString(Bundle.getMessage("Destination"), lmanager.getMaxLocationNameLength() + 1) + 378 Bundle.getMessage("Track") + 379 NEW_LINE; 380 writer.write(s); 381 s = padOutString(si.getTypeName(), cts.getMaxNameLength() + 1) + 382 padOutString(si.getReceiveLoadName(), cls.getMaxNameLength() + 1) + 383 padOutString(si.getShipLoadName(), cls.getMaxNameLength() + 1) + 384 padOutString(si.getDestinationName(), lmanager.getMaxLocationNameLength() + 1) + 385 si.getDestinationTrackName() + 386 NEW_LINE; 387 writer.write(s); 388 389 s = padOutString("", cts.getMaxNameLength() + 1) + 390 padOutString(Bundle.getMessage("Random"), Bundle.getMessage("Random").length() + 1) + 391 padOutString(Bundle.getMessage("Delivery"), Bundle.getMessage("Delivery").length() + 1) + 392 padOutString(Bundle.getMessage("Road"), crs.getMaxNameLength() + 1) + 393 padOutString(Bundle.getMessage("Pickup"), Bundle.getMessage("Delivery").length() + 1) + 394 Bundle.getMessage("Wait") + 395 NEW_LINE; 396 writer.write(s); 397 398 s = padOutString("", cts.getMaxNameLength() + 1) + 399 padOutString(si.getRandom(), Bundle.getMessage("Random").length() + 1) + 400 padOutString(si.getSetoutTrainScheduleName(), Bundle.getMessage("Delivery").length() + 1) + 401 padOutString(si.getRoadName(), crs.getMaxNameLength() + 1) + 402 padOutString(si.getPickupTrainScheduleName(), Bundle.getMessage("Delivery").length() + 1) + 403 si.getWait() + 404 NEW_LINE; 405 writer.write(s); 406 } 407 } 408 if (printComments.isSelected() || 409 printDetails.isSelected() || 410 printAnalysis.isSelected() || 411 printErrorAnalysis.isSelected()) { 412 writer.write(FORM_FEED); 413 } 414 } 415 416 private void printCommentsSelected() throws IOException { 417 String s = Bundle.getMessage("PrintComments") + NEW_LINE + NEW_LINE; 418 writer.write(s); 419 List<Location> locations = lmanager.getLocationsByNameList(); 420 for (Location location : locations) { 421 if (_location != null && location != _location) { 422 continue; 423 } 424 s = location.getName() + NEW_LINE; 425 writer.write(s); 426 s = SPACES_3 + location.getComment() + NEW_LINE; 427 writer.write(s); 428 for (Track track : location.getTracksByNameList(null)) { 429 if (!track.getComment().equals(Track.NONE) || 430 !track.getCommentBoth().equals(Track.NONE) || 431 !track.getCommentPickup().equals(Track.NONE) || 432 !track.getCommentSetout().equals(Track.NONE)) { 433 s = SPACES_2 + track.getName() + NEW_LINE; 434 writer.write(s); 435 if (!track.getComment().equals(Track.NONE)) { 436 s = SPACES_4 + track.getComment() + NEW_LINE; 437 writer.write(s); 438 } 439 if (!track.getCommentBoth().equals(Track.NONE)) { 440 s = SPACES_3 + Bundle.getMessage("CommentBoth") + ":" + NEW_LINE; 441 writer.write(s); 442 s = SPACES_4 + track.getCommentBoth() + NEW_LINE; 443 writer.write(s); 444 } 445 if (!track.getCommentPickup().equals(Track.NONE)) { 446 s = SPACES_3 + Bundle.getMessage("CommentPickup") + ":" + NEW_LINE; 447 writer.write(s); 448 s = SPACES_4 + track.getCommentPickup() + NEW_LINE; 449 writer.write(s); 450 } 451 if (!track.getCommentSetout().equals(Track.NONE)) { 452 s = SPACES_3 + Bundle.getMessage("CommentSetout") + ":" + NEW_LINE; 453 writer.write(s); 454 s = SPACES_4 + track.getCommentSetout() + NEW_LINE; 455 writer.write(s); 456 } 457 } 458 } 459 } 460 if (printDetails.isSelected() || printAnalysis.isSelected() || printErrorAnalysis.isSelected()) { 461 writer.write(FORM_FEED); 462 } 463 } 464 465 private void printDetailsSelected() throws IOException { 466 List<Location> locations = lmanager.getLocationsByNameList(); 467 String s = Bundle.getMessage("DetailedReport") + NEW_LINE; 468 writer.write(s); 469 for (Location location : locations) { 470 if (_location != null && location != _location) { 471 continue; 472 } 473 String name = location.getName(); 474 // services train direction 475 int dir = location.getTrainDirections(); 476 s = NEW_LINE + name + getDirection(dir); 477 writer.write(s); 478 479 // division 480 if (location.getDivision() != null) { 481 s = SPACES_3 + Bundle.getMessage("Division") + ": " + location.getDivisionName() + NEW_LINE; 482 writer.write(s); 483 } 484 485 // services car and engine types 486 s = getLocationTypes(location); 487 writer.write(s); 488 489 List<Track> spurs = location.getTracksByNameList(Track.SPUR); 490 if (spurs.size() > 0) { 491 s = SPACES_3 + Bundle.getMessage("SpurName") + NEW_LINE; 492 writer.write(s); 493 printTrackInfo(location, spurs); 494 } 495 496 List<Track> yards = location.getTracksByNameList(Track.YARD); 497 if (yards.size() > 0) { 498 s = SPACES_3 + Bundle.getMessage("YardName") + NEW_LINE; 499 writer.write(s); 500 printTrackInfo(location, yards); 501 } 502 503 List<Track> interchanges = location.getTracksByNameList(Track.INTERCHANGE); 504 if (interchanges.size() > 0) { 505 s = SPACES_3 + Bundle.getMessage("InterchangeName") + NEW_LINE; 506 writer.write(s); 507 printTrackInfo(location, interchanges); 508 } 509 510 List<Track> staging = location.getTracksByNameList(Track.STAGING); 511 if (staging.size() > 0) { 512 s = SPACES_3 + Bundle.getMessage("StagingName") + NEW_LINE; 513 writer.write(s); 514 printTrackInfo(location, staging); 515 } 516 } 517 if (printAnalysis.isSelected() || printErrorAnalysis.isSelected()) { 518 writer.write(FORM_FEED); 519 } 520 } 521 522 private final boolean showStaging = true; 523 524 private void printAnalysisSelected() throws IOException { 525 CarManager carManager = InstanceManager.getDefault(CarManager.class); 526 List<Location> locations = lmanager.getLocationsByNameList(); 527 List<Car> cars = carManager.getByLocationList(); 528 String[] carTypes = cts.getNames(); 529 530 String s = Bundle.getMessage("TrackAnalysis") + NEW_LINE; 531 writer.write(s); 532 533 // print the car type being analyzed 534 for (String type : carTypes) { 535 // get the total length for a given car type 536 int numberOfCars = 0; 537 int totalTrackLength = 0; 538 for (Car car : cars) { 539 if (car.getTypeName().equals(type) && car.getLocation() != null) { 540 numberOfCars++; 541 totalTrackLength += car.getTotalLength(); 542 } 543 } 544 writer.write(Bundle.getMessage("NumberTypeLength", 545 numberOfCars, type, totalTrackLength, Setup.getLengthUnit().toLowerCase()) + 546 NEW_LINE); 547 // don't bother reporting when the number of cars for a given type 548 // is zero. Round up percentage used by a car type. 549 if (numberOfCars > 0) { 550 // spurs 551 writer.write(SPACES_3 + 552 Bundle.getMessage("SpurTrackThatAccept", type) + 553 NEW_LINE); 554 int trackLength = getTrackLengthAcceptType(locations, type, Track.SPUR); 555 if (trackLength > 0) { 556 writer.write(SPACES_3 + 557 Bundle.getMessage("TotalLengthSpur", type, trackLength, Setup.getLengthUnit().toLowerCase(), 558 Math.ceil((double) 100 * totalTrackLength / trackLength)) + 559 NEW_LINE); 560 } else { 561 writer.write(SPACES_3 + Bundle.getMessage("None") + NEW_LINE); 562 } 563 // yards 564 writer.write(SPACES_3 + 565 Bundle.getMessage("YardTrackThatAccept", type) + 566 NEW_LINE); 567 trackLength = getTrackLengthAcceptType(locations, type, Track.YARD); 568 if (trackLength > 0) { 569 writer.write(SPACES_3 + 570 Bundle.getMessage("TotalLengthYard", type, trackLength, Setup.getLengthUnit().toLowerCase(), 571 Math.ceil((double) 100 * totalTrackLength / trackLength)) + 572 NEW_LINE); 573 } else { 574 writer.write(SPACES_3 + Bundle.getMessage("None") + NEW_LINE); 575 } 576 // interchanges 577 writer.write(SPACES_3 + 578 Bundle.getMessage("InterchangesThatAccept", type) + 579 NEW_LINE); 580 trackLength = getTrackLengthAcceptType(locations, type, Track.INTERCHANGE); 581 if (trackLength > 0) { 582 writer.write(SPACES_3 + 583 Bundle.getMessage("TotalLengthInterchange", 584 type, trackLength, Setup.getLengthUnit().toLowerCase(), 585 Math.ceil((double) 100 * totalTrackLength / trackLength)) + 586 NEW_LINE); 587 } else { 588 writer.write(SPACES_3 + Bundle.getMessage("None") + NEW_LINE); 589 } 590 // staging 591 if (showStaging) { 592 writer.write(SPACES_3 + 593 Bundle.getMessage("StageTrackThatAccept", type) + 594 NEW_LINE); 595 trackLength = getTrackLengthAcceptType(locations, type, Track.STAGING); 596 if (trackLength > 0) { 597 writer.write(SPACES_3 + 598 Bundle.getMessage("TotalLengthStage", 599 type, trackLength, Setup.getLengthUnit().toLowerCase(), 600 Math.ceil((double) 100 * totalTrackLength / trackLength)) + 601 NEW_LINE); 602 } else { 603 writer.write(SPACES_3 + Bundle.getMessage("None") + NEW_LINE); 604 } 605 } 606 } 607 } 608 if (printErrorAnalysis.isSelected()) { 609 writer.write(FORM_FEED); 610 } 611 } 612 613 private void printErrorAnalysisSelected() throws IOException { 614 writer.write(Bundle.getMessage("TrackErrorAnalysis") + NEW_LINE); 615 boolean foundError = false; 616 for (Location location : lmanager.getLocationsByNameList()) { 617 if (_location != null && location != _location) { 618 continue; 619 } 620 writer.write(location.getName() + NEW_LINE); 621 for (Track track : location.getTracksByNameList(null)) { 622 if (!track.checkPickups().equals(Track.PICKUP_OKAY)) { 623 writer.write(TAB + track.checkPickups() + NEW_LINE); 624 foundError = true; 625 } 626 } 627 } 628 if (!foundError) { 629 writer.write(Bundle.getMessage("NoErrors")); 630 } 631 } 632 633 private int getTrackLengthAcceptType(List<Location> locations, String carType, 634 String trackType) 635 throws IOException { 636 int trackLength = 0; 637 for (Location location : locations) { 638 if (_location != null && location != _location) { 639 continue; 640 } 641 List<Track> tracks = location.getTracksByNameList(trackType); 642 for (Track track : tracks) { 643 if (track.isTypeNameAccepted(carType)) { 644 trackLength = trackLength + track.getLength(); 645 writer.write(SPACES_3 + 646 SPACES_3 + 647 Bundle.getMessage("LocationTrackLength", 648 location.getName(), track.getName(), track.getLength(), 649 Setup.getLengthUnit().toLowerCase()) + 650 NEW_LINE); 651 } 652 } 653 } 654 return trackLength; 655 } 656 657 private String getTrackString(Track track) { 658 String s = TAB + 659 padOutString(track.getName(), Control.max_len_string_track_name) + 660 " " + 661 Integer.toString(track.getLength()) + 662 TAB + 663 Integer.toString(track.getUsedLength()) + 664 TAB + 665 Integer.toString(track.getNumberRS()) + 666 TAB + 667 Integer.toString(track.getNumberCars()) + 668 TAB + 669 Integer.toString(track.getNumberEngines()) + 670 TAB + 671 Integer.toString(track.getPickupRS()) + 672 TAB + 673 Integer.toString(track.getDropRS()) + 674 NEW_LINE; 675 return s; 676 } 677 678 private String getDirection(int dir) { 679 if ((Setup.getTrainDirection() & dir) == 0) { 680 return " " + Bundle.getMessage("LocalOnly") + NEW_LINE; 681 } 682 StringBuffer direction = new StringBuffer(" " + Bundle.getMessage("ServicedByTrain") + " "); 683 if ((Setup.getTrainDirection() & dir & Location.NORTH) == Location.NORTH) { 684 direction.append(Bundle.getMessage("North") + " "); 685 } 686 if ((Setup.getTrainDirection() & dir & Location.SOUTH) == Location.SOUTH) { 687 direction.append(Bundle.getMessage("South") + " "); 688 } 689 if ((Setup.getTrainDirection() & dir & Location.EAST) == Location.EAST) { 690 direction.append(Bundle.getMessage("East") + " "); 691 } 692 if ((Setup.getTrainDirection() & dir & Location.WEST) == Location.WEST) { 693 direction.append(Bundle.getMessage("West") + " "); 694 } 695 direction.append(NEW_LINE); 696 return direction.toString(); 697 } 698 699 private void printTrackInfo(Location location, List<Track> tracks) { 700 for (Track track : tracks) { 701 try { 702 String s = TAB + 703 track.getName() + 704 getDirection(location.getTrainDirections() & track.getTrainDirections()); 705 writer.write(s); 706 isAlternate(track); 707 writer.write(getTrackCarTypes(track)); 708 writer.write(getTrackEngineTypes(track)); 709 writer.write(getTrackRoads(track)); 710 writer.write(getTrackLoads(track)); 711 writer.write(getTrackShipLoads(track)); 712 writer.write(getCarOrder(track)); 713 writer.write(getSetOutTrains(track)); 714 writer.write(getPickUpTrains(track)); 715 writer.write(getDestinations(track)); 716 writer.write(getTrackInfo(track)); 717 writer.write(getSpurInfo(track)); 718 writer.write(getSchedule(track)); 719 writer.write(getStagingInfo(track)); 720 writer.write(NEW_LINE); 721 } catch (IOException we) { 722 log.error("Error printing PrintLocationAction: {}", we.getLocalizedMessage()); 723 } 724 } 725 } 726 727 private String getLocationTypes(Location location) { 728 StringBuffer buf = new StringBuffer(TAB + TAB + Bundle.getMessage("TypesServiced") + NEW_LINE + TAB + TAB); 729 int charCount = 0; 730 int typeCount = 0; 731 732 for (String type : cts.getNames()) { 733 if (location.acceptsTypeName(type)) { 734 typeCount++; 735 charCount += type.length() + 2; 736 if (charCount > charactersPerLine - 2 * TAB_LENGTH) { 737 buf.append(NEW_LINE + TAB + TAB); 738 charCount = type.length() + 2; 739 } 740 buf.append(type + ", "); 741 } 742 } 743 744 for (String type : InstanceManager.getDefault(EngineTypes.class).getNames()) { 745 if (location.acceptsTypeName(type)) { 746 typeCount++; 747 charCount += type.length() + 2; 748 if (charCount > charactersPerLine - 2 * TAB_LENGTH) { 749 buf.append(NEW_LINE + TAB + TAB); 750 charCount = type.length() + 2; 751 } 752 buf.append(type + ", "); 753 } 754 } 755 if (buf.length() > 2) { 756 buf.setLength(buf.length() - 2); // remove trailing separators 757 } 758 // does this location accept all types? 759 if (typeCount == cts.getNames().length + InstanceManager.getDefault(EngineTypes.class).getNames().length) { 760 buf = new StringBuffer(TAB + TAB + Bundle.getMessage("LocationAcceptsAllTypes")); 761 } 762 buf.append(NEW_LINE); 763 return buf.toString(); 764 } 765 766 private String getTrackCarTypes(Track track) { 767 StringBuffer buf = 768 new StringBuffer(TAB + TAB + Bundle.getMessage("CarTypesServicedTrack") + NEW_LINE + TAB + TAB); 769 int charCount = 0; 770 int typeCount = 0; 771 772 for (String type : cts.getNames()) { 773 if (track.isTypeNameAccepted(type)) { 774 typeCount++; 775 charCount += type.length() + 2; 776 if (charCount > charactersPerLine - 2 * TAB_LENGTH) { 777 buf.append(NEW_LINE + TAB + TAB); 778 charCount = type.length() + 2; 779 } 780 buf.append(type + ", "); 781 } 782 } 783 if (buf.length() > 2) { 784 buf.setLength(buf.length() - 2); // remove trailing separators 785 } 786 // does this track accept all types? 787 if (typeCount == cts.getNames().length) { 788 buf = new StringBuffer(TAB + TAB + Bundle.getMessage("TrackAcceptsAllCarTypes")); 789 } 790 buf.append(NEW_LINE); 791 return buf.toString(); 792 } 793 794 private String getTrackEngineTypes(Track track) { 795 StringBuffer buf = 796 new StringBuffer(TAB + TAB + Bundle.getMessage("EngineTypesServicedTrack") + NEW_LINE + TAB + TAB); 797 int charCount = 0; 798 int typeCount = 0; 799 800 for (String type : InstanceManager.getDefault(EngineTypes.class).getNames()) { 801 if (track.isTypeNameAccepted(type)) { 802 typeCount++; 803 charCount += type.length() + 2; 804 if (charCount > charactersPerLine - 2 * TAB_LENGTH) { 805 buf.append(NEW_LINE + TAB + TAB); 806 charCount = type.length() + 2; 807 } 808 buf.append(type + ", "); 809 } 810 } 811 if (buf.length() > 2) { 812 buf.setLength(buf.length() - 2); // remove trailing separators 813 } 814 // does this track accept all types? 815 if (typeCount == InstanceManager.getDefault(EngineTypes.class).getNames().length) { 816 buf = new StringBuffer(TAB + TAB + Bundle.getMessage("TrackAcceptsAllEngTypes")); 817 } 818 buf.append(NEW_LINE); 819 return buf.toString(); 820 } 821 822 private String getTrackRoads(Track track) { 823 if (track.getRoadOption().equals(Track.ALL_ROADS)) { 824 return TAB + TAB + Bundle.getMessage("AcceptsAllRoads") + NEW_LINE; 825 } 826 827 String op = Bundle.getMessage("RoadsServicedTrack"); 828 if (track.getRoadOption().equals(Track.EXCLUDE_ROADS)) { 829 op = Bundle.getMessage("ExcludeRoadsTrack"); 830 } 831 832 StringBuffer buf = new StringBuffer(TAB + TAB + op + NEW_LINE + TAB + TAB); 833 int charCount = 0; 834 835 for (String road : track.getRoadNames()) { 836 charCount += road.length() + 2; 837 if (charCount > charactersPerLine - 2 * TAB_LENGTH) { 838 buf.append(NEW_LINE + TAB + TAB); 839 charCount = road.length() + 2; 840 } 841 buf.append(road + ", "); 842 } 843 if (buf.length() > 2) { 844 buf.setLength(buf.length() - 2); // remove trailing separators 845 } 846 buf.append(NEW_LINE); 847 return buf.toString(); 848 } 849 850 private String getTrackLoads(Track track) { 851 if (track.getLoadOption().equals(Track.ALL_LOADS)) { 852 return TAB + TAB + Bundle.getMessage("AcceptsAllLoads") + NEW_LINE; 853 } 854 855 String op = Bundle.getMessage("LoadsServicedTrack"); 856 if (track.getLoadOption().equals(Track.EXCLUDE_LOADS)) { 857 op = Bundle.getMessage("ExcludeLoadsTrack"); 858 } 859 860 StringBuffer buf = new StringBuffer(TAB + TAB + op + NEW_LINE + TAB + TAB); 861 int charCount = 0; 862 863 for (String load : track.getLoadNames()) { 864 charCount += load.length() + 2; 865 if (charCount > charactersPerLine - 2 * TAB_LENGTH) { 866 buf.append(NEW_LINE + TAB + TAB); 867 charCount = load.length() + 2; 868 } 869 buf.append(load + ", "); 870 } 871 if (buf.length() > 2) { 872 buf.setLength(buf.length() - 2); // remove trailing separators 873 } 874 buf.append(NEW_LINE); 875 return buf.toString(); 876 } 877 878 private String getTrackShipLoads(Track track) { 879 // only staging has the ship load control 880 if (!track.isStaging()) { 881 return ""; 882 } 883 if (track.getShipLoadOption().equals(Track.ALL_LOADS)) { 884 return TAB + TAB + Bundle.getMessage("ShipsAllLoads") + NEW_LINE; 885 } 886 String op = Bundle.getMessage("LoadsShippedTrack"); 887 if (track.getShipLoadOption().equals(Track.EXCLUDE_LOADS)) { 888 op = Bundle.getMessage("ExcludeLoadsShippedTrack"); 889 } 890 891 StringBuffer buf = new StringBuffer(TAB + TAB + op + NEW_LINE + TAB + TAB); 892 int charCount = 0; 893 894 for (String load : track.getShipLoadNames()) { 895 charCount += load.length() + 2; 896 if (charCount > charactersPerLine - 2 * TAB_LENGTH) { 897 buf.append(NEW_LINE + TAB + TAB); 898 charCount = load.length() + 2; 899 } 900 buf.append(load + ", "); 901 } 902 if (buf.length() > 2) { 903 buf.setLength(buf.length() - 2); // remove trailing separators 904 } 905 buf.append(NEW_LINE); 906 return buf.toString(); 907 } 908 909 private String getCarOrder(Track track) { 910 // only yards and interchanges have the car order option 911 if (track.isSpur() || track.isStaging() || track.getServiceOrder().equals(Track.NORMAL)) { 912 return ""; 913 } 914 if (track.getServiceOrder().equals(Track.FIFO)) { 915 return TAB + TAB + Bundle.getMessage("TrackPickUpOrderFIFO") + NEW_LINE; 916 } 917 return TAB + TAB + Bundle.getMessage("TrackPickUpOrderLIFO") + NEW_LINE; 918 } 919 920 private String getSetOutTrains(Track track) { 921 if (track.getDropOption().equals(Track.ANY)) { 922 return TAB + TAB + Bundle.getMessage("SetOutAllTrains") + NEW_LINE; 923 } 924 StringBuffer buf; 925 int charCount = 0; 926 String[] ids = track.getDropIds(); 927 if (track.getDropOption().equals(Track.TRAINS) || track.getDropOption().equals(Track.EXCLUDE_TRAINS)) { 928 String trainType = Bundle.getMessage("TrainsSetOutTrack"); 929 if (track.getDropOption().equals(Track.EXCLUDE_TRAINS)) { 930 trainType = Bundle.getMessage("ExcludeTrainsSetOutTrack"); 931 } 932 buf = new StringBuffer(TAB + TAB + trainType + NEW_LINE + TAB + TAB); 933 for (String id : ids) { 934 Train train = InstanceManager.getDefault(TrainManager.class).getTrainById(id); 935 if (train == null) { 936 log.info("Could not find a train for id: {} track ({})", id, track.getName()); 937 continue; 938 } 939 charCount += train.getName().length() + 2; 940 if (charCount > charactersPerLine - 2 * TAB_LENGTH) { 941 buf.append(NEW_LINE + TAB + TAB); 942 charCount = train.getName().length() + 2; 943 } 944 buf.append(train.getName() + ", "); 945 } 946 } else { 947 String routeType = Bundle.getMessage("RoutesSetOutTrack"); 948 if (track.getDropOption().equals(Track.EXCLUDE_ROUTES)) { 949 routeType = Bundle.getMessage("ExcludeRoutesSetOutTrack"); 950 } 951 buf = new StringBuffer(TAB + TAB + routeType + NEW_LINE + TAB + TAB); 952 for (String id : ids) { 953 Route route = InstanceManager.getDefault(RouteManager.class).getRouteById(id); 954 if (route == null) { 955 log.info("Could not find a route for id: {} location ({}) track ({})", id, 956 track.getLocation().getName(), track.getName()); // NOI18N 957 continue; 958 } 959 charCount += route.getName().length() + 2; 960 if (charCount > charactersPerLine - 2 * TAB_LENGTH) { 961 buf.append(NEW_LINE + TAB + TAB); 962 charCount = route.getName().length() + 2; 963 } 964 buf.append(route.getName() + ", "); 965 } 966 } 967 if (buf.length() > 2) { 968 buf.setLength(buf.length() - 2); // remove trailing separators 969 } 970 buf.append(NEW_LINE); 971 return buf.toString(); 972 } 973 974 private String getPickUpTrains(Track track) { 975 if (track.getPickupOption().equals(Track.ANY)) { 976 return TAB + TAB + Bundle.getMessage("PickUpAllTrains") + NEW_LINE; 977 } 978 StringBuffer buf; 979 int charCount = 0; 980 String[] ids = track.getPickupIds(); 981 if (track.getPickupOption().equals(Track.TRAINS) || track.getPickupOption().equals(Track.EXCLUDE_TRAINS)) { 982 String trainType = Bundle.getMessage("TrainsPickUpTrack"); 983 if (track.getPickupOption().equals(Track.EXCLUDE_TRAINS)) { 984 trainType = Bundle.getMessage("ExcludeTrainsPickUpTrack"); 985 } 986 buf = new StringBuffer(TAB + TAB + trainType + NEW_LINE + TAB + TAB); 987 for (String id : ids) { 988 Train train = InstanceManager.getDefault(TrainManager.class).getTrainById(id); 989 if (train == null) { 990 log.info("Could not find a train for id: {} track ({})", id, track.getName()); 991 continue; 992 } 993 charCount += train.getName().length() + 2; 994 if (charCount > charactersPerLine - 2 * TAB_LENGTH) { 995 buf.append(NEW_LINE + TAB + TAB); 996 charCount = train.getName().length() + 2; 997 } 998 buf.append(train.getName() + ", "); 999 } 1000 } else { 1001 String routeType = Bundle.getMessage("RoutesPickUpTrack"); 1002 if (track.getPickupOption().equals(Track.EXCLUDE_ROUTES)) { 1003 routeType = Bundle.getMessage("ExcludeRoutesPickUpTrack"); 1004 } 1005 buf = new StringBuffer(TAB + TAB + routeType + NEW_LINE + TAB + TAB); 1006 for (String id : ids) { 1007 Route route = InstanceManager.getDefault(RouteManager.class).getRouteById(id); 1008 if (route == null) { 1009 log.info("Could not find a route for id: {} location ({}) track ({})", id, 1010 track.getLocation().getName(), track.getName()); // NOI18N 1011 continue; 1012 } 1013 charCount += route.getName().length() + 2; 1014 if (charCount > charactersPerLine - 2 * TAB_LENGTH) { 1015 buf.append(NEW_LINE + TAB + TAB); 1016 charCount = route.getName().length() + 2; 1017 } 1018 buf.append(route.getName() + ", "); 1019 } 1020 } 1021 if (buf.length() > 2) { 1022 buf.setLength(buf.length() - 2); // remove trailing separators 1023 } 1024 buf.append(NEW_LINE); 1025 return buf.toString(); 1026 } 1027 1028 private String getDestinations(Track track) { 1029 StringBuffer buf = new StringBuffer(); 1030 if (track.isOnlyCarsWithFinalDestinationEnabled()) { 1031 buf.append(TAB + TAB + Bundle.getMessage("OnlyCarsWithFD")); 1032 buf.append(NEW_LINE); 1033 } 1034 if (track.getDestinationOption().equals(Track.ALL_DESTINATIONS)) { 1035 return buf.toString(); 1036 } 1037 String op = Bundle.getMessage( 1038 "AcceptOnly") + " " + track.getDestinationListSize() + " " + Bundle.getMessage("Destinations") + ":"; 1039 if (track.getDestinationOption().equals(Track.EXCLUDE_DESTINATIONS)) { 1040 op = Bundle.getMessage("Exclude") + 1041 " " + 1042 (lmanager.getNumberOfLocations() - track.getDestinationListSize()) + 1043 " " + 1044 Bundle.getMessage("Destinations") + 1045 ":"; 1046 } 1047 buf.append(TAB + TAB + op + NEW_LINE + TAB + TAB); 1048 String[] destIds = track.getDestinationIds(); 1049 int charCount = 0; 1050 for (String id : destIds) { 1051 Location location = lmanager.getLocationById(id); 1052 if (location == null) { 1053 continue; 1054 } 1055 charCount += location.getName().length() + 2; 1056 if (charCount > charactersPerLine - 2 * TAB_LENGTH) { 1057 buf.append(NEW_LINE + TAB + TAB); 1058 charCount = location.getName().length() + 2; 1059 } 1060 buf.append(location.getName() + ", "); 1061 } 1062 if (buf.length() > 2) { 1063 buf.setLength(buf.length() - 2); // remove trailing separators 1064 } 1065 buf.append(NEW_LINE); 1066 return buf.toString(); 1067 } 1068 1069 private String getTrackInfo(Track track) { 1070 if (track.getPool() != null) { 1071 StringBuffer buf = 1072 new StringBuffer(TAB + TAB + Bundle.getMessage("Pool") + ": " + track.getPoolName() + NEW_LINE); 1073 return buf.toString(); 1074 } 1075 return ""; 1076 } 1077 1078 private String getSchedule(Track track) { 1079 // only spurs have schedules 1080 if (!track.isSpur() || track.getSchedule() == null) { 1081 return ""; 1082 } 1083 StringBuffer buf = new StringBuffer(TAB + 1084 TAB + 1085 Bundle.getMessage("TrackScheduleName", track.getScheduleName()) + 1086 NEW_LINE); 1087 if (track.getAlternateTrack() != null) { 1088 buf.append(TAB + 1089 TAB + 1090 Bundle.getMessage("AlternateTrackName", 1091 track.getAlternateTrack().getName()) + 1092 NEW_LINE); 1093 } 1094 if (track.getReservationFactor() != 100) { 1095 buf.append(TAB + 1096 TAB + 1097 Bundle.getMessage("PercentageStaging", 1098 track.getReservationFactor()) + 1099 NEW_LINE); 1100 } 1101 return buf.toString(); 1102 } 1103 1104 private void isAlternate(Track track) throws IOException { 1105 if (track.isAlternate()) { 1106 writer.write(TAB + TAB + Bundle.getMessage("AlternateTrack") + NEW_LINE); 1107 } 1108 } 1109 1110 private String getSpurInfo(Track track) { 1111 if (!track.isSpur()) { 1112 return ""; 1113 } 1114 1115 StringBuffer buf = new StringBuffer(); 1116 1117 if (track.isHoldCarsWithCustomLoadsEnabled()) { 1118 buf.append(TAB + TAB + Bundle.getMessage("HoldCarsWithCustomLoads") + NEW_LINE); 1119 } 1120 if (track.isDisableLoadChangeEnabled()) { 1121 buf.append(TAB + TAB + Bundle.getMessage("DisableLoadChange") + NEW_LINE); 1122 } 1123 return buf.toString(); 1124 } 1125 1126 private String getStagingInfo(Track track) { 1127 if (!track.isStaging()) { 1128 return ""; 1129 } 1130 1131 StringBuffer buf = new StringBuffer(); 1132 1133 if (track.isLoadSwapEnabled() || track.isLoadEmptyEnabled()) { 1134 buf.append(TAB + SPACES_3 + Bundle.getMessage("OptionalLoads") + NEW_LINE); 1135 if (track.isLoadSwapEnabled()) { 1136 buf.append(TAB + TAB + Bundle.getMessage("SwapCarLoads") + NEW_LINE); 1137 } 1138 if (track.isLoadEmptyEnabled()) { 1139 buf.append(TAB + TAB + Bundle.getMessage("EmptyDefaultCarLoads") + NEW_LINE); 1140 } 1141 } 1142 1143 if (track.isRemoveCustomLoadsEnabled() || 1144 track.isAddCustomLoadsEnabled() || 1145 track.isAddCustomLoadsAnySpurEnabled() || 1146 track.isAddCustomLoadsAnyStagingTrackEnabled()) { 1147 buf.append(TAB + SPACES_3 + Bundle.getMessage("OptionalCustomLoads") + NEW_LINE); 1148 if (track.isRemoveCustomLoadsEnabled()) { 1149 buf.append(TAB + TAB + Bundle.getMessage("EmptyCarLoads") + NEW_LINE); 1150 } 1151 if (track.isAddCustomLoadsEnabled()) { 1152 buf.append(TAB + TAB + Bundle.getMessage("LoadCarLoads") + NEW_LINE); 1153 } 1154 if (track.isAddCustomLoadsAnySpurEnabled()) { 1155 buf.append(TAB + TAB + Bundle.getMessage("LoadAnyCarLoads") + NEW_LINE); 1156 } 1157 if (track.isAddCustomLoadsAnyStagingTrackEnabled()) { 1158 buf.append(TAB + TAB + Bundle.getMessage("LoadsStaging") + NEW_LINE); 1159 } 1160 } 1161 1162 if (track.isBlockCarsEnabled()) { 1163 buf.append(TAB + SPACES_3 + Bundle.getMessage("OptionalBlocking") + NEW_LINE); 1164 buf.append(TAB + TAB + Bundle.getMessage("BlockCars") + NEW_LINE); 1165 } 1166 return buf.toString(); 1167 } 1168 1169 private String padOutString(String s, int length) { 1170 return TrainCommon.padAndTruncate(s, length); 1171 } 1172 1173 private final static Logger log = LoggerFactory.getLogger(PrintLocationsFrame.class); 1174}