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