def onDeleteClick(self): """ Remove a song from the list and database """ if check_item_selected(self.listView, UiStrings().SelectDelete): items = self.listView.selectedIndexes() if QtGui.QMessageBox.question(self, UiStrings().ConfirmDelete, translate('SongsPlugin.MediaItem', 'Are you sure you want to delete the %n selected song(s)?', '', QtCore.QCoreApplication.CodecForTr, len(items)), QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes | QtGui.QMessageBox.No), QtGui.QMessageBox.Yes) == QtGui.QMessageBox.No: return self.application.set_busy_cursor() self.main_window.displayProgressBar(len(items)) for item in items: item_id = item.data(QtCore.Qt.UserRole) media_files = self.plugin.manager.get_all_objects(MediaFile, MediaFile.song_id == item_id) for media_file in media_files: try: os.remove(media_file.file_name) except: log.exception('Could not remove file: %s', media_file.file_name) try: save_path = os.path.join(AppLocation.get_section_data_path(self.plugin.name), 'audio', str(item_id)) if os.path.exists(save_path): os.rmdir(save_path) except OSError: log.exception(u'Could not remove directory: %s', save_path) self.plugin.manager.delete_object(Song, item_id) self.main_window.incrementProgressBar() self.main_window.finishedProgressBar() self.application.set_normal_cursor() self.onSearchTextButtonClicked()
def on_replace_click(self): """ Called to replace Live background with the media selected. """ if check_item_selected(self.list_view, translate('MediaPlugin.MediaItem', 'You must select a media file to replace the background with.')): item = self.list_view.currentItem() filename = item.data(QtCore.Qt.UserRole) if os.path.exists(filename): service_item = ServiceItem() service_item.title = 'webkit' service_item.processor = 'webkit' (path, name) = os.path.split(filename) service_item.add_from_command(path, name, CLAPPERBOARD) if self.media_controller.video(DisplayControllerType.Live, service_item, video_behind_text=True): self.reset_action.setVisible(True) else: critical_error_message_box(UiStrings().LiveBGError, translate('MediaPlugin.MediaItem', 'There was no display item to amend.')) else: critical_error_message_box(UiStrings().LiveBGError, translate('MediaPlugin.MediaItem', 'There was a problem replacing your background, ' 'the media file "%s" no longer exists.') % filename)
def on_delete_loop(self, field=None): """ Delete a loop triggered by the UI. :param field: """ if check_item_selected(self.loop_list_widget, translate('OpenLP.LoopManager', 'You must select a loop to delete.')): item = self.loop_list_widget.currentItem() cur_loop = item.text() check_answer = QtGui.QMessageBox.question(self, translate('OpenLP.LoopManager', 'Delete Confirmation'), translate('OpenLP.LoopManager', 'Remove %s loop and delete files?' % cur_loop), QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes | QtGui.QMessageBox.No), QtGui.QMessageBox.No) if check_answer == QtGui.QMessageBox.No: return # Remove loop from UI row = self.loop_list_widget.row(item) self.loop_list_widget.takeItem(row) # Remove loop and thumbnail from disk self.application.set_busy_cursor() os.remove(os.path.join(self.path, item.data(QtCore.Qt.UserRole))) os.remove(os.path.join(self.thumb_path, cur_loop + '.jpg')) self.application.set_normal_cursor()
def on_replace_click(self): """ Called to replace Live background with the image selected. """ if check_item_selected( self.list_view, translate('ImagePlugin.MediaItem', 'You must select an image to replace the background with.')): background = QtGui.QColor(Settings().value(self.settings_section + '/background color')) bitem = self.list_view.selectedItems()[0] if not isinstance(bitem.data(0, QtCore.Qt.UserRole), ImageFilenames): # Only continue when an image is selected. return filename = bitem.data(0, QtCore.Qt.UserRole).filename if os.path.exists(filename): if self.live_controller.display.direct_image(filename, background): self.reset_action.setVisible(True) else: critical_error_message_box( UiStrings().LiveBGError, translate('ImagePlugin.MediaItem', 'There was no display item to amend.')) else: critical_error_message_box( UiStrings().LiveBGError, translate('ImagePlugin.MediaItem', 'There was a problem replacing your background, ' 'the image file "%s" no longer exists.') % filename)
def on_delete_click(self): """ Remove a song from the list and database """ if check_item_selected(self.list_view, UiStrings().SelectDelete): items = self.list_view.selectedIndexes() if QtGui.QMessageBox.question( self, UiStrings().ConfirmDelete, translate( 'SongsPlugin.MediaItem', 'Are you sure you want to delete the %n selected song(s)?', '', QtCore.QCoreApplication.CodecForTr, len(items)), QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes | QtGui.QMessageBox.No), QtGui.QMessageBox.Yes) == QtGui.QMessageBox.No: return self.application.set_busy_cursor() self.main_window.display_progress_bar(len(items)) for item in items: item_id = item.data(QtCore.Qt.UserRole) delete_song(item_id, self.plugin) self.main_window.increment_progress_bar() self.main_window.finished_progress_bar() self.application.set_normal_cursor() self.on_search_text_button_clicked()
def on_clone_click(self): """ Clone a Song """ log.debug('on_clone_click') if check_item_selected(self.list_view, UiStrings().SelectEdit): self.edit_item = self.list_view.currentItem() item_id = self.edit_item.data(QtCore.Qt.UserRole) old_song = self.plugin.manager.get_object(Song, item_id) song_xml = self.open_lyrics.song_to_xml(old_song) new_song = self.open_lyrics.xml_to_song(song_xml) new_song.title = '%s <%s>' % \ (new_song.title, translate('SongsPlugin.MediaItem', 'copy', 'For song cloning')) # Copy audio files from the old to the new song if len(old_song.media_files) > 0: save_path = os.path.join(AppLocation.get_section_data_path(self.plugin.name), 'audio', str(new_song.id)) check_directory_exists(save_path) for media_file in old_song.media_files: new_media_file_name = os.path.join(save_path, os.path.basename(media_file.file_name)) shutil.copyfile(media_file.file_name, new_media_file_name) new_media_file = MediaFile() new_media_file.file_name = new_media_file_name new_media_file.type = media_file.type new_media_file.weight = media_file.weight new_song.media_files.append(new_media_file) self.plugin.manager.save_object(new_song) self.on_song_list_load()
def on_display_loop(self, field=None): if check_item_selected(self.loop_list_widget, translate('OpenLP.LoopManager', 'You must select a loop to play.')): item = self.loop_list_widget.currentItem() loop_file = os.path.join(self.path, item.data(QtCore.Qt.UserRole)) vlc_cmd = 'vlc --one-instance --repeat -f \"' + loop_file + '\"' subprocess.Popen(vlc_cmd) return True
def on_delete_click(self): """ Remove a media item from the list. """ if check_item_selected(self.list_view, translate('MediaPlugin.MediaItem', 'You must select a media file to delete.')): row_list = [item.row() for item in self.list_view.selectedIndexes()] row_list.sort(reverse=True) for row in row_list: self.list_view.takeItem(row) Settings().setValue(self.settings_section + '/media files', self.get_file_list())
def onEditClick(self): """ Edit a custom item """ if check_item_selected(self.listView, UiStrings().SelectEdit): item = self.listView.currentItem() item_id = item.data(QtCore.Qt.UserRole) self.edit_custom_form.loadCustom(item_id, False) self.edit_custom_form.exec_() self.autoSelectId = -1 self.onSearchTextButtonClicked()
def on_edit_click(self): """ Edit a custom item """ if check_item_selected(self.list_view, UiStrings().SelectEdit): item = self.list_view.currentItem() item_id = item.data(QtCore.Qt.UserRole) self.edit_custom_form.load_custom(item_id, False) self.edit_custom_form.exec_() self.auto_select_id = -1 self.on_search_text_button_clicked()
def on_edit_click(self): """ Edit a song """ log.debug('on_edit_click') if check_item_selected(self.list_view, UiStrings().SelectEdit): self.edit_item = self.list_view.currentItem() item_id = self.edit_item.data(QtCore.Qt.UserRole) self.edit_song_form.load_song(item_id, False) self.edit_song_form.exec_() self.auto_select_id = -1 self.on_song_list_load() self.edit_item = None
def onEditClick(self): """ Edit a song """ log.debug(u'onEditClick') if check_item_selected(self.listView, UiStrings().SelectEdit): self.editItem = self.listView.currentItem() item_id = self.editItem.data(QtCore.Qt.UserRole) self.editSongForm.loadSong(item_id, False) self.editSongForm.exec_() self.autoSelectId = -1 self.onSongListLoad() self.editItem = None
def on_display_loop(self, field=None): if check_item_selected(self.loop_list_widget, translate('OpenLP.LoopManager', 'You must select a loop to play.')): item = self.loop_list_widget.currentItem() loop_file = os.path.join(self.path, item.data(QtCore.Qt.UserRole)) vlc_cmd = ['vlc', loop_file, '--one-instance', '--repeat', '-f'] subprocess.Popen(vlc_cmd) # Update GUI to show currently playing loop_thumb #f = item.font #QtGui.QFont.setBold(True) #item.setFont(f) #item.setBackgroundColor(QtGui.QColor(0,255,0,255)) return True
def _validate_theme_action(self, select_text, confirm_title, confirm_text, test_plugin=True, confirm=True): """ Check to see if theme has been selected and the destructive action is allowed. :param select_text: Text for message box if no item selected. :param confirm_title: Confirm message title to be displayed. :param confirm_text: Confirm message text to be displayed. :param test_plugin: Do we check the plugins for theme usage. :param confirm: Do we display a confirm box before run checks. :return: True or False depending on the validity. """ self.global_theme = Settings().value(self.settings_section + '/global theme') if check_item_selected(self.theme_list_widget, select_text): item = self.theme_list_widget.currentItem() theme = item.text() # confirm deletion if confirm: answer = QtWidgets.QMessageBox.question( self, confirm_title, confirm_text % theme, QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No), QtWidgets.QMessageBox.No) if answer == QtWidgets.QMessageBox.No: return False # should be the same unless default if theme != item.data(QtCore.Qt.UserRole): critical_error_message_box( message=translate('OpenLP.ThemeManager', 'You are unable to delete the default theme.')) return False # check for use in the system else where. if test_plugin: plugin_usage = "" for plugin in self.plugin_manager.plugins: used_count = plugin.uses_theme(theme) if used_count: plugin_usage = "{plug}{text}".format(plug=plugin_usage, text=(translate('OpenLP.ThemeManager', '{count} time(s) by {plugin}' ).format(name=used_count, plugin=plugin.name))) plugin_usage = "{text}\n".format(text=plugin_usage) if plugin_usage: critical_error_message_box(translate('OpenLP.ThemeManager', 'Unable to delete theme'), translate('OpenLP.ThemeManager', 'Theme is currently used \n\n{text}' ).format(text=plugin_usage)) return False return True return False
def onCloneClick(self): """ Clone a Song """ log.debug(u'onCloneClick') if check_item_selected(self.listView, UiStrings().SelectEdit): self.editItem = self.listView.currentItem() item_id = self.editItem.data(QtCore.Qt.UserRole) old_song = self.plugin.manager.get_object(Song, item_id) song_xml = self.openLyrics.song_to_xml(old_song) new_song = self.openLyrics.xml_to_song(song_xml) new_song.title = u'%s <%s>' % (new_song.title, translate('SongsPlugin.MediaItem', 'copy', 'For song cloning')) self.plugin.manager.save_object(new_song) self.onSongListLoad()
def check_item_selected_true_test(self): """ Test that the check_item_selected() function returns True when there are selected indexes. """ # GIVEN: A mocked out QtGui module and a list widget with selected indexes MockedQtGui = patch(u'openlp.core.lib.QtGui') mocked_list_widget = MagicMock() mocked_list_widget.selectedIndexes.return_value = True message = u'message' # WHEN: We check if there are selected items result = check_item_selected(mocked_list_widget, message) # THEN: The selectedIndexes function should have been called and the result should be true mocked_list_widget.selectedIndexes.assert_called_with() assert result, u'The result should be True'
def test_check_item_selected_true(self): """ Test that the check_item_selected() function returns True when there are selected indexes """ # GIVEN: A mocked out QtWidgets module and a list widget with selected indexes mocked_QtWidgets = patch('openlp.core.lib.QtWidgets') mocked_list_widget = MagicMock() mocked_list_widget.selectedIndexes.return_value = True message = 'message' # WHEN: We check if there are selected items result = check_item_selected(mocked_list_widget, message) # THEN: The selectedIndexes function should have been called and the result should be true mocked_list_widget.selectedIndexes.assert_called_with() self.assertTrue(result, 'The result should be True')
def on_edit_theme(self, field=None): """ Loads the settings for the theme that is to be edited and launches the theme editing form so the user can make their changes. :param field: """ if check_item_selected(self.theme_list_widget, translate('OpenLP.ThemeManager', 'You must select a theme to edit.')): item = self.theme_list_widget.currentItem() theme = self.get_theme_data(item.data(QtCore.Qt.UserRole)) if theme.background_type == 'image' or theme.background_type == 'video': self.old_background_image = theme.background_filename self.theme_form.theme = theme self.theme_form.exec(True) self.old_background_image = None self.renderer.update_theme(theme.theme_name) self.load_themes()
def on_delete_click(self): """ Remove an image item from the list. """ # Turn off auto preview triggers. self.list_view.blockSignals(True) if check_item_selected(self.list_view, translate('ImagePlugin.MediaItem', 'You must select an image or group to delete.')): item_list = self.list_view.selectedItems() self.application.set_busy_cursor() self.main_window.display_progress_bar(len(item_list)) for row_item in item_list: if row_item: item_data = row_item.data(0, QtCore.Qt.UserRole) if isinstance(item_data, ImageFilenames): delete_file(os.path.join(self.service_path, row_item.text(0))) delete_file(self.generate_thumbnail_path(item_data)) if item_data.group_id == 0: self.list_view.takeTopLevelItem(self.list_view.indexOfTopLevelItem(row_item)) else: row_item.parent().removeChild(row_item) self.manager.delete_object(ImageFilenames, row_item.data(0, QtCore.Qt.UserRole).id) elif isinstance(item_data, ImageGroups): if QtGui.QMessageBox.question( self.list_view.parent(), translate('ImagePlugin.MediaItem', 'Remove group'), translate('ImagePlugin.MediaItem', 'Are you sure you want to remove "%s" and everything in it?') % item_data.group_name, QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Yes | QtGui.QMessageBox.No)) == QtGui.QMessageBox.Yes: self.recursively_delete_group(item_data) self.manager.delete_object(ImageGroups, row_item.data(0, QtCore.Qt.UserRole).id) if item_data.parent_id == 0: self.list_view.takeTopLevelItem(self.list_view.indexOfTopLevelItem(row_item)) else: row_item.parent().removeChild(row_item) self.fill_groups_combobox(self.choose_group_form.group_combobox) self.fill_groups_combobox(self.add_group_form.parent_group_combobox) self.main_window.increment_progress_bar() self.main_window.finished_progress_bar() self.application.set_normal_cursor() self.list_view.blockSignals(False)
def on_delete_click(self): """ Remove a presentation item from the list. """ if check_item_selected(self.list_view, UiStrings().SelectDelete): items = self.list_view.selectedIndexes() row_list = [item.row() for item in items] row_list.sort(reverse=True) self.application.set_busy_cursor() self.main_window.display_progress_bar(len(row_list)) for item in items: filepath = str(item.data(QtCore.Qt.UserRole)) self.clean_up_thumbnails(filepath) self.main_window.increment_progress_bar() self.main_window.finished_progress_bar() for row in row_list: self.list_view.takeItem(row) Settings().setValue(self.settings_section + '/presentations files', self.get_file_list()) self.application.set_normal_cursor()
def on_delete_click(self): """ Remove a custom item from the list and database """ if check_item_selected(self.list_view, UiStrings().SelectDelete): items = self.list_view.selectedIndexes() if QtGui.QMessageBox.question(self, UiStrings().ConfirmDelete, translate('CustomPlugin.MediaItem', 'Are you sure you want to delete the %n selected custom slide(s)?', '', QtCore.QCoreApplication.CodecForTr, len(items)), QtGui.QMessageBox.StandardButtons( QtGui.QMessageBox.Yes | QtGui.QMessageBox.No), QtGui.QMessageBox.Yes) == QtGui.QMessageBox.No: return row_list = [item.row() for item in self.list_view.selectedIndexes()] row_list.sort(reverse=True) id_list = [(item.data(QtCore.Qt.UserRole)) for item in self.list_view.selectedIndexes()] for id in id_list: self.plugin.db_manager.delete_object(CustomSlide, id) self.on_search_text_button_clicked()
def test_check_item_selected_false(self): """ Test that the check_item_selected() function returns False when there are no selected indexes. """ # GIVEN: A mocked out QtWidgets module and a list widget with selected indexes with patch('openlp.core.lib.QtWidgets') as MockedQtWidgets, \ patch('openlp.core.lib.translate') as mocked_translate: mocked_translate.return_value = 'mocked translate' mocked_list_widget = MagicMock() mocked_list_widget.selectedIndexes.return_value = False mocked_list_widget.parent.return_value = 'parent' message = 'message' # WHEN: We check if there are selected items result = check_item_selected(mocked_list_widget, message) # THEN: The selectedIndexes function should have been called and the result should be true mocked_list_widget.selectedIndexes.assert_called_with() MockedQtWidgets.QMessageBox.information.assert_called_with('parent', 'mocked translate', 'message') self.assertFalse(result, 'The result should be False')
def onDeleteClick(self): """ Remove a presentation item from the list """ if check_item_selected(self.listView, UiStrings().SelectDelete): items = self.listView.selectedIndexes() row_list = [item.row() for item in items] row_list.sort(reverse=True) self.application.set_busy_cursor() self.main_window.displayProgressBar(len(row_list)) for item in items: filepath = unicode(item.data(QtCore.Qt.UserRole)) for cidx in self.controllers: doc = self.controllers[cidx].add_document(filepath) doc.presentation_deleted() doc.close_presentation() self.main_window.incrementProgressBar() self.main_window.finishedProgressBar() self.application.set_busy_cursor() for row in row_list: self.listView.takeItem(row) Settings().setValue(self.settingsSection + u'/presentations files', self.getFileList())
def on_replace_click(self): """ Called to replace Live background with the media selected. """ if check_item_selected( self.list_view, translate( 'MediaPlugin.MediaItem', 'You must select a media file to replace the background with.' )): item = self.list_view.currentItem() filename = item.data(QtCore.Qt.UserRole) if os.path.exists(filename): service_item = ServiceItem() service_item.title = 'webkit' service_item.processor = 'webkit' (path, name) = os.path.split(filename) service_item.add_from_command(path, name, CLAPPERBOARD) if self.media_controller.video(DisplayControllerType.Live, service_item, video_behind_text=True): self.reset_action.setVisible(True) self.reset_action_context.setVisible(True) else: critical_error_message_box( UiStrings().LiveBGError, translate('MediaPlugin.MediaItem', 'There was no display item to amend.')) else: critical_error_message_box( UiStrings().LiveBGError, translate( 'MediaPlugin.MediaItem', 'There was a problem replacing your background, ' 'the media file "{name}" no longer exists.').format( name=filename))
def on_replace_click(self): """ Called to replace Live background with the image selected. """ if check_item_selected( self.list_view, translate( 'ImagePlugin.MediaItem', 'You must select an image to replace the background with.') ): background = QtGui.QColor(Settings().value(self.settings_section + '/background color')) bitem = self.list_view.selectedItems()[0] if not isinstance(bitem.data(0, QtCore.Qt.UserRole), ImageFilenames): # Only continue when an image is selected. return file_path = bitem.data(0, QtCore.Qt.UserRole).file_path if file_path.exists(): if self.live_controller.display.direct_image( str(file_path), background): self.reset_action.setVisible(True) self.reset_action_context.setVisible(True) else: critical_error_message_box( UiStrings().LiveBGError, translate('ImagePlugin.MediaItem', 'There was no display item to amend.')) else: critical_error_message_box( UiStrings().LiveBGError, translate( 'ImagePlugin.MediaItem', 'There was a problem replacing your background, ' 'the image file "{name}" no longer exists.').format( name=file_path))