def __start__(self, fade=False): for target_id, action in self.targets: cue = Application().cue_model.get(target_id) if cue is not self: cue.execute(action=CueAction[action]) return False
def gain(self): gainUi = GainUi(MainWindow()) gainUi.exec_() if gainUi.result() == QDialog.Accepted: files = {} if gainUi.only_selected(): cues = Application().layout.get_selected_cues(MediaCue) else: cues = Application().cue_model.filter(MediaCue) for cue in cues: media = cue.media uri = media.input_uri() if uri is not None: if uri not in files: files[uri] = [media] else: files[uri].append(media) # Gain (main) thread self._gain_thread = GainMainThread(files, gainUi.threads(), gainUi.mode(), gainUi.ref_level(), gainUi.norm_level()) # Progress dialog self._progress = GainProgressDialog(len(files)) self._gain_thread.on_progress.connect(self._progress.on_progress, mode=Connection.QtQueued) self._progress.show() self._gain_thread.start()
def _execute(self, action): for n, trigger in enumerate(self._triggers.get(action, [])): cue, cue_id = trigger if cue is None or cue.is_finalized(): cue = Application().layout.get_cue_by_id(cue_id) self._triggers[action][n] = (cue, cue_id) if cue is not None: cue.execute()
def execute(self, emit=True): super().execute(emit) layout = Application().layout for cue in layout.get_cues(cue_class=MediaCue): if self['pause_mode']: cue.media.pause() else: cue.media.stop()
def __start__(self, fade=False): if self.relative: index = self.index + self.target_index else: index = self.target_index try: cue = Application().layout.model_adapter.item(index) if cue is not self: cue.execute(CueAction(self.action)) except IndexError: pass
def load_settings(self, settings): # Remove the edited cue from the list of possible targets edited_cue = Application().cue_model.get(settings.get('id')) if edited_cue: self.cue_select.remove_cue(edited_cue) for trigger, targets in settings.get('triggers', {}).items(): for target, action in targets: target = Application().cue_model.get(target) if target is not None: self.triggersModel.appendRow(target.__class__, trigger, target.id, CueAction(action))
def __init__(self): super().__init__() self.__handlers = {} # Register a Cue property to store settings Cue.register_property('triggers', Property({})) # Cue.triggers -> {trigger: [(target_id, action), ...]} # Register SettingsPage CueSettingsRegistry().add_item(TriggersSettings) Application().cue_model.item_added.connect(self.__cue_added) Application().cue_model.item_removed.connect(self.__cue_removed)
def show_info(self, clicked): media_uri = Application().layout.get_context_cue().media.input_uri() if not media_uri: QMessageBox.critical(MainWindow(), translate('MediaInfo', 'Error'), translate('MediaInfo', 'No info to display')) else: gst_info = gst_uri_metadata(media_uri) info = {'URI': unquote(gst_info.get_uri())} # Audio streams info for stream in gst_info.get_audio_streams(): name = stream.get_stream_type_nick().capitalize() info[name] = { 'Bitrate': str(stream.get_bitrate() // 1000) + ' Kb/s', 'Channels': str(stream.get_channels()), 'Sample rate': str(stream.get_sample_rate()) + ' Hz', 'Sample size': str(stream.get_depth()) + ' bit' } # Video streams info for stream in gst_info.get_video_streams(): name = stream.get_stream_type_nick().capitalize() info[name] = { 'Height': str(stream.get_height()) + ' px', 'Width': str(stream.get_width()) + ' px', 'Framerate': str( round(stream.get_framerate_num() / stream.get_framerate_denom())) } # Media tags info['Tags'] = {} tags = gst_info.get_tags() if tags is not None: tags = gst_parse_tags_list(tags) for tag in tags: if type(tags[tag]).__str__ is not object.__str__: info['Tags'][tag.capitalize()] = str(tags[tag]) if not info['Tags']: info.pop('Tags') # Show the dialog dialog = InfoDialog(MainWindow(), info, Application().layout.get_context_cue().name) dialog.exec_()
def execute(self, emit=True): super().execute(emit) layout = Application().layout for cue in layout.get_cues(cue_class=MediaCue): if not set(cue['groups']).isdisjoint(self['groups']): if self['action'] == self.ACTION_PLAY: cue.media.play() elif self['action'] == self.ACTION_PAUSE: cue.media.pause() elif self['action'] == self.ACTION_STOP: cue.media.stop() elif self['action'] == self.ACTION_AUTO: cue.execute()
def __init__(self, **kwargs): super().__init__(**kwargs) self.setLayout(QVBoxLayout(self)) self.layout().setAlignment(Qt.AlignTop) self.cue_select = CueSelectDialog(cues=Application().cue_model) self.triggersModel = TriggersModel() self.triggersView = TriggersView(self.cue_select, parent=self) self.triggersView.setModel(self.triggersModel) self.layout().addWidget(self.triggersView) self.dialogButtons = QDialogButtonBox(self) self.dialogButtons.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum) self.layout().addWidget(self.dialogButtons) self.addButton = self.dialogButtons.addButton( translate('TriggersSettings', 'Add'), QDialogButtonBox.ActionRole) self.addButton.clicked.connect(self._add_trigger) self.delButton = self.dialogButtons.addButton( translate('TriggersSettings', 'Remove'), QDialogButtonBox.ActionRole) self.delButton.clicked.connect(self._remove_trigger)
def __init__(self, **kwargs): super().__init__(**kwargs) self.setLayout(QVBoxLayout()) self.layout().setAlignment(QtCore.Qt.AlignTop) self.cue_id = -1 self.cueDialog = CueSelectDialog( cues=Application().cue_model.filter(MediaCue), parent=self) self.cueGroup = QGroupBox(self) self.cueGroup.setLayout(QVBoxLayout()) self.layout().addWidget(self.cueGroup) self.cueButton = QPushButton(self.cueGroup) self.cueButton.clicked.connect(self.select_cue) self.cueGroup.layout().addWidget(self.cueButton) self.cueLabel = QLabel(self.cueGroup) self.cueLabel.setAlignment(QtCore.Qt.AlignCenter) self.cueGroup.layout().addWidget(self.cueLabel) self.seekGroup = QGroupBox(self) self.seekGroup.setLayout(QHBoxLayout()) self.layout().addWidget(self.seekGroup) self.seekEdit = QTimeEdit(self.seekGroup) self.seekEdit.setDisplayFormat('HH.mm.ss.zzz') self.seekGroup.layout().addWidget(self.seekEdit) self.seekLabel = QLabel(self.seekGroup) self.seekLabel.setAlignment(QtCore.Qt.AlignCenter) self.seekGroup.layout().addWidget(self.seekLabel) self.retranslateUi()
def add_uri_audio_media_cue(): """Add audio MediaCue(s) form user-selected files""" if get_backend() is None: QMessageBox.critical(MainWindow(), 'Error', 'Backend not loaded') return # Default path to system "music" folder path = QStandardPaths.writableLocation(QStandardPaths.MusicLocation) # Get the backend extensions and create a filter for the Qt file-dialog extensions = get_backend().supported_extensions() filters = qfile_filters(extensions, anyfile=False) # Display a file-dialog for the user to choose the media-files files, _ = QFileDialog.getOpenFileNames( MainWindow(), translate('MediaCueMenus', 'Select media files'), path, filters) QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) # Create media cues, and add them to the Application cue_model for file in files: cue = CueFactory.create_cue('URIAudioCue', uri='file://' + file) # Use the filename without extension as cue name cue.name = os.path.splitext(os.path.basename(file))[0] Application().cue_model.add(cue) QApplication.restoreOverrideCursor()
def __init__(self, **kwargs): super().__init__(**kwargs) self.setLayout(QVBoxLayout(self)) self.cue_dialog = CueSelectDialog( cues=Application().cue_model, selection_mode=QAbstractItemView.ExtendedSelection) self.collectionModel = CollectionModel() self.collectionView = CollectionView(self.cue_dialog, parent=self) self.collectionView.setModel(self.collectionModel) self.collectionView.setAlternatingRowColors(True) self.layout().addWidget(self.collectionView) # Buttons self.dialogButtons = QDialogButtonBox(self) self.dialogButtons.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum) self.layout().addWidget(self.dialogButtons) self.addButton = self.dialogButtons.addButton( translate('CollectionCue', 'Add'), QDialogButtonBox.ActionRole) self.addButton.clicked.connect(self._add_dialog) self.delButton = self.dialogButtons.addButton( translate('CollectionCue', 'Remove'), QDialogButtonBox.ActionRole) self.delButton.clicked.connect(self._remove_selected)
def __start__(self, fade=False): for cue in Application().cue_model: action = self.__adjust_action(cue, CueAction(self.action)) if action: cue.execute(action=action) return False
def __create_from_cue(): cue = Application().layout.get_context_cue() name = save_preset_dialog(cue.name) if name is not None: if not (preset_exists(name) and not check_override_dialog(name)): preset = cue.properties(only_changed=True) # Discard id and index preset.pop('id') preset.pop('index') try: write_preset(name, preset) except OSError as e: write_preset_error(e, name, parent=MainWindow())
def __init__(self): super().__init__() self.__client = OlaTimecode() self.__cues = set() # Register a new Cue property to store settings Cue.register_property('timecode', Property(default={})) # Register cue-settings-page CueSettingsRegistry().add_item(TimecodeCueSettings, MediaCue) # Register pref-settings-page AppSettings.register_settings_widget(TimecodeSettings) # Watch cue-model changes Application().cue_model.item_added.connect(self.__cue_added) Application().cue_model.item_removed.connect(self.__cue_removed)
def __load_on_cue(): preset_name = select_preset_dialog() if preset_name is not None: try: load_on_cue(preset_name, Application().layout.get_context_cue()) except OSError as e: load_preset_error(e, preset_name, parent=MainWindow())
def __init__(self): super().__init__() self.__map = {} self.__actions_map = {} self.__protocols = {} # Register a new Cue property to store settings Cue.register_property('controller', Property(default={})) # Listen cue_model changes Application().cue_model.item_added.connect(self.__cue_added) Application().cue_model.item_removed.connect(self.__cue_removed) # Register settings-page CueSettingsRegistry().add_item(ControllerSettings) # Load available protocols self.__load_protocols()
def load_settings(self, settings): cue = Application().cue_model.get(settings.get('target_id', '')) if cue is not None: self.cue_id = settings['target_id'] self.cueLabel.setText(cue.name) self.volumeEdit.setValue(settings.get('volume', 0) * 100) self.fadeSpin.setValue(settings.get('duration', 0) / 1000) self.fadeCurveCombo.setCurrentType(settings.get('fade_type', ''))
def __init__(self, **kwargs): super().__init__(**kwargs) self.setLayout(QVBoxLayout()) self.layout().setAlignment(Qt.AlignTop) self.__v_edit_flag = False self.cue_id = -1 cues = Application().cue_model.filter(MediaCue) self.cueDialog = CueSelectDialog(cues=cues, parent=self) self.cueGroup = QGroupBox(self) self.cueGroup.setLayout(QVBoxLayout()) self.layout().addWidget(self.cueGroup) self.cueLabel = QLabel(self.cueGroup) self.cueLabel.setAlignment(QtCore.Qt.AlignCenter) self.cueLabel.setStyleSheet('font-weight: bold;') self.cueGroup.layout().addWidget(self.cueLabel) self.cueButton = QPushButton(self.cueGroup) self.cueButton.clicked.connect(self.select_cue) self.cueGroup.layout().addWidget(self.cueButton) self.volumeGroup = QGroupBox(self) self.volumeGroup.setLayout(QHBoxLayout()) self.layout().addWidget(self.volumeGroup) self.volumeEdit = QDoubleSpinBox(self.volumeGroup) self.volumeEdit.setDecimals(6) self.volumeEdit.setMaximum(100) self.volumeGroup.layout().addWidget(self.volumeEdit) self.percentLabel = QLabel('%', self.volumeGroup) self.volumeGroup.layout().addWidget(self.percentLabel) self.volumeDbEdit = QDoubleSpinBox(self.volumeGroup) self.volumeDbEdit.setRange(MIN_VOLUME_DB, MAX_VOLUME_DB) self.volumeDbEdit.setValue(MIN_VOLUME_DB) self.volumeGroup.layout().addWidget(self.volumeDbEdit) self.dbLabel = QLabel('dB', self.volumeGroup) self.volumeGroup.layout().addWidget(self.dbLabel) self.volumeEdit.valueChanged.connect(self.__volume_change) self.volumeDbEdit.valueChanged.connect(self.__db_volume_change) # Fade self.fadeGroup = QGroupBox(self) self.fadeGroup.setLayout(QHBoxLayout()) self.layout().addWidget(self.fadeGroup) self.fadeEdit = FadeEdit(self.fadeGroup) self.fadeGroup.layout().addWidget(self.fadeEdit) self.retranslateUi()
def main(): # Create and parse the command-line arguments parser = argparse.ArgumentParser(description='Linux Show Player') parser.add_argument('-f', '--file', default='', help="Session file path") parser.add_argument('-l', '--log', choices=['debug', 'info', 'warning'], default='warning', help='Log level') args = parser.parse_args() # Set the logging level if args.log == 'debug': log = logging.DEBUG elif args.log == 'info': log = logging.INFO else: log = logging.WARNING logging.basicConfig(format='%(levelname)s:: %(message)s', level=log) # Create the QApplication app = QApplication(sys.argv) app.setApplicationName('Linux Show Player') app.setQuitOnLastWindowClosed(True) # Force light font, for environment with "bad" QT support. appFont = app.font() appFont.setWeight(QFont.Light) app.setFont(appFont) # Set icons and theme from the application configuration QIcon.setThemeSearchPaths(styles.IconsThemePaths) QIcon.setThemeName(config['Theme']['icons']) styles.apply_style(config['Theme']['theme']) # Create the application LiSP_app = Application() # Load modules and plugins modules.load_modules() plugins.load_plugins() # Start the application LiSP_app.start(session_file=args.file) # Start the application sys.exit(_exec(app, LiSP_app))
def __load_on_selected(self): item = self.presetsList.currentItem() if item is not None: preset_name = item.text() try: cues = Application().layout.get_selected_cues() if cues: load_on_cues(preset_name, cues) except OSError as e: load_preset_error(e, preset_name, parent=MainWindow())
def _relative_changed(self): max_index = len(Application().cue_model) - 1 if not self.relativeCheck.isChecked(): self.targetIndexSpin.setRange(0, max_index) else: if self._cue_index >= 0: self.targetIndexSpin.setRange(-self._cue_index, max_index - self._cue_index) else: self.targetIndexSpin.setRange(-max_index, max_index)
def load_settings(self, settings): if settings is not None: cue = Application().cue_model.get(settings.get('target_id')) if cue is not None: self.cue_id = settings['target_id'] self.seekEdit.setMaximumTime( QTime.fromMSecsSinceStartOfDay(cue.media.duration)) self.cueLabel.setText(cue.name) self.seekEdit.setTime( QTime.fromMSecsSinceStartOfDay(settings.get('time', 0)))
def __init_fader(self): cue = Application().cue_model.get(self.target_id) if isinstance(cue, MediaCue): volume = cue.media.element('Volume') if volume is not None: if volume is not self.__fader.target: self.__fader.target = volume return True return False
def __cue_from_preset(self, preset_name): try: preset = load_preset(preset_name) if preset is not None: if CueFactory.has_factory(preset.get('_type_')): cue = CueFactory.create_cue(preset['_type_']) cue.update_properties(preset) Application().cue_model.add(cue) else: QMessageBox.warning( self, translate('Presets', 'Warning'), translate( 'Presets', 'Cannot create a cue from this ' 'preset: {}').format(preset_name)) except OSError as e: load_preset_error(e, preset_name, parent=self)
def _update_action_combo(self): if self.relativeCheck.isChecked(): index = self._cue_index + self.targetIndexSpin.value() else: index = self.targetIndexSpin.value() try: target = Application().layout.model_adapter.item(index) target_class = target.__class__ except IndexError: target_class = Cue if target_class is not self._target_class: self._target_class = target_class self.actionGroup.layout().removeWidget(self.actionCombo) self.actionCombo.deleteLater() self.actionCombo = CueActionComboBox( self._target_class, mode=CueActionComboBox.Mode.Value, parent=self.actionGroup) self.actionGroup.layout().addWidget(self.actionCombo)
def get_cue_at(self, index): cue = Application().layout.get_cue_at(index) if cue is not None: return cue.properties() return {}
def execute(self, index): cue = Application().layout.get_cue_at(index) if cue is not None: cue.execute(emit=False)
def get_cue_at(self, index): cue = Application().layout.model_adapter.item(index) if cue is not None: return cue.properties() return {}
def __execute(self, trigger): for target_id, target_action in self.triggers.get(trigger, []): target = Application().cue_model.get(target_id) if target is not None: target.execute(CueAction(target_action))
def execute(self, index): cue = Application().layout.model_adapter.item(index) if cue is not None: cue.execute()
def __start__(self): for target_id, action in self.targets: cue = Application().cue_model.get(target_id) if cue is not None and cue is not self: cue.execute(action=CueAction[action])
def reset(self): Application().layout.key_pressed.disconnect(self.__key_pressed)
def init(self): Application().layout.key_pressed.connect(self.__key_pressed)
def method(): cue = CueFactory.create_cue(cue_class.__name__) Application().cue_model.add(cue)
def __execute(self, trigger): for target_id, action in self.triggers.get(trigger, []): target = Application().cue_model.get(target_id) if target is not None: target.execute(CueAction(action))
def main(): # Parse the command-line arguments parser = argparse.ArgumentParser(description='Linux Show Player') parser.add_argument('-f', '--file', default='', nargs='?', const='', help='Session file path') parser.add_argument('-l', '--log', choices=['debug', 'info', 'warning'], default='warning', help='Log level') parser.add_argument('--locale', default='', help='Force specified locale') args = parser.parse_args() # Set the logging level if args.log == 'debug': log = logging.DEBUG # If something bad happen at low-level (e.g. segfault) print the stack import faulthandler faulthandler.enable() elif args.log == 'info': log = logging.INFO else: log = logging.WARNING logging.basicConfig( format='%(asctime)s.%(msecs)03d %(levelname)s:: %(message)s', datefmt='%H:%M:%S', level=log) # Create the QApplication qt_app = QApplication(sys.argv) qt_app.setApplicationName('Linux Show Player') qt_app.setQuitOnLastWindowClosed(True) # Force light font, for environment with "bad" QT support. appFont = qt_app.font() appFont.setWeight(QFont.Light) qt_app.setFont(appFont) # Set icons and theme from the application configuration QIcon.setThemeSearchPaths(styles.IconsThemePaths) QIcon.setThemeName(config['Theme']['icons']) styles.apply_style(config['Theme']['theme']) # Set application icon (from the theme) qt_app.setWindowIcon(QIcon.fromTheme('linux-show-player')) # Get/Set the locale locale = args.locale if locale: QLocale().setDefault(QLocale(locale)) logging.info('Using {} locale'.format(QLocale().name())) # Main app translations translator = QTranslator() translator.load(QLocale(), 'lisp', '_', path.join(path.dirname(path.realpath(__file__)), 'i18n')) qt_app.installTranslator(translator) ui_translators = [translator] # Qt platform translation translator = QTranslator() translator.load(QLocale(), 'qt', '_', QLibraryInfo.location(QLibraryInfo.TranslationsPath)) qt_app.installTranslator(translator) ui_translators.append(translator) # Modules and plugins translations for tr_file in chain(modules.translations(), plugins.translations()): translator = QTranslator() translator.load(QLocale(), tr_file, '_') qt_app.installTranslator(translator) ui_translators.append(translator) # Create the application lisp_app = Application() # Load modules and plugins modules.load_modules() plugins.load_plugins() # Start/Initialize LiSP Application lisp_app.start(session_file=args.file) # Start Qt Application (block until exit) exit_code = qt_app.exec_() # Finalize the application lisp_app.finalize() # Exit sys.exit(exit_code)
def _reset_selected(self): self._reset(Application().cue_model.filter(MediaCue))
def __start__(self, fade=False): cue = Application().cue_model.get(self.target_id) if isinstance(cue, MediaCue) and self.time >= 0: cue.media.seek(self.time) return False