forked from openlp/openlp
Update Songs forms
This commit is contained in:
parent
873286df9a
commit
43f156d9fe
|
@ -63,7 +63,7 @@ class ServiceNoteForm(QtGui.QDialog):
|
|||
self.dialog_layout = QtGui.QVBoxLayout(self)
|
||||
self.dialog_layout.setContentsMargins(8, 8, 8, 8)
|
||||
self.dialog_layout.setSpacing(8)
|
||||
self.dialog_layout.setObjectName('verticalLayout')
|
||||
self.dialog_layout.setObjectName('vertical_layout')
|
||||
self.text_edit = SpellTextEdit(self, False)
|
||||
self.text_edit.setObjectName('textEdit')
|
||||
self.dialog_layout.addWidget(self.text_edit)
|
||||
|
|
|
@ -215,7 +215,7 @@ class OpenLPWizard(QtGui.QWizard):
|
|||
"""
|
||||
if self.with_progress_page and self.page(pageId) == self.progress_page:
|
||||
self.pre_wizard()
|
||||
self.performWizard()
|
||||
self.perform_wizard()
|
||||
self.post_wizard()
|
||||
else:
|
||||
self.custom_page_changed(pageId)
|
||||
|
@ -294,8 +294,8 @@ class OpenLPWizard(QtGui.QWizard):
|
|||
if filters:
|
||||
filters += ';;'
|
||||
filters += '%s (*)' % UiStrings().AllFiles
|
||||
filename = QtGui.QFileDialog.getOpenFileName(self, title,
|
||||
os.path.dirname(Settings().value(self.plugin.settings_section + '/' + setting_name)), filters)
|
||||
filename = QtGui.QFileDialog.getOpenFileName(
|
||||
self, title, os.path.dirname(Settings().value(self.plugin.settings_section + '/' + setting_name)), filters)
|
||||
if filename:
|
||||
editbox.setText(filename)
|
||||
Settings().setValue(self.plugin.settings_section + '/' + setting_name, filename)
|
||||
|
@ -313,8 +313,9 @@ class OpenLPWizard(QtGui.QWizard):
|
|||
``setting_name``
|
||||
The place where to save the last opened directory.
|
||||
"""
|
||||
folder = QtGui.QFileDialog.getExistingDirectory(self, title,
|
||||
Settings().value(self.plugin.settings_section + '/' + setting_name), QtGui.QFileDialog.ShowDirsOnly)
|
||||
folder = QtGui.QFileDialog.getExistingDirectory(
|
||||
self, title, Settings().value(self.plugin.settings_section + '/' + setting_name),
|
||||
QtGui.QFileDialog.ShowDirsOnly)
|
||||
if folder:
|
||||
editbox.setText(folder)
|
||||
Settings().setValue(self.plugin.settings_section + '/' + setting_name, folder)
|
||||
|
|
|
@ -524,7 +524,7 @@ class BibleImportForm(OpenLPWizard):
|
|||
self.progress_label.setText(WizardStrings.StartingImport)
|
||||
self.application.process_events()
|
||||
|
||||
def performWizard(self):
|
||||
def perform_wizard(self):
|
||||
"""
|
||||
Perform the actual import.
|
||||
"""
|
||||
|
|
|
@ -107,7 +107,7 @@ class BibleUpgradeForm(OpenLPWizard):
|
|||
"""
|
||||
if self.page(pageId) == self.progress_page:
|
||||
self.pre_wizard()
|
||||
self.performWizard()
|
||||
self.perform_wizard()
|
||||
self.post_wizard()
|
||||
elif self.page(pageId) == self.selectPage and not self.files:
|
||||
self.next()
|
||||
|
@ -312,7 +312,7 @@ class BibleUpgradeForm(OpenLPWizard):
|
|||
"""
|
||||
Set default values for the wizard pages.
|
||||
"""
|
||||
log.debug('BibleUpgrade setDefaults')
|
||||
log.debug('BibleUpgrade set_defaults')
|
||||
settings = Settings()
|
||||
settings.beginGroup(self.plugin.settings_section)
|
||||
self.stop_import_flag = False
|
||||
|
@ -338,7 +338,7 @@ class BibleUpgradeForm(OpenLPWizard):
|
|||
self.progress_label.setText(translate('BiblesPlugin.UpgradeWizardForm', 'Starting upgrade...'))
|
||||
self.application.process_events()
|
||||
|
||||
def performWizard(self):
|
||||
def perform_wizard(self):
|
||||
"""
|
||||
Perform the actual upgrade.
|
||||
"""
|
||||
|
|
|
@ -43,16 +43,15 @@ from openlp.plugins.presentations.lib import PresentationController, Presentatio
|
|||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
__default_settings__ = {
|
||||
'presentations/override app': QtCore.Qt.Unchecked,
|
||||
'presentations/enable_pdf_program': QtCore.Qt.Unchecked,
|
||||
'presentations/pdf_program': '',
|
||||
'presentations/Impress': QtCore.Qt.Checked,
|
||||
'presentations/Powerpoint': QtCore.Qt.Checked,
|
||||
'presentations/Powerpoint Viewer': QtCore.Qt.Checked,
|
||||
'presentations/Pdf': QtCore.Qt.Checked,
|
||||
'presentations/presentations files': []
|
||||
}
|
||||
__default_settings__ = {'presentations/override app': QtCore.Qt.Unchecked,
|
||||
'presentations/enable_pdf_program': QtCore.Qt.Unchecked,
|
||||
'presentations/pdf_program': '',
|
||||
'presentations/Impress': QtCore.Qt.Checked,
|
||||
'presentations/Powerpoint': QtCore.Qt.Checked,
|
||||
'presentations/Powerpoint Viewer': QtCore.Qt.Checked,
|
||||
'presentations/Pdf': QtCore.Qt.Checked,
|
||||
'presentations/presentations files': []
|
||||
}
|
||||
|
||||
|
||||
class PresentationPlugin(Plugin):
|
||||
|
@ -147,10 +146,10 @@ class PresentationPlugin(Plugin):
|
|||
Return information about this plugin.
|
||||
"""
|
||||
about_text = translate('PresentationPlugin', '<strong>Presentation '
|
||||
'Plugin</strong><br />The presentation plugin provides the '
|
||||
'ability to show presentations using a number of different '
|
||||
'programs. The choice of available presentation programs is '
|
||||
'available to the user in a drop down box.')
|
||||
'Plugin</strong><br />The presentation plugin provides the '
|
||||
'ability to show presentations using a number of different '
|
||||
'programs. The choice of available presentation programs is '
|
||||
'available to the user in a drop down box.')
|
||||
return about_text
|
||||
|
||||
def set_plugin_text_strings(self):
|
||||
|
|
|
@ -111,8 +111,8 @@ class AuthorsForm(QtGui.QDialog, Ui_AuthorsDialog):
|
|||
elif not self.display_edit.text():
|
||||
if critical_error_message_box(
|
||||
message=translate('SongsPlugin.AuthorsForm',
|
||||
'You have not set a display name for the author, combine the first and last names?'),
|
||||
parent=self, question=True) == QtGui.QMessageBox.Yes:
|
||||
'You have not set a display name for the author, combine the first and last names?'),
|
||||
parent=self, question=True) == QtGui.QMessageBox.Yes:
|
||||
self.display_edit.setText(self.first_name_edit.text() + ' ' + self.last_name_edit.text())
|
||||
return QtGui.QDialog.accept(self)
|
||||
else:
|
||||
|
|
|
@ -47,8 +47,8 @@ log = logging.getLogger(__name__)
|
|||
|
||||
class DuplicateSongRemovalForm(OpenLPWizard):
|
||||
"""
|
||||
This is the Duplicate Song Removal Wizard. It provides functionality to
|
||||
search for and remove duplicate songs in the database.
|
||||
This is the Duplicate Song Removal Wizard. It provides functionality to search for and remove duplicate songs
|
||||
in the database.
|
||||
"""
|
||||
log.info('DuplicateSongRemovalForm loaded')
|
||||
|
||||
|
@ -56,19 +56,16 @@ class DuplicateSongRemovalForm(OpenLPWizard):
|
|||
"""
|
||||
Instantiate the wizard, and run any extra setup we need to.
|
||||
|
||||
``parent``
|
||||
The QWidget-derived parent of the wizard.
|
||||
|
||||
``plugin``
|
||||
The songs plugin.
|
||||
:param plugin: The songs plugin.
|
||||
"""
|
||||
self.duplicate_song_list = []
|
||||
self.review_current_count = 0
|
||||
self.review_total_count = 0
|
||||
# Used to interrupt ongoing searches when cancel is clicked.
|
||||
self.break_search = False
|
||||
super(DuplicateSongRemovalForm, self).__init__(Registry().get('main_window'),
|
||||
plugin, 'duplicateSongRemovalWizard', ':/wizards/wizard_duplicateremoval.bmp', False)
|
||||
super(DuplicateSongRemovalForm, self).__init__(
|
||||
Registry().get('main_window'), plugin, 'duplicateSongRemovalWizard', ':/wizards/wizard_duplicateremoval.bmp'
|
||||
, False)
|
||||
self.setMinimumWidth(730)
|
||||
|
||||
def custom_signals(self):
|
||||
|
@ -127,30 +124,31 @@ class DuplicateSongRemovalForm(OpenLPWizard):
|
|||
"""
|
||||
self.setWindowTitle(translate('Wizard', 'Wizard'))
|
||||
self.title_label.setText(WizardStrings.HeaderStyle % translate('OpenLP.Ui',
|
||||
'Welcome to the Duplicate Song Removal Wizard'))
|
||||
self.information_label.setText(translate("Wizard",
|
||||
'This wizard will help you to remove duplicate songs from the song database. You will have a chance to '
|
||||
'review every potential duplicate song before it is deleted. So no songs will be deleted without your '
|
||||
'explicit approval.'))
|
||||
'Welcome to the Duplicate Song Removal Wizard'))
|
||||
self.information_label.setText(
|
||||
translate("Wizard",
|
||||
'This wizard will help you to remove duplicate songs from the song database. You will have a '
|
||||
'chance to review every potential duplicate song before it is deleted. So no songs will be '
|
||||
'deleted without your explicit approval.'))
|
||||
self.searching_page.setTitle(translate('Wizard', 'Searching for duplicate songs.'))
|
||||
self.searching_page.setSubTitle(translate('Wizard', 'Please wait while your songs database is analyzed.'))
|
||||
self.update_review_counter_text()
|
||||
self.review_page.setSubTitle(translate('Wizard',
|
||||
'Here you can decide which songs to remove and which ones to keep.'))
|
||||
'Here you can decide which songs to remove and which ones to keep.'))
|
||||
|
||||
def update_review_counter_text(self):
|
||||
"""
|
||||
Set the wizard review page header text.
|
||||
"""
|
||||
self.review_page.setTitle(translate('Wizard', 'Review duplicate songs (%s/%s)') % \
|
||||
(self.review_current_count, self.review_total_count))
|
||||
self.review_page.setTitle(
|
||||
translate('Wizard', 'Review duplicate songs (%s/%s)') %
|
||||
(self.review_current_count, self.review_total_count))
|
||||
|
||||
def custom_page_changed(self, page_id):
|
||||
"""
|
||||
Called when changing the wizard page.
|
||||
|
||||
``page_id``
|
||||
ID of the page the wizard changed to.
|
||||
:param page_id: ID of the page the wizard changed to.
|
||||
"""
|
||||
# Hide back button.
|
||||
self.button(QtGui.QWizard.BackButton).hide()
|
||||
|
@ -172,11 +170,11 @@ class DuplicateSongRemovalForm(OpenLPWizard):
|
|||
for outer_song_counter in range(max_songs - 1):
|
||||
for inner_song_counter in range(outer_song_counter + 1, max_songs):
|
||||
if songs_probably_equal(songs[outer_song_counter], songs[inner_song_counter]):
|
||||
duplicate_added = self.add_duplicates_to_song_list(songs[outer_song_counter],
|
||||
songs[inner_song_counter])
|
||||
duplicate_added = self.add_duplicates_to_song_list(
|
||||
songs[outer_song_counter], songs[inner_song_counter])
|
||||
if duplicate_added:
|
||||
self.found_duplicates_edit.appendPlainText(songs[outer_song_counter].title + " = " +
|
||||
songs[inner_song_counter].title)
|
||||
self.found_duplicates_edit.appendPlainText(
|
||||
songs[outer_song_counter].title + " = " + songs[inner_song_counter].title)
|
||||
self.duplicate_search_progress_bar.setValue(self.duplicate_search_progress_bar.value() + 1)
|
||||
# The call to process_events() will keep the GUI responsive.
|
||||
self.application.process_events()
|
||||
|
@ -200,23 +198,20 @@ class DuplicateSongRemovalForm(OpenLPWizard):
|
|||
self.button(QtGui.QWizard.FinishButton).setEnabled(True)
|
||||
self.button(QtGui.QWizard.NextButton).hide()
|
||||
self.button(QtGui.QWizard.CancelButton).hide()
|
||||
QtGui.QMessageBox.information(self, translate('Wizard', 'Information'),
|
||||
QtGui.QMessageBox.information(
|
||||
self, translate('Wizard', 'Information'),
|
||||
translate('Wizard', 'No duplicate songs have been found in the database.'),
|
||||
QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok))
|
||||
|
||||
def add_duplicates_to_song_list(self, search_song, duplicate_song):
|
||||
"""
|
||||
Inserts a song duplicate (two similar songs) to the duplicate song list.
|
||||
If one of the two songs is already part of the duplicate song list,
|
||||
don't add another duplicate group but add the other song to that group.
|
||||
Returns True if at least one of the songs was added, False if both were already
|
||||
member of a group.
|
||||
If one of the two songs is already part of the duplicate song list, don't add another duplicate group but
|
||||
add the other song to that group.
|
||||
Returns True if at least one of the songs was added, False if both were already member of a group.
|
||||
|
||||
``search_song``
|
||||
The song we searched the duplicate for.
|
||||
|
||||
``duplicate_song``
|
||||
The duplicate song.
|
||||
:param search_song: The song we searched the duplicate for.
|
||||
:param duplicate_song: The duplicate song.
|
||||
"""
|
||||
duplicate_group_found = False
|
||||
duplicate_added = False
|
||||
|
@ -259,8 +254,8 @@ class DuplicateSongRemovalForm(OpenLPWizard):
|
|||
|
||||
def validateCurrentPage(self):
|
||||
"""
|
||||
Controls whether we should switch to the next wizard page. This method loops
|
||||
on the review page as long as there are more song duplicates to review.
|
||||
Controls whether we should switch to the next wizard page. This method loops on the review page as long as
|
||||
there are more song duplicates to review.
|
||||
"""
|
||||
if self.currentId() == self.review_page_id:
|
||||
# As long as it's not the last duplicate list entry we revisit the review page.
|
||||
|
@ -273,12 +268,10 @@ class DuplicateSongRemovalForm(OpenLPWizard):
|
|||
|
||||
def remove_button_clicked(self, song_review_widget):
|
||||
"""
|
||||
Removes a song from the database, removes the GUI element representing the
|
||||
song on the review page, and disable the remove button if only one duplicate
|
||||
is left.
|
||||
Removes a song from the database, removes the GUI element representing the song on the review page, and
|
||||
disable the remove button if only one duplicate is left.
|
||||
|
||||
``song_review_widget``
|
||||
The SongReviewWidget whose song we should delete.
|
||||
:param song_review_widget: The SongReviewWidget whose song we should delete.
|
||||
"""
|
||||
# Remove song from duplicate song list.
|
||||
self.duplicate_song_list[-1].remove(song_review_widget.song)
|
||||
|
@ -315,9 +308,8 @@ class DuplicateSongRemovalForm(OpenLPWizard):
|
|||
|
||||
def process_current_duplicate_entry(self):
|
||||
"""
|
||||
Update the review counter in the wizard header, add song widgets for
|
||||
the current duplicate group to review, if it's the last
|
||||
duplicate song group, hide the "next" button and show the "finish" button.
|
||||
Update the review counter in the wizard header, add song widgets for the current duplicate group to review,
|
||||
if it's the last duplicate song group, hide the "next" button and show the "finish" button.
|
||||
"""
|
||||
# Update the counter.
|
||||
self.review_current_count = self.review_total_count - (len(self.duplicate_song_list) - 1)
|
||||
|
|
|
@ -153,8 +153,8 @@ class Ui_EditSongDialog(object):
|
|||
self.topics_layout.setObjectName('topics_layout')
|
||||
self.topic_add_layout = QtGui.QHBoxLayout()
|
||||
self.topic_add_layout.setObjectName('topic_add_layout')
|
||||
self.topicsComboBox = create_combo_box(self.topics_group_box, 'topicsComboBox')
|
||||
self.topic_add_layout.addWidget(self.topicsComboBox)
|
||||
self.topics_combo_box = create_combo_box(self.topics_group_box, 'topics_combo_box')
|
||||
self.topic_add_layout.addWidget(self.topics_combo_box)
|
||||
self.topic_add_button = QtGui.QPushButton(self.topics_group_box)
|
||||
self.topic_add_button.setObjectName('topic_add_button')
|
||||
self.topic_add_layout.addWidget(self.topic_add_button)
|
||||
|
@ -296,7 +296,7 @@ class Ui_EditSongDialog(object):
|
|||
self.verse_edit_all_button.setText(translate('SongsPlugin.EditSongForm', 'Ed&it All'))
|
||||
self.verse_delete_button.setText(UiStrings().Delete)
|
||||
self.song_tab_widget.setTabText(self.song_tab_widget.indexOf(self.lyrics_tab),
|
||||
translate('SongsPlugin.EditSongForm', 'Title && Lyrics'))
|
||||
translate('SongsPlugin.EditSongForm', 'Title && Lyrics'))
|
||||
self.authors_group_box.setTitle(SongStrings.Authors)
|
||||
self.author_add_button.setText(translate('SongsPlugin.EditSongForm', '&Add to Song'))
|
||||
self.author_remove_button.setText(translate('SongsPlugin.EditSongForm', '&Remove'))
|
||||
|
@ -308,7 +308,7 @@ class Ui_EditSongDialog(object):
|
|||
self.song_book_name_label.setText(translate('SongsPlugin.EditSongForm', 'Book:'))
|
||||
self.song_book_number_label.setText(translate('SongsPlugin.EditSongForm', 'Number:'))
|
||||
self.song_tab_widget.setTabText(self.song_tab_widget.indexOf(self.authors_tab),
|
||||
translate('SongsPlugin.EditSongForm', 'Authors, Topics && Song Book'))
|
||||
translate('SongsPlugin.EditSongForm', 'Authors, Topics && Song Book'))
|
||||
self.theme_group_box.setTitle(UiStrings().Theme)
|
||||
self.theme_add_button.setText(translate('SongsPlugin.EditSongForm', 'New &Theme'))
|
||||
self.rights_group_box.setTitle(translate('SongsPlugin.EditSongForm', 'Copyright Information'))
|
||||
|
@ -316,9 +316,9 @@ class Ui_EditSongDialog(object):
|
|||
self.ccli_label.setText(UiStrings().CCLINumberLabel)
|
||||
self.comments_group_box.setTitle(translate('SongsPlugin.EditSongForm', 'Comments'))
|
||||
self.song_tab_widget.setTabText(self.song_tab_widget.indexOf(self.theme_tab),
|
||||
translate('SongsPlugin.EditSongForm', 'Theme, Copyright Info && Comments'))
|
||||
translate('SongsPlugin.EditSongForm', 'Theme, Copyright Info && Comments'))
|
||||
self.song_tab_widget.setTabText(self.song_tab_widget.indexOf(self.audio_tab),
|
||||
translate('SongsPlugin.EditSongForm', 'Linked Audio'))
|
||||
translate('SongsPlugin.EditSongForm', 'Linked Audio'))
|
||||
self.from_file_button.setText(translate('SongsPlugin.EditSongForm', 'Add &File(s)'))
|
||||
self.from_media_button.setText(translate('SongsPlugin.EditSongForm', 'Add &Media'))
|
||||
self.audio_remove_button.setText(translate('SongsPlugin.EditSongForm', '&Remove'))
|
||||
|
|
|
@ -131,6 +131,12 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
|||
self.authors_list_view.addItem(author_item)
|
||||
|
||||
def _extract_verse_order(self, verse_order):
|
||||
"""
|
||||
Split out the verse order
|
||||
|
||||
:param verse_order: The starting verse order
|
||||
:return: revised order
|
||||
"""
|
||||
order = []
|
||||
order_names = str(verse_order).split()
|
||||
for item in order_names:
|
||||
|
@ -153,6 +159,13 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
|||
return order
|
||||
|
||||
def _validate_verse_list(self, verse_order, verse_count):
|
||||
"""
|
||||
Check the verse order list has valid verses
|
||||
|
||||
:param verse_order: Verse order
|
||||
:param verse_count: number of verses
|
||||
:return: Count of invalid verses
|
||||
"""
|
||||
verses = []
|
||||
invalid_verses = []
|
||||
verse_names = []
|
||||
|
@ -171,12 +184,12 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
|||
valid = create_separated_list(verse_names)
|
||||
if len(invalid_verses) > 1:
|
||||
msg = translate('SongsPlugin.EditSongForm', 'There are no verses corresponding to "%(invalid)s".'
|
||||
'Valid entries are %(valid)s.\nPlease enter the verses seperated by spaces.') \
|
||||
% {'invalid' : ', '.join(invalid_verses), 'valid' : valid}
|
||||
'Valid entries are %(valid)s.\nPlease enter the verses separated by spaces.') % \
|
||||
{'invalid': ', '.join(invalid_verses), 'valid' : valid}
|
||||
else:
|
||||
msg = translate('SongsPlugin.EditSongForm', 'There is no verse corresponding to "%(invalid)s".'
|
||||
'Valid entries are %(valid)s.\nPlease enter the verses seperated by spaces.') \
|
||||
% {'invalid' : invalid_verses[0], 'valid' : valid}
|
||||
'Valid entries are %(valid)s.\nPlease enter the verses separated by spaces.') % \
|
||||
{'invalid': invalid_verses[0], 'valid' : valid}
|
||||
critical_error_message_box(title=translate('SongsPlugin.EditSongForm', 'Invalid Verse Order'),
|
||||
message=msg)
|
||||
return len(invalid_verses) == 0
|
||||
|
@ -213,7 +226,8 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
|||
return False
|
||||
text = self.song_book_combo_box.currentText()
|
||||
if self.song_book_combo_box.findText(text, QtCore.Qt.MatchExactly) < 0:
|
||||
if QtGui.QMessageBox.question(self, translate('SongsPlugin.EditSongForm', 'Add Book'),
|
||||
if QtGui.QMessageBox.question(
|
||||
self, translate('SongsPlugin.EditSongForm', 'Add Book'),
|
||||
translate('SongsPlugin.EditSongForm', 'This song book does not exist, do you want to add it?'),
|
||||
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No, QtGui.QMessageBox.Yes) == QtGui.QMessageBox.Yes:
|
||||
book = Book.populate(name=text, publisher='')
|
||||
|
@ -250,17 +264,16 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
|||
|
||||
def keyPressEvent(self, event):
|
||||
"""
|
||||
Reimplement the keyPressEvent to react on Return/Enter keys. When some combo boxes have focus we do not want
|
||||
Re-implement the keyPressEvent to react on Return/Enter keys. When some combo boxes have focus we do not want
|
||||
dialog's default action be triggered but instead our own.
|
||||
|
||||
``event``
|
||||
A QtGui.QKeyEvent event.
|
||||
:param event: A QtGui.QKeyEvent event.
|
||||
"""
|
||||
if event.key() in (QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return):
|
||||
if self.authors_combo_box.hasFocus() and self.authors_combo_box.currentText():
|
||||
self.on_author_add_button_clicked()
|
||||
return
|
||||
if self.topicsComboBox.hasFocus() and self.topicsComboBox.currentText():
|
||||
if self.topics_combo_box.hasFocus() and self.topics_combo_box.currentText():
|
||||
self.on_topic_add_button_clicked()
|
||||
return
|
||||
QtGui.QDialog.keyPressEvent(self, event)
|
||||
|
@ -294,7 +307,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
|||
Load the topics into the combobox.
|
||||
"""
|
||||
self.topics = []
|
||||
self._load_objects(Topic, self.topicsComboBox, self.topics)
|
||||
self._load_objects(Topic, self.topics_combo_box, self.topics)
|
||||
|
||||
def load_books(self):
|
||||
"""
|
||||
|
@ -321,7 +334,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
|||
for plugin in self.plugin_manager.plugins:
|
||||
if plugin.name == 'media' and plugin.status == PluginStatus.Active:
|
||||
self.from_media_button.setVisible(True)
|
||||
self.media_form.populateFiles(plugin.media_item.get_list(MediaType.Audio))
|
||||
self.media_form.populate_files(plugin.media_item.get_list(MediaType.Audio))
|
||||
break
|
||||
|
||||
def new_song(self):
|
||||
|
@ -358,11 +371,8 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
|||
"""
|
||||
Loads a song.
|
||||
|
||||
``song_id``
|
||||
The song id (int).
|
||||
|
||||
``preview``
|
||||
Should be ``True`` if the song is also previewed (boolean).
|
||||
:param song_id: The song id (int).
|
||||
:param preview: Should be ``True`` if the song is also previewed (boolean).
|
||||
"""
|
||||
log.debug('Load Song')
|
||||
self.initialise()
|
||||
|
@ -396,8 +406,8 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
|||
self.verse_list_widget.setRowCount(0)
|
||||
verse_tags_translated = False
|
||||
if self.song.lyrics.startswith('<?xml version='):
|
||||
songXML = SongXML()
|
||||
verse_list = songXML.get_verses(self.song.lyrics)
|
||||
song_xml = SongXML()
|
||||
verse_list = song_xml.get_verses(self.song.lyrics)
|
||||
for count, verse in enumerate(verse_list):
|
||||
self.verse_list_widget.setRowCount(self.verse_list_widget.rowCount() + 1)
|
||||
# This silently migrates from localized verse type markup.
|
||||
|
@ -487,20 +497,21 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
|||
item = int(self.authors_combo_box.currentIndex())
|
||||
text = self.authors_combo_box.currentText().strip(' \r\n\t')
|
||||
# This if statement is for OS X, which doesn't seem to work well with
|
||||
# the QCompleter autocompletion class. See bug #812628.
|
||||
# the QCompleter auto-completion class. See bug #812628.
|
||||
if text in self.authors:
|
||||
# Index 0 is a blank string, so add 1
|
||||
item = self.authors.index(text) + 1
|
||||
if item == 0 and text:
|
||||
if QtGui.QMessageBox.question(self,
|
||||
translate('SongsPlugin.EditSongForm', 'Add Author'),
|
||||
translate('SongsPlugin.EditSongForm', 'This author does not exist, do you want to add them?'),
|
||||
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No, QtGui.QMessageBox.Yes) == QtGui.QMessageBox.Yes:
|
||||
if QtGui.QMessageBox.question(
|
||||
self,
|
||||
translate('SongsPlugin.EditSongForm', 'Add Author'),
|
||||
translate('SongsPlugin.EditSongForm', 'This author does not exist, do you want to add them?'),
|
||||
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No, QtGui.QMessageBox.Yes) == QtGui.QMessageBox.Yes:
|
||||
if text.find(' ') == -1:
|
||||
author = Author.populate(first_name='', last_name='', display_name=text)
|
||||
else:
|
||||
author = Author.populate(first_name=text.rsplit(' ', 1)[0],
|
||||
last_name=text.rsplit(' ', 1)[1], display_name=text)
|
||||
author = Author.populate(first_name=text.rsplit(' ', 1)[0], last_name=text.rsplit(' ', 1)[1],
|
||||
display_name=text)
|
||||
self.manager.save_object(author)
|
||||
self._add_author_to_list(author)
|
||||
self.load_authors()
|
||||
|
@ -510,18 +521,18 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
|||
elif item > 0:
|
||||
item_id = (self.authors_combo_box.itemData(item))
|
||||
author = self.manager.get_object(Author, item_id)
|
||||
if self.authors_list_view.findItems(str(author.display_name),
|
||||
QtCore.Qt.MatchExactly):
|
||||
if self.authors_list_view.findItems(str(author.display_name), QtCore.Qt.MatchExactly):
|
||||
critical_error_message_box(
|
||||
message=translate('SongsPlugin.EditSongForm', 'This author is already in the list.'))
|
||||
else:
|
||||
self._add_author_to_list(author)
|
||||
self.authors_combo_box.setCurrentIndex(0)
|
||||
else:
|
||||
QtGui.QMessageBox.warning(self, UiStrings().NISs,
|
||||
QtGui.QMessageBox.warning(
|
||||
self, UiStrings().NISs,
|
||||
translate('SongsPlugin.EditSongForm', 'You have not selected a valid author. Either select an author '
|
||||
'from the list, or type in a new author and click the "Add Author to Song" button to add '
|
||||
'the new author.'))
|
||||
'from the list, or type in a new author and click the "Add Author to Song" button to add '
|
||||
'the new author.'))
|
||||
|
||||
def on_authors_list_view_clicked(self):
|
||||
"""
|
||||
|
@ -540,10 +551,11 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
|||
self.authors_list_view.takeItem(row)
|
||||
|
||||
def on_topic_add_button_clicked(self):
|
||||
item = int(self.topicsComboBox.currentIndex())
|
||||
text = self.topicsComboBox.currentText()
|
||||
item = int(self.topics_combo_box.currentIndex())
|
||||
text = self.topics_combo_box.currentText()
|
||||
if item == 0 and text:
|
||||
if QtGui.QMessageBox.question(self, translate('SongsPlugin.EditSongForm', 'Add Topic'),
|
||||
if QtGui.QMessageBox.question(
|
||||
self, translate('SongsPlugin.EditSongForm', 'Add Topic'),
|
||||
translate('SongsPlugin.EditSongForm', 'This topic does not exist, do you want to add it?'),
|
||||
QtGui.QMessageBox.Yes | QtGui.QMessageBox.No, QtGui.QMessageBox.Yes) == QtGui.QMessageBox.Yes:
|
||||
topic = Topic.populate(name=text)
|
||||
|
@ -552,25 +564,26 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
|||
topic_item.setData(QtCore.Qt.UserRole, topic.id)
|
||||
self.topics_list_view.addItem(topic_item)
|
||||
self.load_topics()
|
||||
self.topicsComboBox.setCurrentIndex(0)
|
||||
self.topics_combo_box.setCurrentIndex(0)
|
||||
else:
|
||||
return
|
||||
elif item > 0:
|
||||
item_id = (self.topicsComboBox.itemData(item))
|
||||
item_id = (self.topics_combo_box.itemData(item))
|
||||
topic = self.manager.get_object(Topic, item_id)
|
||||
if self.topics_list_view.findItems(str(topic.name),
|
||||
QtCore.Qt.MatchExactly):
|
||||
if self.topics_list_view.findItems(str(topic.name), QtCore.Qt.MatchExactly):
|
||||
critical_error_message_box(
|
||||
message=translate('SongsPlugin.EditSongForm', 'This topic is already in the list.'))
|
||||
else:
|
||||
topic_item = QtGui.QListWidgetItem(str(topic.name))
|
||||
topic_item.setData(QtCore.Qt.UserRole, topic.id)
|
||||
self.topics_list_view.addItem(topic_item)
|
||||
self.topicsComboBox.setCurrentIndex(0)
|
||||
self.topics_combo_box.setCurrentIndex(0)
|
||||
else:
|
||||
QtGui.QMessageBox.warning(self, UiStrings().NISs,
|
||||
QtGui.QMessageBox.warning(
|
||||
self, UiStrings().NISs,
|
||||
translate('SongsPlugin.EditSongForm', 'You have not selected a valid topic. Either select a topic '
|
||||
'from the list, or type in a new topic and click the "Add Topic to Song" button to add the new topic.'))
|
||||
'from the list, or type in a new topic and click the "Add Topic to Song" button to add the '
|
||||
'new topic.'))
|
||||
|
||||
def on_topic_list_view_clicked(self):
|
||||
self.topic_remove_button.setEnabled(True)
|
||||
|
@ -588,7 +601,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
|||
def on_verse_add_button_clicked(self):
|
||||
self.verse_form.set_verse('', True)
|
||||
if self.verse_form.exec_():
|
||||
after_text, verse_tag, verse_num = self.verse_form.get_verse()
|
||||
after_text, verse_tag, verse_num = self.verse_form.get_verse
|
||||
verse_def = '%s%s' % (verse_tag, verse_num)
|
||||
item = QtGui.QTableWidgetItem(after_text)
|
||||
item.setData(QtCore.Qt.UserRole, verse_def)
|
||||
|
@ -606,7 +619,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
|||
verse_id = item.data(QtCore.Qt.UserRole)
|
||||
self.verse_form.set_verse(temp_text, True, verse_id)
|
||||
if self.verse_form.exec_():
|
||||
after_text, verse_tag, verse_num = self.verse_form.get_verse()
|
||||
after_text, verse_tag, verse_num = self.verse_form.get_verse
|
||||
verse_def = '%s%s' % (verse_tag, verse_num)
|
||||
item.setData(QtCore.Qt.UserRole, verse_def)
|
||||
item.setText(after_text)
|
||||
|
@ -628,6 +641,11 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
|||
self.on_verse_order_text_changed(self.verse_order_edit.text())
|
||||
|
||||
def on_verse_edit_all_button_clicked(self):
|
||||
"""
|
||||
Verse edit all button (save) pressed
|
||||
|
||||
:return:
|
||||
"""
|
||||
verse_list = ''
|
||||
if self.verse_list_widget.rowCount() > 0:
|
||||
for row in range(self.verse_list_widget.rowCount()):
|
||||
|
@ -643,7 +661,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
|||
self.verse_form.set_verse('')
|
||||
if not self.verse_form.exec_():
|
||||
return
|
||||
verse_list = self.verse_form.get_all_verses()
|
||||
verse_list = self.verse_form.get_all_verses
|
||||
verse_list = str(verse_list.replace('\r\n', '\n'))
|
||||
self.verse_list_widget.clear()
|
||||
self.verse_list_widget.setRowCount(0)
|
||||
|
@ -686,6 +704,10 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
|||
self.on_verse_order_text_changed(self.verse_order_edit.text())
|
||||
|
||||
def on_verse_delete_button_clicked(self):
|
||||
"""
|
||||
Verse Delete button pressed
|
||||
|
||||
"""
|
||||
self.verse_list_widget.removeRow(self.verse_list_widget.currentRow())
|
||||
if not self.verse_list_widget.selectedItems():
|
||||
self.verse_edit_button.setEnabled(False)
|
||||
|
@ -696,8 +718,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
|||
Checks if the verse order is complete or missing. Shows a error message according to the state of the verse
|
||||
order.
|
||||
|
||||
``text``
|
||||
The text of the verse order edit (ignored).
|
||||
:param text: The text of the verse order edit (ignored).
|
||||
"""
|
||||
# Extract all verses which were used in the order.
|
||||
verses_in_order = self._extract_verse_order(self.verse_order_edit.text())
|
||||
|
@ -719,6 +740,9 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
|||
self.warning_label.setText(label_text)
|
||||
|
||||
def on_copyright_insert_button_triggered(self):
|
||||
"""
|
||||
Copyright insert button pressed
|
||||
"""
|
||||
text = self.copyright_edit.text()
|
||||
pos = self.copyright_edit.cursorPosition()
|
||||
sign = SongStrings.CopyrightSymbol
|
||||
|
@ -728,6 +752,9 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
|||
self.copyright_edit.setCursorPosition(pos + len(sign))
|
||||
|
||||
def on_maintenance_button_clicked(self):
|
||||
"""
|
||||
Maintenance button pressed
|
||||
"""
|
||||
temp_song_book = None
|
||||
item = int(self.song_book_combo_box.currentIndex())
|
||||
text = self.song_book_combo_box.currentText()
|
||||
|
@ -745,8 +772,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
|||
Save and Preview button clicked.
|
||||
The Song is valid so as the plugin to add it to preview to see.
|
||||
|
||||
``button``
|
||||
A button (QPushButton).
|
||||
:param button: A button (QPushButton).
|
||||
"""
|
||||
log.debug('onPreview')
|
||||
if button.objectName() == 'preview_button':
|
||||
|
@ -758,9 +784,9 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
|||
Loads file(s) from the filesystem.
|
||||
"""
|
||||
filters = '%s (*)' % UiStrings().AllFiles
|
||||
filenames = FileDialog.getOpenFileNames(self,
|
||||
translate('SongsPlugin.EditSongForm', 'Open File(s)'), '', filters)
|
||||
for filename in filenames:
|
||||
file_names = FileDialog.getOpenFileNames(self, translate('SongsPlugin.EditSongForm', 'Open File(s)'), '',
|
||||
filters)
|
||||
for filename in file_names:
|
||||
item = QtGui.QListWidgetItem(os.path.split(str(filename))[1])
|
||||
item.setData(QtCore.Qt.UserRole, filename)
|
||||
self.audio_list_widget.addItem(item)
|
||||
|
@ -770,7 +796,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
|||
Loads file(s) from the media plugin.
|
||||
"""
|
||||
if self.media_form.exec_():
|
||||
for filename in self.media_form.getSelectedFiles():
|
||||
for filename in self.media_form.get_selected_files():
|
||||
item = QtGui.QListWidgetItem(os.path.split(str(filename))[1])
|
||||
item.setData(QtCore.Qt.UserRole, filename)
|
||||
self.audio_list_widget.addItem(item)
|
||||
|
@ -814,7 +840,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
|||
|
||||
def clear_caches(self):
|
||||
"""
|
||||
Free up autocompletion memory on dialog exit
|
||||
Free up auto-completion memory on dialog exit
|
||||
"""
|
||||
log.debug('SongEditForm.clearCaches')
|
||||
self.authors = []
|
||||
|
@ -826,7 +852,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
|||
"""
|
||||
Exit Dialog and do not save
|
||||
"""
|
||||
log.debug ('SongEditForm.reject')
|
||||
log.debug('SongEditForm.reject')
|
||||
self.clear_caches()
|
||||
QtGui.QDialog.reject(self)
|
||||
|
||||
|
@ -843,13 +869,10 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
|||
|
||||
def save_song(self, preview=False):
|
||||
"""
|
||||
Get all the data from the widgets on the form, and then save it to the
|
||||
database. The form has been validated and all reference items
|
||||
(Authors, Books and Topics) have been saved before this function is
|
||||
called.
|
||||
Get all the data from the widgets on the form, and then save it to the database. The form has been validated
|
||||
and all reference items (Authors, Books and Topics) have been saved before this function is called.
|
||||
|
||||
``preview``
|
||||
Should be ``True`` if the song is also previewed (boolean).
|
||||
:param preview: Should be ``True`` if the song is also previewed (boolean).
|
||||
"""
|
||||
# The Song() assignment. No database calls should be made while a
|
||||
# Song() is in a partially complete state.
|
||||
|
@ -863,9 +886,9 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
|||
self.song.search_lyrics = ''
|
||||
self.song.verse_order = ''
|
||||
self.song.comments = self.comments_edit.toPlainText()
|
||||
ordertext = self.verse_order_edit.text()
|
||||
order_text = self.verse_order_edit.text()
|
||||
order = []
|
||||
for item in ordertext.split():
|
||||
for item in order_text.split():
|
||||
verse_tag = VerseType.tags[VerseType.from_translated_tag(item[0])]
|
||||
verse_num = item[1:].lower()
|
||||
order.append('%s%s' % (verse_tag, verse_num))
|
||||
|
@ -874,8 +897,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
|||
self.song.song_number = self.song_book_number_edit.text()
|
||||
book_name = self.song_book_combo_box.currentText()
|
||||
if book_name:
|
||||
self.song.book = self.manager.get_object_filtered(Book,
|
||||
Book.name == book_name)
|
||||
self.song.book = self.manager.get_object_filtered(Book, Book.name == book_name)
|
||||
else:
|
||||
self.song.book = None
|
||||
theme_name = self.theme_combo_box.currentText()
|
||||
|
@ -887,15 +909,15 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
|||
self.song.authors = []
|
||||
for row in range(self.authors_list_view.count()):
|
||||
item = self.authors_list_view.item(row)
|
||||
authorId = (item.data(QtCore.Qt.UserRole))
|
||||
author = self.manager.get_object(Author, authorId)
|
||||
author_id = (item.data(QtCore.Qt.UserRole))
|
||||
author = self.manager.get_object(Author, author_id)
|
||||
if author is not None:
|
||||
self.song.authors.append(author)
|
||||
self.song.topics = []
|
||||
for row in range(self.topics_list_view.count()):
|
||||
item = self.topics_list_view.item(row)
|
||||
topicId = (item.data(QtCore.Qt.UserRole))
|
||||
topic = self.manager.get_object(Topic, topicId)
|
||||
topic_id = (item.data(QtCore.Qt.UserRole))
|
||||
topic = self.manager.get_object(Topic, topic_id)
|
||||
if topic is not None:
|
||||
self.song.topics.append(topic)
|
||||
# Save the song here because we need a valid id for the audio files.
|
||||
|
@ -904,7 +926,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
|||
audio_files = [a.file_name for a in self.song.media_files]
|
||||
log.debug(audio_files)
|
||||
save_path = os.path.join(AppLocation.get_section_data_path(self.media_item.plugin.name), 'audio',
|
||||
str(self.song.id))
|
||||
str(self.song.id))
|
||||
check_directory_exists(save_path)
|
||||
self.song.media_files = []
|
||||
files = []
|
||||
|
@ -912,8 +934,8 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog):
|
|||
item = self.audio_list_widget.item(row)
|
||||
filename = item.data(QtCore.Qt.UserRole)
|
||||
if not filename.startswith(save_path):
|
||||
oldfile, filename = filename, os.path.join(save_path, os.path.split(filename)[1])
|
||||
shutil.copyfile(oldfile, filename)
|
||||
old_file, filename = filename, os.path.join(save_path, os.path.split(filename)[1])
|
||||
shutil.copyfile(old_file, filename)
|
||||
files.append(filename)
|
||||
media_file = MediaFile()
|
||||
media_file.file_name = filename
|
||||
|
|
|
@ -86,4 +86,4 @@ class Ui_EditVerseDialog(object):
|
|||
self.split_button.setToolTip(UiStrings().SplitToolTip)
|
||||
self.insert_button.setText(translate('SongsPlugin.EditVerseForm', '&Insert'))
|
||||
self.insert_button.setToolTip(translate('SongsPlugin.EditVerseForm',
|
||||
'Split a slide into two by inserting a verse splitter.'))
|
||||
'Split a slide into two by inserting a verse splitter.'))
|
||||
|
|
|
@ -50,16 +50,18 @@ class EditVerseForm(QtGui.QDialog, Ui_EditVerseDialog):
|
|||
"""
|
||||
super(EditVerseForm, self).__init__(parent)
|
||||
self.setupUi(self)
|
||||
self.verse_text_edit.customContextMenuRequested.connect(self.context_menu)
|
||||
self.insert_button.clicked.connect(self.on_insert_button_clicked)
|
||||
self.split_button.clicked.connect(self.on_split_button_clicked)
|
||||
self.verse_text_edit.cursorPositionChanged.connect(self.on_cursor_position_changed)
|
||||
self.verse_type_combo_box.currentIndexChanged.connect(self.on_verse_type_combo_box_changed)
|
||||
|
||||
def context_menu(self, point):
|
||||
item = self.serviceManagerList.itemAt(point)
|
||||
|
||||
def insert_verse(self, verse_tag, verse_num=1):
|
||||
"""
|
||||
Insert a verse
|
||||
|
||||
:param verse_tag: The verse tag
|
||||
:param verse_num: The verse number
|
||||
"""
|
||||
if self.verse_text_edit.textCursor().columnNumber() != 0:
|
||||
self.verse_text_edit.insertPlainText('\n')
|
||||
verse_tag = VerseType.translated_name(verse_tag)
|
||||
|
@ -67,24 +69,36 @@ class EditVerseForm(QtGui.QDialog, Ui_EditVerseDialog):
|
|||
self.verse_text_edit.setFocus()
|
||||
|
||||
def on_split_button_clicked(self):
|
||||
"""
|
||||
The split button has been pressed
|
||||
"""
|
||||
text = self.verse_text_edit.toPlainText()
|
||||
position = self.verse_text_edit.textCursor().position()
|
||||
insert_string = '[---]'
|
||||
if position and text[position-1] != '\n':
|
||||
insert_string = '\n' + insert_string
|
||||
if position == len(text) or text[position] != '\n':
|
||||
if position == len(text) or text[position] != '\n':
|
||||
insert_string += '\n'
|
||||
self.verse_text_edit.insertPlainText(insert_string)
|
||||
self.verse_text_edit.setFocus()
|
||||
|
||||
def on_insert_button_clicked(self):
|
||||
"""
|
||||
The insert button has been pressed
|
||||
"""
|
||||
verse_type_index = self.verse_type_combo_box.currentIndex()
|
||||
self.insert_verse(VerseType.tags[verse_type_index], self.verse_number_box.value())
|
||||
|
||||
def on_verse_type_combo_box_changed(self):
|
||||
"""
|
||||
The verse type combo has been changed
|
||||
"""
|
||||
self.update_suggested_verse_number()
|
||||
|
||||
def on_cursor_position_changed(self):
|
||||
"""
|
||||
The cursor position has been changed
|
||||
"""
|
||||
self.update_suggested_verse_number()
|
||||
|
||||
def update_suggested_verse_number(self):
|
||||
|
@ -117,6 +131,13 @@ class EditVerseForm(QtGui.QDialog, Ui_EditVerseDialog):
|
|||
self.verse_number_box.setValue(verse_num)
|
||||
|
||||
def set_verse(self, text, single=False, tag='%s1' % VerseType.tags[VerseType.Verse]):
|
||||
"""
|
||||
Save the verse
|
||||
|
||||
:param text: The text
|
||||
:param single: is this a single verse
|
||||
:param tag: The tag
|
||||
"""
|
||||
self.has_single_verse = single
|
||||
if single:
|
||||
verse_type_index = VerseType.from_tag(tag[0], None)
|
||||
|
@ -136,10 +157,20 @@ class EditVerseForm(QtGui.QDialog, Ui_EditVerseDialog):
|
|||
self.verse_text_edit.moveCursor(QtGui.QTextCursor.End)
|
||||
|
||||
def get_verse(self):
|
||||
"""
|
||||
Extract the verse text
|
||||
|
||||
:return: The text
|
||||
"""
|
||||
return self.verse_text_edit.toPlainText(), VerseType.tags[self.verse_type_combo_box.currentIndex()], \
|
||||
str(self.verse_number_box.value())
|
||||
|
||||
def get_all_verses(self):
|
||||
"""
|
||||
Extract all the verses
|
||||
|
||||
:return: The text
|
||||
"""
|
||||
text = self.verse_text_edit.toPlainText()
|
||||
if not text.startswith('---['):
|
||||
text = '---[%s:1]---\n%s' % (VerseType.translated_names[VerseType.Verse], text)
|
||||
|
|
|
@ -69,5 +69,6 @@ class Ui_MediaFilesDialog(object):
|
|||
"""
|
||||
media_files_dialog.setWindowTitle(translate('SongsPlugin.MediaFilesForm', 'Select Media File(s)'))
|
||||
self.select_label.setText(translate('SongsPlugin.MediaFilesForm',
|
||||
'Select one or more audio files from the list below, and click OK to import them into this song.'))
|
||||
'Select one or more audio files from the list below, and click OK to import them '
|
||||
'into this song.'))
|
||||
|
||||
|
|
|
@ -47,13 +47,13 @@ class MediaFilesForm(QtGui.QDialog, Ui_MediaFilesDialog):
|
|||
super(MediaFilesForm, self).__init__()
|
||||
self.setupUi(self)
|
||||
|
||||
def populateFiles(self, files):
|
||||
def populate_files(self, files):
|
||||
self.file_list_widget.clear()
|
||||
for file in files:
|
||||
item = QtGui.QListWidgetItem(os.path.split(file)[1])
|
||||
item.setData(QtCore.Qt.UserRole, file)
|
||||
self.file_list_widget.addItem(item)
|
||||
|
||||
def getSelectedFiles(self):
|
||||
def get_selected_files(self):
|
||||
return [item.data(QtCore.Qt.UserRole) for item in self.file_list_widget.selectedItems()]
|
||||
|
||||
|
|
|
@ -52,8 +52,7 @@ class SongBookForm(QtGui.QDialog, Ui_SongBookDialog):
|
|||
"""
|
||||
Execute the song book form.
|
||||
|
||||
``clear``
|
||||
Clear the fields on the form before displaying it.
|
||||
:param clear: Clear the fields on the form before displaying it.
|
||||
"""
|
||||
if clear:
|
||||
self.name_edit.clear()
|
||||
|
|
|
@ -55,11 +55,8 @@ class SongExportForm(OpenLPWizard):
|
|||
"""
|
||||
Instantiate the wizard, and run any extra setup we need to.
|
||||
|
||||
``parent``
|
||||
The QWidget-derived parent of the wizard.
|
||||
|
||||
``plugin``
|
||||
The songs plugin.
|
||||
:param parent: The QWidget-derived parent of the wizard.
|
||||
:param plugin: The songs plugin.
|
||||
"""
|
||||
super(SongExportForm, self).__init__(parent, plugin, 'song_export_wizard', ':/wizards/wizard_exportsong.bmp')
|
||||
self.stop_export_flag = False
|
||||
|
@ -82,71 +79,71 @@ class SongExportForm(OpenLPWizard):
|
|||
"""
|
||||
Song wizard specific signals.
|
||||
"""
|
||||
self.availableListWidget.itemActivated.connect(self.onItemActivated)
|
||||
self.searchLineEdit.textEdited.connect(self.onSearchLineEditChanged)
|
||||
self.uncheckButton.clicked.connect(self.onUncheckButtonClicked)
|
||||
self.checkButton.clicked.connect(self.onCheckButtonClicked)
|
||||
self.directoryButton.clicked.connect(self.onDirectoryButtonClicked)
|
||||
self.available_list_widget.itemActivated.connect(self.on_item_activated)
|
||||
self.search_line_edit.textEdited.connect(self.on_search_line_edit_changed)
|
||||
self.uncheck_button.clicked.connect(self.on_uncheck_button_clicked)
|
||||
self.check_button.clicked.connect(self.on_check_button_clicked)
|
||||
self.directory_button.clicked.connect(self.on_directory_button_clicked)
|
||||
|
||||
def add_custom_pages(self):
|
||||
"""
|
||||
Add song wizard specific pages.
|
||||
"""
|
||||
# The page with all available songs.
|
||||
self.availableSongsPage = QtGui.QWizardPage()
|
||||
self.availableSongsPage.setObjectName('availableSongsPage')
|
||||
self.availableSongsLayout = QtGui.QHBoxLayout(self.availableSongsPage)
|
||||
self.availableSongsLayout.setObjectName('availableSongsLayout')
|
||||
self.verticalLayout = QtGui.QVBoxLayout()
|
||||
self.verticalLayout.setObjectName('verticalLayout')
|
||||
self.availableListWidget = QtGui.QListWidget(self.availableSongsPage)
|
||||
self.availableListWidget.setObjectName('availableListWidget')
|
||||
self.verticalLayout.addWidget(self.availableListWidget)
|
||||
self.horizontalLayout = QtGui.QHBoxLayout()
|
||||
self.horizontalLayout.setObjectName('horizontalLayout')
|
||||
self.searchLabel = QtGui.QLabel(self.availableSongsPage)
|
||||
self.searchLabel.setObjectName('searchLabel')
|
||||
self.horizontalLayout.addWidget(self.searchLabel)
|
||||
self.searchLineEdit = QtGui.QLineEdit(self.availableSongsPage)
|
||||
self.searchLineEdit.setObjectName('searchLineEdit')
|
||||
self.horizontalLayout.addWidget(self.searchLineEdit)
|
||||
self.available_songs_page = QtGui.QWizardPage()
|
||||
self.available_songs_page.setObjectName('available_songs_page')
|
||||
self.available_songs_layout = QtGui.QHBoxLayout(self.available_songs_page)
|
||||
self.available_songs_layout.setObjectName('available_songs_layout')
|
||||
self.vertical_layout = QtGui.QVBoxLayout()
|
||||
self.vertical_layout.setObjectName('vertical_layout')
|
||||
self.available_list_widget = QtGui.QListWidget(self.available_songs_page)
|
||||
self.available_list_widget.setObjectName('available_list_widget')
|
||||
self.vertical_layout.addWidget(self.available_list_widget)
|
||||
self.horizontal_layout = QtGui.QHBoxLayout()
|
||||
self.horizontal_layout.setObjectName('horizontal_layout')
|
||||
self.search_label = QtGui.QLabel(self.available_songs_page)
|
||||
self.search_label.setObjectName('search_label')
|
||||
self.horizontal_layout.addWidget(self.search_label)
|
||||
self.search_line_edit = QtGui.QLineEdit(self.available_songs_page)
|
||||
self.search_line_edit.setObjectName('search_line_edit')
|
||||
self.horizontal_layout.addWidget(self.search_line_edit)
|
||||
spacer_item = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
|
||||
self.horizontalLayout.addItem(spacer_item)
|
||||
self.uncheckButton = QtGui.QPushButton(self.availableSongsPage)
|
||||
self.uncheckButton.setObjectName('uncheckButton')
|
||||
self.horizontalLayout.addWidget(self.uncheckButton)
|
||||
self.checkButton = QtGui.QPushButton(self.availableSongsPage)
|
||||
self.checkButton.setObjectName('selectButton')
|
||||
self.horizontalLayout.addWidget(self.checkButton)
|
||||
self.verticalLayout.addLayout(self.horizontalLayout)
|
||||
self.availableSongsLayout.addLayout(self.verticalLayout)
|
||||
self.addPage(self.availableSongsPage)
|
||||
self.horizontal_layout.addItem(spacer_item)
|
||||
self.uncheck_button = QtGui.QPushButton(self.available_songs_page)
|
||||
self.uncheck_button.setObjectName('uncheck_button')
|
||||
self.horizontal_layout.addWidget(self.uncheck_button)
|
||||
self.check_button = QtGui.QPushButton(self.available_songs_page)
|
||||
self.check_button.setObjectName('selectButton')
|
||||
self.horizontal_layout.addWidget(self.check_button)
|
||||
self.vertical_layout.addLayout(self.horizontal_layout)
|
||||
self.available_songs_layout.addLayout(self.vertical_layout)
|
||||
self.addPage(self.available_songs_page)
|
||||
# The page with the selected songs.
|
||||
self.exportSongPage = QtGui.QWizardPage()
|
||||
self.exportSongPage.setObjectName('availableSongsPage')
|
||||
self.exportSongLayout = QtGui.QHBoxLayout(self.exportSongPage)
|
||||
self.exportSongLayout.setObjectName('exportSongLayout')
|
||||
self.gridLayout = QtGui.QGridLayout()
|
||||
self.gridLayout.setObjectName('gridLayout')
|
||||
self.selectedListWidget = QtGui.QListWidget(self.exportSongPage)
|
||||
self.selectedListWidget.setObjectName('selectedListWidget')
|
||||
self.gridLayout.addWidget(self.selectedListWidget, 1, 0, 1, 1)
|
||||
# FIXME: self.horizontalLayout is already defined above?!?!?
|
||||
self.horizontalLayout = QtGui.QHBoxLayout()
|
||||
self.horizontalLayout.setObjectName('horizontalLayout')
|
||||
self.directoryLabel = QtGui.QLabel(self.exportSongPage)
|
||||
self.directoryLabel.setObjectName('directoryLabel')
|
||||
self.horizontalLayout.addWidget(self.directoryLabel)
|
||||
self.directoryLineEdit = QtGui.QLineEdit(self.exportSongPage)
|
||||
self.directoryLineEdit.setObjectName('directoryLineEdit')
|
||||
self.horizontalLayout.addWidget(self.directoryLineEdit)
|
||||
self.directoryButton = QtGui.QToolButton(self.exportSongPage)
|
||||
self.directoryButton.setIcon(build_icon(':/exports/export_load.png'))
|
||||
self.directoryButton.setObjectName('directoryButton')
|
||||
self.horizontalLayout.addWidget(self.directoryButton)
|
||||
self.gridLayout.addLayout(self.horizontalLayout, 0, 0, 1, 1)
|
||||
self.exportSongLayout.addLayout(self.gridLayout)
|
||||
self.addPage(self.exportSongPage)
|
||||
self.export_song_page = QtGui.QWizardPage()
|
||||
self.export_song_page.setObjectName('available_songs_page')
|
||||
self.export_song_layout = QtGui.QHBoxLayout(self.export_song_page)
|
||||
self.export_song_layout.setObjectName('export_song_layout')
|
||||
self.grid_layout = QtGui.QGridLayout()
|
||||
self.grid_layout.setObjectName('grid_layout')
|
||||
self.selected_list_widget = QtGui.QListWidget(self.export_song_page)
|
||||
self.selected_list_widget.setObjectName('selected_list_widget')
|
||||
self.grid_layout.addWidget(self.selected_list_widget, 1, 0, 1, 1)
|
||||
# FIXME: self.horizontal_layout is already defined above?!?!?
|
||||
self.horizontal_layout = QtGui.QHBoxLayout()
|
||||
self.horizontal_layout.setObjectName('horizontal_layout')
|
||||
self.directory_label = QtGui.QLabel(self.export_song_page)
|
||||
self.directory_label.setObjectName('directory_label')
|
||||
self.horizontal_layout.addWidget(self.directory_label)
|
||||
self.directory_line_edit = QtGui.QLineEdit(self.export_song_page)
|
||||
self.directory_line_edit.setObjectName('directory_line_edit')
|
||||
self.horizontal_layout.addWidget(self.directory_line_edit)
|
||||
self.directory_button = QtGui.QToolButton(self.export_song_page)
|
||||
self.directory_button.setIcon(build_icon(':/exports/export_load.png'))
|
||||
self.directory_button.setObjectName('directory_button')
|
||||
self.horizontal_layout.addWidget(self.directory_button)
|
||||
self.grid_layout.addLayout(self.horizontal_layout, 0, 0, 1, 1)
|
||||
self.export_song_layout.addLayout(self.grid_layout)
|
||||
self.addPage(self.export_song_page)
|
||||
|
||||
def retranslateUi(self):
|
||||
"""
|
||||
|
@ -154,22 +151,23 @@ class SongExportForm(OpenLPWizard):
|
|||
"""
|
||||
self.setWindowTitle(translate('SongsPlugin.ExportWizardForm', 'Song Export Wizard'))
|
||||
self.title_label.setText(WizardStrings.HeaderStyle %
|
||||
translate('OpenLP.Ui', 'Welcome to the Song Export Wizard'))
|
||||
translate('OpenLP.Ui', 'Welcome to the Song Export Wizard'))
|
||||
self.information_label.setText(translate('SongsPlugin.ExportWizardForm', 'This wizard will help to'
|
||||
' export your songs to the open and free <strong>OpenLyrics </strong> worship song format.'))
|
||||
self.availableSongsPage.setTitle(translate('SongsPlugin.ExportWizardForm', 'Select Songs'))
|
||||
self.availableSongsPage.setSubTitle(translate('SongsPlugin.ExportWizardForm',
|
||||
'Check the songs you want to export.'))
|
||||
self.searchLabel.setText('%s:' % UiStrings().Search)
|
||||
self.uncheckButton.setText(translate('SongsPlugin.ExportWizardForm', 'Uncheck All'))
|
||||
self.checkButton.setText(translate('SongsPlugin.ExportWizardForm', 'Check All'))
|
||||
self.exportSongPage.setTitle(translate('SongsPlugin.ExportWizardForm', 'Select Directory'))
|
||||
self.exportSongPage.setSubTitle(translate('SongsPlugin.ExportWizardForm',
|
||||
'Select the directory where you want the songs to be saved.'))
|
||||
self.directoryLabel.setText(translate('SongsPlugin.ExportWizardForm', 'Directory:'))
|
||||
' export your songs to the open and free <strong>OpenLyrics </strong> worship '
|
||||
'song format.'))
|
||||
self.available_songs_page.setTitle(translate('SongsPlugin.ExportWizardForm', 'Select Songs'))
|
||||
self.available_songs_page.setSubTitle(translate('SongsPlugin.ExportWizardForm',
|
||||
'Check the songs you want to export.'))
|
||||
self.search_label.setText('%s:' % UiStrings().Search)
|
||||
self.uncheck_button.setText(translate('SongsPlugin.ExportWizardForm', 'Uncheck All'))
|
||||
self.check_button.setText(translate('SongsPlugin.ExportWizardForm', 'Check All'))
|
||||
self.export_song_page.setTitle(translate('SongsPlugin.ExportWizardForm', 'Select Directory'))
|
||||
self.export_song_page.setSubTitle(translate('SongsPlugin.ExportWizardForm',
|
||||
'Select the directory where you want the songs to be saved.'))
|
||||
self.directory_label.setText(translate('SongsPlugin.ExportWizardForm', 'Directory:'))
|
||||
self.progress_page.setTitle(translate('SongsPlugin.ExportWizardForm', 'Exporting'))
|
||||
self.progress_page.setSubTitle(translate('SongsPlugin.ExportWizardForm',
|
||||
'Please wait while your songs are exported.'))
|
||||
'Please wait while your songs are exported.'))
|
||||
self.progress_label.setText(WizardStrings.Ready)
|
||||
self.progress_bar.setFormat(WizardStrings.PercentSymbolFormat)
|
||||
|
||||
|
@ -179,46 +177,46 @@ class SongExportForm(OpenLPWizard):
|
|||
"""
|
||||
if self.currentPage() == self.welcome_page:
|
||||
return True
|
||||
elif self.currentPage() == self.availableSongsPage:
|
||||
elif self.currentPage() == self.available_songs_page:
|
||||
items = [
|
||||
item for item in self._findListWidgetItems(
|
||||
self.availableListWidget) if item.checkState()
|
||||
item for item in self._find_list_widget_items(self.available_list_widget) if item.checkState()
|
||||
]
|
||||
if not items:
|
||||
critical_error_message_box(UiStrings().NISp,
|
||||
critical_error_message_box(
|
||||
UiStrings().NISp,
|
||||
translate('SongsPlugin.ExportWizardForm', 'You need to add at least one Song to export.'))
|
||||
return False
|
||||
self.selectedListWidget.clear()
|
||||
self.selected_list_widget.clear()
|
||||
# Add the songs to the list of selected songs.
|
||||
for item in items:
|
||||
song = QtGui.QListWidgetItem(item.text())
|
||||
song.setData(QtCore.Qt.UserRole, item.data(QtCore.Qt.UserRole))
|
||||
song.setFlags(QtCore.Qt.ItemIsEnabled)
|
||||
self.selectedListWidget.addItem(song)
|
||||
self.selected_list_widget.addItem(song)
|
||||
return True
|
||||
elif self.currentPage() == self.exportSongPage:
|
||||
if not self.directoryLineEdit.text():
|
||||
elif self.currentPage() == self.export_song_page:
|
||||
if not self.directory_line_edit.text():
|
||||
critical_error_message_box(
|
||||
translate('SongsPlugin.ExportWizardForm', 'No Save Location specified'),
|
||||
translate('SongsPlugin.ExportWizardForm', 'You need to specify a directory.'))
|
||||
return False
|
||||
return True
|
||||
elif self.currentPage() == self.progress_page:
|
||||
self.availableListWidget.clear()
|
||||
self.selectedListWidget.clear()
|
||||
self.available_list_widget.clear()
|
||||
self.selected_list_widget.clear()
|
||||
return True
|
||||
|
||||
def setDefaults(self):
|
||||
def set_defaults(self):
|
||||
"""
|
||||
Set default form values for the song export wizard.
|
||||
"""
|
||||
self.restart()
|
||||
self.finish_button.setVisible(False)
|
||||
self.cancel_button.setVisible(True)
|
||||
self.availableListWidget.clear()
|
||||
self.selectedListWidget.clear()
|
||||
self.directoryLineEdit.clear()
|
||||
self.searchLineEdit.clear()
|
||||
self.available_list_widget.clear()
|
||||
self.selected_list_widget.clear()
|
||||
self.directory_line_edit.clear()
|
||||
self.search_line_edit.clear()
|
||||
# Load the list of songs.
|
||||
self.application.set_busy_cursor()
|
||||
songs = self.plugin.manager.get_all_objects(Song)
|
||||
|
@ -233,7 +231,7 @@ class SongExportForm(OpenLPWizard):
|
|||
item.setData(QtCore.Qt.UserRole, song)
|
||||
item.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled)
|
||||
item.setCheckState(QtCore.Qt.Unchecked)
|
||||
self.availableListWidget.addItem(item)
|
||||
self.available_list_widget.addItem(item)
|
||||
self.application.set_normal_cursor()
|
||||
|
||||
def pre_wizard(self):
|
||||
|
@ -244,86 +242,81 @@ class SongExportForm(OpenLPWizard):
|
|||
self.progress_label.setText(translate('SongsPlugin.ExportWizardForm', 'Starting export...'))
|
||||
self.application.process_events()
|
||||
|
||||
def performWizard(self):
|
||||
def perform_wizard(self):
|
||||
"""
|
||||
Perform the actual export. This creates an *openlyricsexport* instance
|
||||
and calls the *do_export* method.
|
||||
Perform the actual export. This creates an *openlyricsexport* instance and calls the *do_export* method.
|
||||
"""
|
||||
songs = [
|
||||
song.data(QtCore.Qt.UserRole)
|
||||
for song in self._findListWidgetItems(self.selectedListWidget)
|
||||
for song in self._find_list_widget_items(self.selected_list_widget)
|
||||
]
|
||||
exporter = OpenLyricsExport(self, songs, self.directoryLineEdit.text())
|
||||
exporter = OpenLyricsExport(self, songs, self.directory_line_edit.text())
|
||||
if exporter.do_export():
|
||||
self.progress_label.setText(translate('SongsPlugin.SongExportForm',
|
||||
'Finished export. To import these files use the <strong>OpenLyrics</strong> importer.'))
|
||||
self.progress_label.setText(
|
||||
translate('SongsPlugin.SongExportForm',
|
||||
'Finished export. To import these files use the <strong>OpenLyrics</strong> importer.'))
|
||||
else:
|
||||
self.progress_label.setText(translate('SongsPlugin.SongExportForm', 'Your song export failed.'))
|
||||
|
||||
def _findListWidgetItems(self, listWidget, text=''):
|
||||
def _find_list_widget_items(self, list_widget, text=''):
|
||||
"""
|
||||
Returns a list of *QListWidgetItem*s of the ``listWidget``. Note, that
|
||||
hidden items are included.
|
||||
Returns a list of *QListWidgetItem*s of the ``list_widget``. Note, that hidden items are included.
|
||||
|
||||
``listWidget``
|
||||
The widget to get all items from. (QListWidget)
|
||||
|
||||
``text``
|
||||
The text to search for. (unicode string)
|
||||
:param list_widget: The widget to get all items from. (QListWidget)
|
||||
:param text: The text to search for. (unicode string)
|
||||
"""
|
||||
return [
|
||||
item for item in listWidget.findItems(text, QtCore.Qt.MatchContains)
|
||||
item for item in list_widget.findItems(text, QtCore.Qt.MatchContains)
|
||||
]
|
||||
|
||||
def onItemActivated(self, item):
|
||||
def on_item_activated(self, item):
|
||||
"""
|
||||
Called, when an item in the *availableListWidget* has been triggered.
|
||||
Called, when an item in the *available_list_widget* has been triggered.
|
||||
The item is check if it was not checked, whereas it is unchecked when it
|
||||
was checked.
|
||||
|
||||
``item``
|
||||
The *QListWidgetItem* which was triggered.
|
||||
:param item: The *QListWidgetItem* which was triggered.
|
||||
"""
|
||||
item.setCheckState(
|
||||
QtCore.Qt.Unchecked if item.checkState() else QtCore.Qt.Checked)
|
||||
|
||||
def onSearchLineEditChanged(self, text):
|
||||
def on_search_line_edit_changed(self, text):
|
||||
"""
|
||||
The *searchLineEdit*'s text has been changed. Update the list of
|
||||
The *search_line_edit*'s text has been changed. Update the list of
|
||||
available songs. Note that any song, which does not match the ``text``
|
||||
will be hidden, but not unchecked!
|
||||
|
||||
``text``
|
||||
The text of the *searchLineEdit*.
|
||||
:param text: The text of the *search_line_edit*.
|
||||
"""
|
||||
search_result = [
|
||||
song for song in self._findListWidgetItems(self.availableListWidget, text)
|
||||
song for song in self._find_list_widget_items(self.available_list_widget, text)
|
||||
]
|
||||
for item in self._findListWidgetItems(self.availableListWidget):
|
||||
for item in self._find_list_widget_items(self.available_list_widget):
|
||||
item.setHidden(item not in search_result)
|
||||
|
||||
def onUncheckButtonClicked(self):
|
||||
def on_uncheck_button_clicked(self):
|
||||
"""
|
||||
The *uncheckButton* has been clicked. Set all visible songs unchecked.
|
||||
The *uncheck_button* has been clicked. Set all visible songs unchecked.
|
||||
"""
|
||||
for row in range(self.availableListWidget.count()):
|
||||
item = self.availableListWidget.item(row)
|
||||
for row in range(self.available_list_widget.count()):
|
||||
item = self.available_list_widget.item(row)
|
||||
if not item.isHidden():
|
||||
item.setCheckState(QtCore.Qt.Unchecked)
|
||||
|
||||
def onCheckButtonClicked(self):
|
||||
def on_check_button_clicked(self):
|
||||
"""
|
||||
The *checkButton* has been clicked. Set all visible songs checked.
|
||||
The *check_button* has been clicked. Set all visible songs checked.
|
||||
"""
|
||||
for row in range(self.availableListWidget.count()):
|
||||
item = self.availableListWidget.item(row)
|
||||
for row in range(self.available_list_widget.count()):
|
||||
item = self.available_list_widget.item(row)
|
||||
if not item.isHidden():
|
||||
item.setCheckState(QtCore.Qt.Checked)
|
||||
|
||||
def onDirectoryButtonClicked(self):
|
||||
def on_directory_button_clicked(self):
|
||||
"""
|
||||
Called when the *directoryButton* was clicked. Opens a dialog and writes
|
||||
the path to *directoryLineEdit*.
|
||||
Called when the *directory_button* was clicked. Opens a dialog and writes
|
||||
the path to *directory_line_edit*.
|
||||
"""
|
||||
self.get_folder(translate('SongsPlugin.ExportWizardForm', 'Select Destination Folder'),
|
||||
self.directoryLineEdit, 'last directory export')
|
||||
self.get_folder(
|
||||
translate('SongsPlugin.ExportWizardForm', 'Select Destination Folder'),
|
||||
self.directory_line_edit, 'last directory export')
|
||||
|
|
|
@ -55,11 +55,8 @@ class SongImportForm(OpenLPWizard):
|
|||
"""
|
||||
Instantiate the wizard, and run any extra setup we need to.
|
||||
|
||||
``parent``
|
||||
The QWidget-derived parent of the wizard.
|
||||
|
||||
``plugin``
|
||||
The songs plugin.
|
||||
:param parent: The QWidget-derived parent of the wizard.
|
||||
:param plugin: The songs plugin.
|
||||
"""
|
||||
super(SongImportForm, self).__init__(parent, plugin, 'songImportWizard', ':/wizards/wizard_importsong.bmp')
|
||||
self.clipboard = self.main_window.clipboard
|
||||
|
@ -72,9 +69,9 @@ class SongImportForm(OpenLPWizard):
|
|||
super(SongImportForm, self).setupUi(image)
|
||||
self.current_format = SongFormat.OpenLyrics
|
||||
self.format_stack.setCurrentIndex(self.current_format)
|
||||
self.format_combo_box.currentIndexChanged.connect(self.onCurrentIndexChanged)
|
||||
self.format_combo_box.currentIndexChanged.connect(self.on_current_index_changed)
|
||||
|
||||
def onCurrentIndexChanged(self, index):
|
||||
def on_current_index_changed(self, index):
|
||||
"""
|
||||
Called when the format combo box's index changed.
|
||||
"""
|
||||
|
@ -99,10 +96,10 @@ class SongImportForm(OpenLPWizard):
|
|||
select_mode = SongFormat.get(song_format, 'selectMode')
|
||||
if select_mode == SongFormatSelect.MultipleFiles:
|
||||
self.format_widgets[song_format]['addButton'].clicked.connect(self.on_add_button_clicked)
|
||||
self.format_widgets[song_format]['removeButton'].clicked.connect(self.onRemoveButtonClicked)
|
||||
self.format_widgets[song_format]['removeButton'].clicked.connect(self.on_remove_button_clicked)
|
||||
else:
|
||||
self.format_widgets[song_format]['browseButton'].clicked.connect(self.on_browse_button_clicked)
|
||||
self.format_widgets[song_format]['file_path_edit'].textChanged.connect(self.onFilepathEditTextChanged)
|
||||
self.format_widgets[song_format]['file_path_edit'].textChanged.connect(self.on_filepath_edit_text_changed)
|
||||
|
||||
def add_custom_pages(self):
|
||||
"""
|
||||
|
@ -131,7 +128,7 @@ class SongImportForm(OpenLPWizard):
|
|||
self.format_stack.setObjectName('format_stack')
|
||||
self.disablable_formats = []
|
||||
for self.current_format in SongFormat.get_format_list():
|
||||
self.addFileSelectItem()
|
||||
self.add_file_select_item()
|
||||
self.source_layout.addLayout(self.format_stack)
|
||||
self.addPage(self.source_page)
|
||||
|
||||
|
@ -140,33 +137,35 @@ class SongImportForm(OpenLPWizard):
|
|||
Song wizard localisation.
|
||||
"""
|
||||
self.setWindowTitle(translate('SongsPlugin.ImportWizardForm', 'Song Import Wizard'))
|
||||
self.title_label.setText(WizardStrings.HeaderStyle % translate('OpenLP.Ui', 'Welcome to the Song Import Wizard'))
|
||||
self.information_label.setText(translate('SongsPlugin.ImportWizardForm',
|
||||
'This wizard will help you to import songs from a variety of '
|
||||
'formats. Click the next button below to start the process by selecting a format to import from.'))
|
||||
self.title_label.setText(WizardStrings.HeaderStyle % translate('OpenLP.Ui',
|
||||
'Welcome to the Song Import Wizard'))
|
||||
self.information_label.setText(
|
||||
translate('SongsPlugin.ImportWizardForm',
|
||||
'This wizard will help you to import songs from a variety of formats. Click the next button '
|
||||
'below to start the process by selecting a format to import from.'))
|
||||
self.source_page.setTitle(WizardStrings.ImportSelect)
|
||||
self.source_page.setSubTitle(WizardStrings.ImportSelectLong)
|
||||
self.format_label.setText(WizardStrings.FormatLabel)
|
||||
for format in SongFormat.get_format_list():
|
||||
for format_list in SongFormat.get_format_list():
|
||||
format_name, custom_combo_text, description_text, select_mode = \
|
||||
SongFormat.get(format, 'name', 'comboBoxText', 'descriptionText', 'selectMode')
|
||||
SongFormat.get(format_list, 'name', 'comboBoxText', 'descriptionText', 'selectMode')
|
||||
combo_box_text = (custom_combo_text if custom_combo_text else format_name)
|
||||
self.format_combo_box.setItemText(format, combo_box_text)
|
||||
self.format_combo_box.setItemText(format_list, combo_box_text)
|
||||
if description_text is not None:
|
||||
self.format_widgets[format]['description_label'].setText(description_text)
|
||||
self.format_widgets[format_list]['description_label'].setText(description_text)
|
||||
if select_mode == SongFormatSelect.MultipleFiles:
|
||||
self.format_widgets[format]['addButton'].setText(
|
||||
self.format_widgets[format_list]['addButton'].setText(
|
||||
translate('SongsPlugin.ImportWizardForm', 'Add Files...'))
|
||||
self.format_widgets[format]['removeButton'].setText(
|
||||
self.format_widgets[format_list]['removeButton'].setText(
|
||||
translate('SongsPlugin.ImportWizardForm', 'Remove File(s)'))
|
||||
else:
|
||||
self.format_widgets[format]['browseButton'].setText(UiStrings().Browse)
|
||||
self.format_widgets[format_list]['browseButton'].setText(UiStrings().Browse)
|
||||
f_label = 'Filename:'
|
||||
if select_mode == SongFormatSelect.SingleFolder:
|
||||
f_label = 'Folder:'
|
||||
self.format_widgets[format]['filepathLabel'].setText(translate('SongsPlugin.ImportWizardForm', f_label))
|
||||
for format in self.disablable_formats:
|
||||
self.format_widgets[format]['disabled_label'].setText(SongFormat.get(format, 'disabledLabelText'))
|
||||
self.format_widgets[format_list]['filepathLabel'].setText(translate('SongsPlugin.ImportWizardForm', f_label))
|
||||
for format_list in self.disablable_formats:
|
||||
self.format_widgets[format_list]['disabled_label'].setText(SongFormat.get(format_list, 'disabledLabelText'))
|
||||
self.progress_page.setTitle(WizardStrings.Importing)
|
||||
self.progress_page.setSubTitle(
|
||||
translate('SongsPlugin.ImportWizardForm', 'Please wait while your songs are imported.'))
|
||||
|
@ -179,7 +178,7 @@ class SongImportForm(OpenLPWizard):
|
|||
labels = [self.format_widgets[f]['filepathLabel'] for f in formats]
|
||||
# Get max width of all labels
|
||||
max_label_width = max(self.format_label.minimumSizeHint().width(),
|
||||
max([label.minimumSizeHint().width() for label in labels]))
|
||||
max([label.minimumSizeHint().width() for label in labels]))
|
||||
self.format_spacer.changeSize(max_label_width, 0, QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
|
||||
spacers = [self.format_widgets[f]['filepathSpacer'] for f in formats]
|
||||
for index, spacer in enumerate(spacers):
|
||||
|
@ -187,9 +186,9 @@ class SongImportForm(OpenLPWizard):
|
|||
max_label_width - labels[index].minimumSizeHint().width(), 0,
|
||||
QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
|
||||
# Align descriptionLabels with rest of layout
|
||||
for format in SongFormat.get_format_list():
|
||||
if SongFormat.get(format, 'descriptionText') is not None:
|
||||
self.format_widgets[format]['descriptionSpacer'].changeSize(
|
||||
for format_list in SongFormat.get_format_list():
|
||||
if SongFormat.get(format_list, 'descriptionText') is not None:
|
||||
self.format_widgets[format_list]['descriptionSpacer'].changeSize(
|
||||
max_label_width + self.format_h_spacing, 0, QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
|
||||
|
||||
def custom_page_changed(self, page_id):
|
||||
|
@ -197,11 +196,11 @@ class SongImportForm(OpenLPWizard):
|
|||
Called when changing to a page other than the progress page.
|
||||
"""
|
||||
if self.page(page_id) == self.source_page:
|
||||
self.onCurrentIndexChanged(self.format_stack.currentIndex())
|
||||
self.on_current_index_changed(self.format_stack.currentIndex())
|
||||
|
||||
def validateCurrentPage(self):
|
||||
"""
|
||||
Re-implement te validateCurrentPage() method. Validate the current page before moving on to the next page.
|
||||
Re-implement the validateCurrentPage() method. Validate the current page before moving on to the next page.
|
||||
Provide each song format class with a chance to validate its input by overriding isValidSource().
|
||||
"""
|
||||
if self.currentPage() == self.welcome_page:
|
||||
|
@ -230,37 +229,36 @@ class SongImportForm(OpenLPWizard):
|
|||
"""
|
||||
Opens a QFileDialog and writes the filenames to the given listbox.
|
||||
|
||||
``title``
|
||||
The title of the dialog (unicode).
|
||||
|
||||
``listbox``
|
||||
A listbox (QListWidget).
|
||||
|
||||
``filters``
|
||||
The file extension filters. It should contain the file descriptions
|
||||
:param title: The title of the dialog (unicode).
|
||||
:param listbox: A listbox (QListWidget).
|
||||
:param filters: The file extension filters. It should contain the file descriptions
|
||||
as well as the file extensions. For example::
|
||||
|
||||
u'SongBeamer Files (*.sng)'
|
||||
"""
|
||||
if filters:
|
||||
filters += ';;'
|
||||
filters += '%s (*)' % UiStrings().AllFiles
|
||||
filenames = FileDialog.getOpenFileNames(self, title,
|
||||
file_names = FileDialog.getOpenFileNames(
|
||||
self, title,
|
||||
Settings().value(self.plugin.settings_section + '/last directory import'), filters)
|
||||
if filenames:
|
||||
listbox.addItems(filenames)
|
||||
if file_names:
|
||||
listbox.addItems(file_names)
|
||||
Settings().setValue(self.plugin.settings_section + '/last directory import',
|
||||
os.path.split(str(filenames[0]))[0])
|
||||
os.path.split(str(file_names[0]))[0])
|
||||
|
||||
def get_list_of_files(self, listbox):
|
||||
def get_list_of_files(self, list_box):
|
||||
"""
|
||||
Return a list of file from the listbox
|
||||
Return a list of file from the list_box
|
||||
|
||||
:param list_box: The source list box
|
||||
"""
|
||||
return [listbox.item(i).text() for i in range(listbox.count())]
|
||||
return [list_box.item(i).text() for i in range(list_box.count())]
|
||||
|
||||
def remove_selected_items(self, list_box):
|
||||
"""
|
||||
Remove selected list_box items
|
||||
|
||||
:param list_box: the source list box
|
||||
"""
|
||||
for item in list_box.selectedItems():
|
||||
item = list_box.takeItem(list_box.row(item))
|
||||
|
@ -291,14 +289,14 @@ class SongImportForm(OpenLPWizard):
|
|||
self.get_files(title, self.format_widgets[this_format]['file_list_widget'], ext_filter)
|
||||
self.source_page.emit(QtCore.SIGNAL('completeChanged()'))
|
||||
|
||||
def onRemoveButtonClicked(self):
|
||||
def on_remove_button_clicked(self):
|
||||
"""
|
||||
Remove a file from the list.
|
||||
"""
|
||||
self.remove_selected_items(self.format_widgets[self.current_format]['file_list_widget'])
|
||||
self.source_page.emit(QtCore.SIGNAL('completeChanged()'))
|
||||
|
||||
def onFilepathEditTextChanged(self):
|
||||
def on_filepath_edit_text_changed(self):
|
||||
"""
|
||||
Called when the content of the Filename/Folder edit box changes.
|
||||
"""
|
||||
|
@ -315,12 +313,12 @@ class SongImportForm(OpenLPWizard):
|
|||
if last_import_type < 0 or last_import_type >= self.format_combo_box.count():
|
||||
last_import_type = 0
|
||||
self.format_combo_box.setCurrentIndex(last_import_type)
|
||||
for format in SongFormat.get_format_list():
|
||||
select_mode = SongFormat.get(format, 'selectMode')
|
||||
for format_list in SongFormat.get_format_list():
|
||||
select_mode = SongFormat.get(format_list, 'selectMode')
|
||||
if select_mode == SongFormatSelect.MultipleFiles:
|
||||
self.format_widgets[format]['file_list_widget'].clear()
|
||||
self.format_widgets[format_list]['file_list_widget'].clear()
|
||||
else:
|
||||
self.format_widgets[format]['file_path_edit'].setText('')
|
||||
self.format_widgets[format_list]['file_path_edit'].setText('')
|
||||
self.error_report_text_edit.clear()
|
||||
self.error_report_text_edit.setHidden(True)
|
||||
self.error_copy_to_button.setHidden(True)
|
||||
|
@ -334,22 +332,22 @@ class SongImportForm(OpenLPWizard):
|
|||
self.progress_label.setText(WizardStrings.StartingImport)
|
||||
self.application.process_events()
|
||||
|
||||
def performWizard(self):
|
||||
def perform_wizard(self):
|
||||
"""
|
||||
Perform the actual import. This method pulls in the correct importer
|
||||
class, and then runs the ``doImport`` method of the importer to do
|
||||
the actual importing.
|
||||
Perform the actual import. This method pulls in the correct importer class, and then runs the ``doImport``
|
||||
method of the importer to do the actual importing.
|
||||
"""
|
||||
source_format = self.current_format
|
||||
select_mode = SongFormat.get(source_format, 'selectMode')
|
||||
if select_mode == SongFormatSelect.SingleFile:
|
||||
importer = self.plugin.importSongs(source_format,
|
||||
filename=self.format_widgets[source_format]['file_path_edit'].text())
|
||||
importer = self.plugin.import_songs(source_format,
|
||||
filename=self.format_widgets[source_format]['file_path_edit'].text())
|
||||
elif select_mode == SongFormatSelect.SingleFolder:
|
||||
importer = self.plugin.importSongs(source_format,
|
||||
folder=self.format_widgets[source_format]['file_path_edit'].text())
|
||||
importer = self.plugin.import_songs(source_format,
|
||||
folder=self.format_widgets[source_format]['file_path_edit'].text())
|
||||
else:
|
||||
importer = self.plugin.importSongs(source_format,
|
||||
importer = self.plugin.import_songs(
|
||||
source_format,
|
||||
filenames=self.get_list_of_files(self.format_widgets[source_format]['file_list_widget']))
|
||||
importer.doImport()
|
||||
self.progress_label.setText(WizardStrings.FinishedImport)
|
||||
|
@ -364,15 +362,15 @@ class SongImportForm(OpenLPWizard):
|
|||
"""
|
||||
Save the error report to a file.
|
||||
"""
|
||||
filename = QtGui.QFileDialog.getSaveFileName(self,
|
||||
Settings().value(self.plugin.settings_section + '/last directory import'))
|
||||
filename = QtGui.QFileDialog.getSaveFileName(
|
||||
self, Settings().value(self.plugin.settings_section + '/last directory import'))
|
||||
if not filename:
|
||||
return
|
||||
report_file = codecs.open(filename, 'w', 'utf-8')
|
||||
report_file.write(self.error_report_text_edit.toPlainText())
|
||||
report_file.close()
|
||||
|
||||
def addFileSelectItem(self):
|
||||
def add_file_select_item(self):
|
||||
"""
|
||||
Add a file selection page.
|
||||
"""
|
||||
|
@ -382,75 +380,75 @@ class SongImportForm(OpenLPWizard):
|
|||
page = QtGui.QWidget()
|
||||
page.setObjectName(prefix + 'Page')
|
||||
if can_disable:
|
||||
importWidget = self.disablableWidget(page, prefix)
|
||||
import_widget = self.disablable_widget(page, prefix)
|
||||
else:
|
||||
importWidget = page
|
||||
importLayout = QtGui.QVBoxLayout(importWidget)
|
||||
importLayout.setMargin(0)
|
||||
importLayout.setObjectName(prefix + 'ImportLayout')
|
||||
import_widget = page
|
||||
import_layout = QtGui.QVBoxLayout(import_widget)
|
||||
import_layout.setMargin(0)
|
||||
import_layout.setObjectName(prefix + 'ImportLayout')
|
||||
if description_text is not None:
|
||||
descriptionLayout = QtGui.QHBoxLayout()
|
||||
descriptionLayout.setObjectName(prefix + 'DescriptionLayout')
|
||||
descriptionSpacer = QtGui.QSpacerItem(0, 0, QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
|
||||
descriptionLayout.addSpacerItem(descriptionSpacer)
|
||||
description_label = QtGui.QLabel(importWidget)
|
||||
description_layout = QtGui.QHBoxLayout()
|
||||
description_layout.setObjectName(prefix + 'DescriptionLayout')
|
||||
description_spacer = QtGui.QSpacerItem(0, 0, QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
|
||||
description_layout.addSpacerItem(description_spacer)
|
||||
description_label = QtGui.QLabel(import_widget)
|
||||
description_label.setWordWrap(True)
|
||||
description_label.setOpenExternalLinks(True)
|
||||
description_label.setObjectName(prefix + '_description_label')
|
||||
descriptionLayout.addWidget(description_label)
|
||||
importLayout.addLayout(descriptionLayout)
|
||||
description_layout.addWidget(description_label)
|
||||
import_layout.addLayout(description_layout)
|
||||
self.format_widgets[this_format]['description_label'] = description_label
|
||||
self.format_widgets[this_format]['descriptionSpacer'] = descriptionSpacer
|
||||
self.format_widgets[this_format]['descriptionSpacer'] = description_spacer
|
||||
if select_mode == SongFormatSelect.SingleFile or select_mode == SongFormatSelect.SingleFolder:
|
||||
file_path_layout = QtGui.QHBoxLayout()
|
||||
file_path_layout.setObjectName(prefix + '_file_path_layout')
|
||||
file_path_layout.setContentsMargins(0, self.format_v_spacing, 0, 0)
|
||||
filepathLabel = QtGui.QLabel(importWidget)
|
||||
filepathLabel.setObjectName(prefix + 'FilepathLabel')
|
||||
file_path_layout.addWidget(filepathLabel)
|
||||
filepathSpacer = QtGui.QSpacerItem(0, 0, QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
|
||||
file_path_layout.addSpacerItem(filepathSpacer)
|
||||
file_path_edit = QtGui.QLineEdit(importWidget)
|
||||
file_path_label = QtGui.QLabel(import_widget)
|
||||
file_path_label.setObjectName(prefix + 'FilepathLabel')
|
||||
file_path_layout.addWidget(file_path_label)
|
||||
file_path_spacer = QtGui.QSpacerItem(0, 0, QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
|
||||
file_path_layout.addSpacerItem(file_path_spacer)
|
||||
file_path_edit = QtGui.QLineEdit(import_widget)
|
||||
file_path_edit.setObjectName(prefix + '_file_path_edit')
|
||||
file_path_layout.addWidget(file_path_edit)
|
||||
browseButton = QtGui.QToolButton(importWidget)
|
||||
browseButton.setIcon(self.open_icon)
|
||||
browseButton.setObjectName(prefix + 'BrowseButton')
|
||||
file_path_layout.addWidget(browseButton)
|
||||
importLayout.addLayout(file_path_layout)
|
||||
importLayout.addSpacerItem(self.stack_spacer)
|
||||
self.format_widgets[this_format]['filepathLabel'] = filepathLabel
|
||||
self.format_widgets[this_format]['filepathSpacer'] = filepathSpacer
|
||||
browse_button = QtGui.QToolButton(import_widget)
|
||||
browse_button.setIcon(self.open_icon)
|
||||
browse_button.setObjectName(prefix + 'BrowseButton')
|
||||
file_path_layout.addWidget(browse_button)
|
||||
import_layout.addLayout(file_path_layout)
|
||||
import_layout.addSpacerItem(self.stack_spacer)
|
||||
self.format_widgets[this_format]['filepathLabel'] = file_path_label
|
||||
self.format_widgets[this_format]['filepathSpacer'] = file_path_spacer
|
||||
self.format_widgets[this_format]['file_path_layout'] = file_path_layout
|
||||
self.format_widgets[this_format]['file_path_edit'] = file_path_edit
|
||||
self.format_widgets[this_format]['browseButton'] = browseButton
|
||||
self.format_widgets[this_format]['browseButton'] = browse_button
|
||||
elif select_mode == SongFormatSelect.MultipleFiles:
|
||||
fileListWidget = QtGui.QListWidget(importWidget)
|
||||
fileListWidget.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)
|
||||
fileListWidget.setObjectName(prefix + 'FileListWidget')
|
||||
importLayout.addWidget(fileListWidget)
|
||||
file_list_widget = QtGui.QListWidget(import_widget)
|
||||
file_list_widget.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)
|
||||
file_list_widget.setObjectName(prefix + 'FileListWidget')
|
||||
import_layout.addWidget(file_list_widget)
|
||||
button_layout = QtGui.QHBoxLayout()
|
||||
button_layout.setObjectName(prefix + '_button_layout')
|
||||
addButton = QtGui.QPushButton(importWidget)
|
||||
addButton.setIcon(self.open_icon)
|
||||
addButton.setObjectName(prefix + 'AddButton')
|
||||
button_layout.addWidget(addButton)
|
||||
add_button = QtGui.QPushButton(import_widget)
|
||||
add_button.setIcon(self.open_icon)
|
||||
add_button.setObjectName(prefix + 'AddButton')
|
||||
button_layout.addWidget(add_button)
|
||||
button_layout.addStretch()
|
||||
removeButton = QtGui.QPushButton(importWidget)
|
||||
removeButton.setIcon(self.delete_icon)
|
||||
removeButton.setObjectName(prefix + 'RemoveButton')
|
||||
button_layout.addWidget(removeButton)
|
||||
importLayout.addLayout(button_layout)
|
||||
self.format_widgets[this_format]['file_list_widget'] = fileListWidget
|
||||
remove_button = QtGui.QPushButton(import_widget)
|
||||
remove_button.setIcon(self.delete_icon)
|
||||
remove_button.setObjectName(prefix + 'RemoveButton')
|
||||
button_layout.addWidget(remove_button)
|
||||
import_layout.addLayout(button_layout)
|
||||
self.format_widgets[this_format]['file_list_widget'] = file_list_widget
|
||||
self.format_widgets[this_format]['button_layout'] = button_layout
|
||||
self.format_widgets[this_format]['addButton'] = addButton
|
||||
self.format_widgets[this_format]['removeButton'] = removeButton
|
||||
self.format_widgets[this_format]['addButton'] = add_button
|
||||
self.format_widgets[this_format]['removeButton'] = remove_button
|
||||
self.format_stack.addWidget(page)
|
||||
self.format_widgets[this_format]['page'] = page
|
||||
self.format_widgets[this_format]['importLayout'] = importLayout
|
||||
self.format_widgets[this_format]['importLayout'] = import_layout
|
||||
self.format_combo_box.addItem('')
|
||||
|
||||
def disablableWidget(self, page, prefix):
|
||||
def disablable_widget(self, page, prefix):
|
||||
"""
|
||||
Disable a widget.
|
||||
"""
|
||||
|
@ -526,10 +524,10 @@ class SongImportSourcePage(QtGui.QWizardPage):
|
|||
if wizard.format_widgets[this_format]['file_list_widget'].count() > 0:
|
||||
return True
|
||||
else:
|
||||
filepath = str(wizard.format_widgets[this_format]['file_path_edit'].text())
|
||||
if filepath:
|
||||
if select_mode == SongFormatSelect.SingleFile and os.path.isfile(filepath):
|
||||
file_path = str(wizard.format_widgets[this_format]['file_path_edit'].text())
|
||||
if file_path:
|
||||
if select_mode == SongFormatSelect.SingleFile and os.path.isfile(file_path):
|
||||
return True
|
||||
elif select_mode == SongFormatSelect.SingleFolder and os.path.isdir(filepath):
|
||||
elif select_mode == SongFormatSelect.SingleFolder and os.path.isdir(file_path):
|
||||
return True
|
||||
return False
|
||||
|
|
|
@ -161,6 +161,7 @@ class Ui_SongMaintenanceDialog(object):
|
|||
self.add_book_button.setText(UiStrings().Add)
|
||||
self.edit_book_button.setText(UiStrings().Edit)
|
||||
self.delete_book_button.setText(UiStrings().Delete)
|
||||
typeListWidth = max(self.fontMetrics().width(SongStrings.Authors),
|
||||
self.fontMetrics().width(SongStrings.Topics), self.fontMetrics().width(SongStrings.SongBooks))
|
||||
self.type_list_widget.setFixedWidth(typeListWidth + self.type_list_widget.iconSize().width() + 32)
|
||||
type_list_width = max(self.fontMetrics().width(SongStrings.Authors),
|
||||
self.fontMetrics().width(SongStrings.Topics),
|
||||
self.fontMetrics().width(SongStrings.SongBooks))
|
||||
self.type_list_widget.setFixedWidth(type_list_width + self.type_list_widget.iconSize().width() + 32)
|
||||
|
|
|
@ -98,8 +98,7 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
|
|||
"""
|
||||
Get the ID of the currently selected item.
|
||||
|
||||
``list_widget``
|
||||
The list widget to examine.
|
||||
:param list_widget: The list widget to examine.
|
||||
"""
|
||||
item = list_widget.currentItem()
|
||||
if item:
|
||||
|
@ -163,6 +162,9 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
|
|||
def check_author_exists(self, new_author, edit=False):
|
||||
"""
|
||||
Returns *False* if the given Author already exists, otherwise *True*.
|
||||
|
||||
:param new_author: The new Author.
|
||||
:param edit: Are we editing the song?
|
||||
"""
|
||||
authors = self.manager.get_all_objects(
|
||||
Author,
|
||||
|
@ -177,6 +179,9 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
|
|||
def check_topic_exists(self, new_topic, edit=False):
|
||||
"""
|
||||
Returns *False* if the given Topic already exists, otherwise *True*.
|
||||
|
||||
:param new_topic: The new Topic.
|
||||
:param edit: Are we editing the song?
|
||||
"""
|
||||
topics = self.manager.get_all_objects(Topic, Topic.name == new_topic.name)
|
||||
return self.__check_object_exists(topics, new_topic, edit)
|
||||
|
@ -184,17 +189,21 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
|
|||
def check_song_book_exists(self, new_book, edit=False):
|
||||
"""
|
||||
Returns *False* if the given Topic already exists, otherwise *True*.
|
||||
|
||||
:param new_book: The new Book.
|
||||
:param edit: Are we editing the song?
|
||||
"""
|
||||
books = self.manager.get_all_objects(Book,
|
||||
and_(Book.name == new_book.name, Book.publisher == new_book.publisher))
|
||||
books = self.manager.get_all_objects(
|
||||
Book, and_(Book.name == new_book.name, Book.publisher == new_book.publisher))
|
||||
return self.__check_object_exists(books, new_book, edit)
|
||||
|
||||
def __check_object_exists(self, existing_objects, new_object, edit):
|
||||
"""
|
||||
Utility method to check for an existing object.
|
||||
|
||||
``edit``
|
||||
If we edit an item, this should be *True*.
|
||||
:param existing_objects: The objects reference
|
||||
:param new_object: An individual object
|
||||
:param edit: If we edit an item, this should be *True*.
|
||||
"""
|
||||
if existing_objects:
|
||||
# If we edit an existing object, we need to make sure that we do
|
||||
|
@ -297,8 +306,7 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
|
|||
'author %s use the existing author %s?') %
|
||||
(author.display_name, temp_display_name, author.display_name), parent=self, question=True) == \
|
||||
QtGui.QMessageBox.Yes:
|
||||
self._merge_objects(author, self.merge_authors,
|
||||
self.reset_authors)
|
||||
self._merge_objects(author, self.merge_authors, self.reset_authors)
|
||||
else:
|
||||
# We restore the author's old first and last name as well as
|
||||
# his display name.
|
||||
|
@ -330,15 +338,16 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
|
|||
message=translate('SongsPlugin.SongMaintenanceForm', 'Could not save your changes.'))
|
||||
elif critical_error_message_box(
|
||||
message=translate('SongsPlugin.SongMaintenanceForm',
|
||||
'The topic %s already exists. Would you like to make songs with topic %s use the existing topic %s?') %
|
||||
(topic.name, temp_name, topic.name), parent=self, question=True) == QtGui.QMessageBox.Yes:
|
||||
'The topic %s already exists. Would you like to make songs with topic %s use the '
|
||||
'existing topic %s?') % (topic.name, temp_name, topic.name),
|
||||
parent=self, question=True) == QtGui.QMessageBox.Yes:
|
||||
self._merge_objects(topic, self.merge_topics, self.reset_topics)
|
||||
else:
|
||||
# We restore the topics's old name.
|
||||
topic.name = temp_name
|
||||
critical_error_message_box(
|
||||
message=translate('SongsPlugin.SongMaintenanceForm',
|
||||
'Could not save your modified topic, because it already exists.'))
|
||||
'Could not save your modified topic, because it already exists.'))
|
||||
|
||||
def on_edit_book_button_clicked(self):
|
||||
"""
|
||||
|
@ -367,8 +376,9 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
|
|||
message=translate('SongsPlugin.SongMaintenanceForm', 'Could not save your changes.'))
|
||||
elif critical_error_message_box(
|
||||
message=translate('SongsPlugin.SongMaintenanceForm',
|
||||
'The book %s already exists. Would you like to make songs with book %s use the existing book %s?') %
|
||||
(book.name, temp_name, book.name), parent=self, question=True) == QtGui.QMessageBox.Yes:
|
||||
'The book %s already exists. Would you like to make '
|
||||
'songs with book %s use the existing book %s?') % (book.name, temp_name, book.name),
|
||||
parent=self, question=True) == QtGui.QMessageBox.Yes:
|
||||
self._merge_objects(book, self.merge_song_books, self.reset_song_books)
|
||||
else:
|
||||
# We restore the book's old name and publisher.
|
||||
|
@ -390,8 +400,7 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
|
|||
"""
|
||||
Merges two authors into one author.
|
||||
|
||||
``old_author``
|
||||
The object, which was edited, that will be deleted
|
||||
:param old_author: The object, which was edited, that will be deleted
|
||||
"""
|
||||
# Find the duplicate.
|
||||
existing_author = self.manager.get_object_filtered(
|
||||
|
@ -418,15 +427,11 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
|
|||
"""
|
||||
Merges two topics into one topic.
|
||||
|
||||
``old_topic``
|
||||
The object, which was edited, that will be deleted
|
||||
:param old_topic: The object, which was edited, that will be deleted
|
||||
"""
|
||||
# Find the duplicate.
|
||||
existing_topic = self.manager.get_object_filtered(
|
||||
Topic,
|
||||
and_(
|
||||
Topic.name == old_topic.name, Topic.id != old_topic.id
|
||||
)
|
||||
Topic, and_(Topic.name == old_topic.name, Topic.id != old_topic.id)
|
||||
)
|
||||
# Find the songs, which have the old_topic as topic.
|
||||
songs = self.manager.get_all_objects(Song, Song.topics.contains(old_topic))
|
||||
|
@ -467,30 +472,34 @@ class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog):
|
|||
Delete the author if the author is not attached to any songs.
|
||||
"""
|
||||
self._delete_item(Author, self.authors_list_widget, self.reset_authors,
|
||||
translate('SongsPlugin.SongMaintenanceForm', 'Delete Author'),
|
||||
translate('SongsPlugin.SongMaintenanceForm', 'Are you sure you want to delete the selected author?'),
|
||||
translate('SongsPlugin.SongMaintenanceForm',
|
||||
'This author cannot be deleted, they are currently assigned to at least one song.'))
|
||||
translate('SongsPlugin.SongMaintenanceForm', 'Delete Author'),
|
||||
translate('SongsPlugin.SongMaintenanceForm',
|
||||
'Are you sure you want to delete the selected author?'),
|
||||
translate('SongsPlugin.SongMaintenanceForm',
|
||||
'This author cannot be deleted, they are currently assigned to at least one song'
|
||||
'.'))
|
||||
|
||||
def on_delete_topic_button_clicked(self):
|
||||
"""
|
||||
Delete the Book if the Book is not attached to any songs.
|
||||
"""
|
||||
self._delete_item(Topic, self.topics_list_widget, self.reset_topics,
|
||||
translate('SongsPlugin.SongMaintenanceForm', 'Delete Topic'),
|
||||
translate('SongsPlugin.SongMaintenanceForm', 'Are you sure you want to delete the selected topic?'),
|
||||
translate('SongsPlugin.SongMaintenanceForm',
|
||||
'This topic cannot be deleted, it is currently assigned to at least one song.'))
|
||||
translate('SongsPlugin.SongMaintenanceForm', 'Delete Topic'),
|
||||
translate('SongsPlugin.SongMaintenanceForm',
|
||||
'Are you sure you want to delete the selected topic?'),
|
||||
translate('SongsPlugin.SongMaintenanceForm',
|
||||
'This topic cannot be deleted, it is currently assigned to at least one song.'))
|
||||
|
||||
def on_delete_book_button_clicked(self):
|
||||
"""
|
||||
Delete the Book if the Book is not attached to any songs.
|
||||
"""
|
||||
self._delete_item(Book, self.song_books_list_widget, self.reset_song_books,
|
||||
translate('SongsPlugin.SongMaintenanceForm', 'Delete Book'),
|
||||
translate('SongsPlugin.SongMaintenanceForm', 'Are you sure you want to delete the selected book?'),
|
||||
translate('SongsPlugin.SongMaintenanceForm',
|
||||
'This book cannot be deleted, it is currently assigned to at least one song.'))
|
||||
translate('SongsPlugin.SongMaintenanceForm', 'Delete Book'),
|
||||
translate('SongsPlugin.SongMaintenanceForm',
|
||||
'Are you sure you want to delete the selected book?'),
|
||||
translate('SongsPlugin.SongMaintenanceForm',
|
||||
'This book cannot be deleted, it is currently assigned to at least one song.'))
|
||||
|
||||
def on_authors_list_row_changed(self, row):
|
||||
"""
|
||||
|
|
|
@ -186,7 +186,7 @@ class SongReviewWidget(QtGui.QWidget):
|
|||
# Some pixels are missing at the bottom of the table, but all themes I tried still allowed
|
||||
# to read the last verse line, so I'll just leave it at that.
|
||||
self.song_info_verse_list_widget.setFixedHeight(self.song_info_verse_list_widget.verticalHeader().length() +
|
||||
self.song_info_verse_list_widget.verticalHeader().offset() + 6)
|
||||
self.song_info_verse_list_widget.verticalHeader().offset() + 6)
|
||||
self.song_group_box_layout.addWidget(self.song_info_verse_list_widget)
|
||||
self.song_group_box_layout.addStretch()
|
||||
self.song_vertical_layout.addWidget(self.song_group_box)
|
||||
|
|
|
@ -62,8 +62,8 @@ class TopicsForm(QtGui.QDialog, Ui_TopicsDialog):
|
|||
Override the inherited method to check before we close.
|
||||
"""
|
||||
if not self.name_edit.text():
|
||||
critical_error_message_box(message=translate('SongsPlugin.TopicsForm',
|
||||
'You need to type in a topic name.'))
|
||||
critical_error_message_box(
|
||||
message=translate('SongsPlugin.TopicsForm', 'You need to type in a topic name.'))
|
||||
self.name_edit.setFocus()
|
||||
return False
|
||||
else:
|
||||
|
|
|
@ -107,7 +107,7 @@ class SongFormat(object):
|
|||
|
||||
``u'prefix'``
|
||||
Prefix for Qt objects. Use mixedCase, e.g. ``u'openLyrics'``
|
||||
See ``SongImportForm.addFileSelectItem()``
|
||||
See ``SongImportForm.add_file_select_item()``
|
||||
|
||||
Optional attributes for each song format:
|
||||
|
||||
|
|
|
@ -54,26 +54,23 @@ from openlp.plugins.songs.forms.duplicatesongremovalform import DuplicateSongRem
|
|||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
__default_settings__ = {
|
||||
'songs/db type': 'sqlite',
|
||||
'songs/last search type': SongSearch.Entire,
|
||||
'songs/last import type': SongFormat.OpenLyrics,
|
||||
'songs/update service on edit': False,
|
||||
'songs/search as type': False,
|
||||
'songs/add song from service': True,
|
||||
'songs/display songbar': True,
|
||||
'songs/last directory import': '',
|
||||
'songs/last directory export': ''
|
||||
}
|
||||
__default_settings__ = {'songs/db type': 'sqlite',
|
||||
'songs/last search type': SongSearch.Entire,
|
||||
'songs/last import type': SongFormat.OpenLyrics,
|
||||
'songs/update service on edit': False,
|
||||
'songs/search as type': False,
|
||||
'songs/add song from service': True,
|
||||
'songs/display songbar': True,
|
||||
'songs/last directory import': '',
|
||||
'songs/last directory export': ''
|
||||
}
|
||||
|
||||
|
||||
class SongsPlugin(Plugin):
|
||||
"""
|
||||
This is the number 1 plugin, if importance were placed on any
|
||||
plugins. This plugin enables the user to create, edit and display
|
||||
songs. Songs are divided into verses, and the verse order can be
|
||||
specified. Authors, topics and song books can be assigned to songs
|
||||
as well.
|
||||
This is the number 1 plugin, if importance were placed on any plugins. This plugin enables the user to create,
|
||||
edit and display songs. Songs are divided into verses, and the verse order can be specified. Authors, topics and
|
||||
song books can be assigned to songs as well.
|
||||
"""
|
||||
log.info('Song Plugin loaded')
|
||||
|
||||
|
@ -94,6 +91,9 @@ class SongsPlugin(Plugin):
|
|||
return self.manager.session is not None
|
||||
|
||||
def initialise(self):
|
||||
"""
|
||||
Lets Initialise the plugin
|
||||
"""
|
||||
log.info('Songs Initialising')
|
||||
super(SongsPlugin, self).initialise()
|
||||
self.song_import_item.setVisible(True)
|
||||
|
@ -108,15 +108,13 @@ class SongsPlugin(Plugin):
|
|||
|
||||
def add_import_menu_item(self, import_menu):
|
||||
"""
|
||||
Give the Songs plugin the opportunity to add items to the
|
||||
**Import** menu.
|
||||
Give the Songs plugin the opportunity to add items to the **Import** menu.
|
||||
|
||||
``import_menu``
|
||||
The actual **Import** menu item, so that your actions can
|
||||
use it as their parent.
|
||||
:param import_menu: The actual **Import** menu item, so that your actions can use it as their parent.
|
||||
"""
|
||||
# Main song import menu item - will eventually be the only one
|
||||
self.song_import_item = create_action(import_menu, 'songImportItem',
|
||||
self.song_import_item = create_action(
|
||||
import_menu, 'songImportItem',
|
||||
text=translate('SongsPlugin', '&Song'),
|
||||
tooltip=translate('SongsPlugin', 'Import songs using the import wizard.'),
|
||||
triggers=self.on_song_import_item_clicked)
|
||||
|
@ -124,15 +122,13 @@ class SongsPlugin(Plugin):
|
|||
|
||||
def add_export_menu_Item(self, export_menu):
|
||||
"""
|
||||
Give the Songs plugin the opportunity to add items to the
|
||||
**Export** menu.
|
||||
Give the Songs plugin the opportunity to add items to the **Export** menu.
|
||||
|
||||
``export_menu``
|
||||
The actual **Export** menu item, so that your actions can
|
||||
use it as their parent.
|
||||
:param export_menu: The actual **Export** menu item, so that your actions can use it as their parent.
|
||||
"""
|
||||
# Main song import menu item - will eventually be the only one
|
||||
self.song_export_item = create_action(export_menu, 'songExportItem',
|
||||
self.song_export_item = create_action(
|
||||
export_menu, 'songExportItem',
|
||||
text=translate('SongsPlugin', '&Song'),
|
||||
tooltip=translate('SongsPlugin', 'Exports songs using the export wizard.'),
|
||||
triggers=self.on_song_export_item_clicked)
|
||||
|
@ -140,24 +136,22 @@ class SongsPlugin(Plugin):
|
|||
|
||||
def add_tools_menu_item(self, tools_menu):
|
||||
"""
|
||||
Give the Songs plugin the opportunity to add items to the
|
||||
**Tools** menu.
|
||||
Give the Songs plugin the opportunity to add items to the **Tools** menu.
|
||||
|
||||
``tools_menu``
|
||||
The actual **Tools** menu item, so that your actions can
|
||||
use it as their parent.
|
||||
:param tools_menu: The actual **Tools** menu item, so that your actions can use it as their parent.
|
||||
"""
|
||||
log.info('add tools menu')
|
||||
self.tools_reindex_item = create_action(tools_menu, 'toolsReindexItem',
|
||||
self.tools_reindex_item = create_action(
|
||||
tools_menu, 'toolsReindexItem',
|
||||
text=translate('SongsPlugin', '&Re-index Songs'),
|
||||
icon=':/plugins/plugin_songs.png',
|
||||
statustip=translate('SongsPlugin', 'Re-index the songs database to improve searching and ordering.'),
|
||||
visible=False, triggers=self.on_tools_reindex_item_triggered)
|
||||
tools_menu.addAction(self.tools_reindex_item)
|
||||
self.tools_find_duplicates = create_action(tools_menu, 'toolsFindDuplicates',
|
||||
self.tools_find_duplicates = create_action(
|
||||
tools_menu, 'toolsFindDuplicates',
|
||||
text=translate('SongsPlugin', 'Find &Duplicate Songs'),
|
||||
statustip=translate('SongsPlugin',
|
||||
'Find and remove duplicate songs in the song database.'),
|
||||
statustip=translate('SongsPlugin', 'Find and remove duplicate songs in the song database.'),
|
||||
visible=False, triggers=self.on_tools_find_duplicates_triggered, can_shortcuts=True)
|
||||
tools_menu.addAction(self.tools_find_duplicates)
|
||||
|
||||
|
@ -165,11 +159,11 @@ class SongsPlugin(Plugin):
|
|||
"""
|
||||
Rebuild each song.
|
||||
"""
|
||||
maxSongs = self.manager.get_object_count(Song)
|
||||
if maxSongs == 0:
|
||||
max_songs = self.manager.get_object_count(Song)
|
||||
if max_songs == 0:
|
||||
return
|
||||
progress_dialog = QtGui.QProgressDialog(translate('SongsPlugin', 'Reindexing songs...'), UiStrings().Cancel,
|
||||
0, maxSongs, self.main_window)
|
||||
progress_dialog = QtGui.QProgressDialog(
|
||||
translate('SongsPlugin', 'Reindexing songs...'), UiStrings().Cancel, 0, max_songs, self.main_window)
|
||||
progress_dialog.setWindowTitle(translate('SongsPlugin', 'Reindexing songs'))
|
||||
progress_dialog.setWindowModality(QtCore.Qt.WindowModal)
|
||||
songs = self.manager.get_all_objects(Song)
|
||||
|
@ -186,16 +180,22 @@ class SongsPlugin(Plugin):
|
|||
DuplicateSongRemovalForm(self).exec_()
|
||||
|
||||
def on_song_import_item_clicked(self):
|
||||
"""
|
||||
The song import option has been selected
|
||||
"""
|
||||
if self.media_item:
|
||||
self.media_item.on_import_click()
|
||||
|
||||
def on_song_export_item_clicked(self):
|
||||
"""
|
||||
The song export option has been selected
|
||||
"""
|
||||
if self.media_item:
|
||||
self.media_item.on_export_click()
|
||||
|
||||
def about(self):
|
||||
return translate('SongsPlugin', '<strong>Songs Plugin</strong>'
|
||||
'<br />The songs plugin provides the ability to display and manage songs.')
|
||||
'<br />The songs plugin provides the ability to display and manage songs.')
|
||||
|
||||
def uses_theme(self, theme):
|
||||
"""
|
||||
|
@ -207,24 +207,27 @@ class SongsPlugin(Plugin):
|
|||
return True
|
||||
return False
|
||||
|
||||
def rename_theme(self, oldTheme, newTheme):
|
||||
def rename_theme(self, old_theme, new_theme):
|
||||
"""
|
||||
Renames a theme the song plugin is using making the plugin use the new
|
||||
name.
|
||||
Renames a theme the song plugin is using making the plugin use the new name.
|
||||
|
||||
``oldTheme``
|
||||
The name of the theme the plugin should stop using.
|
||||
|
||||
``newTheme``
|
||||
The new name the plugin should now use.
|
||||
:param old_theme: The name of the theme the plugin should stop using.
|
||||
:param new_theme: The new name the plugin should now use.
|
||||
"""
|
||||
songsUsingTheme = self.manager.get_all_objects(Song, Song.theme_name == oldTheme)
|
||||
for song in songsUsingTheme:
|
||||
song.theme_name = newTheme
|
||||
songs_using_theme = self.manager.get_all_objects(Song, Song.theme_name == old_theme)
|
||||
for song in songs_using_theme:
|
||||
song.theme_name = new_theme
|
||||
self.manager.save_object(song)
|
||||
|
||||
def importSongs(self, format, **kwargs):
|
||||
class_ = SongFormat.get(format, 'class')
|
||||
def import_songs(self, import_format, **kwargs):
|
||||
"""
|
||||
Add the correct importer class
|
||||
|
||||
:param import_format: The import_format to be used
|
||||
:param kwargs: The arguments
|
||||
:return: the correct importer
|
||||
"""
|
||||
class_ = SongFormat.get(import_format, 'class')
|
||||
importer = class_(self.manager, **kwargs)
|
||||
importer.register(self.media_item.import_wizard)
|
||||
return importer
|
||||
|
@ -257,8 +260,7 @@ class SongsPlugin(Plugin):
|
|||
|
||||
def first_time(self):
|
||||
"""
|
||||
If the first time wizard has run, this function is run to import all the
|
||||
new songs into the database.
|
||||
If the first time wizard has run, this function is run to import all the new songs into the database.
|
||||
"""
|
||||
self.application.process_events()
|
||||
self.on_tools_reindex_item_triggered()
|
||||
|
@ -272,7 +274,7 @@ class SongsPlugin(Plugin):
|
|||
if sfile.startswith('songs_') and sfile.endswith('.sqlite'):
|
||||
self.application.process_events()
|
||||
song_dbs.append(os.path.join(db_dir, sfile))
|
||||
song_count += self._countSongs(os.path.join(db_dir, sfile))
|
||||
song_count += self._count_songs(os.path.join(db_dir, sfile))
|
||||
if not song_dbs:
|
||||
return
|
||||
self.application.process_events()
|
||||
|
@ -319,9 +321,11 @@ class SongsPlugin(Plugin):
|
|||
for song in songs:
|
||||
self.manager.delete_object(Song, song.id)
|
||||
|
||||
def _countSongs(self, db_file):
|
||||
def _count_songs(self, db_file):
|
||||
"""
|
||||
Provide a count of the songs in the database
|
||||
|
||||
:param db_file: the database name to count
|
||||
"""
|
||||
connection = sqlite3.connect(db_file)
|
||||
cursor = connection.cursor()
|
||||
|
|
Loading…
Reference in New Issue