Beispiel #1
0
    def setUp(self):
        GuiTest.setUp(self)
        self.mockController = MockController()

        self.main = Device("Main")
        self.mockController.addDevice(self.main)
        self.main.sendInputToOutput = MagicMock(return_value=1)

        self.preview = Device("Preview")
        self.mockController.addDevice(self.preview)
        self.preview.sendInputToOutput = MagicMock(return_value=1)

        self.extras = Device("Extras")
        self.mockController.addDevice(self.extras)
        self.extras.sendInputToOutput = MagicMock(return_value=1)

        fakeMainWindow = object()
        self.vs = VideoSwitcher(self.mockController, fakeMainWindow)
 def makeVS(self):
     return VideoSwitcher(self.mockController, self.mainWindow,
                          self.switcherState)
Beispiel #3
0
class TestVideoSwitcher(GuiTest):

    def setUp(self):
        GuiTest.setUp(self)
        self.mockController = MockController()

        self.main = Device("Main")
        self.mockController.addDevice(self.main)
        self.main.sendInputToOutput = MagicMock(return_value=1)

        self.preview = Device("Preview")
        self.mockController.addDevice(self.preview)
        self.preview.sendInputToOutput = MagicMock(return_value=1)

        self.extras = Device("Extras")
        self.mockController.addDevice(self.extras)
        self.extras.sendInputToOutput = MagicMock(return_value=1)

        fakeMainWindow = object()
        self.vs = VideoSwitcher(self.mockController, fakeMainWindow)

    def testSendInputsToOutputs(self):
        outputsGrid = self.vs.findChild(OutputsGrid)
        self.assertTrue(outputsGrid is not None)

        self.vs.btnCamera1.click()
        self.assertPreviewCalledFor(1)  # Camera 1 is previewed

        outputsGrid.btnChurch.click()
        self.main.sendInputToOutput.assert_called_with(1, 4)  # Camera 1 sent to output 4 (church)

        self.vs.btnCamera3.click()
        self.assertPreviewCalledFor(3)  # Camera 3 previewed
        outputsGrid.btnGallery.click()
        self.main.sendInputToOutput.assert_called_with(3, 6)  # Camera 3 sent to output 6 (gallery)
        outputsGrid.btnPCMix.click()
        self.preview.sendInputToOutput.assert_called_with(3, 2)  # Camera 3 sent to PC Mix

        self.vs.btnBlank.click()
        outputsGrid.btnAll.click()
        self.main.sendInputToOutput.assert_called_with(0, 0)  # Everything blanked

        self.extras.sendInputToOutput.reset_mock()
        self.vs.btnExtras.click()
        self.extras.sendInputToOutput.assert_not_called()  # main sw not involved and no input selected
        self.vs.extrasSwitcher.inputs.buttons()[4].click()  # Visuals PC video
        self.assertEqual("PC video", self.vs.btnExtras.text())
        self.extras.sendInputToOutput.assert_called_with(8, EXTRAS_OUTPUT_TO_PREVIEW)
        self.assertEqual(self.vs.extrasSwitcher.inputs.checkedButton(), self.vs.extrasSwitcher.inputs.buttons()[4])
        outputsGrid.btnAll.click()  # This one click should trigger two takes, one on each switcher
        self.extras.sendInputToOutput.assert_called_with(8, 1)
        self.main.sendInputToOutput.assert_called_with(5, 0)  # Extras to everywhere
        outputsGrid.updateOutputMappings({'Main': {0: 5}})
        self.assertEqual("PC video", outputsGrid.btnMonitor1.inputDisplay.text())
        self.main.sendInputToOutput.reset_mock()
        self.extras.sendInputToOutput.reset_mock()
        self.assertTrue(outputsGrid.isEnabled())
        self.assertTrue(outputsGrid.btnPCMix.isEnabled())
        outputsGrid.btnPCMix.click()
        self.assertTrue(outputsGrid.isEnabled())
        self.extras.sendInputToOutput.assert_called_with(8, 2)
        self.preview.sendInputToOutput.assert_called_with(6, 2)  # Extras to PC Mix

    def testCantSendPCMixToItself(self):
        outputsGrid = self.vs.findChild(OutputsGrid)

        self.vs.btnVisualsPC.click()
        self.assertPreviewCalledFor(6)
        self.main.sendInputToOutput.reset_mock()
        outputsGrid.btnPCMix.click()
        self.assertFalse(self.preview.sendInputToOutput.called)
        self.assertFalse(self.main.sendInputToOutput.called)
        self.assertFalse(outputsGrid.btnPCMix.isEnabled())

    def testCantBlankPCMix(self):
        outputsGrid = self.vs.findChild(OutputsGrid)

        self.vs.btnBlank.click()
        outputsGrid.btnPCMix.click()
        self.assertFalse(self.preview.sendInputToOutput.called)
        self.assertFalse(self.main.sendInputToOutput.called)
        self.assertFalse(outputsGrid.btnPCMix.isEnabled())

    def testKeyboardControls(self):
        QTest.keyClick(self.vs, Qt.Key_0)
        QTest.keyClick(self.vs, Qt.Key_Space)
        self.main.sendInputToOutput.assert_called_with(0, 0)

        QTest.keyClick(self.vs, Qt.Key_1)
        self.assertPreviewCalledFor(1)
        QTest.keyClick(self.vs, Qt.Key_Space)
        self.main.sendInputToOutput.assert_called_with(1, 0)

        QTest.keyClick(self.vs, Qt.Key_2)
        self.assertPreviewCalledFor(2)
        QTest.keyClick(self.vs, Qt.Key_Space)
        self.main.sendInputToOutput.assert_called_with(2, 0)

        QTest.keyClick(self.vs, Qt.Key_3)
        self.assertPreviewCalledFor(3)
        QTest.keyClick(self.vs, Qt.Key_Space)
        self.main.sendInputToOutput.assert_called_with(3, 0)

        QTest.keyClick(self.vs, Qt.Key_4)
        self.assertPreviewCalledFor(4)
        QTest.keyClick(self.vs, Qt.Key_Space)
        self.main.sendInputToOutput.assert_called_with(4, 0)

        self.extras.sendInputToOutput.reset_mock()
        QTest.keyClick(self.vs, Qt.Key_5)
        self.extras.sendInputToOutput.assert_not_called()  # main sw not involved and no input selected
        # Make sure there's an actual channel selected
        self.vs.extrasSwitcher.inputs.buttons()[3].click()
        self.assertEqual("Extras 4", self.vs.btnExtras.text())
        self.extras.sendInputToOutput.assert_called_with(4, EXTRAS_OUTPUT_TO_PREVIEW)
        QTest.keyClick(self.vs, Qt.Key_Space)
        self.main.sendInputToOutput.assert_called_with(5, 0)

        QTest.keyClick(self.vs, Qt.Key_6)
        self.assertPreviewCalledFor(6)
        QTest.keyClick(self.vs, Qt.Key_Space)
        self.main.sendInputToOutput.assert_called_with(6, 0)

        self.main.sendInputToOutput.reset_mock()
        self.preview.sendInputToOutput.reset_mock()
        QTest.keyClick(self.vs, Qt.Key_7)
        self.assertFalse(self.preview.sendInputToOutput.called)
        QTest.keyClick(self.vs, Qt.Key_Space)
        self.main.sendInputToOutput.assert_called_with(6, 0)  # which was the last valid input key pressed

    def testNotSendNullExtra(self):
        outputsGrid = self.vs.findChild(OutputsGrid)
        self.vs.btnExtras.click()
        self.assertIsNone(self.vs.extrasSwitcher.currentInput())
        self.assertFalse(outputsGrid.isEnabled())
        self.assertTrue(self.vs.extrasSwitcher.noInputWarning.isVisibleTo(self.vs.extrasSwitcher))

    def assertPreviewCalledFor(self, inputID):
        self.main.sendInputToOutput.assert_called_with(inputID, 1)
        return self.extras.sendInputToOutput.assert_called_with(EXTRAS_INPUT_FROM_MAIN, EXTRAS_OUTPUT_TO_PREVIEW)
Beispiel #4
0
    def __init__(self, controller):
        super(MainWindow, self).__init__()
        self.controller = controller

        self.setWindowTitle("av-control")
        self.resize(1024, 600)
        self.setWindowIcon(QIcon(":icons/video-display"))

        self.mainScreen = VideoSwitcher(controller, self)
        self.stack = QStackedWidget()
        self.stack.addWidget(self.mainScreen)

        outer = QWidget()
        mainLayout = QGridLayout()
        mainLayout.addWidget(self.stack, 0, 0, 1, 7)

        column = 0

        self.spc = SystemPowerWidget(controller, self)

        syspower = ExpandingButton()
        syspower.setText("Power")
        syspower.clicked.connect(self.showSystemPower)
        syspower.setIcon(QIcon(":icons/system-shutdown"))
        syspower.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon)
        mainLayout.addWidget(syspower, 1, column)
        column += 1

        self.bc = BlindsControl(controller["Blinds"], self)

        blinds = ExpandingButton()
        blinds.setText("Blinds")
        blinds.clicked.connect(lambda: self.showScreen(self.bc))
        blinds.setIcon(QIcon(":icons/blinds"))
        blinds.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon)
        mainLayout.addWidget(blinds, 1, column)
        column += 1

        self.sc = ProjectorScreensControl(controller["Screens"], self)

        screens = ExpandingButton()
        screens.setText("Screens")
        screens.clicked.connect(lambda: self.showScreen(self.sc))
        screens.setIcon(QIcon(":icons/screens"))
        screens.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon)
        mainLayout.addWidget(screens, 1, column)
        column += 1

        if controller.hasDevice("Lights"):
            self.lightsMenu = LightingControl(controller["Lights"], self)

            lights = ExpandingButton()
            lights.setText("Lights")
            lights.clicked.connect(lambda: self.showScreen(self.lightsMenu))
            lights.setIcon(QIcon(":icons/lightbulb_on"))
            lights.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon)
            mainLayout.addWidget(lights, 1, column)
            column += 1

        self.advMenu = AdvancedMenu(self.controller, self)

        adv = ExpandingButton()
        adv.setText("Advanced")
        adv.setIcon(QIcon(":icons/applications-system"))
        adv.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon)
        adv.clicked.connect(lambda: self.showScreen(self.advMenu))
        mainLayout.addWidget(adv, 1, column)
        column += 1

        for i in range(column):
            mainLayout.setColumnStretch(i, 1)

        tray = QHBoxLayout()
        tray.addWidget(Clock())
        tray.addWidget(SystemStatus(controller))
        mainLayout.addLayout(tray, 1, column)

        mainLayout.setRowStretch(0, 8)
        mainLayout.setRowStretch(1, 0)

        outer.setLayout(mainLayout)

        self.setCentralWidget(outer)

        self.pnd = PowerNotificationDialog(self)
        self.pnd.accepted.connect(self.hidePowerDialog)
Beispiel #5
0
    def __init__(self, controller, joystickAdapter=None):
        super(MainWindow, self).__init__()
        self.controller = controller

        self.setWindowTitle("av-control")
        self.resize(1024, 600)
        self.setWindowIcon(QIcon(":icons/video-display"))

        atem = controller['ATEM']
        self.switcherState = SwitcherState(atem)

        self.mainScreen = VideoSwitcher(controller, self, self.switcherState, joystickAdapter)

        # This is possibly a bad / too complicated idea...
        # self.mainScreen.setEnabled(self.switcherState.connected)
        # self.switcherState.connectionChanged.connect(self.mainScreen.setEnabled)

        self.stack = QStackedWidget()
        self.stack.addWidget(self.mainScreen)

        outer = QWidget()
        mainLayout = QGridLayout()
        mainLayout.addWidget(self.stack, 0, 0, 1, 7)

        column = 0

        self.spc = SystemPowerWidget(controller, self)

        syspower = ExpandingButton()
        syspower.setText("Power")
        syspower.clicked.connect(self.showSystemPower)
        syspower.setIcon(QIcon(":icons/system-shutdown"))
        syspower.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon)
        mainLayout.addWidget(syspower, 1, column)
        column += 1

        if controller.hasDevice("Blinds"):
            self.bc = BlindsControl(controller["Blinds"], self)

            blinds = ExpandingButton()
            blinds.setText("Blinds")
            blinds.clicked.connect(lambda: self.showScreen(self.bc))
            blinds.setIcon(QIcon(":icons/blinds"))
            blinds.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon)
            mainLayout.addWidget(blinds, 1, column)
            column += 1

        if controller.hasDevice("Lights"):
            self.lightsMenu = LightingControl(controller["Lights"], self)

            lights = ExpandingButton()
            lights.setText("Lights")
            lights.clicked.connect(lambda: self.showScreen(self.lightsMenu))
            lights.setIcon(QIcon(":icons/lightbulb_on"))
            lights.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon)
            mainLayout.addWidget(lights, 1, column)
            column += 1

        if controller.hasDevice("Recorder"):
            hyperdeck = controller['Recorder']
            self.hyperdeckState = HyperdeckState(hyperdeck)
            self.recorderScreen = RecorderControl(hyperdeck, atem, self.hyperdeckState, self)
            recorder = ExpandingButton()
            recorder.setText("Recorder")
            recorder.setIcon(QIcon(":icons/drive-optical"))
            recorder.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon)
            recorder.clicked.connect(lambda: self.showScreen(self.recorderScreen))
            mainLayout.addWidget(recorder, 1, column)
            column += 1

            def update_recorder_icon(transport):
                if 'status' in transport:
                    if transport['status'] == TransportState.RECORD:
                        recorder.setIcon(QIcon(":icons/media-record"))
                    elif transport['status'] == TransportState.PLAYING:
                        recorder.setIcon(QIcon(":icons/media-playback-start"))
                    else:
                        recorder.setIcon(QIcon(":icons/drive-optical"))
            self.hyperdeckState.transportChange.connect(update_recorder_icon)

        self.advMenu = AdvancedMenu(self.controller, self.switcherState.mixTransition, atem, self)

        adv = ExpandingButton()
        adv.setText("Advanced")
        adv.setIcon(QIcon(":icons/applications-system"))
        adv.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon)
        adv.clicked.connect(lambda: self.showScreen(self.advMenu))
        mainLayout.addWidget(adv, 1, column)
        column += 1

        for i in range(column):
            mainLayout.setColumnStretch(i, 1)

        tray = QHBoxLayout()
        tray.addWidget(Clock())
        tray.addWidget(SystemStatus(controller))
        mainLayout.addLayout(tray, 1, column)

        mainLayout.setRowStretch(0, 8)
        mainLayout.setRowStretch(1, 0)

        outer.setLayout(mainLayout)

        self.setCentralWidget(outer)

        self.pnd = PowerNotificationDialog(self)
        self.pnd.accepted.connect(self.hidePowerDialog)
Beispiel #6
0
class MainWindow(QMainWindow):

    def __init__(self, controller, joystickAdapter=None):
        super(MainWindow, self).__init__()
        self.controller = controller

        self.setWindowTitle("av-control")
        self.resize(1024, 600)
        self.setWindowIcon(QIcon(":icons/video-display"))

        atem = controller['ATEM']
        self.switcherState = SwitcherState(atem)

        self.mainScreen = VideoSwitcher(controller, self, self.switcherState, joystickAdapter)

        # This is possibly a bad / too complicated idea...
        # self.mainScreen.setEnabled(self.switcherState.connected)
        # self.switcherState.connectionChanged.connect(self.mainScreen.setEnabled)

        self.stack = QStackedWidget()
        self.stack.addWidget(self.mainScreen)

        outer = QWidget()
        mainLayout = QGridLayout()
        mainLayout.addWidget(self.stack, 0, 0, 1, 7)

        column = 0

        self.spc = SystemPowerWidget(controller, self)

        syspower = ExpandingButton()
        syspower.setText("Power")
        syspower.clicked.connect(self.showSystemPower)
        syspower.setIcon(QIcon(":icons/system-shutdown"))
        syspower.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon)
        mainLayout.addWidget(syspower, 1, column)
        column += 1

        if controller.hasDevice("Blinds"):
            self.bc = BlindsControl(controller["Blinds"], self)

            blinds = ExpandingButton()
            blinds.setText("Blinds")
            blinds.clicked.connect(lambda: self.showScreen(self.bc))
            blinds.setIcon(QIcon(":icons/blinds"))
            blinds.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon)
            mainLayout.addWidget(blinds, 1, column)
            column += 1

        if controller.hasDevice("Lights"):
            self.lightsMenu = LightingControl(controller["Lights"], self)

            lights = ExpandingButton()
            lights.setText("Lights")
            lights.clicked.connect(lambda: self.showScreen(self.lightsMenu))
            lights.setIcon(QIcon(":icons/lightbulb_on"))
            lights.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon)
            mainLayout.addWidget(lights, 1, column)
            column += 1

        if controller.hasDevice("Recorder"):
            hyperdeck = controller['Recorder']
            self.hyperdeckState = HyperdeckState(hyperdeck)
            self.recorderScreen = RecorderControl(hyperdeck, atem, self.hyperdeckState, self)
            recorder = ExpandingButton()
            recorder.setText("Recorder")
            recorder.setIcon(QIcon(":icons/drive-optical"))
            recorder.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon)
            recorder.clicked.connect(lambda: self.showScreen(self.recorderScreen))
            mainLayout.addWidget(recorder, 1, column)
            column += 1

            def update_recorder_icon(transport):
                if 'status' in transport:
                    if transport['status'] == TransportState.RECORD:
                        recorder.setIcon(QIcon(":icons/media-record"))
                    elif transport['status'] == TransportState.PLAYING:
                        recorder.setIcon(QIcon(":icons/media-playback-start"))
                    else:
                        recorder.setIcon(QIcon(":icons/drive-optical"))
            self.hyperdeckState.transportChange.connect(update_recorder_icon)

        self.advMenu = AdvancedMenu(self.controller, self.switcherState.mixTransition, atem, self)

        adv = ExpandingButton()
        adv.setText("Advanced")
        adv.setIcon(QIcon(":icons/applications-system"))
        adv.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon)
        adv.clicked.connect(lambda: self.showScreen(self.advMenu))
        mainLayout.addWidget(adv, 1, column)
        column += 1

        for i in range(column):
            mainLayout.setColumnStretch(i, 1)

        tray = QHBoxLayout()
        tray.addWidget(Clock())
        tray.addWidget(SystemStatus(controller))
        mainLayout.addLayout(tray, 1, column)

        mainLayout.setRowStretch(0, 8)
        mainLayout.setRowStretch(1, 0)

        outer.setLayout(mainLayout)

        self.setCentralWidget(outer)

        self.pnd = PowerNotificationDialog(self)
        self.pnd.accepted.connect(self.hidePowerDialog)

    def showScreen(self, screenWidget):
        if self.stack.currentWidget() == screenWidget:
            self.stepBack()
        else:
            self.stack.insertWidget(0, screenWidget)
            self.stack.setCurrentWidget(screenWidget)

    def showSystemPower(self):
        self.showScreen(self.spc)

    def stepBack(self):
        self.stack.removeWidget(self.stack.currentWidget())

    def errorBox(self, text):
        Dialogs.errorBox(text)

    def showPowerDialog(self, message):
        self.pnd.message = message
        self.pnd.exec_()

    def hidePowerDialog(self):
        self.pnd.close()
        if self.stack.currentWidget() == self.spc:
            self.stepBack()

    def updateOutputMappings(self, deviceID, mapping):
        self.mainScreen.updateOutputMappings({deviceID: mapping})

    def handleMessage(self, msgType, sourceDeviceID, data):
        if msgType == MessageTypes.SHOW_POWER_ON:
            self.showPowerDialog(StringConstants.poweringOn)
        elif msgType == MessageTypes.SHOW_POWER_OFF:
            self.showPowerDialog(StringConstants.poweringOff)
        elif msgType == MessageTypes.HIDE_POWER:
            self.hidePowerDialog()
        elif sourceDeviceID == "ATEM":
            self.switcherState.handleMessage(msgType, data)
        elif sourceDeviceID == "Recorder":
            self.hyperdeckState.handleMessage(msgType, data)