Files
2026-06-17 14:00:51 +02:00

1297 lines
59 KiB
Python

# Script to automatically Generate Icons on Panel for automation purposes
#
# Author: Dave Sand, Bill Fitch, copyright 2022
# Part of the JMRI distribution
from javax.swing import JOptionPane
from java.awt.geom import Point2D
from java.awt import Color
# from jython.DispatcherSystem.Startup import OptionDialog
# IS:DSCT:nnn Control sensors
# IS:DSMT:nnn Move TO sensors
# IS:DSMP:nnn Move Progress sensors
# IX:DSLX:1 Logix
# Remove Icons
# Block content labels
# Labels
# Sensors
# Remove Logix
# Remove Transits
# Remove Sections
# Remove SML
# Remove Sensors
#
# Add sensors
# Generate SML and Sections
# Add Logix
# Add Icons
# Sensors
# Labels
# Block content labels
class processPanels(jmri.jmrit.automat.AbstractAutomaton):
if "list" in globals() and type(globals()["list"]).__name__ != "type":
# print(" Detected shadowed 'list' type: ", type(globals()["list"])) # list is being used in JMRI. This enables us to use list in Jython
del globals()["list"]
if "set" in globals() and type(globals()["set"]).__name__ != "type":
# print(" Detected shadowed 'set' type: ", type(globals()["set"])) # set is being used in JMRI. This enables us to use set in Jython
del globals()["set"]
logLevel = 0
version_no = 0.2 #used to delete DispatcherPanel for new versions if the number of controlsensors/icons has changed
list_of_stopping_points = []
blockPoints1 = {}
blockPoints = {} # Block center points used by direct access process
editorManager = jmri.InstanceManager.getDefault(jmri.jmrit.display.EditorManager)
# row number, user name, label name, x offset, y offset
i = 1
controlSensors = []
controlSensors.append([i, 'startDispatcherSensor', 'Run Dispatcher System', 0, 0]); i += 1
controlSensors.append([i, 'stopMasterSensor', 'Stop Dispatcher System', 0, 0]); i += 1
controlSensors.append([i, 'modifyMasterSensor', 'Modify Dispatcher System', 0, 0]); i += 1
controlSensors.append([i, 'Express', 'Express Train (no stopping)', 10, 5]); i += 1
controlSensors.append([i, 'newTrainSensor', 'Setup Train in Section', 10, 5]); i += 1
controlSensors.append([i, 'soundSensor', 'Enable Announcements', 10, 5]); i += 1
controlSensors.append([i, 'simulateSensor', 'Simulate Dispatched Trains', 10, 5]); i += 1
controlSensors.append([i, 'checkRouteSensor', 'Dispatch Path must be clear', 10, 5]); i += 1
controlSensors.append([i, 'stopAtStopSensor', 'Stop at Stop Sensors (Default)', 10, 5]); i += 1
controlSensors.append([i, 'setDispatchSensor', 'Run Dispatch', 0, 5]); i += 1
controlSensors.append([i, 'setRouteSensor', 'Setup Route', 0, 5]); i += 1
controlSensors.append([i, 'setStoppingDistanceSensor', 'Set Stopping Length', 0, 5]); i += 1
controlSensors.append([i, 'setStopSensor', 'Set Stop Sensor', 0, 5]); i += 1
controlSensors.append([i, 'setStationWaitTimeSensor', 'Set Station Wait Time', 0, 5]); i += 1
controlSensors.append([i, 'setStationDirectionSensor', 'Set Station Direction', 0, 5]); i += 1
controlSensors.append([i, 'setTransitBlockRestrictionSensor', 'Restrict Transit Operation', 0, 5]); i += 1
controlSensors.append([i, 'runRouteSensor', 'Run Route', 10, 5]); i += 1
controlSensors.append([i, 'editRoutesSensor', 'View/Edit Routes', 10, 5]); i += 1
controlSensors.append([i, 'viewScheduledSensor', 'View/Edit Scheduled Trains', 10, 5]); i += 1
controlSensors.append([i, 'showClockSensor', 'Show Analog Clock', 10, 5]); i += 1
controlSensors.append([i, 'startSchedulerSensor', 'Start Scheduler', 10, 5]); i += 1
controlSensors.append([i, 'timetableSensor', 'Show Timetable', 10, 5]); i += 1
controlSensors.append([i, 'departureTimeSensor', 'Setup Departure Times', 10, 5]); i += 1
controlSensors.append([i, 'helpSensor', 'Help', 0, 5]); i += 1
def __init__(self):
self.result = "Success" #value is returned in __str__ and set to "Failure" in self.tryme()
self.define_DisplayProgress_global()
if self.perform_initial_checks():
self.show_progress(0)
self.tryme(self.saveForwardStoppingSensors, "Cannot save Forward Stopping Sensors: Contact Developer")
self.tryme(self.removeIconsAndLabels, "Cannot remove Icons And Labels: Contact Developer")
self.tryme(self.removeLogix, "Cannot remove startup Logix: Contact Developer")
self.tryme(self.removeTransits, "Cannot remove Transits: Contact Developer")
self.tryme(self.removeSML, "Cannot remove SML: Contact Developer") # do before removeSections in case direction sensors have been added to the SML
self.tryme(self.removeSections, "Cannot remove Sections: Contact Developer")
self.show_progress(20)
self.tryme(self.removeSensors, "Cannot generate startup Logix: Contact Developer")
self.show_progress(40)
# print "A"
self.tryme(self.updatePanels, "Cannot update Panels: Contact Developer")
# print "B"
self.get_list_of_stopping_points()
# print "C"
# self.tryme(self.get_list_of_stopping_points, "Cannot get list of stopping points, Contact Developer")
self.addSensors()
# print "D"
self.generateSML()
# print "E"
self.show_progress(60)
self.generateSections() # if it fails need a better fail message
# print "F"
# self.tryme(self.generateSections, "Cannot generate Sections: Signal Masts not set up correctly. Needs to be fixed before using Dispatcher System.")
self.show_progress(80)
self.tryme(self.addLogix, "Cannot generate startup Logix: Contact Developer")
# print "G"
self.addIcons()
self.tryme(self.retrieveForwardStoppingSensors, "Cannot retrieve Stopping Sensors: Contact Developer")
self.setVersionNo()
self.stop_all_threads()
self.end_show_progress()
else:
self.result = "Failure"
def __str__(self):
return self.result
def setVersionNo(self):
memory = memories.provideMemory('IS:ISMEM:' + "versionNo")
if memory is not None:
memory.setValue(self.version_no)
def version_number_changed(self):
memory = memories.getMemory('IMIS:ISMEM:' + "versionNo")
# print "memory", memory, type(memory)
if memory is None:
# print "version_no changed", "memory:", "version", self.version_no
return True
elif memory.getValue() != self.version_no:
# print "version_no changed", "memory:", memory.getValue(), "version", self.version_no
return True
else:
# print "version_no not changed", "memory:", memory.getValue(), "version", self.version_no
return False
def stop_all_threads(self):
summary = jmri.jmrit.automat.AutomatSummary.instance()
automatsList = java.util.concurrent.CopyOnWriteArrayList()
for automat in summary.getAutomats():
automatsList.add(automat)
for automat in automatsList:
automat.stop()
def tryme(self, func, failure_message):
try:
func()
except:
title = "Error in Routine"
Query().displayMessage(failure_message,title)
self.result = "Failure"
pass
def define_DisplayProgress_global(self):
global dpg
dpg = DisplayProgress()
def show_progress(self, progress):
global dpg
dpg.Update("creating icons: " + str(progress)+ "% complete")
def end_show_progress(self):
global dpg
dpg.killLabel()
# **************************************************
# perform initial checks
# **************************************************
def perform_initial_checks(self):
sensors_OK = False
block_sensors_OK = False
stops_OK = False
lengths_OK = False
speed_profiles_OK = False
#JOptionPane.showMessageDialog(None, "Performing some preliminary checks to ensure the trains run correctly\nAll errors will need to be fixed for Dispatcher to run correctly\nSome errors will cause the panel to be set up incorrectly in this stage", 'Checks', JOptionPane.WARNING_MESSAGE)
# check all blocks have sensors
if self.check_all_blocks_have_sensors() == False:
self.msg = self.msg + "\n***********************\n Do you wish to continue\n***********************"
myAnswer = JOptionPane.showConfirmDialog(None, self.msg)
if myAnswer == JOptionPane.YES_OPTION:
#JOptionPane.showMessageDialog(None, 'OK continuing', "As you wish", JOptionPane.WARNING_MESSAGE)
pass
elif myAnswer == JOptionPane.NO_OPTION:
msg = 'Stopping'
JOptionPane.showMessageDialog(None, 'Stopping', "Fix Error" , JOptionPane.WARNING_MESSAGE)
return False
elif myAnswer == JOptionPane.CANCEL_OPTION:
msg = 'Stopping'
JOptionPane.showMessageDialog(None, 'Stopping', "Have a cup of Tea", JOptionPane.WARNING_MESSAGE)
return False
elif myAnswer == JOptionPane.CLOSED_OPTION:
if self.logLevel > 0: print "You closed the window. How rude!"
else:
sensors_OK = True
if self.check_no_blocks_have_same_sensor() == False:
self.msg1 = self.msg1 + "\n***********************\n Do you wish to continue\n***********************"
myAnswer = JOptionPane.showConfirmDialog(None, self.msg1)
if self.logLevel > 0: print(1)
if myAnswer == JOptionPane.YES_OPTION:
#JOptionPane.showMessageDialog(None, 'OK continuing', "As you wish", JOptionPane.WARNING_MESSAGE)
pass
elif myAnswer == JOptionPane.NO_OPTION:
msg = 'Stopping'
JOptionPane.showMessageDialog(None, 'Stopping', "You need a cup of Tea" , JOptionPane.WARNING_MESSAGE)
return False
elif myAnswer == JOptionPane.CANCEL_OPTION:
msg = 'Stopping'
JOptionPane.showMessageDialog(None, 'Stopping', "Have a cup of Tea", JOptionPane.WARNING_MESSAGE)
return False
elif myAnswer == JOptionPane.CLOSED_OPTION:
if self.logLevel > 0: print "You closed the window. How rude!"
else:
block_sensors_OK = True
if self.check_sufficient_number_of_blocks() == False:
self.msg2 = "There are insufficient stopping points for Dispatcher to work\n" + self.msg2 + "\n***********************\n Do you wish to continue? You are advised to stop as the current stage cannot perfom correctly\n***********************"
if self.logLevel > 0: print(3)
myAnswer = JOptionPane.showConfirmDialog(None, self.msg2)
if myAnswer == JOptionPane.YES_OPTION:
#JOptionPane.showMessageDialog(None, 'OK continuing', "As you wish", JOptionPane.WARNING_MESSAGE)
pass
elif myAnswer == JOptionPane.NO_OPTION:
msg = 'Stopping'
JOptionPane.showMessageDialog(None, "Specify the stopping points by inserting 'stop' in the comment fields of the blocks" , "Stopping" , JOptionPane.WARNING_MESSAGE)
return False
elif myAnswer == JOptionPane.CANCEL_OPTION:
msg = 'Stopping'
JOptionPane.showMessageDialog(None, 'Stopping', "Have a cup of Tea", JOptionPane.WARNING_MESSAGE)
return False
elif myAnswer == JOptionPane.CLOSED_OPTION:
if self.logLevel > 0: print "You closed the window. How rude!"
else:
stops_OK = True
if self.check_all_blocks_have_lengths() == False:
self.msg5 = "Not all blocks have lengths\n" + self.msg5 + "\n***********************\n Do you wish to continue? Trains will not run correctly.\n***********************"
if self.logLevel > 0: print(3)
myAnswer = JOptionPane.showConfirmDialog(None, self.msg5)
if myAnswer == JOptionPane.YES_OPTION:
#JOptionPane.showMessageDialog(None, 'OK continuing', "As you wish", JOptionPane.WARNING_MESSAGE)
pass
elif myAnswer == JOptionPane.NO_OPTION:
msg = 'Stopping'
JOptionPane.showMessageDialog(None, "Specify the stopping points by inserting 'stop' in the comment fields of the blocks" , "Stopping" , JOptionPane.WARNING_MESSAGE)
return False
elif myAnswer == JOptionPane.CANCEL_OPTION:
msg = 'Stopping'
JOptionPane.showMessageDialog(None, 'Stopping', "Have a cup of Tea", JOptionPane.WARNING_MESSAGE)
return False
elif myAnswer == JOptionPane.CLOSED_OPTION:
if self.logLevel > 0: print "You closed the window. How rude!"
else:
lengths_OK = True
if self.check_engines_with_speed_profiles_exist() == False:
self.msg5 = "There are no engines with speed profiles\n" + self.msg5 + "\n***********************\n To continue either set up speed profiles for a train, \nor for a quick examination of Dispatcher System you can install the speed profiles stored in the Dispatcher System Folder\n*********Do you wish to continue?**************"
if self.logLevel > 0: print(3)
myAnswer = JOptionPane.showConfirmDialog(None, self.msg5)
if myAnswer == JOptionPane.YES_OPTION:
JOptionPane.showMessageDialog(None, 'Please install some of the speed profiles provided', "Look in the speed profile folder in the Dispatcher System Folder", JOptionPane.WARNING_MESSAGE)
return False
elif myAnswer == JOptionPane.NO_OPTION:
msg = 'Stopping'
JOptionPane.showMessageDialog(None, "Please run your trains over a suitable track with 3 blocks - see help" , "Install speed profiles" , JOptionPane.WARNING_MESSAGE)
return False
elif myAnswer == JOptionPane.CANCEL_OPTION:
msg = 'Stopping'
JOptionPane.showMessageDialog(None, 'Stopping', "Have a cup of Tea", JOptionPane.WARNING_MESSAGE)
return False
elif myAnswer == JOptionPane.CLOSED_OPTION:
if self.logLevel > 0: print "You closed the window. How rude!"
else:
speed_profiles_OK = True
msg = ""
some_checks_OK = False
if sensors_OK:
msg = msg + "All blocks have lengths\n"
some_checks_OK = True
if block_sensors_OK:
msg = msg + "All blocks have lengths\n"
some_checks_OK = True
if stops_OK:
msg = msg + "All blocks have lengths\n"
some_checks_OK = True
if lengths_OK:
msg = msg + "All blocks have lengths\n"
some_checks_OK = True
if speed_profiles_OK:
msg = msg + "You have engine(s) with speed profile\n"
some_checks_OK = True
if some_checks_OK:
msg = "Performed some preliminary checks to ensure the trains run correctly\n\nAll Checks OK"
title = "Checks"
opt1 = "Continue"
opt2 = "Look in more detail"
reply = Query().customQuestionMessage2str(msg, title, opt1, opt2)
if reply == opt2:
if sensors_OK:
Message = "All blocks have sensors"
JOptionPane.showMessageDialog(None, Message, 'Message', JOptionPane.INFORMATION_MESSAGE)
if block_sensors_OK:
Message = "no two blocks have the same sensor\nPassed check OK"
JOptionPane.showMessageDialog(None, Message, 'Message', JOptionPane.INFORMATION_MESSAGE)
if stops_OK:
Message = "The following blocks have been specified as stopping points\n" + self.msg2 + "\n there are sufficient blocks set up"
JOptionPane.showMessageDialog(None, Message, 'Message', JOptionPane.INFORMATION_MESSAGE)
if lengths_OK:
Message = "All blocks have lengths\n OK to continue \nNote that trains should also be set up with a speed profile to stop correctly"
JOptionPane.showMessageDialog(None, Message, 'Message', JOptionPane.INFORMATION_MESSAGE)
if speed_profiles_OK:
msg = ""
for engine in self.get_all_roster_entries_with_speed_profile():
msg += "\n" + str(engine)
Message = "You have the following trains with speed profiles" + msg
JOptionPane.showMessageDialog(None, Message, 'Message', JOptionPane.INFORMATION_MESSAGE)
return True
def check_all_blocks_have_sensors(self):
LayoutBlockManager=jmri.InstanceManager.getDefault(jmri.jmrit.display.layoutEditor.LayoutBlockManager)
list_of_errors = []
success = True
for block in blocks.getNamedBeanSet():
if block.getSensor() == None:
if LayoutBlockManager.getLayoutBlock(block) != None: #only include blocks included in a layout panel
if block.getUserName() != None: #all layout blocks have usernames, should not need this check
msg = "block {} does not have a sensor".format(block.getUserName())
else:
msg = "block {} does not have a sensor".format(block.getSystemName())
msg = msg + "\nblock {} does not have a username".format(block.getSystemName())
list_of_errors.append(msg)
self.msg = ""
for message in list_of_errors:
self.msg = self.msg +"\n" + message
success = False
return success
def check_no_blocks_have_same_sensor(self):
LayoutBlockManager=jmri.InstanceManager.getDefault(jmri.jmrit.display.layoutEditor.LayoutBlockManager)
dict = {}
success = True
for block in blocks.getNamedBeanSet():
if LayoutBlockManager.getLayoutBlock(block) != None: #only include blocks included in a layout panel
if block.getUserName() != None: #all layout blocks have usernames, should not need this check
block_name = block.getUserName()
else:
block_name = block.getSystemName()
sensor = block.getSensor()
if sensor != None:
if sensor.getUserName() != None:
sensor_name = sensor.getUserName()
else:
sensor_name = sensor.getSystemName()
dict[block_name] = sensor_name
list_of_errors = self.get_duplicate_values_in_dict(dict)
if self.logLevel > 0: print list_of_errors
if list_of_errors == []:
success = True
else:
success = False
self.msg1 = ""
for message in list_of_errors:
self.msg1 = self.msg1 + "\n" + message
return success
def get_duplicate_values_in_dict(self, input_dict):
# finding duplicate values
# from dictionary
# using a naive approach
rev_dict = {}
for key, value in input_dict.items():
rev_dict.setdefault(value, set()).add(key)
result = ["blocks " +', '.join(values) + " have the same sensor " + str( key) for key, values in rev_dict.items()
if len(values) > 1]
return result
def check_sufficient_number_of_blocks(self):
LayoutBlockManager=jmri.InstanceManager.getDefault(jmri.jmrit.display.layoutEditor.LayoutBlockManager)
list_of_stops = []
list_of_blocks = []
for block in blocks.getNamedBeanSet():
if LayoutBlockManager.getLayoutBlock(block) != None: #only include blocks included in a layout panel
if block.getUserName() != None: #all layout blocks have usernames, should not need this check
block_name = block.getUserName()
else:
block_name = block.getSystemName()
comment = str(block.getComment())
if comment !=None:
if "stop" in comment.lower():
list_of_stops.append("block " + block_name + " has a stop")
if self.logLevel > 0: print list_of_stops
else:
list_of_blocks.append("block " + block_name + " has no stop")
if self.logLevel > 0: print list_of_blocks
else:
list_of_blocks.append("block " + block_name + " has no stop")
#countthe number of blocks in dictionary
no_stops = len(list_of_stops)
if self.logLevel > 0: print "no_stops", no_stops
no_blocks = len(list_of_blocks)
if self.logLevel > 0: print "no blocks", no_blocks
if no_stops < 2:
success = False
else:
success = True
self.msg2 = " - "
self.msg2 = self.msg2 + '\n - '.join(list_of_stops)
if self.logLevel > 0: print self.msg2
self.msg3 = ""
self.msg3 = '\n - '.join(list_of_blocks)
if self.logLevel > 0: print self.msg3
if no_stops == 0:
self.msg2 = " - there are no stops"
return success
def check_all_blocks_have_lengths(self):
LayoutBlockManager=jmri.InstanceManager.getDefault(jmri.jmrit.display.layoutEditor.LayoutBlockManager)
list_of_errors = []
success = True
for block in blocks.getNamedBeanSet():
if LayoutBlockManager.getLayoutBlock(block) != None: #only include blocks included in a layout panel
if block.getLengthMm() < 0.01:
if block.getUserName() != None: #all layout blocks have usernames, should not need this check
msg = "block {} does not have a length".format(block.getUserName())
else:
msg = "block {} does not have a length".format(block.getSystemName())
msg = msg + "\nblock {} does not have a username".format(block.getSystemName())
list_of_errors.append(msg)
success = False
self.msg5 = " - "
self.msg5 = self.msg5 + '\n - '.join(list_of_errors)
return success
def check_engines_with_speed_profiles_exist(self):
roster_entries_with_speed_profile = self.get_all_roster_entries_with_speed_profile()
if roster_entries_with_speed_profile == []:
return False
else:
return True
# return True
def get_all_roster_entries_with_speed_profile(self):
roster_entries_with_speed_profile = []
r = jmri.jmrit.roster.Roster.getDefault()
for roster_entry in jmri.jmrit.roster.Roster.getAllEntries(r):
if self.logLevel > 0: print "roster_entry.getSpeedProfile()",roster_entry,roster_entry.getSpeedProfile()
if roster_entry.getSpeedProfile() != None:
roster_entries_with_speed_profile.append(roster_entry.getId())
if self.logLevel > 0: print "roster_entry.getId()",roster_entry.getId()
return roster_entries_with_speed_profile
def updatePanels(self):
for panel in self.editorManager.getAll(jmri.jmrit.display.layoutEditor.LayoutEditor):
if panel.getTitle() != 'Dispatcher System':
panel.invalidate()
panel.validate()
panel.repaint()
pass
# **************************************************
# remove icons and labels from panels
# **************************************************
def removeIconsAndLabels(self):
for panel in self.editorManager.getAll(jmri.jmrit.display.layoutEditor.LayoutEditor):
if panel.getTitle() == 'Dispatcher System':
if self.version_number_changed():
# print "removing panel, version number changed"
self.editorManager.remove(panel)
panel.dispose()
# Skip the Dispatcher System control panel if it exists
continue
self.removeBlockContentIcons(panel)
self.removeLabels(panel)
self.removeSensorIcons(panel)
def removeBlockContentIcons(self, panel):
deleteList = [] # Prevent concurrent modification
icons = panel.getBlockContentsLabelList()
for icon in icons:
blk = icon.getBlock()
if blk is not None:
deleteList.append(icon)
for item in deleteList:
panel.removeFromContents(item)
def removeLabels(self, panel):
labelText = []
for control in self.controlSensors:
labelText.append(control[2])
deleteList = [] # Prevent concurrent modification
for label in panel.getLabelImageList():
if label.isText():
if label.getText() in labelText:
deleteList.append(label)
for item in deleteList:
panel.removeFromContents(item)
def removeSensorIcons(self, panel):
blockSensors = []
for block in blocks.getNamedBeanSet():
sensor = block.getSensor()
if sensor is not None:
blockSensors.append(sensor)
deleteList = [] # Prevent concurrent modification
icons = panel.getSensorList()
for icon in icons:
sensor = icon.getSensor()
if sensor is not None:
name = sensor.getDisplayName()
if 'MoveTo' in name or 'MoveInProgress' in name:
# dispatcher system sensors
deleteList.append(icon)
else:
# block sensors
if sensor in blockSensors:
deleteList.append(icon)
for item in deleteList:
panel.removeFromContents(item)
# **************************************************
# remove Logix
# **************************************************
def removeLogix(self):
logixManager = jmri.InstanceManager.getDefault(jmri.LogixManager)
logix = logixManager.getLogix('Run Dispatcher')
if logix is not None:
logix.deActivateLogix()
logixManager.deleteLogix(logix)
# **************************************************
# remove Transits
# **************************************************
def removeTransits(self):
deleteList = [] # Prevent concurrent modification
for transit in transits.getNamedBeanSet():
deleteList.append(transit)
for item in deleteList:
transits.deleteBean(item, 'DoDelete')
# **************************************************
# remove Sections
# **************************************************
def removeSections(self):
#remove sections
deleteList = [] # Prevent concurrent modification
directionSensorDeleteList = []
for section in sections.getNamedBeanSet():
deleteList.append(section)
forward_sensor = section.getForwardBlockingSensor()
if forward_sensor is not None:
directionSensorDeleteList.append(forward_sensor)
reverse_sensor = section.getReverseBlockingSensor()
if reverse_sensor is not None:
directionSensorDeleteList.append(reverse_sensor)
for item in deleteList:
sections.deleteBean(item, 'DoDelete')
for item in directionSensorDeleteList:
sensors.deleteBean(item, 'DoDelete')
deleteList = []
directionSensorDeleteList = []
# **************************************************
# remove signal mast logic
# **************************************************
def removeSML(self):
smlManger = jmri.InstanceManager.getDefault(jmri.SignalMastLogicManager)
deleteList = [] # Prevent concurrent modification
for sml in smlManger.getNamedBeanSet():
deleteList.append(sml)
for item in deleteList:
smlManger.deleteBean(item, 'DoDelete')
# **************************************************
# remove sensors
# **************************************************
def removeSensors(self):
controlName = []
if self.editorManager.get("Dispatcher System") is None:
# OK to delete control sensors
for control in self.controlSensors:
controlName.append(control[1])
deleteList = [] # Prevent concurrent modification
for sensor in sensors.getNamedBeanSet():
userName = sensor.getUserName()
sysName = sensor.getSystemName()
if userName is not None:
if 'MoveTo' in userName or 'MoveInProgress' in userName:
deleteList.append(sensor)
elif userName in controlName:
deleteList.append(sensor)
for item in deleteList:
#print 'remove sensor {}'.format(item.getDisplayName())
sensors.deleteBean(item, 'DoDelete')
# ***********************************************************
# gets the list of stopping points (stations, sidings etc.)
# ***********************************************************
def get_list_of_stopping_points(self):
if self.logLevel > 0: print "in get_list_of_stopping_points"
stopping_points_set = set()
# First, get stopping points from block comments
for block in blocks.getNamedBeanSet():
comment = block.getComment()
if comment != None:
if "stop" in comment.lower():
stopping_points_set.add(block.getUserName())
# Second, automatically add blocks associated with LayoutTurntables and LayoutTraversers
editorManager = jmri.InstanceManager.getDefault(jmri.jmrit.display.EditorManager)
for editor in editorManager.getAll():
if isinstance(editor, jmri.jmrit.display.layoutEditor.LayoutEditor):
# The returned object is a Java Set, which needs to be converted to a list for safe iteration in Jython
for turntable in list(editor.getLayoutTurntables()):
layout_block = turntable.getLayoutBlock()
if layout_block is not None and layout_block.getUserName() is not None:
stopping_points_set.add(layout_block.getUserName())
# The returned object is a Java Set, which needs to be converted to a list for safe iteration in Jython
for traverser in list(editor.getLayoutTraversers()):
layout_block = traverser.getLayoutBlock()
if layout_block is not None and layout_block.getUserName() is not None:
stopping_points_set.add(layout_block.getUserName())
self.list_of_stopping_points = sorted(list(stopping_points_set))
if self.logLevel > 0: print "list of stopping points", self.list_of_stopping_points
# **************************************************
# add sensors
# **************************************************
def addSensors(self):
# Create the control sensors
for control in self.controlSensors:
sensor = sensors.provideSensor('IS:DSCT:' + str(control[0]))
if sensor is not None:
sensor.setUserName(control[1])
# Create a dummy sensor
sensor = sensors.provideSensor('IS:DSCT:' + str(0))
sensor.setUserName("DummyControlSensor")
sensor = sensors.provideSensor('IS:DSCTA:' + str(0))
sensor.setUserName("Jdialog_closed") # used when setting nonmodal dialogs closed
sensor = sensors.provideSensor('IS:DSCTB:' + str(0))
sensor.setUserName("stoppingDistanceSet") # used when setting stopping distances
# Create the stop sensors
index = 0
for stop in self.list_of_stopping_points:
block = blocks.getBlock(stop)
if block is not None:
index += 1
moveto = sensors.provideSensor('IS:DSMT:' + str(index))
if moveto is not None:
moveto.setUserName('MoveTo' + block.getDisplayName().replace(" ","_") + '_stored')
inproc = sensors.provideSensor('IS:DSMP:' + str(index))
if inproc is not None:
inproc.setUserName('MoveInProgress' + block.getDisplayName().replace(" ","_"))
# **************************************************
# generate SML
# **************************************************
def generateSML(self):
layoutblocks.enableAdvancedRouting(True)
layoutblocks.setRoutingStabilised()
if self.logLevel > 0: print "Generating Signal Mast Logic"
smlManager = jmri.InstanceManager.getDefault(jmri.SignalMastLogicManager)
smlManager.automaticallyDiscoverSignallingPairs()
if self.logLevel > 0: print "Signal Mast Logic Generated"
# **************************************************
# generate sections
# **************************************************
def generateSections(self):
if self.logLevel > 0: print "Generating Sections"
smlManager = jmri.InstanceManager.getDefault(jmri.SignalMastLogicManager)
# generate sections()
smlManager.generateSection()
if self.logLevel > 0: print "Sections Generated"
self.show_progress(80)
# print "+++++++++++++++++++++++ generate block sections ++++++++++++++++++++++++++++++"
sections.generateBlockSections()
# print "+++++++++++++++++++++++ end generate block sections ++++++++++++++++++++++++++++++"
# **************************************************
# add Logix
# **************************************************
def addLogix(self):
lgxManager = jmri.InstanceManager.getDefault(jmri.LogixManager)
cdlManager = jmri.InstanceManager.getDefault(jmri.ConditionalManager)
lgx = lgxManager.createNewLogix('IX:DSLX:1', 'Run Dispatcher')
cdl = cdlManager.createNewConditional('IX:DSLX:1C1', 'Run Dispatcher')
lgx.addConditional('IX:DSLX:1C1', 0)
if cdl is not None:
cdl.setUserName('Run Dispatcher')
vars = []
vars.append(jmri.ConditionalVariable(False, jmri.Conditional.Operator.AND, jmri.Conditional.Type.SENSOR_ACTIVE, 'startDispatcherSensor', True))
cdl.setStateVariables(vars)
actions = []
actions.append(jmri.implementation.DefaultConditionalAction(1, jmri.Conditional.Action.RUN_SCRIPT, '', -1, 'program:jython/DispatcherSystem/Startup.py'))
cdl.setAction(actions)
lgx.activateLogix()
# **************************************************
# add Icons
# **************************************************
def addIcons(self):
for panel in self.editorManager.getAll(jmri.jmrit.display.layoutEditor.LayoutEditor):
self.getBlockCenterPoints(panel)
self.addStopIcons(panel)
self.addOccupancyIconsAndLabels(panel)
#add control icons in separate editor panel
self.addControlIconsAndLabels()
def getCenterPointOfNearestBlockToMid(self, panel):
if self.logLevel > 0: print "in getCenterPointOfNearestBlockToMid"
self.index = 0
self.blockPoints.clear()
blocks_with_track_segments = set()
# reassign the blockpoints to the nearest track segment to mid if one exists
for tsv in panel.getTrackSegmentViews():
blk = tsv.getBlockName()
pt1 = panel.getCoords(tsv.getConnect1(), tsv.getType1())
pt2 = panel.getCoords(tsv.getConnect2(), tsv.getType2())
[x1,y1] = [pt1.getX(), pt1.getY()]
[x2,y2] = [pt2.getX(), pt2.getY()]
if blk in self.list_of_stopping_points:
if abs(float(y1)-float(y2)) < 15.0: # East-West place icon to right of circle
x_reqd = int((float(x1)+float(x2))/2.0)+25 # to put to right of circle
y_reqd = int((float(y1)+float(y2))/2.0) # to put just under track
else: # North south place icon under circle
x_reqd = int((float(x1)+float(x2))/2.0)-20 # to centralise
y_reqd = int((float(y1)+float(y2))/2.0)+15 # to put under circle
blocks_with_track_segments.add(blk)
else:
x_reqd = int((float(x1)+float(x2))/2.0) # to put to right of circle
y_reqd = int((float(y1)+float(y2))/2.0)
pt_to_try = Point2D.Double(x_reqd, y_reqd)
if blk in self.blockPoints1:
pt_mid = self.blockPoints1[blk]
self.updateCoords1(blk, pt_to_try, pt_mid)
# Handle turntables
for turntableView in panel.getLayoutTurntableViews():
turntable = turntableView.getTurntable()
layoutBlock = turntable.getLayoutBlock()
if layoutBlock is not None:
blk = layoutBlock.getUserName()
if blk in self.blockPoints1:
pt_mid = self.blockPoints1[blk]
# For a turntable, the icon position is calculated relative to its own center
[x_reqd, y_reqd] = self.get_turntable_icon_position(turntable, turntableView)
pt_to_try = Point2D.Double(x_reqd, y_reqd)
self.updateCoords1(blk, pt_to_try, pt_mid)
# Handle traversers
for traverserView in panel.getLayoutTraverserViews():
traverser = traverserView.getTraverser()
layoutBlock = traverser.getLayoutBlock()
if layoutBlock is not None:
blk = layoutBlock.getUserName()
if blk in self.blockPoints1:
pt_mid = self.blockPoints1[blk]
# For a traverser, the icon position is calculated relative to its own center
[x_reqd, y_reqd] = self.get_traverser_icon_position(traverser, traverserView)
pt_to_try = Point2D.Double(x_reqd, y_reqd)
self.updateCoords1(blk, pt_to_try, pt_mid)
# Handle turnouts
for turnoutView in panel.getLayoutTurnoutViews():
turnout = turnoutView.getTurnout()
layoutBlock = turnoutView.getLayoutBlock()
if layoutBlock is not None:
blk = layoutBlock.getUserName()
if blk in blocks_with_track_segments:
continue
if blk in self.blockPoints1:
pt_mid = self.blockPoints1[blk]
coords = turnoutView.getCoordsCenter()
pt_to_try = Point2D.Double(coords.getX(), coords.getY())
self.updateCoords1(blk, pt_to_try, pt_mid)
def get_turntable_icon_position(self, turntable, turntableView):
import math
# print "--- Calculating icon position for turntable:", turntable.getName(), "---"
turntable_center = turntableView.getCoordsCenter()
radius = turntable.getRadius()
rays = turntable.getRayTrackList()
if len(rays) < 2:
# Fallback for turntables with 0 or 1 ray: place icon bottom-right
# print " Fewer than 2 rays, using fallback position."
x_reqd = int(turntable_center.getX()) + 30
y_reqd = int(turntable_center.getY()) + 25
return [x_reqd, y_reqd]
# Get all ray angles in degrees and sort them
angles = sorted([ray.getAngle() for ray in rays])
# print " Sorted ray angles (degrees):", angles
# Calculate angular gaps between adjacent rays
gaps = []
for i in range(len(angles) - 1):
gap = angles[i+1] - angles[i]
gaps.append(gap)
# Add the wrap-around gap between the last and first ray
wrap_around_gap = (360.0 - angles[-1]) + angles[0]
gaps.append(wrap_around_gap)
# print " Calculated gaps:", gaps
max_gap = max(gaps)
# print " Max gap found:", max_gap
# Find all gaps that are the largest
best_mid_angle = -1
min_angle_diff = 361 # Larger than any possible angle difference
# Define a preferred angle for tie-breaking (bottom-right quadrant)
preferred_angle = math.degrees(math.atan2(25, 30)) # atan2(y, x)
# print " Preferred angle for tie-breaking:", preferred_angle
for i in range(len(gaps)):
if abs(gaps[i] - max_gap) < 1e-6: # Compare floats with a tolerance
# print " Found a max gap at index", i
if i < len(angles) - 1:
mid_angle = angles[i] + max_gap / 2.0
else: # Wrap-around case
mid_angle = (angles[-1] + max_gap / 2.0) % 360.0
# print " Mid-angle of this gap:", mid_angle
# Normalize angle difference for tie-breaking
angle_diff = abs(mid_angle - preferred_angle)
# print " Difference from preferred angle:", angle_diff
if angle_diff < min_angle_diff:
# print " This is the new best candidate."
min_angle_diff = angle_diff
best_mid_angle = mid_angle
# print " Final chosen mid-angle:", best_mid_angle
# Convert the final angle to radians for trig functions
final_angle_rad = math.radians(best_mid_angle)
if best_mid_angle > 180.0 and best_mid_angle < 360.0:
icon_distance = radius + 70 # Place icon 20 pixels out from the turntable radius plus a bit to allow for the icon length
else:
icon_distance = radius + 30 # Place icon 20 pixels out from the turntable radius
x_reqd = int(turntable_center.getX() + icon_distance * math.sin(final_angle_rad))
y_reqd = int(turntable_center.getY() - icon_distance * math.cos(final_angle_rad))
# print " Turntable Centre (x, y):", int(turntable_center.getX()), ",", int(turntable_center.getY())
# print " Calculated position (x, y):", x_reqd, ",", y_reqd
# print "----------------------------------------------------"
return [x_reqd, y_reqd]
def get_traverser_icon_position(self, traverser, traverserView):
import math
if self.logLevel > 0: print "--- Calculating icon position for traverser:", traverser.getName(), "---"
traverser_center = traverserView.getCoordsCenter()
if self.logLevel > 0: print "traverser_center", traverser_center
slotOffset = traverser.getSlotOffset()
numberOfSlots = traverser.getNumberSlots()
if self.logLevel > 0: print "numberOfSlots", numberOfSlots
deckWidth = traverser.getDeckWidth()
# deck_height = ((deckWidth/4.0) + (slotOffset * numberOfSlots))/4.0
deck_height = traverser.getDeckLength()
# offset = -1.5 * deckWidth/4.0
offset = 0.0
# Check if all RHS (even index) slots are disabled
rhs_disabled = True
slots = traverser.getSlotList()
for i in range(len(slots)):
if i % 2 == 0: # Even index = RHS
if not slots[i].isDisabled():
rhs_disabled = False
break
# Check if all LHS (odd index) slots are disabled
lhs_disabled = True
for i in range(len(slots)):
if i % 2 != 0: # Odd index = LHS
if not slots[i].isDisabled():
lhs_disabled = False
break
if rhs_disabled:
if traverser.getOrientation() == traverser.HORIZONTAL:
x_reqd = int(traverser_center.getX() - deckWidth/2.0 - 70.0 )
y_reqd = int(traverser_center.getY())
else:
x_reqd = int(traverser_center.getX() - 25.0)
y_reqd = int(traverser_center.getY() - deckWidth/2.0 - 25.0)
elif lhs_disabled:
if traverser.getOrientation() == traverser.HORIZONTAL:
x_reqd = int(traverser_center.getX() + deckWidth/2.0 + 20.0)
y_reqd = int(traverser_center.getY())
else:
x_reqd = int(traverser_center.getX() - 25.0)
y_reqd = int(traverser_center.getY() + deckWidth/2.0 + 15.0)
else:
if traverser.getOrientation() == traverser.HORIZONTAL:
x_reqd = int(traverser_center.getX()) - 25
y_reqd = int(traverser_center.getY()) + deck_height/2.0 + offset
else:
x_reqd = int(traverser_center.getX()) + deck_height/2.0 + 20.0
y_reqd = int(traverser_center.getY())
if self.logLevel > 0: print "finished calculating icon position"
return [x_reqd, y_reqd]
def updateCoords1(self, blk, pt_to_try, pt_mid):
if blk is not None:
if blk in self.blockPoints:
if (jmri.util.MathUtil.distance(pt_mid, pt_to_try) < \
jmri.util.MathUtil.distance(pt_mid, self.blockPoints[blk])):
self.blockPoints[blk] = pt_to_try
else:
self.blockPoints[blk] = pt_to_try
def updateCoords(self, blk, xy):
if blk is not None:
if blk in self.blockPoints1:
self.blockPoints1[blk] = jmri.util.MathUtil.midPoint(self.blockPoints1[blk], xy)
else:
self.blockPoints1[blk] = xy
def getBlockCenterPoints(self, panel):
self.index = 0
self.blockPoints1.clear()
for tsv in panel.getTrackSegmentViews():
blk = tsv.getBlockName()
pt1 = panel.getCoords(tsv.getConnect1(), tsv.getType1())
pt2 = panel.getCoords(tsv.getConnect2(), tsv.getType2())
mid = jmri.util.MathUtil.midPoint(pt1, pt2)
self.updateCoords(blk, mid)
for tov in panel.getLayoutTurnoutAndSlipViews():
blkA = tov.getBlockName()
blkB = tov.getBlockBName()
blkC = tov.getBlockCName()
blkD = tov.getBlockDName()
xyA = tov.getCoordsA()
xyB = tov.getCoordsB()
xyC = tov.getCoordsC()
xyD = tov.getCoordsD()
self.updateCoords(blkA, xyA)
self.updateCoords(blkB, xyB)
self.updateCoords(blkC, xyC)
self.updateCoords(blkD, xyD)
for lxv in panel.getLevelXingViews():
blkAC = lxv.getBlockNameAC()
blkBD = lxv.getBlockNameBD()
# A level crossing has 4 points but only two blocks. To prevent both points being in the
# middle, use the A and D points.
xyA = lxv.getCoordsA()
xyD = lxv.getCoordsD()
self.updateCoords(blkAC, xyA)
self.updateCoords(blkBD, xyD)
# Handle turntables
for turntableView in panel.getLayoutTurntableViews():
turntable = turntableView.getTurntable()
layoutBlock = turntable.getLayoutBlock()
if layoutBlock is not None:
blockName = layoutBlock.getUserName()
# The center of the turntable is its main coordinate, get it from the View
centerCoords = turntableView.getCoordsCenter()
self.updateCoords(blockName, centerCoords)
# Handle traversers
for traverserView in panel.getLayoutTraverserViews():
traverser = traverserView.getTraverser()
layoutBlock = traverser.getLayoutBlock()
if layoutBlock is not None:
blockName = layoutBlock.getUserName()
# The center of the traverser is its main coordinate, get it from the View
centerCoords = traverserView.getCoordsCenter()
self.updateCoords(blockName, centerCoords)
# place the stations at the block nearest the mid-point
self.getCenterPointOfNearestBlockToMid(panel)
# **************************************************
# stop icons
# **************************************************
def addStopIcons(self, panel):
for blockName in self.list_of_stopping_points:
if blockName in self.blockPoints.keys():
# print "addStopIcons blockName", blockName
x = self.blockPoints[blockName].getX()
y = self.blockPoints[blockName].getY()
mtSensor = sensors.getSensor('MoveTo' + blockName.replace(" ","_") + '_stored')
if mtSensor is not None:
self.addMarkerIcon(panel, mtSensor, blockName, x, y)
mpSensor = sensors.getSensor('MoveInProgress' + blockName.replace(" ","_"))
if mpSensor is not None:
self.addSmallIcon(panel, mpSensor.getDisplayName(), x - 10, y)
# **************************************************
# occupancy sensor icons and block content labels
# **************************************************
def addOccupancyIconsAndLabels(self, panel):
for blockName in self.blockPoints.keys():
x = self.blockPoints[blockName].getX() - 10
y = self.blockPoints[blockName].getY() + 10
block = blocks.getBlock(blockName)
if block is not None:
sensor = block.getSensor()
if sensor is not None:
self.addSmallIcon(panel, sensor.getDisplayName(), x, y)
y = int(y) - 30 if int(y) > 35 else 5
self.addBlockContentLabel(panel, block, x, y)
# **************************************************
# control sensor icons and label
# **************************************************
def addControlIconsAndLabels(self):
if (not self.version_number_changed()) and self.dispatcher_system_panel_exists():
if self.logLevel > 0: print "not adding control Icons and labels"
return
# Create the Dispatcher System control panel
panel = jmri.jmrit.display.layoutEditor.LayoutEditor("Dispatcher System")
self.editorManager.add(panel)
for control in self.controlSensors:
sensor = sensors.getSensor('IS:DSCT:' + str(control[0]))
if sensor is not None:
x = 20 + control[3]
y = (control[0] * 20) + 0 + control[4]
self.addMediumIcon(panel, sensor, x, y)
x += 20
self.addTextLabel(panel, control[2], x, y)
panel.setSize(300,600)
panel.setAllEditable(False)
panel.setVisible(True)
def dispatcher_system_panel_exists(self):
for frame1 in java.awt.Frame.getFrames():
# print "frame", frame1.getName()
if frame1.getName() == "Dispatcher System":
if frame1.isVisible():
return True
# print "Dispatcher System Panel does not exist"
return False
# **************************************************
# small icon
# **************************************************
def addSmallIcon(self, panel, sensorName, x, y):
icn = jmri.jmrit.display.SensorIcon(panel)
icn.setIcon("SensorStateActive", jmri.jmrit.catalog.NamedIcon("resources/icons/smallschematics/tracksegments/circuit-occupied.gif", "active"));
icn.setIcon("SensorStateInactive", jmri.jmrit.catalog.NamedIcon("resources/icons/smallschematics/tracksegments/circuit-empty.gif", "inactive"));
icn.setIcon("BeanStateInconsistent", jmri.jmrit.catalog.NamedIcon("resources/icons/smallschematics/tracksegments/circuit-error.gif", "incons"));
icn.setIcon("BeanStateUnknown", jmri.jmrit.catalog.NamedIcon("resources/icons/smallschematics/tracksegments/circuit-error.gif", "unknown"));
# Assign the sensor and set the location
icn.setSensor(sensorName)
icn.setLocation(int(x), int(y))
# Add the icon to the layout editor panel
panel.putSensor(icn)
# **************************************************
# medium icon
# **************************************************
def addMediumIcon(self, panel, sensor, x, y):
icn = jmri.jmrit.display.SensorIcon(panel)
icn.setIcon("SensorStateActive", jmri.jmrit.catalog.NamedIcon("resources/icons/mediumschematics/LEDs/AMBERLED.gif", "active"));
icn.setIcon("SensorStateInactive", jmri.jmrit.catalog.NamedIcon("resources/icons/mediumschematics/LEDs/GRAYLED.gif", "inactive"));
icn.setIcon("BeanStateInconsistent", jmri.jmrit.catalog.NamedIcon("resources/icons/mediumschematics/LEDs/REDLED.gif", "incons"));
icn.setIcon("BeanStateUnknown", jmri.jmrit.catalog.NamedIcon("resources/icons/mediumschematics/LEDs/REDLED.gif", "unknown"));
# Assign the sensor and set the location
icn.setSensor(sensor.getDisplayName())
icn.setLocation(int(x), int(y))
# Add the icon to the layout editor panel
panel.putSensor(icn)
# **************************************************
# marker icon
# **************************************************
def addMarkerIcon(self, panel, sensor, blockName, x, y):
icn = jmri.jmrit.display.SensorIcon(panel)
icn.setIcon("SensorStateActive", jmri.jmrit.catalog.NamedIcon("resources/icons/markers/loco-green.gif", "active"));
icn.setIcon("SensorStateInactive", jmri.jmrit.catalog.NamedIcon("resources/icons/markers/loco-red.gif", "inactive"));
icn.setIcon("BeanStateInconsistent", jmri.jmrit.catalog.NamedIcon("resources/icons/markers/loco-yellow.gif", "incons"));
icn.setIcon("BeanStateUnknown", jmri.jmrit.catalog.NamedIcon("resources/icons/markers/loco-gray.gif", "unknown"));
if len(blockName) > 9:
icn.setText(blockName[:11])
icn.getPopupUtility().setFontSize(9)
else:
icn.setText(blockName[:9])
icn.getPopupUtility().setFontSize(11)
icn.setTextActive(Color.RED)
icn.setTextInActive(Color.YELLOW)
icn.setTextInconsistent(Color.BLACK)
icn.setTextUnknown(Color.BLUE)
# Assign the sensor and set the location
icn.setSensor(sensor.getDisplayName())
icn.setLocation(int(x), int(y))
# Add the icon to the layout editor panel
panel.putSensor(icn)
# **************************************************
# text label
# **************************************************
def addTextLabel(self, panel, text, x, y):
label = jmri.jmrit.display.PositionableLabel(text, panel)
label.setLocation(int(x), int(y))
label.setSize(label.getPreferredSize().width, label.getPreferredSize().height);
label.setDisplayLevel(4)
panel.putItem(label)
# **************************************************
# block content label
# **************************************************
def addBlockContentLabel(self, panel, block, x, y):
label = jmri.jmrit.display.BlockContentsIcon(block.getDisplayName(), panel)
label.setBlock(block.getDisplayName())
label.setLocation(int(x), int(y))
panel.putItem(label)
def saveForwardStoppingSensors(self):
forward_stop_sensors = \
[["section: " , str(section.getUserName()), " stop sensor: " , str(section.getForwardStoppingSensor().getUserName())] \
for section in sections.getNamedBeanSet() if section.getForwardStoppingSensor() != None]
self.write_list(forward_stop_sensors)
def retrieveForwardStoppingSensors(self):
forward_stop_sensors = self.read_list()
if forward_stop_sensors != []:
[sections.getSection(section_name).setForwardStoppingSensorName(forward_stopping_sensor_name) \
for [sn_prompt, section_name, fss_prompt, forward_stopping_sensor_name] in forward_stop_sensors \
if forward_stop_sensors is not [] and sections.getSection(section_name) is not None]
def directory(self):
path = jmri.util.FileUtil.getUserFilesPath() + "dispatcher" + java.io.File.separator + "forwardStoppingSensors"
if not os.path.exists(path):
os.makedirs(path)
return path + java.io.File.separator
def write_list(self, a_list):
# store list in binary file so 'wb' mode
file = self.directory() + "forwardStoppingSensors.txt"
#print "block_info" , a_list
#print "file" +file
with open(file, 'wb') as fp:
for items in a_list:
i = 0
for item in items:
fp.write('%s' %item)
if i < 3 : fp.write(",")
i+=1
fp.write('\n')
# Read list to memory
def read_list(self):
# for reading also binary mode is important
file = self.directory() + "forwardStoppingSensors.txt"
n_list = []
try:
with open(file, 'rb') as fp:
for line in fp:
x = line[:-1]
#print x
y = x.split(",")
#print "y" , y
n_list.append(y)
return n_list
except:
return []
class DisplayProgress:
def __init__(self):
#labels don't seem to work. This is the only thing I could get to work. Improvements welcome
self.frame1 = JFrame('Starting Processing!', defaultCloseOperation=JFrame.DISPOSE_ON_CLOSE, size=(500, 50), locationRelativeTo=None)
self.frame1.setVisible(True)
def Update(self,msg):
self.frame1.setTitle(msg)
def killLabel(self):
self.frame1.setVisible(False)
self.frame1 = None
class Query:
def customQuestionMessage2str(self, msg, title, opt1, opt2):
self.CLOSED_OPTION = False
options = [opt1, opt2]
s = JOptionPane.showOptionDialog(None,
msg,
title,
JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE,
None,
options,
options[1])
if s == JOptionPane.CLOSED_OPTION:
self.CLOSED_OPTION = True
return
if s == JOptionPane.YES_OPTION:
s1 = opt1
else:
s1 = opt2
return s1
def displayMessage(self, msg, title = ""):
self.CLOSED_OPTION = False
s = JOptionPane.showOptionDialog(None,
msg,
title,
JOptionPane.YES_NO_OPTION,
JOptionPane.PLAIN_MESSAGE,
None,
["OK"],
None)
#JOptionPane.showMessageDialog(None, msg, 'Message', JOptionPane.WARNING_MESSAGE)
if s == JOptionPane.CLOSED_OPTION:
self.CLOSED_OPTION = True
return
return s