# -*- coding: utf-8 -*- # vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 ############################################################################### # OpenLP - Open Source Lyrics Projection # # --------------------------------------------------------------------------- # # Copyright (c) 2008-2010 Raoul Snyman # # Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael # # Gorven, Scott Guerrieri, Meinert Jordan, Andreas Preikschat, Christian # # Richter, Philip Ridout, Maikel Stuivenberg, Martin Thompson, Jon Tibble, # # Carsten Tinggaard, Frode Woldsund # # --------------------------------------------------------------------------- # # This program is free software; you can redistribute it and/or modify it # # under the terms of the GNU General Public License as published by the Free # # Software Foundation; version 2 of the License. # # # # This program is distributed in the hope that it will be useful, but WITHOUT # # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # # more details. # # # # You should have received a copy of the GNU General Public License along # # with this program; if not, write to the Free Software Foundation, Inc., 59 # # Temple Place, Suite 330, Boston, MA 02111-1307 USA # ############################################################################### from PyQt4 import QtGui, QtCore from sqlalchemy.sql import and_ from openlp.core.lib import Receiver, translate from openlp.plugins.songs.forms import AuthorsForm, TopicsForm, SongBookForm from openlp.plugins.songs.lib.db import Author, Book, Topic, Song from songmaintenancedialog import Ui_SongMaintenanceDialog class SongMaintenanceForm(QtGui.QDialog, Ui_SongMaintenanceDialog): """ Class documentation goes here. """ def __init__(self, songmanager, parent=None): """ Constructor """ QtGui.QDialog.__init__(self, parent) self.setupUi(self) self.songmanager = songmanager self.authorform = AuthorsForm(self) self.topicform = TopicsForm(self) self.bookform = SongBookForm(self) QtCore.QObject.connect(self.AuthorAddButton, QtCore.SIGNAL(u'pressed()'), self.onAuthorAddButtonClick) QtCore.QObject.connect(self.TopicAddButton, QtCore.SIGNAL(u'pressed()'), self.onTopicAddButtonClick) QtCore.QObject.connect(self.BookAddButton, QtCore.SIGNAL(u'pressed()'), self.onBookAddButtonClick) QtCore.QObject.connect(self.AuthorEditButton, QtCore.SIGNAL(u'pressed()'), self.onAuthorEditButtonClick) QtCore.QObject.connect(self.TopicEditButton, QtCore.SIGNAL(u'pressed()'), self.onTopicEditButtonClick) QtCore.QObject.connect(self.BookEditButton, QtCore.SIGNAL(u'pressed()'), self.onBookEditButtonClick) QtCore.QObject.connect(self.AuthorDeleteButton, QtCore.SIGNAL(u'pressed()'), self.onAuthorDeleteButtonClick) QtCore.QObject.connect(self.TopicDeleteButton, QtCore.SIGNAL(u'pressed()'), self.onTopicDeleteButtonClick) QtCore.QObject.connect(self.BookDeleteButton, QtCore.SIGNAL(u'pressed()'), self.onBookDeleteButtonClick) def exec_(self): self.TypeListWidget.setCurrentRow(0) self.resetAuthors() self.resetTopics() self.resetBooks() self.TypeListWidget.setFocus() return QtGui.QDialog.exec_(self) def _getCurrentItemId(self, ListWidget): item = ListWidget.currentItem() if item: item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0] return item_id else: return -1 def _deleteItem(self, item_class, list_widget, reset_func, dlg_title, del_text, err_text, sel_text): item_id = self._getCurrentItemId(list_widget) if item_id != -1: item = self.songmanager.get_object(item_class, item_id) if item and len(item.songs) == 0: if QtGui.QMessageBox.warning(self, dlg_title, del_text, QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.No | QtGui.QMessageBox.Yes)) == QtGui.QMessageBox.Yes: self.songmanager.delete_object(item_class, item.id) reset_func() else: QtGui.QMessageBox.critical(self, dlg_title, err_text) else: QtGui.QMessageBox.critical(self, dlg_title, sel_text) def resetAuthors(self): """ Reloads the Authors list. """ self.AuthorsListWidget.clear() authors = self.songmanager.get_all_objects(Author, order_by_ref=Author.display_name) for author in authors: if author.display_name: author_name = QtGui.QListWidgetItem(author.display_name) else: author_name = QtGui.QListWidgetItem( u'%s %s' % (author.first_name, author.last_name)) author_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(author.id)) self.AuthorsListWidget.addItem(author_name) if self.AuthorsListWidget.count() == 0: self.AuthorDeleteButton.setEnabled(False) self.AuthorEditButton.setEnabled(False) else: self.AuthorDeleteButton.setEnabled(True) self.AuthorEditButton.setEnabled(True) def resetTopics(self): """ Reloads the Topics list. """ self.TopicsListWidget.clear() topics = self.songmanager.get_all_objects(Topic, order_by_ref=Topic.name) for topic in topics: topic_name = QtGui.QListWidgetItem(topic.name) topic_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(topic.id)) self.TopicsListWidget.addItem(topic_name) if self.TopicsListWidget.count() == 0: self.TopicDeleteButton.setEnabled(False) self.TopicEditButton.setEnabled(False) else: self.TopicDeleteButton.setEnabled(True) self.TopicEditButton.setEnabled(True) def resetBooks(self): """ Reloads the Books list. """ self.BooksListWidget.clear() books = self.songmanager.get_all_objects(Book, order_by_ref=Book.name) for book in books: book_name = QtGui.QListWidgetItem(u'%s (%s)' % (book.name, book.publisher)) book_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(book.id)) self.BooksListWidget.addItem(book_name) if self.BooksListWidget.count() == 0: self.BookDeleteButton.setEnabled(False) self.BookEditButton.setEnabled(False) else: self.BookDeleteButton.setEnabled(True) self.BookEditButton.setEnabled(True) def checkAuthor(self, new_author, edit=False): """ Returns False if the given Author is already in the list otherwise True. """ authors = self.songmanager.get_all_objects(Author, and_(Author.first_name == new_author.first_name, Author.last_name == new_author.last_name, Author.display_name == new_author.display_name)) if len(authors) > 0: # If we edit an existing Author, we need to make sure that we do # not return False when nothing has changed (because this would # cause an error message later on). if edit: if authors[0].id == new_author.id: return True else: return False else: return False else: return True def checkTopic(self, new_topic, edit=False): """ Returns False if the given Topic is already in the list otherwise True. """ topics = self.songmanager.get_all_objects(Topic, Topic.name == new_topic.name) if len(topics) > 0: # If we edit an existing Topic, we need to make sure that we do # not return False when nothing has changed (because this would # cause an error message later on). if edit: if topics[0].id == new_topic.id: return True else: return False else: return False else: return True def checkBook(self, new_book, edit=False): """ Returns False if the given Book is already in the list otherwise True. """ books = self.songmanager.get_all_objects(Book, and_(Book.name == new_book.name, Book.publisher == new_book.publisher)) if len(books) > 0: # If we edit an existing Book, we need to make sure that we do # not return False when nothing has changed (because this would # cause an error message later on). if edit: if books[0].id == new_book.id: return True else: return False else: return False else: return True def onAuthorAddButtonClick(self): self.authorform.setAutoDisplayName(True) if self.authorform.exec_(): author = Author.populate( first_name=unicode(self.authorform.FirstNameEdit.text()), last_name=unicode(self.authorform.LastNameEdit.text()), display_name=unicode(self.authorform.DisplayEdit.text())) if self.checkAuthor(author): if self.songmanager.save_object(author): self.resetAuthors() else: QtGui.QMessageBox.critical(self, translate('SongsPlugin.SongMaintenanceForm', 'Error'), translate('SongsPlugin.SongMaintenanceForm', 'Could not add your author.')) else: QtGui.QMessageBox.critical(self, translate('SongsPlugin.SongMaintenanceForm', 'Error'), translate('SongsPlugin.SongMaintenanceForm', 'This author already exists.')) def onTopicAddButtonClick(self): if self.topicform.exec_(): topic = Topic.populate(name=unicode(self.topicform.NameEdit.text())) if self.checkTopic(topic): if self.songmanager.save_object(topic): self.resetTopics() else: QtGui.QMessageBox.critical(self, translate('SongsPlugin.SongMaintenanceForm', 'Error'), translate('SongsPlugin.SongMaintenanceForm', 'Could not add your topic.')) else: QtGui.QMessageBox.critical(self, translate('SongsPlugin.SongMaintenanceForm', 'Error'), translate('SongsPlugin.SongMaintenanceForm', 'This topic already exists.')) def onBookAddButtonClick(self): if self.bookform.exec_(): book = Book.populate(name=unicode(self.bookform.NameEdit.text()), publisher=unicode(self.bookform.PublisherEdit.text())) if self.checkBook(book): if self.songmanager.save_object(book): self.resetBooks() else: QtGui.QMessageBox.critical(self, translate('SongsPlugin.SongMaintenanceForm', 'Error'), translate('SongsPlugin.SongMaintenanceForm', 'Could not add your book.')) else: QtGui.QMessageBox.critical(self, translate('SongsPlugin.SongMaintenanceForm', 'Error'), translate('SongsPlugin.SongMaintenanceForm', 'This book already exists.')) def onAuthorEditButtonClick(self): author_id = self._getCurrentItemId(self.AuthorsListWidget) if author_id != -1: author = self.songmanager.get_object(Author, author_id) self.authorform.setAutoDisplayName(False) self.authorform.FirstNameEdit.setText(author.first_name) self.authorform.LastNameEdit.setText(author.last_name) self.authorform.DisplayEdit.setText(author.display_name) # Save the author's first and last name as well as the display name # for the case that they have to be restored. temp_first_name = author.first_name temp_last_name = author.last_name temp_display_name = author.display_name if self.authorform.exec_(False): author.first_name = unicode( self.authorform.FirstNameEdit.text()) author.last_name = unicode(self.authorform.LastNameEdit.text()) author.display_name = unicode( self.authorform.DisplayEdit.text()) if self.checkAuthor(author, True): if self.songmanager.save_object(author): self.resetAuthors() Receiver.send_message(u'songs_load_list') else: QtGui.QMessageBox.critical(self, translate('SongsPlugin.SongMaintenanceForm', 'Error'), translate('SongsPlugin.SongMaintenanceForm', 'Could not save your changes.')) elif QtGui.QMessageBox.critical(self, translate('SongsPlugin.SongMaintenanceForm', 'Error'), translate('SongsPlugin.SongMaintenanceForm', 'The author %s' ' already exists. Would you like to make songs with author ' '%s use the existing author %s?' % (author.display_name, temp_display_name, author.display_name)), QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.No | QtGui.QMessageBox.Yes)) == QtGui.QMessageBox.Yes: self.mergeAuthors(author) self.resetAuthors() Receiver.send_message(u'songs_load_list') else: # We restore the author's old first and last name as well as # his display name. author.first_name = temp_first_name author.last_name = temp_last_name author.display_name = temp_display_name QtGui.QMessageBox.critical(self, translate('SongsPlugin.SongMaintenanceForm', 'Error'), translate('SongsPlugin.SongMaintenanceForm', 'Could not save your modified author, because the ' 'author already exists.')) def onTopicEditButtonClick(self): topic_id = self._getCurrentItemId(self.TopicsListWidget) if topic_id != -1: topic = self.songmanager.get_object(Topic, topic_id) self.topicform.NameEdit.setText(topic.name) # Save the topic's name for the case that he has to be restored. temp_name = topic.name if self.topicform.exec_(False): topic.name = unicode(self.topicform.NameEdit.text()) if self.checkTopic(topic, True): if self.songmanager.save_object(topic): self.resetTopics() else: QtGui.QMessageBox.critical(self, translate('SongsPlugin.SongMaintenanceForm', 'Error'), translate('SongsPlugin.SongMaintenanceForm', 'Could not save your changes.')) elif QtGui.QMessageBox.critical(self, translate('SongsPlugin.SongMaintenanceForm', 'Error'), 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)), QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.No | QtGui.QMessageBox.Yes)) == QtGui.QMessageBox.Yes: self.mergeTopics(topic) self.resetTopics() else: # We restore the topics's old name. topic.name = temp_name QtGui.QMessageBox.critical(self, translate('SongsPlugin.SongMaintenanceForm', 'Error'), translate('SongsPlugin.SongMaintenanceForm', 'Could not save your modified topic, because it ' 'already exists.')) def onBookEditButtonClick(self): book_id = self._getCurrentItemId(self.BooksListWidget) if book_id != -1: book = self.songmanager.get_object(Book, book_id) if book.publisher is None: book.publisher = u'' self.bookform.NameEdit.setText(book.name) self.bookform.PublisherEdit.setText(book.publisher) # Save the book's name and publisher for the case that they have to # be restored. temp_name = book.name temp_publisher = book.publisher if self.bookform.exec_(False): book.name = unicode(self.bookform.NameEdit.text()) book.publisher = unicode(self.bookform.PublisherEdit.text()) if self.checkBook(book, True): if self.songmanager.save_object(book): self.resetBooks() else: QtGui.QMessageBox.critical(self, translate('SongsPlugin.SongMaintenanceForm', 'Error'), translate('SongsPlugin.SongMaintenanceForm', 'Could not save your changes.')) elif QtGui.QMessageBox.critical(self, translate('SongsPlugin.SongMaintenanceForm', 'Error'), 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)), QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.No | QtGui.QMessageBox.Yes)) == QtGui.QMessageBox.Yes: self.mergeBooks(book) self.resetBooks() else: # We restore the book's old name and publisher. book.name = temp_name book.publisher = temp_publisher def mergeAuthors(self, old_author): """ Merges two authors into one author. ``old_author`` The author which will be deleted afterwards. """ existing_author = self.songmanager.get_object_filtered(Author, and_(Author.first_name == old_author.first_name, Author.last_name == old_author.last_name, Author.display_name == old_author.display_name)) songs = self.songmanager.get_all_objects(Song, Song.authors.contains(old_author)) for song in songs: # We check if the song has already existing_author as author. If # that is not the case we add it. if existing_author not in song.authors: song.authors.append(existing_author) song.authors.remove(old_author) self.songmanager.save_object(song) self.songmanager.delete_object(Author, old_author.id) def mergeTopics(self, old_topic): """ Merges two topics into one topic. ``old_topic`` The topic which will be deleted afterwards. """ existing_topic = self.songmanager.get_object_filtered(Topic, Topic.name == old_topic.name) songs = self.songmanager.get_all_objects(Song, Song.topics.contains(old_topic)) for song in songs: # We check if the song has already existing_topic as topic. If that # is not the case we add it. if existing_topic not in song.topics: song.topics.append(existing_topic) song.topics.remove(old_topic) self.songmanager.save_object(song) self.songmanager.delete_object(Topic, old_topic.id) def mergeBooks(self, old_book): """ Merges two books into one book. ``old_book`` The book which will be deleted afterwards. """ existing_book = self.songmanager.get_object_filtered(Book, and_(Book.name == old_book.name, Book.publisher == old_book.publisher)) songs = self.songmanager.get_all_objects(Song, Song.song_book_id == old_book.id) for song in songs: song.song_book_id = existing_book.id self.songmanager.save_object(song) self.songmanager.delete_object(Book, old_book.id) def onAuthorDeleteButtonClick(self): """ Delete the author if the author is not attached to any songs. """ self._deleteItem(Author, self.AuthorsListWidget, self.resetAuthors, 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', 'No author selected!')) def onTopicDeleteButtonClick(self): """ Delete the Book is the Book is not attached to any songs. """ self._deleteItem(Topic, self.TopicsListWidget, self.resetTopics, 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', 'No topic selected!')) def onBookDeleteButtonClick(self): """ Delete the Book is the Book is not attached to any songs. """ self._deleteItem(Book, self.BooksListWidget, self.resetBooks, 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', 'No book selected!'))