class WwStripExchanger: def __init__(self, gui): self.updater = SxUpdater(gui) self.update_ticker = Ticker(self.updater.start, parent=gui) self.gui = gui self.running = False def start(self): self.update_ticker.start(SX_update_interval) self.running = True def stopAndWait(self): if self.isRunning( ): # CHECK: do we need to wait for any running SXsender threads as well? self.update_ticker.stop() self.updater.wait() self.running = False self.updater.ATCs_on_last_run.clear() self.updater.current_contact_claims.clear() def isRunning(self): return self.running def connectedATCs(self): return self.updater.ATCs_on_last_run[:] def isConnected(self, atc_callsign): return any(atc.callsign == atc_callsign for atc in self.updater.ATCs_on_last_run) def claimingContact(self, callsign): return self.updater.current_contact_claims.get(callsign, None) def handOver(self, strip, atc_id): ''' returns cleanly if transfer is properly initiated (contact linked), otherwise: HandoverBlocked (handover aborted) ''' acft = strip.linkedAircraft() if acft == None: raise HandoverBlocked( 'Unlinked strips cannot be sent through the OpenRadar system.') else: SXsender(self.gui, strip, acft.identifier, handover=atc_id).start()
class RadioBox(QWidget, Ui_radioBox): def __init__(self, parent, external, port): ''' external is a host (possibly localhost) for external FGCom instance, or None for internal (child process) ''' QWidget.__init__(self, parent) self.setupUi(self) client_address = some(external, 'localhost'), port self.settings = FgcomSettings(socket(AF_INET, SOCK_DGRAM), client_address) self.controller = Ticker(self.settings.send, parent=self) self.frequency_combo.addFrequencies([(frq, descr) for frq, descr, t in env.frequencies]) self.frequency_combo.addFrequencies(frequencies_always_proposed) if external == None: # child process self.onOff_button.setToolTip('Internal FGCom instance using local port %d' % port) ad = world_navpoint_db.findClosest(env.radarPos(), types=[Navpoint.AD]).code if env.airport_data == None else settings.location_code self.instance = InternalFgcomInstance(port, ['--airport=%s' % ad], self) self.instance.started.connect(self.processHasStarted) self.instance.finished.connect(self.processHasStopped) self.onOff_button.toggled.connect(self.switchFGCom) else: # creating box for external instance self.instance = None self.onOff_button.setToolTip('External FGCom instance on %s:%d' % client_address) self.onOff_button.setChecked(True) # keep checked (tested for RDF) self.onOff_button.setEnabled(False) self.PTT_button.setEnabled(True) self.controller.start(fgcom_controller_ticker_interval) self.PTT_button.pressed.connect(lambda: self.PTT(True)) self.PTT_button.released.connect(lambda: self.PTT(False)) self.softVolume_tickBox.clicked.connect(self.setVolume) self.frequency_combo.frequencyChanged.connect(self.setFrequency) self.updateRDF() self.RDF_tickBox.toggled.connect(self.updateRDF) self.onOff_button.toggled.connect(self.updateRDF) signals.localSettingsChanged.connect(self.updateRDF) def isInternal(self): return self.instance != None def clientAddress(self): return self.settings.address def getReadyForRemoval(self): if self.isInternal(): self.switchFGCom(False) self.instance.waitForFinished(1000) else: self.controller.stop() try: del settings.MP_RDF_frequencies[self.settings.address[1]] except KeyError: pass def setVolume(self): if settings.FGCom_radios_muted: self.settings.vol = 0 elif self.softVolume_tickBox.isChecked(): self.settings.vol = soft_sound_level else: self.settings.vol = loud_sound_level self.settings.send() def setFrequency(self, frq): self.PTT(False) self.settings.frq = frq self.updateRDF() self.settings.send() def PTT(self, toggle): self.settings.ptt = toggle self.PTT_button.setChecked(toggle and self.PTT_button.isEnabled()) # NOTE: line below is unreliable on mouse+kbd mix, but not a serious problem. settings.transmitting_radio = toggle # accounts for direct mouse PTT press self.settings.send() def updateRDF(self): frq_select_available = settings.radio_direction_finding and settings.session_manager.session_type == SessionType.FLIGHTGEAR_MP self.RDF_tickBox.setEnabled(frq_select_available) box_key = self.settings.address[1] if frq_select_available and self.RDF_tickBox.isChecked(): settings.MP_RDF_frequencies[box_key] = self.settings.frq else: try: del settings.MP_RDF_frequencies[box_key] except KeyError: pass ## Controlling FGCom process def switchFGCom(self, on_off): if self.isInternal(): self.removeBox_button.setEnabled(not on_off) if on_off: # Start FGCom self.instance.start() else: # Stop FGCom self.PTT(False) self.instance.kill() def processHasStarted(self): self.PTT_button.setEnabled(True) self.controller.start(fgcom_controller_ticker_interval) def processHasStopped(self, exit_code, status): self.controller.stop() self.PTT_button.setEnabled(False) self.PTT_button.setChecked(False) self.onOff_button.setChecked(False)