class AlarmWidget(QWidget): def __init__(self, main): super(AlarmWidget, self).__init__() self.main = main self.config = main.config self.logger = main.logger self.alarm = None self.alarmDateTime = None self.imageDir = self.config.get("display", "image_dir", fallback="images") self.elapsedTimer = QTimer(self) self.elapsedTimer.setInterval(1000) self.elapsedTimer.setSingleShot(False) self.elapsedTimer.timeout.connect(self.elapsedTimeout) verLayout = QVBoxLayout(self) verLayout.setSpacing(0) verLayout.setContentsMargins(0, 0, 0, 0) titleLayout = QHBoxLayout() titleLayout.setSpacing(0) verLayout.addLayout(titleLayout, 0) self.symbolLabel = QLabel(self) self.symbolLabel.setStyleSheet(""" background-color: rgb(120, 0, 0); padding: 10px; """) titleLayout.addWidget(self.symbolLabel, 0) self.titleLabel = QLabel(self) self.titleLabel.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Preferred) self.titleLabel.setStyleSheet(""" color: white; font-size: 80px; background-color: rgb(120, 0, 0); padding: 10px; """) titleLayout.addWidget(self.titleLabel, 1) self.timerLabel = QLabel(self) self.timerLabel.setAlignment(Qt.AlignRight | Qt.AlignVCenter) self.timerLabel.setStyleSheet(""" color: white; background-color: rgb(120, 0, 0); padding: 10px; """) titleLayout.addWidget(self.timerLabel, 0) locationLayout = QHBoxLayout() locationLayout.setSpacing(0) verLayout.addLayout(locationLayout, 0) self.locationSymbolLabel = QLabel(self) self.locationSymbolLabel.setStyleSheet(""" padding: 10px; """) locationLayout.addWidget(self.locationSymbolLabel, 0) innerLocationLayout = QVBoxLayout() innerLocationLayout.setSpacing(0) locationLayout.addLayout(innerLocationLayout, 1) sourceLayout = QVBoxLayout() sourceLayout.setSpacing(0) locationLayout.addLayout(sourceLayout, 0) self.locationLabel = QLabel(self) self.locationLabel.setIndent(0) self.locationLabel.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Preferred) self.locationLabel.setStyleSheet(""" padding: 10px; """) innerLocationLayout.addWidget(self.locationLabel, 1) self.locationHintLabel = QLabel(self) self.locationHintLabel.setIndent(0) self.locationHintLabel.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Preferred) self.locationHintLabel.setStyleSheet(""" padding: 10px; font-size: 40px; """) innerLocationLayout.addWidget(self.locationHintLabel, 1) self.pagerLabel = QLabel(self) sourceLayout.addWidget(self.pagerLabel, 1) self.xmlLabel = QLabel(self) sourceLayout.addWidget(self.xmlLabel, 1) self.jsonLabel = QLabel(self) sourceLayout.addWidget(self.jsonLabel, 1) # Attention row ------------------------------------------------------ attentionLayout = QHBoxLayout() attentionLayout.setSpacing(0) verLayout.addLayout(attentionLayout, 0) self.attentionSymbolLabel = QLabel(self) self.attentionSymbolLabel.setStyleSheet(""" padding: 10px; """) attentionLayout.addWidget(self.attentionSymbolLabel, 0) self.attentionLabel = QLabel(self) self.attentionLabel.setIndent(0) self.attentionLabel.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Preferred) self.attentionLabel.setStyleSheet(""" padding: 10px; font-size: 40px; """) attentionLayout.addWidget(self.attentionLabel, 1) self.callerSymbolLabel = QLabel(self) self.callerSymbolLabel.setStyleSheet(""" padding: 10px; """) attentionLayout.addWidget(self.callerSymbolLabel, 0) self.callerLabel = QLabel(self) self.callerLabel.setIndent(0) self.callerLabel.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Preferred) self.callerLabel.setStyleSheet(""" padding: 10px; font-size: 40px; """) attentionLayout.addWidget(self.callerLabel, 1) # Fallback row ------------------------------------------------------- self.fallbackLabel = QLabel(self) self.fallbackLabel.setIndent(0) self.fallbackLabel.setWordWrap(True) self.fallbackLabel.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Preferred) self.fallbackLabel.setStyleSheet(""" padding: 10px; font-size: 40px; """) verLayout.addWidget(self.fallbackLabel, 0) # Maps --------------------------------------------------------------- horLayout = QHBoxLayout() horLayout.setSpacing(2) verLayout.addLayout(horLayout, 2) self.leftMap = MapWidget(self, self.config, self.logger) self.leftMap.setStyleSheet(""" font-size: 60px; color: #cc0000; """) horLayout.addWidget(self.leftMap, 3) self.rightMap = RouteWidget(self, self.config, self.logger) self.rightMap.setStyleSheet(""" font-size: 40px; """) horLayout.addWidget(self.rightMap, 3) def startTimer(self, alarmDateTime): self.alarmDateTime = alarmDateTime self.elapsedTimer.start() self.elapsedTimeout() def setRoute(self, route): self.logger.info('Destination map...') self.leftMap.setTarget(self.alarm.lat, self.alarm.lon, route) self.logger.info('Route map...') self.rightMap.setTarget(self.alarm.lat, self.alarm.lon, route) def setHourGlass(self, state): if state: path = os.path.join(self.imageDir, 'hourglass.svg') pixmap = pixmapFromSvg(path, 60) self.timerLabel.setPixmap(pixmap) self.timerLabel.setText('') else: self.timerLabel.setPixmap(QPixmap()) QApplication.processEvents() def processAlarm(self, alarm): self.alarm = alarm title = self.alarm.title() if self.alarm.eskalation and len(self.alarm.eskalation) < 5: title += ' / ' + self.alarm.eskalation self.titleLabel.setText(title) image = self.alarm.imageBase() if image: image += '.svg' pixmap = QPixmap(os.path.join(self.imageDir, image)) else: pixmap = QPixmap() self.symbolLabel.setPixmap(pixmap) self.locationLabel.setText(self.alarm.location()) self.locationHintLabel.setText(self.alarm.ortshinweis) if self.locationHintLabel.text(): self.locationHintLabel.show() else: self.locationHintLabel.hide() if self.locationLabel.text() or self.locationHintLabel.text(): pixmap = QPixmap(os.path.join(self.imageDir, 'go-home.svg')) else: pixmap = QPixmap() self.locationSymbolLabel.setPixmap(pixmap) self.attentionLabel.setText(self.alarm.attention()) if self.attentionLabel.text(): pixmap = QPixmap( os.path.join(self.imageDir, 'emblem-important.svg')) self.attentionSymbolLabel.setPixmap(pixmap) self.attentionSymbolLabel.show() self.attentionLabel.show() else: pixmap = QPixmap() self.attentionSymbolLabel.setPixmap(pixmap) self.attentionSymbolLabel.hide() self.attentionLabel.hide() self.callerLabel.setText(self.alarm.callerInfo()) if self.callerLabel.text(): pixmap = QPixmap(os.path.join(self.imageDir, 'caller.svg')) self.callerSymbolLabel.setPixmap(pixmap) self.callerSymbolLabel.show() self.callerLabel.show() else: pixmap = QPixmap() self.callerSymbolLabel.setPixmap(pixmap) self.callerSymbolLabel.hide() self.callerLabel.hide() self.fallbackLabel.setText(self.alarm.fallbackStr) if self.fallbackLabel.text(): self.fallbackLabel.show() else: self.fallbackLabel.hide() self.leftMap.invalidate() self.leftMap.setObjectPlan(self.alarm.objektnummer) self.rightMap.invalidate() if 'xml' in alarm.sources: pixmap = QPixmap(os.path.join(self.imageDir, 'xml.svg')) else: pixmap = QPixmap() self.xmlLabel.setPixmap(pixmap) if 'pager' in alarm.sources: pixmap = QPixmap(os.path.join(self.imageDir, 'pager.svg')) else: pixmap = QPixmap() self.pagerLabel.setPixmap(pixmap) if 'json' in alarm.sources: pixmap = QPixmap(os.path.join(self.imageDir, 'json.svg')) else: pixmap = QPixmap() self.jsonLabel.setPixmap(pixmap) def elapsedTimeout(self): pixmap = self.timerLabel.pixmap() if pixmap and not pixmap.isNull(): return now = QDateTime.currentDateTime() diffMs = self.alarmDateTime.msecsTo(now) seconds = math.floor(diffMs / 1000) hours = math.floor(seconds / 3600) seconds -= hours * 3600 minutes = math.floor(seconds / 60) seconds -= minutes * 60 if hours > 0: text = u'%u:%02u:%02u' % (hours, minutes, seconds) else: text = u'%u:%02u' % (minutes, seconds) self.timerLabel.setText(text)
class HistoryWidget(QWidget): finished = pyqtSignal() historySize = 5 def __init__(self, config, logger): super(HistoryWidget, self).__init__() self.config = config self.logger = logger self.imageDir = self.config.get("display", "image_dir", fallback="images") self.cycleTimer = QTimer(self) self.cycleTimer.setInterval( \ self.config.getint("idle", "history_period", fallback = 10) \ * 1000) self.cycleTimer.setSingleShot(False) self.cycleTimer.timeout.connect(self.cycle) horLayout = QHBoxLayout(self) horLayout.setSpacing(0) horLayout.setContentsMargins(0, 0, 0, 0) verLayout = QVBoxLayout() verLayout.setSpacing(0) verLayout.setContentsMargins(0, 0, 0, 0) horLayout.addLayout(verLayout, 1) self.targetMap = MapWidget(self, self.config, self.logger) self.targetMap.maxCacheEntries = self.historySize self.targetMap.setStyleSheet(""" font-size: 60px; color: #cc0000; """) horLayout.addWidget(self.targetMap, 1) label = QLabel(self) label.setText('Letzte Einsätze') label.setIndent(0) label.setStyleSheet(""" font-size: 50px; padding: 10px 10px 10px 60px; """) verLayout.addWidget(label) self.symbolLabels = [] self.titleLabels = [] self.descLabels = [] self.index = 0 for i in range(0, self.historySize): itemLayout = QHBoxLayout() itemLayout.setSpacing(0) itemLayout.setContentsMargins(0, 0, 0, 0) verLayout.addLayout(itemLayout) label = QLabel(self) itemLayout.addWidget(label, 0) self.symbolLabels.append(label) label = QLabel(self) label.setIndent(0) label.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Preferred) itemLayout.addWidget(label, 1) self.titleLabels.append(label) label = QLabel(self) label.setIndent(0) label.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Preferred) verLayout.addWidget(label) self.descLabels.append(label) def updateStyles(self): for i in range(0, self.historySize): label = self.symbolLabels[i] label.setStyleSheet(self.style(i, 'symbol')) label = self.titleLabels[i] label.setStyleSheet(self.style(i, 'title')) label = self.descLabels[i] label.setStyleSheet(self.style(i, 'desc')) def style(self, index, section): style = '' if section == 'symbol': style += 'padding: 0px 10px 0px 10px;' if section == 'title': style += 'font-size: 40px;' if section == 'desc': style += 'font-size: 25px;' style += 'padding: 0px 0px 20px 60px;' style += 'alignment: top;' if index == self.index: style += 'background-color: #5050a0;' else: if index % 2: style += 'background-color: #101020;' else: style += 'background-color: #202040;' return style def start(self): self.cycleTimer.stop() path = self.config.get("db", "path", fallback=None) if not path: return paths = [os.path.join(path, entry) for entry in os.listdir(path)] paths = [path for path in paths if \ (path.endswith('.dme') or \ path.endswith('.xml') or \ path.endswith('.json')) and \ os.path.isfile(path)] paths = sorted(paths, reverse=True) self.alarms = [] index = 0 while index < self.historySize and len(paths) > 0: path = paths[0] paths = paths[1:] alarm = Alarm(self.config) try: alarm.load(path) except Exception as e: self.logger.error('History failed to load %s: %s', path, e) continue if alarm.fallbackStr: # ignore incomplete or invalid alarms in history continue if len(self.alarms) and self.alarms[-1].matches(alarm): self.alarms[-1].merge(alarm) else: self.alarms.append(alarm) index += 1 local_tz = get_localzone() now = local_tz.localize(datetime.datetime.now()) index = 0 for alarm in self.alarms: dateStr = alarm.datetime.strftime('%A, %d. %B, %H:%M') delta = alarm.datetime - now dateStr += ' (' + babel.dates.format_timedelta( delta, add_direction=True) + ')' image = alarm.imageBase() if image: image += '.svg' pixmap = pixmapFromSvg(os.path.join(self.imageDir, image), 40) else: pixmap = QPixmap() self.symbolLabels[index].setPixmap(pixmap) title = alarm.title() if not title: title = alarm.fallbackStr self.titleLabels[index].setText(title) desc = dateStr loc = alarm.location() if loc: desc += '\n' + loc self.descLabels[index].setText(desc) index += 1 self.index = 0 if len(self.alarms): alarm = self.alarms[self.index] self.targetMap.setTarget(alarm.lat, alarm.lon, ([], )) self.cycleTimer.start() self.updateStyles() else: self.finished.emit() def stop(self): self.cycleTimer.stop() def cycle(self): self.index += 1 if self.index >= len(self.alarms): self.index = 0 self.cycleTimer.stop() self.finished.emit() alarm = self.alarms[self.index] self.targetMap.setTarget(alarm.lat, alarm.lon, ([], )) self.updateStyles()