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); 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> yards = location.getTracksByNameList(Track.YARD); 486 if (yards.size() > 0) { 487 s = SPACES_3 + Bundle.getMessage("YardName") + NEW_LINE; 488 writer.write(s); 489 printTrackInfo(location, yards); 490 } 491 492 List<Track> spurs = location.getTracksByNameList(Track.SPUR); 493 if (spurs.size() > 0) { 494 s = SPACES_3 + Bundle.getMessage("SpurName") + NEW_LINE; 495 writer.write(s); 496 printTrackInfo(location, spurs); 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 writer.write(getTrackCarTypes(track)); 703 writer.write(getTrackEngineTypes(track)); 704 writer.write(getTrackRoads(track)); 705 writer.write(getTrackLoads(track)); 706 writer.write(getTrackShipLoads(track)); 707 writer.write(getCarOrder(track)); 708 writer.write(getSetOutTrains(track)); 709 writer.write(getPickUpTrains(track)); 710 writer.write(getDestinations(track)); 711 writer.write(getSpurInfo(track)); 712 writer.write(getSchedule(track)); 713 writer.write(getStagingInfo(track)); 714 writer.write(NEW_LINE); 715 } catch (IOException we) { 716 log.error("Error printing PrintLocationAction", we); 717 } 718 } 719 } 720 721 private String getLocationTypes(Location location) { 722 StringBuffer buf = new StringBuffer(TAB + TAB + Bundle.getMessage("TypesServiced") + NEW_LINE + TAB + TAB); 723 int charCount = 0; 724 int typeCount = 0; 725 726 for (String type : cts.getNames()) { 727 if (location.acceptsTypeName(type)) { 728 typeCount++; 729 charCount += type.length() + 2; 730 if (charCount > charactersPerLine - 2 * TAB_LENGTH) { 731 buf.append(NEW_LINE + TAB + TAB); 732 charCount = type.length() + 2; 733 } 734 buf.append(type + ", "); 735 } 736 } 737 738 for (String type : InstanceManager.getDefault(EngineTypes.class).getNames()) { 739 if (location.acceptsTypeName(type)) { 740 typeCount++; 741 charCount += type.length() + 2; 742 if (charCount > charactersPerLine - 2 * TAB_LENGTH) { 743 buf.append(NEW_LINE + TAB + TAB); 744 charCount = type.length() + 2; 745 } 746 buf.append(type + ", "); 747 } 748 } 749 if (buf.length() > 2) { 750 buf.setLength(buf.length() - 2); // remove trailing separators 751 } 752 // does this location accept all types? 753 if (typeCount == cts.getNames().length + InstanceManager.getDefault(EngineTypes.class).getNames().length) { 754 buf = new StringBuffer(TAB + TAB + Bundle.getMessage("LocationAcceptsAllTypes")); 755 } 756 buf.append(NEW_LINE); 757 return buf.toString(); 758 } 759 760 private String getTrackCarTypes(Track track) { 761 StringBuffer buf = 762 new StringBuffer(TAB + TAB + Bundle.getMessage("CarTypesServicedTrack") + NEW_LINE + TAB + TAB); 763 int charCount = 0; 764 int typeCount = 0; 765 766 for (String type : cts.getNames()) { 767 if (track.isTypeNameAccepted(type)) { 768 typeCount++; 769 charCount += type.length() + 2; 770 if (charCount > charactersPerLine - 2 * TAB_LENGTH) { 771 buf.append(NEW_LINE + TAB + TAB); 772 charCount = type.length() + 2; 773 } 774 buf.append(type + ", "); 775 } 776 } 777 if (buf.length() > 2) { 778 buf.setLength(buf.length() - 2); // remove trailing separators 779 } 780 // does this track accept all types? 781 if (typeCount == cts.getNames().length) { 782 buf = new StringBuffer(TAB + TAB + Bundle.getMessage("TrackAcceptsAllCarTypes")); 783 } 784 buf.append(NEW_LINE); 785 return buf.toString(); 786 } 787 788 private String getTrackEngineTypes(Track track) { 789 StringBuffer buf = 790 new StringBuffer(TAB + TAB + Bundle.getMessage("EngineTypesServicedTrack") + NEW_LINE + TAB + TAB); 791 int charCount = 0; 792 int typeCount = 0; 793 794 for (String type : InstanceManager.getDefault(EngineTypes.class).getNames()) { 795 if (track.isTypeNameAccepted(type)) { 796 typeCount++; 797 charCount += type.length() + 2; 798 if (charCount > charactersPerLine - 2 * TAB_LENGTH) { 799 buf.append(NEW_LINE + TAB + TAB); 800 charCount = type.length() + 2; 801 } 802 buf.append(type + ", "); 803 } 804 } 805 if (buf.length() > 2) { 806 buf.setLength(buf.length() - 2); // remove trailing separators 807 } 808 // does this track accept all types? 809 if (typeCount == InstanceManager.getDefault(EngineTypes.class).getNames().length) { 810 buf = new StringBuffer(TAB + TAB + Bundle.getMessage("TrackAcceptsAllEngTypes")); 811 } 812 buf.append(NEW_LINE); 813 return buf.toString(); 814 } 815 816 private String getTrackRoads(Track track) { 817 if (track.getRoadOption().equals(Track.ALL_ROADS)) { 818 return TAB + TAB + Bundle.getMessage("AcceptsAllRoads") + NEW_LINE; 819 } 820 821 String op = Bundle.getMessage("RoadsServicedTrack"); 822 if (track.getRoadOption().equals(Track.EXCLUDE_ROADS)) { 823 op = Bundle.getMessage("ExcludeRoadsTrack"); 824 } 825 826 StringBuffer buf = new StringBuffer(TAB + TAB + op + NEW_LINE + TAB + TAB); 827 int charCount = 0; 828 829 for (String road : track.getRoadNames()) { 830 charCount += road.length() + 2; 831 if (charCount > charactersPerLine - 2 * TAB_LENGTH) { 832 buf.append(NEW_LINE + TAB + TAB); 833 charCount = road.length() + 2; 834 } 835 buf.append(road + ", "); 836 } 837 if (buf.length() > 2) { 838 buf.setLength(buf.length() - 2); // remove trailing separators 839 } 840 buf.append(NEW_LINE); 841 return buf.toString(); 842 } 843 844 private String getTrackLoads(Track track) { 845 if (track.getLoadOption().equals(Track.ALL_LOADS)) { 846 return TAB + TAB + Bundle.getMessage("AcceptsAllLoads") + NEW_LINE; 847 } 848 849 String op = Bundle.getMessage("LoadsServicedTrack"); 850 if (track.getLoadOption().equals(Track.EXCLUDE_LOADS)) { 851 op = Bundle.getMessage("ExcludeLoadsTrack"); 852 } 853 854 StringBuffer buf = new StringBuffer(TAB + TAB + op + NEW_LINE + TAB + TAB); 855 int charCount = 0; 856 857 for (String load : track.getLoadNames()) { 858 charCount += load.length() + 2; 859 if (charCount > charactersPerLine - 2 * TAB_LENGTH) { 860 buf.append(NEW_LINE + TAB + TAB); 861 charCount = load.length() + 2; 862 } 863 buf.append(load + ", "); 864 } 865 if (buf.length() > 2) { 866 buf.setLength(buf.length() - 2); // remove trailing separators 867 } 868 buf.append(NEW_LINE); 869 return buf.toString(); 870 } 871 872 private String getTrackShipLoads(Track track) { 873 // only staging has the ship load control 874 if (!track.isStaging()) { 875 return ""; 876 } 877 if (track.getShipLoadOption().equals(Track.ALL_LOADS)) { 878 return TAB + TAB + Bundle.getMessage("ShipsAllLoads") + NEW_LINE; 879 } 880 String op = Bundle.getMessage("LoadsShippedTrack"); 881 if (track.getShipLoadOption().equals(Track.EXCLUDE_LOADS)) { 882 op = Bundle.getMessage("ExcludeLoadsShippedTrack"); 883 } 884 885 StringBuffer buf = new StringBuffer(TAB + TAB + op + NEW_LINE + TAB + TAB); 886 int charCount = 0; 887 888 for (String load : track.getShipLoadNames()) { 889 charCount += load.length() + 2; 890 if (charCount > charactersPerLine - 2 * TAB_LENGTH) { 891 buf.append(NEW_LINE + TAB + TAB); 892 charCount = load.length() + 2; 893 } 894 buf.append(load + ", "); 895 } 896 if (buf.length() > 2) { 897 buf.setLength(buf.length() - 2); // remove trailing separators 898 } 899 buf.append(NEW_LINE); 900 return buf.toString(); 901 } 902 903 private String getCarOrder(Track track) { 904 // only yards and interchanges have the car order option 905 if (track.isSpur() || track.isStaging() || track.getServiceOrder().equals(Track.NORMAL)) { 906 return ""; 907 } 908 if (track.getServiceOrder().equals(Track.FIFO)) { 909 return TAB + TAB + Bundle.getMessage("TrackPickUpOrderFIFO") + NEW_LINE; 910 } 911 return TAB + TAB + Bundle.getMessage("TrackPickUpOrderLIFO") + NEW_LINE; 912 } 913 914 private String getSetOutTrains(Track track) { 915 if (track.getDropOption().equals(Track.ANY)) { 916 return TAB + TAB + Bundle.getMessage("SetOutAllTrains") + NEW_LINE; 917 } 918 StringBuffer buf; 919 int charCount = 0; 920 String[] ids = track.getDropIds(); 921 if (track.getDropOption().equals(Track.TRAINS) || track.getDropOption().equals(Track.EXCLUDE_TRAINS)) { 922 String trainType = Bundle.getMessage("TrainsSetOutTrack"); 923 if (track.getDropOption().equals(Track.EXCLUDE_TRAINS)) { 924 trainType = Bundle.getMessage("ExcludeTrainsSetOutTrack"); 925 } 926 buf = new StringBuffer(TAB + TAB + trainType + NEW_LINE + TAB + TAB); 927 for (String id : ids) { 928 Train train = InstanceManager.getDefault(TrainManager.class).getTrainById(id); 929 if (train == null) { 930 log.info("Could not find a train for id: {} track ({})", id, track.getName()); 931 continue; 932 } 933 charCount += train.getName().length() + 2; 934 if (charCount > charactersPerLine - 2 * TAB_LENGTH) { 935 buf.append(NEW_LINE + TAB + TAB); 936 charCount = train.getName().length() + 2; 937 } 938 buf.append(train.getName() + ", "); 939 } 940 } else { 941 String routeType = Bundle.getMessage("RoutesSetOutTrack"); 942 if (track.getDropOption().equals(Track.EXCLUDE_ROUTES)) { 943 routeType = Bundle.getMessage("ExcludeRoutesSetOutTrack"); 944 } 945 buf = new StringBuffer(TAB + TAB + routeType + NEW_LINE + TAB + TAB); 946 for (String id : ids) { 947 Route route = InstanceManager.getDefault(RouteManager.class).getRouteById(id); 948 if (route == null) { 949 log.info("Could not find a route for id: {} location ({}) track ({})", id, 950 track.getLocation().getName(), track.getName()); // NOI18N 951 continue; 952 } 953 charCount += route.getName().length() + 2; 954 if (charCount > charactersPerLine - 2 * TAB_LENGTH) { 955 buf.append(NEW_LINE + TAB + TAB); 956 charCount = route.getName().length() + 2; 957 } 958 buf.append(route.getName() + ", "); 959 } 960 } 961 if (buf.length() > 2) { 962 buf.setLength(buf.length() - 2); // remove trailing separators 963 } 964 buf.append(NEW_LINE); 965 return buf.toString(); 966 } 967 968 private String getPickUpTrains(Track track) { 969 if (track.getPickupOption().equals(Track.ANY)) { 970 return TAB + TAB + Bundle.getMessage("PickUpAllTrains") + NEW_LINE; 971 } 972 StringBuffer buf; 973 int charCount = 0; 974 String[] ids = track.getPickupIds(); 975 if (track.getPickupOption().equals(Track.TRAINS) || track.getPickupOption().equals(Track.EXCLUDE_TRAINS)) { 976 String trainType = Bundle.getMessage("TrainsPickUpTrack"); 977 if (track.getPickupOption().equals(Track.EXCLUDE_TRAINS)) { 978 trainType = Bundle.getMessage("ExcludeTrainsPickUpTrack"); 979 } 980 buf = new StringBuffer(TAB + TAB + trainType + NEW_LINE + TAB + TAB); 981 for (String id : ids) { 982 Train train = InstanceManager.getDefault(TrainManager.class).getTrainById(id); 983 if (train == null) { 984 log.info("Could not find a train for id: {} track ({})", id, track.getName()); 985 continue; 986 } 987 charCount += train.getName().length() + 2; 988 if (charCount > charactersPerLine - 2 * TAB_LENGTH) { 989 buf.append(NEW_LINE + TAB + TAB); 990 charCount = train.getName().length() + 2; 991 } 992 buf.append(train.getName() + ", "); 993 } 994 } else { 995 String routeType = Bundle.getMessage("RoutesPickUpTrack"); 996 if (track.getPickupOption().equals(Track.EXCLUDE_ROUTES)) { 997 routeType = Bundle.getMessage("ExcludeRoutesPickUpTrack"); 998 } 999 buf = new StringBuffer(TAB + TAB + routeType + NEW_LINE + TAB + TAB); 1000 for (String id : ids) { 1001 Route route = InstanceManager.getDefault(RouteManager.class).getRouteById(id); 1002 if (route == null) { 1003 log.info("Could not find a route for id: {} location ({}) track ({})", id, 1004 track.getLocation().getName(), track.getName()); // NOI18N 1005 continue; 1006 } 1007 charCount += route.getName().length() + 2; 1008 if (charCount > charactersPerLine - 2 * TAB_LENGTH) { 1009 buf.append(NEW_LINE + TAB + TAB); 1010 charCount = route.getName().length() + 2; 1011 } 1012 buf.append(route.getName() + ", "); 1013 } 1014 } 1015 if (buf.length() > 2) { 1016 buf.setLength(buf.length() - 2); // remove trailing separators 1017 } 1018 buf.append(NEW_LINE); 1019 return buf.toString(); 1020 } 1021 1022 private String getDestinations(Track track) { 1023 StringBuffer buf = new StringBuffer(); 1024 if (track.isOnlyCarsWithFinalDestinationEnabled()) { 1025 buf.append(TAB + TAB + Bundle.getMessage("OnlyCarsWithFD")); 1026 buf.append(NEW_LINE); 1027 } 1028 if (track.getDestinationOption().equals(Track.ALL_DESTINATIONS)) { 1029 return buf.toString(); 1030 } 1031 String op = Bundle.getMessage( 1032 "AcceptOnly") + " " + track.getDestinationListSize() + " " + Bundle.getMessage("Destinations") + ":"; 1033 if (track.getDestinationOption().equals(Track.EXCLUDE_DESTINATIONS)) { 1034 op = Bundle.getMessage("Exclude") + 1035 " " + 1036 (lmanager.getNumberOfLocations() - track.getDestinationListSize()) + 1037 " " + 1038 Bundle.getMessage("Destinations") + 1039 ":"; 1040 } 1041 buf.append(TAB + TAB + op + NEW_LINE + TAB + TAB); 1042 String[] destIds = track.getDestinationIds(); 1043 int charCount = 0; 1044 for (String id : destIds) { 1045 Location location = lmanager.getLocationById(id); 1046 if (location == null) { 1047 continue; 1048 } 1049 charCount += location.getName().length() + 2; 1050 if (charCount > charactersPerLine - 2 * TAB_LENGTH) { 1051 buf.append(NEW_LINE + TAB + TAB); 1052 charCount = location.getName().length() + 2; 1053 } 1054 buf.append(location.getName() + ", "); 1055 } 1056 if (buf.length() > 2) { 1057 buf.setLength(buf.length() - 2); // remove trailing separators 1058 } 1059 buf.append(NEW_LINE); 1060 return buf.toString(); 1061 } 1062 1063 private String getSchedule(Track track) { 1064 // only spurs have schedules 1065 if (!track.isSpur() || track.getSchedule() == null) { 1066 return ""; 1067 } 1068 StringBuffer buf = new StringBuffer(TAB + 1069 TAB + 1070 Bundle.getMessage("TrackScheduleName", track.getScheduleName()) + 1071 NEW_LINE); 1072 if (track.getAlternateTrack() != null) { 1073 buf.append(TAB + 1074 TAB + 1075 Bundle.getMessage("AlternateTrackName", 1076 track.getAlternateTrack().getName()) + 1077 NEW_LINE); 1078 } 1079 if (track.getReservationFactor() != 100) { 1080 buf.append(TAB + 1081 TAB + 1082 Bundle.getMessage("PercentageStaging", 1083 track.getReservationFactor()) + 1084 NEW_LINE); 1085 } 1086 return buf.toString(); 1087 } 1088 1089 private String getSpurInfo(Track track) { 1090 if (!track.isSpur()) { 1091 return ""; 1092 } 1093 1094 StringBuffer buf = new StringBuffer(); 1095 1096 if (track.isHoldCarsWithCustomLoadsEnabled()) { 1097 buf.append(TAB + TAB + Bundle.getMessage("HoldCarsWithCustomLoads") + NEW_LINE); 1098 } 1099 if (track.isDisableLoadChangeEnabled()) { 1100 buf.append(TAB + TAB + Bundle.getMessage("DisableLoadChange") + NEW_LINE); 1101 } 1102 return buf.toString(); 1103 } 1104 1105 private String getStagingInfo(Track track) { 1106 if (!track.isStaging()) { 1107 return ""; 1108 } 1109 1110 StringBuffer buf = new StringBuffer(); 1111 1112 if (track.isLoadSwapEnabled() || track.isLoadEmptyEnabled()) { 1113 buf.append(TAB + SPACES_3 + Bundle.getMessage("OptionalLoads") + NEW_LINE); 1114 if (track.isLoadSwapEnabled()) { 1115 buf.append(TAB + TAB + Bundle.getMessage("SwapCarLoads") + NEW_LINE); 1116 } 1117 if (track.isLoadEmptyEnabled()) { 1118 buf.append(TAB + TAB + Bundle.getMessage("EmptyDefaultCarLoads") + NEW_LINE); 1119 } 1120 } 1121 1122 if (track.isRemoveCustomLoadsEnabled() || 1123 track.isAddCustomLoadsEnabled() || 1124 track.isAddCustomLoadsAnySpurEnabled() || 1125 track.isAddCustomLoadsAnyStagingTrackEnabled()) { 1126 buf.append(TAB + SPACES_3 + Bundle.getMessage("OptionalCustomLoads") + NEW_LINE); 1127 if (track.isRemoveCustomLoadsEnabled()) { 1128 buf.append(TAB + TAB + Bundle.getMessage("EmptyCarLoads") + NEW_LINE); 1129 } 1130 if (track.isAddCustomLoadsEnabled()) { 1131 buf.append(TAB + TAB + Bundle.getMessage("LoadCarLoads") + NEW_LINE); 1132 } 1133 if (track.isAddCustomLoadsAnySpurEnabled()) { 1134 buf.append(TAB + TAB + Bundle.getMessage("LoadAnyCarLoads") + NEW_LINE); 1135 } 1136 if (track.isAddCustomLoadsAnyStagingTrackEnabled()) { 1137 buf.append(TAB + TAB + Bundle.getMessage("LoadsStaging") + NEW_LINE); 1138 } 1139 } 1140 1141 if (track.isBlockCarsEnabled()) { 1142 buf.append(TAB + SPACES_3 + Bundle.getMessage("OptionalBlocking") + NEW_LINE); 1143 buf.append(TAB + TAB + Bundle.getMessage("BlockCars") + NEW_LINE); 1144 } 1145 return buf.toString(); 1146 } 1147 1148 private String padOutString(String s, int length) { 1149 return TrainCommon.padAndTruncate(s, length); 1150 } 1151 1152 private final static Logger log = LoggerFactory.getLogger(PrintLocationsFrame.class); 1153}