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 __init__(self, controller, subscriber): super(WinRecHistoric, self).__init__() self.ui = None self.resource_icon_path = "SeaGoatVision/client/resource/img/" self.controller = controller self.subscriber = subscriber self.shared_info = SharedInfo() self.lst_old_record_historic = [] self.reload_ui() self.subscriber.subscribe(keys.get_key_lst_rec_historic(), self.update_record_table)
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 __init__(self, controller, subscriber): super(WinDebugKeyz, self).__init__() self.ui = None self.controller = controller self.subscriber = subscriber self.shared_info = SharedInfo() self.reload_ui() subscriber.subscribe(keys.get_key_count(), self.update_record_table)
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 __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()
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)
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)
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 __init__(self, controller, set_value): super(WinParamParent, self).__init__() self.signal_update_param.connect(self.update_param) self.shared_info = SharedInfo() self.controller = controller self.lst_param = None self._set_value = None self.layout = None self.ui = None self.lst_active_widget = [] self.lst_inactive_widget = [] self.parent_layout = None self.cb_group = None self.set_value = set_value self.reload_ui()
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()
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)
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("")
class WinRecHistoric(QtCore.QObject): onPreviewClick = QtCore.Signal(object, object, object) def __init__(self, controller, subscriber): super(WinRecHistoric, self).__init__() self.ui = None self.resource_icon_path = "SeaGoatVision/client/resource/img/" self.controller = controller self.subscriber = subscriber self.shared_info = SharedInfo() self.lst_old_record_historic = [] self.reload_ui() self.subscriber.subscribe(keys.get_key_lst_rec_historic(), self.update_record_table) def reload_ui(self): self.ui = get_ui(self) self.refresh_list() self.update_old_record_table() def refresh_list(self): lst_record = self.controller.get_lst_record_historic() for item in lst_record: self.update_record_table(item) def update_record_table(self, data): if not ("time" in data and "media_name" in data and "path" in data): return table = self.ui.tableRecord no_row = table.rowCount() table.insertRow(no_row) date = datetime.datetime.fromtimestamp(data.get("time")) str_date = date.strftime('%Y-%m-%d %H:%M:%S') table.setItem(no_row, 0, QtGui.QTableWidgetItem(str_date)) table.setItem(no_row, 1, QtGui.QTableWidgetItem(data.get("media_name"))) table.setItem(no_row, 2, QtGui.QTableWidgetItem(data.get("path"))) table.setItem(no_row, 3, QtGui.QTableWidgetItem()) table.item(no_row, 3).setIcon( QIcon(self.resource_icon_path + "PreviewAction.png")) table.item(no_row, 3).setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled) table.itemDoubleClicked.connect(self._rec_prvw_dbl_clicked) def preview(self, file_name): self.shared_info.set(SharedInfo.GLOBAL_PATH_MEDIA, file_name) self.shared_info.set(SharedInfo.GLOBAL_HIST_REC_PATH_MEDIA, file_name) def update_old_record_table(self): self.clear_old_records() self.lst_old_record_historic = self.controller.get_lst_old_record_historic() table = self.ui.tableFileName table.itemDoubleClicked.connect(self._old_rec_prvw_dbl_clicked) no_row = 0 for rec in self.lst_old_record_historic: table.insertRow(no_row) date = datetime.datetime.fromtimestamp(rec.get("time")) str_date = date.strftime('%Y-%m-%d %H:%M:%S') table.setItem(no_row, 0, QtGui.QTableWidgetItem(str_date)) table.setItem(no_row, 1, QtGui.QTableWidgetItem(rec.get("name"))) table.setItem(no_row, 2, QtGui.QTableWidgetItem(rec.get("path"))) table.setItem(no_row, 3, QtGui.QTableWidgetItem()) table.item(no_row, 3).setIcon( QIcon(self.resource_icon_path + "PreviewAction.png")) table.item(no_row, 3).setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled) def clear_old_records(self): table = self.ui.tableFileName while table.rowCount(): table.removeRow(0) def _rec_prvw_dbl_clicked(self, item): if item.column() == 3: table = self.ui.tableRecord file_name = table.item(item.row(), 2).text() self.preview(file_name) def _old_rec_prvw_dbl_clicked(self, item): if item.column() == 3: table = self.ui.tableFileName file_name = table.item(item.row(), 2).text() + "/" + table.item(item.row(), 1).text() self.preview(file_name)
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("")
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
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)
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()