Esempio n. 1
0
class WinFilterList(QtCore.QObject):

    """Allow the user to select a filter to add to the filterchain"""
    onAddFilter = QtCore.Signal(object)

    def __init__(self, controller):
        super(WinFilterList, self).__init__()
        self.controller = controller
        self.shared_info = SharedInfo()
        self.shared_info.connect(SharedInfo.GLOBAL_FILTERCHAIN_EDIT_MODE,
                                 self._filterchain_edit_mode)
        self.shared_info.connect(SharedInfo.GLOBAL_FILTER, self.change_filter)
        self.ui = None
        self.dct_filter = None
        self.lst_filter_sort = []
        self.reload_ui()

    def _filterchain_edit_mode(self, value):
        is_edit = value
        self.ui.addFilterButton.setEnabled(bool(is_edit))

    def reload_ui(self):
        self.ui = get_ui(self)
        self.ui.addFilterButton.clicked.connect(self._add_filter)
        self.ui.reloadFilterButton.clicked.connect(self._reload_filter)
        self.ui.filterListWidget.doubleClicked.connect(self._add_filter)
        self.ui.filterListWidget.currentItemChanged.connect(
            self._selected_filter_changed)
        self.reload_list_filter(self.controller.get_filter_list())

    def reload_list_filter(self, dct_filter):
        self.dct_filter = dct_filter
        self.lst_filter_sort = sorted(dct_filter.keys())
        for name in self.lst_filter_sort:
            self.ui.filterListWidget.addItem(name)

    def change_filter(self, filter_name):
        # Need to remove junk info in filter_name
        if not filter_name:
            return
        pos = filter_name.rfind("-")
        if pos:
            filter_name = filter_name[:pos]
        index = self.lst_filter_sort.index(filter_name)
        if index >= 0:
            self.ui.filterListWidget.setCurrentRow(index)

    def _selected_filter_changed(self):
        filter_name = self.ui.filterListWidget.currentItem().text()
        self.ui.lbl_doc.setText(
            "Description: %s" % self.dct_filter[filter_name])

    def _add_filter(self):
        self.onAddFilter.emit(self.ui.filterListWidget.currentItem().text())

    def _reload_filter(self):
        filter_name = self.ui.filterListWidget.currentItem().text()
        self.controller.reload_filter(filter_name)
        self.shared_info.set(SharedInfo.GLOBAL_RELOAD_FILTER, filter_name)
Esempio n. 2
0
class WinFilterList(QtCore.QObject):
    """Allow the user to select a filter to add to the filterchain"""
    onAddFilter = QtCore.Signal(object)

    def __init__(self, controller):
        super(WinFilterList, self).__init__()
        self.controller = controller
        self.shared_info = SharedInfo()
        self.shared_info.connect(SharedInfo.GLOBAL_FILTERCHAIN_EDIT_MODE,
                                 self._filterchain_edit_mode)
        self.shared_info.connect(SharedInfo.GLOBAL_FILTER, self.change_filter)
        self.ui = None
        self.dct_filter = None
        self.lst_filter_sort = []
        self.reload_ui()

    def _filterchain_edit_mode(self, value):
        is_edit = value
        self.ui.addFilterButton.setEnabled(bool(is_edit))

    def reload_ui(self):
        self.ui = get_ui(self)
        self.ui.addFilterButton.clicked.connect(self._add_filter)
        self.ui.reloadFilterButton.clicked.connect(self._reload_filter)
        self.ui.filterListWidget.doubleClicked.connect(self._add_filter)
        self.ui.filterListWidget.currentItemChanged.connect(
            self._selected_filter_changed)
        self.reload_list_filter(self.controller.get_filter_list())

    def reload_list_filter(self, dct_filter):
        self.dct_filter = dct_filter
        self.lst_filter_sort = sorted(dct_filter.keys())
        for name in self.lst_filter_sort:
            self.ui.filterListWidget.addItem(name)

    def change_filter(self, filter_name):
        # Need to remove junk info in filter_name
        if not filter_name:
            return
        pos = filter_name.rfind("-")
        if pos:
            filter_name = filter_name[:pos]
        index = self.lst_filter_sort.index(filter_name)
        if index >= 0:
            self.ui.filterListWidget.setCurrentRow(index)

    def _selected_filter_changed(self):
        filter_name = self.ui.filterListWidget.currentItem().text()
        self.ui.lbl_doc.setText("Description: %s" %
                                self.dct_filter[filter_name])

    def _add_filter(self):
        self.onAddFilter.emit(self.ui.filterListWidget.currentItem().text())

    def _reload_filter(self):
        filter_name = self.ui.filterListWidget.currentItem().text()
        self.controller.reload_filter(filter_name)
        self.shared_info.set(SharedInfo.GLOBAL_RELOAD_FILTER, filter_name)
Esempio n. 3
0
class WinMedia(QtCore.QObject):
    def __init__(self, controller, subscriber):
        super(WinMedia, self).__init__()
        self.resource_icon_path = "SeaGoatVision/client/resource/img/"
        self.ui = None
        self.controller = controller
        self.subscriber = subscriber
        self.shared_info = SharedInfo()
        self.shared_info.connect(SharedInfo.GLOBAL_START_EXEC, self.set_info)

        self.is_recorded = False
        self.is_play = False
        self.record_icon = QIcon(self.resource_icon_path +
                                 "RecordVideoAction.png")
        self.save_record_icon = QIcon(self.resource_icon_path +
                                      "SaveServerImageAction.png")
        self.play_icon = QIcon(
            "/usr/share/icons/gnome/24x24/actions/player_play.png")
        self.pause_icon = QIcon(
            "/usr/share/icons/gnome/24x24/actions/player_pause.png")

        self.dct_media = None

        self.last_value_frame = 0
        self.max_frame = 0

        self.shared_info.connect(SharedInfo.GLOBAL_START_EXEC,
                                 self._start_execution)
        self.shared_info.connect(SharedInfo.GLOBAL_EXEC, self.change_execution)
        self.shared_info.connect(SharedInfo.GLOBAL_HIST_REC_PATH_MEDIA,
                                 self._change_hist_media_path)

        # TODO optimize starting thread.
        self.thread_player = PlayerFile(controller, self._get_actual_no_frame,
                                        self.set_slider_value)
        self.thread_player.start()
        self.reload_ui()

    def stop(self):
        if self.thread_player:
            self.thread_player.close()

    def reload_ui(self):
        self.ui = get_ui(self)

        self.ui.recordButton.clicked.connect(self.click_record_button)
        self.ui.cbMedia.currentIndexChanged.connect(self._change_media)
        self.ui.openDirButton.clicked.connect(self.open_directory)
        self.ui.openFileButton.clicked.connect(self.open_file)
        self.ui.btnplay.clicked.connect(self.play)
        self.ui.loopchb.clicked.connect(self.active_loop)
        self.ui.movieLineEdit.textChanged.connect(self._movie_changed)
        self.ui.slider_frame.valueChanged.connect(self._slider_value_change)
        self.ui.txtframe.returnPressed.connect(self._txt_frame_value_change)
        self.ui.spin_box_fps.valueChanged.connect(self._change_fps)
        self.ui.sliceButton.clicked.connect(self.click_slice_button)
        self.ui.cancelButton.clicked.connect(self.click_cancel_button)
        self.ui.cutButton.clicked.connect(self.click_cut_button)
        self.ui.cleanButton.clicked.connect(self.click_clean_button)

        self._set_record_icon()
        self._set_play_icon()
        self._update_media()

    def _update_media(self):
        self.ui.cbMedia.currentIndexChanged.disconnect(self._change_media)
        self.dct_media = self.controller.get_media_list()
        lst_media = sorted(self.dct_media.keys(), key=lambda x: x.lower())
        for media in lst_media:
            self.ui.cbMedia.addItem(media)
            # subscribe to notification
            self.subscriber.subscribe("media.%s" % media,
                                      self._subscribe_cb(media))
        self._change_media(after_update=True)
        self.ui.cbMedia.currentIndexChanged.connect(self._change_media)

        default_select_media = config.default_media_selected
        if default_select_media not in self.dct_media.keys():
            default_select_media = self.controller.get_default_media_name()
        self.last_selected_media = default_select_media
        self.select_media(default_select_media)

    def _subscribe_cb(self, media):
        def _cb(data):
            if self.ui.cbMedia.currentText() == media:
                fps = data.get("fps")
                if fps is not None:
                    self.ui.lblFPS.setText("%s" % fps)
                status = data.get("status")
                if status is not None:
                    self.ui.lblStatus.setText("%s" % status)

        return _cb

    def _change_media(self, index=-1, after_update=False):
        media_name = self.ui.cbMedia.currentText()
        frame_webcam = self.ui.frame_webcam
        frame_slice = self.ui.frame_slice
        frame_webcam.setVisible(False)
        frame_slice.setVisible(False)
        frame_video = self.ui.frame_video
        frame_video.setVisible(False)

        media_type = self.dct_media.get(media_name, None)
        if not media_type:
            self.shared_info.set(SharedInfo.GLOBAL_MEDIA, None)
            return
        if media_type == keys.get_media_type_video_name():
            frame_video.setVisible(True)
        elif media_type == keys.get_media_type_streaming_name():
            frame_webcam.setVisible(True)
            self.shared_info.set(SharedInfo.GLOBAL_PATH_MEDIA, None)
        self.shared_info.set(SharedInfo.GLOBAL_MEDIA, media_name)
        self.set_info()
        if not after_update:
            self.last_selected_media = media_name

    def _movie_changed(self):
        self.shared_info.set(SharedInfo.GLOBAL_PATH_MEDIA,
                             self.ui.movieLineEdit.text())

    def set_slider_value(self, value, force_value=False):
        last_value = self.ui.slider_frame.value()
        if last_value != value:
            self.ui.slider_frame.setValue(value)
        else:
            # force change value in video context
            self._slider_value_change(value)

    def _slider_value_change(self, value):
        self.ui.txtframe.setText(str(value))
        self._txt_frame_value_change()

    def _txt_frame_value_change(self):
        str_value = self.ui.txtframe.text()
        try:
            value = int(str_value)
        except BaseException:
            self.ui.txtframe.setText(str(self.last_value_frame))
            return
        if value < 1 or value > self.max_frame:
            self.ui.txtframe.setText(str(self.last_value_frame))
            return
        self.last_value_frame = value
        self.ui.txtframe.setText(str(value))
        self.set_frame_video(value)

    def _change_fps(self, value):
        self.thread_player.set_fps(value)

    def _get_actual_no_frame(self):
        return self.ui.slider_frame.value()

    def _start_execution(self, value=None):
        if not value or not isinstance(value, dict):
            return
        media_name = value.get("media")
        if media_name == keys.get_media_file_video_name():
            self.set_slider_value(1)
            self.is_play = False
            self.play()

    def click_record_button(self):
        if not self.is_recorded:
            path = self.ui.txt_name_record.text()
            if not path:
                path = None
            if self.ui.rbn_avi.isChecked():
                format_rec = keys.get_key_format_avi()
            else:
                format_rec = keys.get_key_format_png()
            options = {
                "compress": self.ui.sb_compress.value(),
                "format": format_rec
            }
            if not self.controller.start_record(self.ui.cbMedia.currentText(),
                                                path, options):
                # TODO improve error message
                logger.error("Trying start record...")
            else:
                self.is_recorded = True
        else:
            if not self.controller.stop_record(self.ui.cbMedia.currentText()):
                logger.error("Trying stop record...")
            self.is_recorded = False
        self.set_info()

    def open_directory(self):
        filename = QFileDialog.getExistingDirectory()
        if len(filename) > 0:
            self.ui.movieLineEdit.setText(filename)

    def open_file(self):
        filename = QFileDialog.getOpenFileName()[0]
        if len(filename) > 0:
            self.ui.movieLineEdit.setText(filename)

    def set_frame_video(self, value):
        media_name = self.shared_info.get(SharedInfo.GLOBAL_MEDIA)
        if not media_name:
            return
        self.controller.cmd_to_media(media_name, keys.get_key_media_frame(),
                                     value - 1)

    def set_info(self, value=None):
        # Ignore the value
        media_name = self.shared_info.get(SharedInfo.GLOBAL_MEDIA)
        if not media_name:
            return
        info = self.controller.get_info_media(media_name)
        if not info:
            logger.warning("WinMedia: info is empty from get_info_media.")
        self.max_frame = info.get("nb_frame", -1)
        self.ui.lblframe.setText("/%s" % self.max_frame)
        self.ui.txtframe.setText(str(self.last_value_frame))
        self.ui.slider_frame.setMinimum(1)
        self.ui.slider_frame.setMaximum(self.max_frame)
        self.thread_player.set_max_frame(self.max_frame)
        self.ui.lblFPS.setText("%s" % info.get("fps", "-1"))
        self.ui.lblStatus.setText("%s" % info.get("status", "None"))
        record_name = info.get("record_file_name", "")
        self.ui.txt_name_record.setText("%s" % record_name)
        self.is_recorded = bool(record_name)
        self._set_record_icon()

    def play(self):
        # media_name = self.ui.cbMedia.currentText()
        if self.is_play:
            # if self.controller.cmd_to_media(media_name,
            # keys.get_key_media_play()):
            self.thread_player.set_pause(True)
            self.is_play = False
            self._set_play_icon()
        else:
            # if self.controller.cmd_to_media(media_name,
            # keys.get_key_media_pause()):
            self.thread_player.set_pause(False)
            self.is_play = True
            self._set_play_icon()

    def active_loop(self):
        media_name = self.ui.cbMedia.currentText()
        self.controller.cmd_to_media(media_name, keys.get_key_media_loop(),
                                     None)

    def _set_play_icon(self):
        if not self.is_play:
            self.ui.btnplay.setIcon(self.play_icon)
        else:
            self.ui.btnplay.setIcon(self.pause_icon)

    def _set_record_icon(self):
        self.ui.sb_compress.setEnabled(not self.is_recorded)
        self.ui.rbn_avi.setEnabled(not self.is_recorded)
        self.ui.rbn_png.setEnabled(not self.is_recorded)
        self.ui.txt_name_record.setReadOnly(self.is_recorded)
        if not self.is_recorded:
            self.ui.recordButton.setIcon(self.record_icon)
        else:
            self.ui.recordButton.setIcon(self.save_record_icon)

    def get_file_path(self):
        item_cbmedia = self.ui.cbMedia.currentText()
        media_type = self.dct_media.get(item_cbmedia, None)
        if media_type != keys.get_media_type_video_name():
            return
        return self.ui.movieLineEdit.text()

    def change_execution(self, exec_info):
        media_name = exec_info[2]
        self.select_media(media_name)

    def select_media(self, media_name):
        # find index
        index = self.ui.cbMedia.findText(media_name)
        if index < 0:
            return False
        # TODO Need to re-send signal if it's the same media? Maybe not
        # necessary
        self.ui.cbMedia.setCurrentIndex(index)
        return True

    def _change_hist_media_path(self, value=None):
        filename = self.shared_info.get(SharedInfo.GLOBAL_HIST_REC_PATH_MEDIA)
        if len(filename) > 0:
            self.ui.movieLineEdit.setText(filename)

    def click_slice_button(self):
        self.ui.frame_slice.setVisible(True)

    def click_cancel_button(self):
        self.ui.frame_slice.setVisible(False)

    def click_cut_button(self):
        begin = self.ui.beginSpinBox.value()
        end = self.ui.endSpinBox.value()
        file_name = self.ui.movieLineEdit.text()
        cut_file_name = self.ui.nameLineEdit.text()
        self.controller.cut_video(file_name, begin, end, cut_file_name)
        self.ui.frame_slice.setVisible(False)

    def click_clean_button(self):
        self.ui.beginSpinBox.setValue(0)
        self.ui.endSpinBox.setValue(0)
        self.ui.nameLineEdit.setText("")
Esempio n. 4
0
class WinFilterChain(QtCore.QObject):
    """Main window
    Allow the user to create, edit and test filter chains
    """

    def __init__(self, controller):
        super(WinFilterChain, self).__init__()

        self.controller = controller
        self.last_row_fc_select = 0
        self.shared_info = SharedInfo()
        self.ui = None
        self.lock_preview = False
        self.edit_mode = False
        self.mode_new = False

        self.reload_ui()

    def reload_ui(self):
        self.ui = get_ui(self)
        self.ui.filterListWidget.currentItemChanged.connect(self.on_selected_filter_changed)
        self.ui.filterchainListWidget.currentItemChanged.connect(self.on_selected_filter_chain_changed)
        self.ui.uploadButton.clicked.connect(self.upload)
        self.ui.editButton.clicked.connect(self.edit)
        self.ui.saveButton.clicked.connect(self.save)
        self.ui.cancelButton.clicked.connect(self.cancel)
        self.ui.deleteButton.clicked.connect(self.delete)
        self.ui.copyButton.clicked.connect(self.copy)
        self.ui.newButton.clicked.connect(self.new)
        self.ui.upButton.clicked.connect(self.move_up_selected_filter)
        self.ui.downButton.clicked.connect(self.move_down_selected_filter)
        self.ui.removeButton.clicked.connect(self.remove_filter)

        self.update_filter_chain_list()
        self.ui.frame_filter_edit.setEnabled(False)
        self.lock_preview = False

        self.edit_mode = False
        self.mode_new = False
        self._mode_edit(False)
        self._list_filterchain_is_selected(False)

        self.shared_info.connect(SharedInfo.GLOBAL_MEDIA, self._update_media_default_edit)
        self.shared_info.connect(SharedInfo.GLOBAL_EXEC, self.select_filterchain)

    #
    # SIGNAL  ###############################
    #
    def _update_media_default_edit(self, value):
        if self.edit_mode and not self.mode_new:
            return
        txt = ""
        if value != keys.get_media_file_video_name():
            txt = value
        self.ui.media_default_edit.setText(txt)

    def add_filter(self, filter_name):
        if not self.edit_mode:
            return
        if filter_name:
            self.ui.filterListWidget.addItem(filter_name)

    def remove_filter(self):
        self.ui.filterListWidget.takeItem(self.ui.filterListWidget.currentRow())

    def upload(self):
        # open a file, copy the contain to the controller
        str_ext = ".filterchain"
        filename = QtGui.QFileDialog().getOpenFileName(filter="*%s" % str_ext)[0]
        if filename:
            fc_name = filename[filename.rfind("/") + 1 : -len(str_ext)]
            if self._is_unique_filterchain_name(fc_name):
                f = open(filename, "r")
                if f:
                    s_contain = "".join(f.readlines())
                    # if success, add the filter name on list widget
                    if self.controller.upload_filterchain(fc_name, s_contain):
                        self.ui.filterchainListWidget.addItem(fc_name)
                else:
                    logger.error("Can't open the file : %s" % filename)
            else:
                logger.error("This filtername already exist : %s" % fc_name)

    def edit(self):
        self.last_row_fc_select = self.ui.filterchainListWidget.currentRow()
        self._mode_edit(True)

    def cancel(self):
        self.update_filter_chain_list()
        self._list_filterchain_is_selected(False)
        self.ui.filterchainListWidget.setCurrentRow(self.last_row_fc_select)
        self._mode_edit(False)
        logger.info("Cancel changement.")

    def save(self):
        new_name = self.ui.filterchainEdit.text()
        old_name = self.ui.filterchainListWidget.currentItem().text()
        # validate new name
        new_name = new_name.strip()
        if new_name != old_name and not self._is_unique_filterchain_name(new_name):
            msg = 'The filtername "%s" already exist.' % new_name
            QtGui.QMessageBox.warning(
                self.ui.centralwidget, "Wrong name", msg, QtGui.QMessageBox.Ok, QtGui.QMessageBox.Ok
            )
            return

        self.ui.filterchainEdit.setText(new_name)

        lst_filter = self._get_list_string_qlist(self.ui.filterListWidget)
        default_media = self.ui.media_default_edit.text()

        if self.controller.modify_filterchain(old_name, new_name, lst_filter, default_media):
            self.ui.filterchainListWidget.currentItem().setText(new_name)
            logger.info("Editing success on filterchain %s" % new_name)
            self._mode_edit(False)
            self.update_filter_list()
            self.on_selected_filter_changed()
            # update actual filterchain
            self.shared_info.set(SharedInfo.GLOBAL_FILTERCHAIN, new_name)
        else:
            logger.error("Saving edit on filterchain %s." % new_name)
            self.cancel()

    def delete(self):
        self._mode_edit(True)
        no_line = self.ui.filterchainListWidget.currentRow()
        if no_line >= 0:
            filterchain_name = self.ui.filterchainListWidget.item(no_line).text()
            # security ask
            response = QtGui.QMessageBox.question(
                self.ui.centralwidget,
                "Delete filterchain",
                'Do you want to delete filterchain "%s"' % filterchain_name,
                QtGui.QMessageBox.Yes | QtGui.QMessageBox.No,
                QtGui.QMessageBox.No,
            )
            if response == QtGui.QMessageBox.Yes:
                # delete the filterchain
                self.controller.delete_filterchain(filterchain_name)
                self.ui.filterchainListWidget.takeItem(no_line)
                logger.info("Delete %s" % filterchain_name)
            else:
                logger.info("Cancel delete %s" % filterchain_name)
        self._mode_edit(False)
        # update the widget
        self.on_selected_filter_chain_changed()

    def copy(self):
        self.edit()

        # we copy the selected filterchain
        no_row = self.ui.filterchainListWidget.currentRow()
        filterchain_name_temp = self.ui.filterchainListWidget.item(no_row).text() + " - copy"

        # find name of copy filterchain
        i = 1
        filterchain_name = filterchain_name_temp
        while not self._is_unique_filterchain_name(filterchain_name):
            i += 1
            filterchain_name = filterchain_name_temp + "- %s" % i

        # add copy line
        lst_filter_str = self._get_list_string_qlist(self.ui.filterListWidget)
        self.ui.filterchainListWidget.insertItem(no_row + 1, filterchain_name)
        self.ui.filterchainListWidget.setCurrentRow(no_row + 1)
        self.ui.filterchainEdit.setText(filterchain_name)

        for item in lst_filter_str:
            self.ui.filterListWidget.addItem(item)

    def new(self):
        self.mode_new = True
        self.edit()

        # find name of new filterchain
        i = 1
        filterchain_name = "new"
        while not self._is_unique_filterchain_name(filterchain_name):
            i += 1
            filterchain_name = "new-%s" % i

        # add new line
        self.ui.filterchainListWidget.addItem(filterchain_name)
        self.ui.filterchainListWidget.setCurrentRow(self.ui.filterchainListWidget.count() - 1)
        self.ui.filterchainEdit.setText(filterchain_name)

        self.ui.filterListWidget.clear()

    def update_filter_list(self, fc_name=None):
        if not fc_name:
            fc_name = self._get_selected_filterchain_name()
        self.ui.filterListWidget.clear()

        if fc_name == keys.get_empty_filterchain_name():
            return

        info = self.controller.get_filterchain_info(fc_name)
        lst_filter = info.get("filters", None)
        if not lst_filter:
            logger.warning("Recieve empty filter list from filterchain %s" % fc_name)
            return
        for o_filter in lst_filter:
            name = o_filter.get("name", "")
            if name == keys.get_empty_filter_name():
                continue
            self.ui.filterListWidget.addItem(name)
        default_media = info.get("default_media", "")
        self.ui.media_default_edit.setText(default_media)

    def update_filter_chain_list(self):
        self.ui.filterchainListWidget.clear()
        self.ui.filterListWidget.clear()
        self.ui.filterchainEdit.clear()
        lst_filterchain = sorted(self.controller.get_filterchain_list(), key=lambda x: x.get("name").lower())
        for filterchain in lst_filterchain:
            self.ui.filterchainListWidget.addItem(filterchain.get("name"))
        self.ui.filterchainListWidget.addItem(keys.get_empty_filterchain_name())

    def move_up_selected_filter(self):
        self._move_current_item_on_qtlist(self.ui.filterListWidget, -1)

    def move_down_selected_filter(self):
        self._move_current_item_on_qtlist(self.ui.filterListWidget, 1)

    def on_selected_filter_changed(self):
        filter_name = self._get_selected_filter_name()
        self.ui.frame_filter_edit.setEnabled(filter_name is not None)
        if filter_name:
            self.shared_info.set(SharedInfo.GLOBAL_FILTER, filter_name)
        else:
            self.shared_info.set(SharedInfo.GLOBAL_FILTER, None)

    def on_selected_filter_chain_changed(self):
        if self.edit_mode:
            return
        filterchain_name = self._get_selected_filterchain_name()
        if filterchain_name:
            # set the filters section
            self.ui.filterchainEdit.setText(filterchain_name)
            self.update_filter_list(filterchain_name)
            self._list_filterchain_is_selected(True)

            filterchain_name = self._get_selected_filterchain_name()

            # Exception, don't edit or delete special empty filterchain
            self.ui.deleteButton.setEnabled(filterchain_name != keys.get_empty_filterchain_name())
            self.ui.editButton.setEnabled(filterchain_name != keys.get_empty_filterchain_name())
            self.shared_info.set(SharedInfo.GLOBAL_FILTERCHAIN, filterchain_name)

            self.ui.filterListWidget.setCurrentRow(0)
        else:
            self._list_filterchain_is_selected(False)
            self.shared_info.set(SharedInfo.GLOBAL_FILTERCHAIN, None)

    def get_filter_list(self):
        return self._get_list_string_qlist(self.ui.filterListWidget)

    def select_filterchain(self, exec_info):
        filterchain_name = exec_info[1]
        items = self.ui.filterchainListWidget.findItems(filterchain_name, QtCore.Qt.MatchExactly)
        if not items:
            return
        self.ui.filterchainListWidget.setCurrentItem(items[0])
        if not self.ui.filterListWidget.currentRow():
            self.on_selected_filter_changed()
        else:
            self.ui.filterListWidget.setCurrentRow(0)

    #
    # PRIVATE FUNCTION  ############################
    #

    def _is_unique_filterchain_name(self, filterchain_name):
        for noLine in range(self.ui.filterchainListWidget.count()):
            if self.ui.filterchainListWidget.item(noLine).text() == filterchain_name:
                return False
        return True

    def _get_selected_filterchain_name(self):
        return self._get_selected_list(self.ui.filterchainListWidget)

    def _get_selected_filter_name(self):
        return self._get_selected_list(self.ui.filterListWidget)

    @staticmethod
    def _get_selected_list(ui_list):
        no_line = ui_list.currentRow()
        if no_line >= 0:
            return ui_list.item(no_line).text()
        return

    def _mode_edit(self, status=True):
        self.edit_mode = status
        self.ui.frame_editing.setVisible(status)
        self.ui.frame_editing_2.setVisible(status)
        self.ui.frame_filter_edit.setVisible(status)
        self.ui.frame_edit.setEnabled(not status)
        self.ui.filterchainEdit.setReadOnly(not status)
        self.ui.filterchainListWidget.setEnabled(not status)
        self.shared_info.set(SharedInfo.GLOBAL_FILTERCHAIN_EDIT_MODE, status)
        if status:
            self.ui.filterchainEdit.setFocus()
        else:
            self.mode_new = False

    def _list_filterchain_is_selected(self, is_selected=True):
        self.ui.editButton.setEnabled(is_selected)
        self.ui.copyButton.setEnabled(is_selected)
        self.ui.deleteButton.setEnabled(is_selected)

    @staticmethod
    def _get_list_string_qlist(ui):
        return [ui.item(no).text() for no in range(ui.count())]

    @staticmethod
    def _move_current_item_on_qtlist(ui, nb_line):
        # take the action if nbLine is different of 0 and the limit is correct
        if nb_line:
            no_row = ui.currentRow()
            new_no_row = no_row + nb_line
            if 0 <= new_no_row < ui.count():
                # remove and add to move the item
                item = ui.takeItem(no_row)
                ui.insertItem(new_no_row, item)
                ui.setCurrentRow(new_no_row)
Esempio n. 5
0
class WinExecution(QtCore.QObject):
    onPreviewClick = QtCore.Signal(object, object, object)

    def __init__(self, controller, subscriber):
        super(WinExecution, self).__init__()
        self.controller = controller
        self.subscriber = subscriber
        self.shared_info = SharedInfo()

        self.mode_edit = False
        self.last_index = 0

        self.ui = None
        self.reload_ui()

        self.shared_info.connect(SharedInfo.GLOBAL_MEDIA, self._change_media)
        self.shared_info.connect(SharedInfo.GLOBAL_FILTERCHAIN,
                                 self._change_filterchain)
        self.shared_info.connect(SharedInfo.GLOBAL_HIST_REC_PATH_MEDIA,
                                 self._change_media_path)

        self.subscriber.subscribe(keys.get_key_execution_list(),
                                  self.update_execution_list)

    def reload_ui(self):
        self.ui = get_ui(self)

        self.ui.newButton.clicked.connect(self.new)
        self.ui.cancelButton.clicked.connect(self.cancel)
        self.ui.executeButton.clicked.connect(self.execute)
        self.ui.previewButton.clicked.connect(self.preview)
        self.ui.stopButton.clicked.connect(self.stop)
        self.ui.lstExecution.currentItemChanged.connect(
            self._on_selected_lst_execution_change)
        self.ui.lstExecution.itemClicked.connect(self._lst_execution_clicked)

        self._update_execution_list()

    def preview(self):
        # feature, if not into edit mode, we are create a new execution
        if not self.mode_edit:
            if not self.ui.lstExecution.count():
                self._mode_edit(True)
            execution_name = self.ui.txtExecution.text()
            if not execution_name:
                # this case is when no selected item in the list, so select the
                # first and restart
                self.ui.lstExecution.setCurrentRow(0)
                self.preview()
                # and select the associated filterchain
                self._lst_execution_clicked()
                return
        else:
            execution_name = self.ui.txtExecution.text()

        media_name = self.ui.txtMedia.text()
        filterchain_name = self.ui.txtFilterchain.text()
        first_filterchain_name = filterchain_name
        if not filterchain_name:
            filterchain_name = keys.get_empty_filterchain_name()
        if self.mode_edit or not first_filterchain_name:
            if not self._execute(execution_name, media_name, filterchain_name):
                return
            else:
                self._lst_execution_clicked()
        self.onPreviewClick.emit(execution_name, media_name, filterchain_name)

    def execute(self):
        execution_name = self.ui.txtExecution.text()
        media_name = self.ui.txtMedia.text()
        filterchain_name = self.ui.txtFilterchain.text()
        self._execute(execution_name, media_name, filterchain_name)

    def stop(self):
        # remove an execution
        no_line = self.ui.lstExecution.currentRow()
        if no_line >= 0:
            execution_name = self.ui.txtExecution.text()
            self.controller.stop_filterchain_execution(execution_name)
            self._enable_stop_button(False)

    def new(self):
        self._mode_edit(True)

    def cancel(self):
        self._mode_edit(False)
        self._on_selected_lst_execution_change()

    #
    # PRIVATE FUNCTION  ############################
    #
    def _lst_execution_clicked(self):
        execution_name = self.ui.txtExecution.text()
        filterchain_name = self.ui.txtFilterchain.text()
        media_name = self.ui.txtMedia.text()
        self.shared_info.set(SharedInfo.GLOBAL_EXEC,
                             (execution_name, filterchain_name, media_name))

    def _on_selected_lst_execution_change(self):
        execution = self._get_selected_list(self.ui.lstExecution)
        if execution:
            self.ui.previewButton.setEnabled(True)
            self.ui.stopButton.setEnabled(True)
        else:
            self.ui.stopButton.setEnabled(False)
            self.ui.txtFilterchain.setText("")
            self.ui.txtMedia.setText("")
            self.ui.txtExecution.setText("")
            return
        self.ui.txtExecution.setText(execution)
        exec_info = self.controller.get_execution_info(execution)
        if not exec_info:
            logger.error(
                "WinExecution Internal sync error with execution info :(")
            return
        self.ui.txtFilterchain.setText(exec_info.get("filterchain"))
        self.ui.txtMedia.setText(exec_info.get("media"))

    def update_execution_list(self, data):
        operator = data[0]
        execution_name = data[1:]
        if operator == "+":
            self.ui.lstExecution.addItem(execution_name)
            self.ui.lstExecution.setCurrentRow(
                self.ui.lstExecution.count() - 1)
        elif operator == "-":
            self.shared_info.set(SharedInfo.GLOBAL_CLOSE_EXEC, execution_name)
            # more easy to update all, like that, the client is protected by
            # modification
            for row in range(self.ui.lstExecution.count()):
                item = self.ui.lstExecution.item(row)
                if item and item.text() == execution_name:
                    self.ui.lstExecution.takeItem(row)
                    break
            self._clear_form(True)
        else:
            logger.warning("Error in update_execution_list, wrong operator : \
            %s" % operator)

    def _update_execution_list(self):
        self.mode_edit = False
        self._mode_edit(self.mode_edit)

        self.last_index += 1
        self.ui.lstExecution.clear()
        exec_list = self.controller.get_execution_list()
        for execution_name in exec_list:
            self.ui.lstExecution.addItem(execution_name)

    @staticmethod
    def _get_selected_list(ui_list):
        no_line = ui_list.currentRow()
        if no_line >= 0:
            return ui_list.item(no_line).text()
        return

    def _is_unique_execution_name(self, execution_name):
        for noLine in range(self.ui.lstExecution.count()):
            if self.ui.lstExecution.item(noLine).text() == execution_name:
                return False
        return True

    def _execute(self, execution_name, media_name, filterchain_name):
        if not self._is_unique_execution_name(execution_name):
            QtGui.QMessageBox.warning(self.ui.centralwidget,
                                      "Wrong name",
                                      "The execution name \"%s\" already \
                                      exist." % execution_name,
                                      QtGui.QMessageBox.Ok,
                                      QtGui.QMessageBox.Ok)
            return False
        file_name = self.shared_info.get(SharedInfo.GLOBAL_PATH_MEDIA)
        is_client_manager = media_name == keys.get_media_file_video_name()
        status = self.controller.start_filterchain_execution(
            execution_name,
            media_name,
            filterchain_name,
            file_name,
            is_client_manager
        )
        if not status:
            self.cancel()
            return False
        self._mode_edit(False)
        exec_info = {"media": media_name,
                     "execution_name": execution_name,
                     "filterchain_name": filterchain_name,
                     "file_name": file_name}
        self.shared_info.set(SharedInfo.GLOBAL_START_EXEC, exec_info)
        self._lst_execution_clicked()
        return True

    def _mode_edit(self, mode_edit):
        self.mode_edit = mode_edit
        self.ui.frameEdit.setVisible(mode_edit)
        self._clear_form(mode_edit)
        self.ui.txtExecution.setReadOnly(not mode_edit)
        self.ui.newButton.setEnabled(not mode_edit)
        self._enable_stop_button(mode_edit)
        self.ui.lstExecution.setEnabled(not mode_edit)
        if mode_edit:
            filterchain_name = self.shared_info.get(
                SharedInfo.GLOBAL_FILTERCHAIN)
            if filterchain_name:
                self.ui.txtFilterchain.setText(filterchain_name)
            self.last_index += 1
            self.ui.txtExecution.setText("Execution-%d" % self.last_index)
            media_name = self.shared_info.get(SharedInfo.GLOBAL_MEDIA)
            if media_name:
                self.ui.txtMedia.setText(media_name)

    def _enable_stop_button(self, mode_edit):
        self.ui.stopButton.setEnabled(
            bool(not mode_edit and self.ui.lstExecution.count()))

    def _get_selected_execution_name(self):
        no_line = self.ui.lstExecution.currentRow()
        if no_line >= 0:
            return self.ui.lstExecution.item(no_line).text()
        return

    def _clear_form(self, mode_edit):
        if mode_edit:
            self.ui.txtExecution.clear()
            self.ui.txtMedia.clear()
            self.ui.txtFilterchain.clear()

    def _change_media(self, value=None):
        # Ignore the value
        if self.mode_edit:
            media_name = self.shared_info.get(SharedInfo.GLOBAL_MEDIA)
            if media_name:
                self.ui.txtMedia.setText(media_name)

    def _change_filterchain(self, value=None):
        # Ignore the value
        if self.mode_edit:
            filterchain_name = self.shared_info.get(
                SharedInfo.GLOBAL_FILTERCHAIN)
            if filterchain_name:
                self.ui.txtFilterchain.setText(filterchain_name)

    def _change_media_path(self, value=None):
        # TODO validate if not another execution is created with same argument
        if self.ui.newButton.isEnabled():
            self.new()
        self.ui.txtMedia.setText(keys.get_media_file_video_name())
        if self.ui.previewButton.isEnabled():
            self.preview()
Esempio n. 6
0
class WinViewer(QtGui.QDockWidget):
    """Show the media after being processed by the filter chain.
    The window receives a filter in its constructor.
    This is the last executed filter on the media.
    """

    newImage = QtCore.Signal(QtGui.QImage)
    closePreview = QtCore.Signal(object)

    def __init__(self, controller, subscriber, execution_name, media_name,
                 filterchain_name, host, uid):
        super(WinViewer, self).__init__()
        self.host = host
        self.port = 5030
        self.shared_info = SharedInfo()

        self.controller = controller
        self.subscriber = subscriber
        self.execution_name = execution_name
        self.uid = uid
        self.filterchain_name = filterchain_name
        self.media_name = media_name
        self.is_turn_off = False
        self.execution_stopped = False

        self.ui = None
        self.actual_filter = None
        self.size = 1
        self.thread_output = None
        self.last_output = ""
        self.last_second_fps = None
        self.fps_count = 0
        self.light_observer = None

        self.shared_info.connect(SharedInfo.GLOBAL_CLOSE_EXEC,
                                 self.update_execution)

        self.reload_ui()
        self.qhlayout_light = self.ui.qhboxlayout_2
        self.light_observer = self._get_light_observer()

        if self.controller.add_image_observer(self.update_image,
                                              execution_name,
                                              self.actual_filter):
            self.__add_output_observer()
            self.subscriber.subscribe("media.%s" % self.media_name,
                                      self.update_fps)
        self.light_observer.start()

    def reload_ui(self):
        self.ui = get_ui(self)
        self.ui.lbl_media_name.setText(self.media_name)
        self.newImage.connect(self.set_pixmap)
        self.ui.filterComboBox.currentIndexChanged.connect(self._change_filter)
        self.ui.closeButton.clicked.connect(self.__close)
        self.ui.sizeComboBox.currentIndexChanged[str].connect(
            self.set_image_scale)

        self._update_filters()
        self.actual_filter = self.ui.filterComboBox.currentText()
        self.ui.lbl_exec.setText(self.execution_name)

    def closeEvent(self):
        # this is fake closeEvent, it's called by button close with signal
        if self.is_turn_off:
            return
        if not self.execution_stopped and self.actual_filter:
            self.controller.remove_image_observer(
                self.update_image,
                self.execution_name,
                self.actual_filter)
            self.controller.remove_output_observer(self.execution_name)
        if self.thread_output:
            self.thread_output.stop()
        self.subscriber.desubscribe(self.media_name, self.update_fps)
        if self.light_observer:
            self.light_observer.stop()
        logger.info("WinViewer %s quit." % self.execution_name)

    #
    # PRIVATE FUNCTION  ############################
    #
    def _get_light_observer(self):
        # call me just one time
        light_widget = LightWidget()
        size = self.qhlayout_light.minimumSize()
        min_size = min(size.width(), size.height())
        light_widget.setGeometry(0, 0, min_size, min_size)

        self.ui.qhboxlayout_2.addWidget(light_widget)
        return LightObserver(light_widget)

    def __close(self):
        self.closePreview.emit(self.uid)

    def __add_output_observer(self):
        self.thread_output = ListenOutput(
            self.update_log,
            self.host,
            self.port)
        self.thread_output.start()
        # TODO fait un thread de client dude
        self.controller.add_output_observer(self.execution_name)

    def _update_filters(self):
        self.ui.filterComboBox.clear()
        info = self.controller.get_filterchain_info(self.filterchain_name)
        if not info:
            logger.error("Missing info from get_filterchain_info.")
            return
        lst_filter = info.get("filters", None)
        if not lst_filter:
            logger.warning(
                "Recieve empty filter list from filterchain %s" %
                self.filterchain_name)
            return
        for sFilter in lst_filter:
            self.ui.filterComboBox.addItem(sFilter.get("name", ""))
        self.ui.filterComboBox.setCurrentIndex(
            self.ui.filterComboBox.count() - 1)

    def _change_filter(self):
        if self.actual_filter:
            filter_name = self.ui.filterComboBox.currentText()
            self.controller.set_image_observer(
                self.update_image,
                self.execution_name,
                self.actual_filter,
                filter_name)
            self.actual_filter = filter_name

    def update_log(self, data):
        data = str(data).strip()
        logger.info("Qt output exec %s - %s" % (self.execution_name, data))

    def update_fps(self, data):
        if type(data) is not dict:
            return
        fps = data.get("fps")
        if fps is not None:
            self.ui.lbl_fps.setText("%s" % fps)

    def update_image(self, image):
        self.light_observer.active_light()
        # fps
        actual_time = time.time()
        if self.last_second_fps is None:
            # Initiate fps
            self.last_second_fps = actual_time
            self.fps_count = 1
        elif actual_time - self.last_second_fps > 1.0:
            self.ui.lbl_stream_fps.setText("%d" % int(self.fps_count))
            # new set
            self.last_second_fps = actual_time
            self.fps_count = 1
        else:
            self.fps_count += 1

        try:
            self.numpy_to_qimage(image)
        except BaseException as e:
            log.printerror_stacktrace(logger, e, check_duplicate=True)

    def set_pixmap(self, img):
        pix = QtGui.QPixmap.fromImage(img)
        self.ui.imageLabel.setPixmap(pix)

    def numpy_to_qimage(self, image):
        img = Image.fromarray(image)
        buff = StringIO.StringIO()
        img.save(buff, 'ppm')
        data = buff.getvalue()
        buff.close()
        qimage = QtGui.QImage.fromData(data)
        if self.size != 1.0:
            shape = image.shape
            qimage = qimage.scaled(shape[1] * self.size, shape[0] * self.size)
        self.newImage.emit(qimage)

    def set_image_scale(self, text_size):
        text_size = text_size[:-1]
        self.size = float(text_size) / 100

    def update_execution(self, execution_name):
        if execution_name == self.execution_name:
            self.execution_stopped = True
            if self.light_observer:
                self.light_observer.turn_off()
            self.closeEvent()
            self.is_turn_off = True
Esempio n. 7
0
class WinMedia(QtCore.QObject):
    def __init__(self, controller, subscriber):
        super(WinMedia, self).__init__()
        self.resource_icon_path = "SeaGoatVision/client/resource/img/"
        self.ui = None
        self.controller = controller
        self.subscriber = subscriber
        self.shared_info = SharedInfo()
        self.shared_info.connect(SharedInfo.GLOBAL_START_EXEC, self.set_info)

        self.is_recorded = False
        self.is_play = False
        self.record_icon = QIcon(
            self.resource_icon_path + "RecordVideoAction.png")
        self.save_record_icon = QIcon(
            self.resource_icon_path + "SaveServerImageAction.png")
        self.play_icon = QIcon(
            "/usr/share/icons/gnome/24x24/actions/player_play.png")
        self.pause_icon = QIcon(
            "/usr/share/icons/gnome/24x24/actions/player_pause.png")

        self.dct_media = None

        self.last_value_frame = 0
        self.max_frame = 0

        self.shared_info.connect(
            SharedInfo.GLOBAL_START_EXEC, self._start_execution)
        self.shared_info.connect(SharedInfo.GLOBAL_EXEC, self.change_execution)
        self.shared_info.connect(SharedInfo.GLOBAL_HIST_REC_PATH_MEDIA,
                                 self._change_hist_media_path)

        # TODO optimize starting thread.
        self.thread_player = PlayerFile(controller, self._get_actual_no_frame,
                                        self.set_slider_value)
        self.thread_player.start()
        self.reload_ui()

    def stop(self):
        if self.thread_player:
            self.thread_player.close()

    def reload_ui(self):
        self.ui = get_ui(self)

        self.ui.recordButton.clicked.connect(self.click_record_button)
        self.ui.cbMedia.currentIndexChanged.connect(self._change_media)
        self.ui.openDirButton.clicked.connect(self.open_directory)
        self.ui.openFileButton.clicked.connect(self.open_file)
        self.ui.btnplay.clicked.connect(self.play)
        self.ui.loopchb.clicked.connect(self.active_loop)
        self.ui.movieLineEdit.textChanged.connect(self._movie_changed)
        self.ui.slider_frame.valueChanged.connect(self._slider_value_change)
        self.ui.txtframe.returnPressed.connect(self._txt_frame_value_change)
        self.ui.spin_box_fps.valueChanged.connect(self._change_fps)
        self.ui.sliceButton.clicked.connect(self.click_slice_button)
        self.ui.cancelButton.clicked.connect(self.click_cancel_button)
        self.ui.cutButton.clicked.connect(self.click_cut_button)
        self.ui.cleanButton.clicked.connect(self.click_clean_button)

        self._set_record_icon()
        self._set_play_icon()
        self._update_media()

    def _update_media(self):
        self.ui.cbMedia.currentIndexChanged.disconnect(self._change_media)
        self.dct_media = self.controller.get_media_list()
        lst_media = sorted(self.dct_media.keys(), key=lambda x: x.lower())
        for media in lst_media:
            self.ui.cbMedia.addItem(media)
            # subscribe to notification
            self.subscriber.subscribe("media.%s" % media,
                                      self._subscribe_cb(media))
        self._change_media(after_update=True)
        self.ui.cbMedia.currentIndexChanged.connect(self._change_media)

        default_select_media = config.default_media_selected
        if default_select_media not in self.dct_media.keys():
            default_select_media = self.controller.get_default_media_name()
        self.last_selected_media = default_select_media
        self.select_media(default_select_media)

    def _subscribe_cb(self, media):
        def _cb(data):
            if self.ui.cbMedia.currentText() == media:
                fps = data.get("fps")
                if fps is not None:
                    self.ui.lblFPS.setText("%s" % fps)
                status = data.get("status")
                if status is not None:
                    self.ui.lblStatus.setText("%s" % status)

        return _cb

    def _change_media(self, index=-1, after_update=False):
        media_name = self.ui.cbMedia.currentText()
        frame_webcam = self.ui.frame_webcam
        frame_slice = self.ui.frame_slice
        frame_webcam.setVisible(False)
        frame_slice.setVisible(False)
        frame_video = self.ui.frame_video
        frame_video.setVisible(False)

        media_type = self.dct_media.get(media_name, None)
        if not media_type:
            self.shared_info.set(SharedInfo.GLOBAL_MEDIA, None)
            return
        if media_type == keys.get_media_type_video_name():
            frame_video.setVisible(True)
        elif media_type == keys.get_media_type_streaming_name():
            frame_webcam.setVisible(True)
            self.shared_info.set(SharedInfo.GLOBAL_PATH_MEDIA, None)
        self.shared_info.set(SharedInfo.GLOBAL_MEDIA, media_name)
        self.set_info()
        if not after_update:
            self.last_selected_media = media_name

    def _movie_changed(self):
        self.shared_info.set(
            SharedInfo.GLOBAL_PATH_MEDIA, self.ui.movieLineEdit.text())

    def set_slider_value(self, value, force_value=False):
        last_value = self.ui.slider_frame.value()
        if last_value != value:
            self.ui.slider_frame.setValue(value)
        else:
            # force change value in video context
            self._slider_value_change(value)

    def _slider_value_change(self, value):
        self.ui.txtframe.setText(str(value))
        self._txt_frame_value_change()

    def _txt_frame_value_change(self):
        str_value = self.ui.txtframe.text()
        try:
            value = int(str_value)
        except BaseException:
            self.ui.txtframe.setText(str(self.last_value_frame))
            return
        if value < 1 or value > self.max_frame:
            self.ui.txtframe.setText(str(self.last_value_frame))
            return
        self.last_value_frame = value
        self.ui.txtframe.setText(str(value))
        self.set_frame_video(value)

    def _change_fps(self, value):
        self.thread_player.set_fps(value)

    def _get_actual_no_frame(self):
        return self.ui.slider_frame.value()

    def _start_execution(self, value=None):
        if not value or not isinstance(value, dict):
            return
        media_name = value.get("media")
        if media_name == keys.get_media_file_video_name():
            self.set_slider_value(1)
            self.is_play = False
            self.play()

    def click_record_button(self):
        if not self.is_recorded:
            path = self.ui.txt_name_record.text()
            if not path:
                path = None
            if self.ui.rbn_avi.isChecked():
                format_rec = keys.get_key_format_avi()
            else:
                format_rec = keys.get_key_format_png()
            options = {
                "compress": self.ui.sb_compress.value(), "format": format_rec}
            if not self.controller.start_record(self.ui.cbMedia.currentText(),
                                                path, options):
                # TODO improve error message
                logger.error("Trying start record...")
            else:
                self.is_recorded = True
        else:
            if not self.controller.stop_record(self.ui.cbMedia.currentText()):
                logger.error("Trying stop record...")
            self.is_recorded = False
        self.set_info()

    def open_directory(self):
        filename = QFileDialog.getExistingDirectory()
        if len(filename) > 0:
            self.ui.movieLineEdit.setText(filename)

    def open_file(self):
        filename = QFileDialog.getOpenFileName()[0]
        if len(filename) > 0:
            self.ui.movieLineEdit.setText(filename)

    def set_frame_video(self, value):
        media_name = self.shared_info.get(SharedInfo.GLOBAL_MEDIA)
        if not media_name:
            return
        self.controller.cmd_to_media(
            media_name, keys.get_key_media_frame(), value - 1)

    def set_info(self, value=None):
        # Ignore the value
        media_name = self.shared_info.get(SharedInfo.GLOBAL_MEDIA)
        if not media_name:
            return
        info = self.controller.get_info_media(media_name)
        if not info:
            logger.warning("WinMedia: info is empty from get_info_media.")
        self.max_frame = info.get("nb_frame", -1)
        self.ui.lblframe.setText("/%s" % self.max_frame)
        self.ui.txtframe.setText(str(self.last_value_frame))
        self.ui.slider_frame.setMinimum(1)
        self.ui.slider_frame.setMaximum(self.max_frame)
        self.thread_player.set_max_frame(self.max_frame)
        self.ui.lblFPS.setText("%s" % info.get("fps", "-1"))
        self.ui.lblStatus.setText("%s" % info.get("status", "None"))
        record_name = info.get("record_file_name", "")
        self.ui.txt_name_record.setText("%s" % record_name)
        self.is_recorded = bool(record_name)
        self._set_record_icon()

    def play(self):
        # media_name = self.ui.cbMedia.currentText()
        if self.is_play:
            # if self.controller.cmd_to_media(media_name,
            # keys.get_key_media_play()):
            self.thread_player.set_pause(True)
            self.is_play = False
            self._set_play_icon()
        else:
            # if self.controller.cmd_to_media(media_name,
            # keys.get_key_media_pause()):
            self.thread_player.set_pause(False)
            self.is_play = True
            self._set_play_icon()

    def active_loop(self):
        media_name = self.ui.cbMedia.currentText()
        self.controller.cmd_to_media(
            media_name, keys.get_key_media_loop(), None)

    def _set_play_icon(self):
        if not self.is_play:
            self.ui.btnplay.setIcon(self.play_icon)
        else:
            self.ui.btnplay.setIcon(self.pause_icon)

    def _set_record_icon(self):
        self.ui.sb_compress.setEnabled(not self.is_recorded)
        self.ui.rbn_avi.setEnabled(not self.is_recorded)
        self.ui.rbn_png.setEnabled(not self.is_recorded)
        self.ui.txt_name_record.setReadOnly(self.is_recorded)
        if not self.is_recorded:
            self.ui.recordButton.setIcon(self.record_icon)
        else:
            self.ui.recordButton.setIcon(self.save_record_icon)

    def get_file_path(self):
        item_cbmedia = self.ui.cbMedia.currentText()
        media_type = self.dct_media.get(item_cbmedia, None)
        if media_type != keys.get_media_type_video_name():
            return
        return self.ui.movieLineEdit.text()

    def change_execution(self, exec_info):
        media_name = exec_info[2]
        self.select_media(media_name)

    def select_media(self, media_name):
        # find index
        index = self.ui.cbMedia.findText(media_name)
        if index < 0:
            return False
        # TODO Need to re-send signal if it's the same media? Maybe not
        # necessary
        self.ui.cbMedia.setCurrentIndex(index)
        return True

    def _change_hist_media_path(self, value=None):
        filename = self.shared_info.get(SharedInfo.GLOBAL_HIST_REC_PATH_MEDIA)
        if len(filename) > 0:
            self.ui.movieLineEdit.setText(filename)

    def click_slice_button(self):
        self.ui.frame_slice.setVisible(True)

    def click_cancel_button(self):
        self.ui.frame_slice.setVisible(False)

    def click_cut_button(self):
        begin = self.ui.beginSpinBox.value()
        end = self.ui.endSpinBox.value()
        file_name = self.ui.movieLineEdit.text()
        cut_file_name = self.ui.nameLineEdit.text()
        self.controller.cut_video(file_name, begin, end, cut_file_name)
        self.ui.frame_slice.setVisible(False)

    def click_clean_button(self):
        self.ui.beginSpinBox.setValue(0)
        self.ui.endSpinBox.setValue(0)
        self.ui.nameLineEdit.setText("")
Esempio n. 8
0
class WinFilterChain(QtCore.QObject):
    """Main window
    Allow the user to create, edit and test filter chains
    """

    def __init__(self, controller):
        super(WinFilterChain, self).__init__()

        self.controller = controller
        self.last_row_fc_select = 0
        self.shared_info = SharedInfo()
        self.ui = None
        self.lock_preview = False
        self.edit_mode = False
        self.mode_new = False

        self.reload_ui()

    def reload_ui(self):
        self.ui = get_ui(self)
        self.ui.filterListWidget.currentItemChanged.connect(
            self.on_selected_filter_changed)
        self.ui.filterchainListWidget.currentItemChanged.connect(
            self.on_selected_filter_chain_changed)
        self.ui.uploadButton.clicked.connect(self.upload)
        self.ui.editButton.clicked.connect(self.edit)
        self.ui.saveButton.clicked.connect(self.save)
        self.ui.cancelButton.clicked.connect(self.cancel)
        self.ui.deleteButton.clicked.connect(self.delete)
        self.ui.copyButton.clicked.connect(self.copy)
        self.ui.newButton.clicked.connect(self.new)
        self.ui.upButton.clicked.connect(self.move_up_selected_filter)
        self.ui.downButton.clicked.connect(self.move_down_selected_filter)
        self.ui.removeButton.clicked.connect(self.remove_filter)

        self.update_filter_chain_list()
        self.ui.frame_filter_edit.setEnabled(False)
        self.lock_preview = False

        self.edit_mode = False
        self.mode_new = False
        self._mode_edit(False)
        self._list_filterchain_is_selected(False)

        self.shared_info.connect(
            SharedInfo.GLOBAL_MEDIA, self._update_media_default_edit)
        self.shared_info.connect(
            SharedInfo.GLOBAL_EXEC, self.select_filterchain)

    #
    # SIGNAL  ###############################
    #
    def _update_media_default_edit(self, value):
        if self.edit_mode and not self.mode_new:
            return
        txt = ""
        if value != keys.get_media_file_video_name():
            txt = value
        self.ui.media_default_edit.setText(txt)

    def add_filter(self, filter_name):
        if not self.edit_mode:
            return
        if filter_name:
            self.ui.filterListWidget.addItem(filter_name)

    def remove_filter(self):
        self.ui.filterListWidget.takeItem(
            self.ui.filterListWidget.currentRow())

    def upload(self):
        # open a file, copy the contain to the controller
        str_ext = ".filterchain"
        filename = QtGui.QFileDialog().getOpenFileName(
            filter="*%s" % str_ext)[0]
        if filename:
            fc_name = filename[filename.rfind("/") + 1:-len(str_ext)]
            if self._is_unique_filterchain_name(fc_name):
                f = open(filename, 'r')
                if f:
                    s_contain = "".join(f.readlines())
                    # if success, add the filter name on list widget
                    if self.controller.upload_filterchain(fc_name, s_contain):
                        self.ui.filterchainListWidget.addItem(fc_name)
                else:
                    logger.error("Can't open the file : %s" % filename)
            else:
                logger.error("This filtername already exist : %s" % fc_name)

    def edit(self):
        self.last_row_fc_select = self.ui.filterchainListWidget.currentRow()
        self._mode_edit(True)

    def cancel(self):
        self.update_filter_chain_list()
        self._list_filterchain_is_selected(False)
        self.ui.filterchainListWidget.setCurrentRow(
            self.last_row_fc_select)
        self._mode_edit(False)
        logger.info("Cancel changement.")

    def save(self):
        new_name = self.ui.filterchainEdit.text()
        old_name = self.ui.filterchainListWidget.currentItem().text()
        # validate new name
        new_name = new_name.strip()
        if new_name != old_name and not self._is_unique_filterchain_name(
                new_name):
            msg = "The filtername \"%s\" already exist." % new_name
            QtGui.QMessageBox.warning(self.ui.centralwidget,
                                      "Wrong name",
                                      msg,
                                      QtGui.QMessageBox.Ok,
                                      QtGui.QMessageBox.Ok)
            return

        self.ui.filterchainEdit.setText(new_name)

        lst_filter = self._get_list_string_qlist(self.ui.filterListWidget)
        default_media = self.ui.media_default_edit.text()

        if self.controller.modify_filterchain(old_name, new_name, lst_filter,
                                              default_media):
            self.ui.filterchainListWidget.currentItem().setText(new_name)
            logger.info("Editing success on filterchain %s" % new_name)
            self._mode_edit(False)
            self.update_filter_list()
            self.on_selected_filter_changed()
            # update actual filterchain
            self.shared_info.set(SharedInfo.GLOBAL_FILTERCHAIN, new_name)
        else:
            logger.error("Saving edit on filterchain %s." % new_name)
            self.cancel()

    def delete(self):
        self._mode_edit(True)
        no_line = self.ui.filterchainListWidget.currentRow()
        if no_line >= 0:
            filterchain_name = self.ui.filterchainListWidget.item(
                no_line).text()
            # security ask
            response = QtGui.QMessageBox.question(
                self.ui.centralwidget,
                "Delete filterchain",
                "Do you want to delete filterchain \"%s\"" % filterchain_name,
                QtGui.QMessageBox.Yes | QtGui.QMessageBox.No,
                QtGui.QMessageBox.No
            )
            if response == QtGui.QMessageBox.Yes:
                # delete the filterchain
                self.controller.delete_filterchain(filterchain_name)
                self.ui.filterchainListWidget.takeItem(no_line)
                logger.info("Delete %s" % filterchain_name)
            else:
                logger.info("Cancel delete %s" % filterchain_name)
        self._mode_edit(False)
        # update the widget
        self.on_selected_filter_chain_changed()

    def copy(self):
        self.edit()

        # we copy the selected filterchain
        no_row = self.ui.filterchainListWidget.currentRow()
        filterchain_name_temp = self.ui.filterchainListWidget.item(
            no_row).text() + " - copy"

        # find name of copy filterchain
        i = 1
        filterchain_name = filterchain_name_temp
        while not self._is_unique_filterchain_name(filterchain_name):
            i += 1
            filterchain_name = filterchain_name_temp + "- %s" % i

        # add copy line
        lst_filter_str = self._get_list_string_qlist(self.ui.filterListWidget)
        self.ui.filterchainListWidget.insertItem(no_row + 1, filterchain_name)
        self.ui.filterchainListWidget.setCurrentRow(no_row + 1)
        self.ui.filterchainEdit.setText(filterchain_name)

        for item in lst_filter_str:
            self.ui.filterListWidget.addItem(item)

    def new(self):
        self.mode_new = True
        self.edit()

        # find name of new filterchain
        i = 1
        filterchain_name = "new"
        while not self._is_unique_filterchain_name(filterchain_name):
            i += 1
            filterchain_name = "new-%s" % i

        # add new line
        self.ui.filterchainListWidget.addItem(filterchain_name)
        self.ui.filterchainListWidget.setCurrentRow(
            self.ui.filterchainListWidget.count() - 1)
        self.ui.filterchainEdit.setText(filterchain_name)

        self.ui.filterListWidget.clear()

    def update_filter_list(self, fc_name=None):
        if not fc_name:
            fc_name = self._get_selected_filterchain_name()
        self.ui.filterListWidget.clear()

        if fc_name == keys.get_empty_filterchain_name():
            return

        info = self.controller.get_filterchain_info(fc_name)
        lst_filter = info.get("filters", None)
        if not lst_filter:
            logger.warning(
                "Recieve empty filter list from filterchain %s" % fc_name)
            return
        for o_filter in lst_filter:
            name = o_filter.get("name", "")
            if name == keys.get_empty_filter_name():
                continue
            self.ui.filterListWidget.addItem(name)
        default_media = info.get("default_media", "")
        self.ui.media_default_edit.setText(default_media)

    def update_filter_chain_list(self):
        self.ui.filterchainListWidget.clear()
        self.ui.filterListWidget.clear()
        self.ui.filterchainEdit.clear()
        lst_filterchain = sorted(self.controller.get_filterchain_list(),
                                 key=lambda x: x.get("name").lower())
        for filterchain in lst_filterchain:
            self.ui.filterchainListWidget.addItem(filterchain.get("name"))
        self.ui.filterchainListWidget.addItem(
            keys.get_empty_filterchain_name())

    def move_up_selected_filter(self):
        self._move_current_item_on_qtlist(self.ui.filterListWidget, -1)

    def move_down_selected_filter(self):
        self._move_current_item_on_qtlist(self.ui.filterListWidget, 1)

    def on_selected_filter_changed(self):
        filter_name = self._get_selected_filter_name()
        self.ui.frame_filter_edit.setEnabled(filter_name is not None)
        if filter_name:
            self.shared_info.set(SharedInfo.GLOBAL_FILTER, filter_name)
        else:
            self.shared_info.set(SharedInfo.GLOBAL_FILTER, None)

    def on_selected_filter_chain_changed(self):
        if self.edit_mode:
            return
        filterchain_name = self._get_selected_filterchain_name()
        if filterchain_name:
            # set the filters section
            self.ui.filterchainEdit.setText(filterchain_name)
            self.update_filter_list(filterchain_name)
            self._list_filterchain_is_selected(True)

            filterchain_name = self._get_selected_filterchain_name()

            # Exception, don't edit or delete special empty filterchain
            self.ui.deleteButton.setEnabled(
                filterchain_name != keys.get_empty_filterchain_name())
            self.ui.editButton.setEnabled(
                filterchain_name != keys.get_empty_filterchain_name())
            self.shared_info.set(
                SharedInfo.GLOBAL_FILTERCHAIN, filterchain_name)

            self.ui.filterListWidget.setCurrentRow(0)
        else:
            self._list_filterchain_is_selected(False)
            self.shared_info.set(SharedInfo.GLOBAL_FILTERCHAIN, None)

    def get_filter_list(self):
        return self._get_list_string_qlist(self.ui.filterListWidget)

    def select_filterchain(self, exec_info):
        filterchain_name = exec_info[1]
        items = self.ui.filterchainListWidget.findItems(
            filterchain_name, QtCore.Qt.MatchExactly)
        if not items:
            return
        self.ui.filterchainListWidget.setCurrentItem(items[0])
        if not self.ui.filterListWidget.currentRow():
            self.on_selected_filter_changed()
        else:
            self.ui.filterListWidget.setCurrentRow(0)

    #
    # PRIVATE FUNCTION  ############################
    #

    def _is_unique_filterchain_name(self, filterchain_name):
        for noLine in range(self.ui.filterchainListWidget.count()):
            if self.ui.filterchainListWidget.item(
                    noLine).text() == filterchain_name:
                return False
        return True

    def _get_selected_filterchain_name(self):
        return self._get_selected_list(self.ui.filterchainListWidget)

    def _get_selected_filter_name(self):
        return self._get_selected_list(self.ui.filterListWidget)

    @staticmethod
    def _get_selected_list(ui_list):
        no_line = ui_list.currentRow()
        if no_line >= 0:
            return ui_list.item(no_line).text()
        return

    def _mode_edit(self, status=True):
        self.edit_mode = status
        self.ui.frame_editing.setVisible(status)
        self.ui.frame_editing_2.setVisible(status)
        self.ui.frame_filter_edit.setVisible(status)
        self.ui.frame_edit.setEnabled(not status)
        self.ui.filterchainEdit.setReadOnly(not status)
        self.ui.filterchainListWidget.setEnabled(not status)
        self.shared_info.set(SharedInfo.GLOBAL_FILTERCHAIN_EDIT_MODE, status)
        if status:
            self.ui.filterchainEdit.setFocus()
        else:
            self.mode_new = False

    def _list_filterchain_is_selected(self, is_selected=True):
        self.ui.editButton.setEnabled(is_selected)
        self.ui.copyButton.setEnabled(is_selected)
        self.ui.deleteButton.setEnabled(is_selected)

    @staticmethod
    def _get_list_string_qlist(ui):
        return [ui.item(no).text() for no in range(ui.count())]

    @staticmethod
    def _move_current_item_on_qtlist(ui, nb_line):
        # take the action if nbLine is different of 0 and the limit is correct
        if nb_line:
            no_row = ui.currentRow()
            new_no_row = no_row + nb_line
            if 0 <= new_no_row < ui.count():
                # remove and add to move the item
                item = ui.takeItem(no_row)
                ui.insertItem(new_no_row, item)
                ui.setCurrentRow(new_no_row)