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