diff --git a/openlp/plugins/songs/forms/editsongdialog.py b/openlp/plugins/songs/forms/editsongdialog.py index d613715dd..3bec03a09 100644 --- a/openlp/plugins/songs/forms/editsongdialog.py +++ b/openlp/plugins/songs/forms/editsongdialog.py @@ -439,58 +439,58 @@ class Ui_EditSongDialog(object): def retranslateUi(self, EditSongDialog): EditSongDialog.setWindowTitle( - translate(u'SongsPlugin.EditSongForm', u'Song Editor')) + translate('SongsPlugin.EditSongForm', 'Song Editor')) self.TitleLabel.setText( - translate(u'SongsPlugin.EditSongForm', u'Title:')) + translate('SongsPlugin.EditSongForm', '&Title:')) self.AlternativeTitleLabel.setText( - translate(u'SongsPlugin.EditSongForm', u'Alternative Title:')) + translate('SongsPlugin.EditSongForm', 'Alt&ernative Title:')) self.LyricsLabel.setText( - translate(u'SongsPlugin.EditSongForm', u'Lyrics:')) + translate('SongsPlugin.EditSongForm', '&Lyrics:')) self.VerseOrderLabel.setText( - translate(u'SongsPlugin.EditSongForm', u'Verse Order:')) + translate('SongsPlugin.EditSongForm', '&Verse Order:')) self.VerseAddButton.setText( - translate(u'SongsPlugin.EditSongForm', u'Add')) + translate('SongsPlugin.EditSongForm', '&Add')) self.VerseEditButton.setText( - translate(u'SongsPlugin.EditSongForm', u'Edit')) + translate('SongsPlugin.EditSongForm', '&Edit')) self.VerseEditAllButton.setText( - translate(u'SongsPlugin.EditSongForm', u'Edit All')) + translate('SongsPlugin.EditSongForm', 'Ed&it All')) self.VerseDeleteButton.setText( - translate(u'SongsPlugin.EditSongForm', u'Delete')) + translate('SongsPlugin.EditSongForm', '&Delete')) self.SongTabWidget.setTabText( self.SongTabWidget.indexOf(self.LyricsTab), - translate(u'SongsPlugin.EditSongForm', u'Title && Lyrics')) + translate('SongsPlugin.EditSongForm', 'Title && Lyrics')) self.AuthorsGroupBox.setTitle( - translate(u'SongsPlugin.EditSongForm', u'Authors')) + translate('SongsPlugin.EditSongForm', 'Authors')) self.AuthorAddButton.setText( - translate(u'SongsPlugin.EditSongForm', u'&Add to Song')) + translate('SongsPlugin.EditSongForm', '&Add to Song')) self.AuthorRemoveButton.setText( - translate(u'SongsPlugin.EditSongForm', u'&Remove')) - self.MaintenanceButton.setText(translate(u'SongsPlugin.EditSongForm', - u'&Manage Authors, Topics, Books')) + translate('SongsPlugin.EditSongForm', '&Remove')) + self.MaintenanceButton.setText(translate('SongsPlugin.EditSongForm', + '&Manage Authors, Topics, Books')) self.TopicGroupBox.setTitle( - translate(u'SongsPlugin.EditSongForm', u'Topic')) + translate('SongsPlugin.EditSongForm', 'Topic')) self.TopicAddButton.setText( - translate(u'SongsPlugin.EditSongForm', u'A&dd to Song')) + translate('SongsPlugin.EditSongForm', 'A&dd to Song')) self.TopicRemoveButton.setText( - translate(u'SongsPlugin.EditSongForm', u'R&emove')) + translate('SongsPlugin.EditSongForm', 'R&emove')) self.SongBookGroup.setTitle( - translate(u'SongsPlugin.EditSongForm', u'Song Book')) + translate('SongsPlugin.EditSongForm', 'Song Book')) self.SongTabWidget.setTabText( self.SongTabWidget.indexOf(self.AuthorsTab), - translate(u'SongsPlugin.EditSongForm', u'Authors, Topics && Book')) + translate('SongsPlugin.EditSongForm', 'Authors, Topics && Book')) self.ThemeGroupBox.setTitle( - translate(u'SongsPlugin.EditSongForm', u'Theme')) + translate('SongsPlugin.EditSongForm', 'Theme')) self.ThemeAddButton.setText( - translate(u'SongsPlugin.EditSongForm', u'Add a Theme')) + translate('SongsPlugin.EditSongForm', 'Add a &Theme')) self.CopyrightGroupBox.setTitle( - translate(u'SongsPlugin.EditSongForm', u'Copyright Information')) + translate('SongsPlugin.EditSongForm', 'Copyright Information')) self.CopyrightInsertButton.setText( - translate(u'SongsPlugin.EditSongForm', u'\xa9')) + translate('SongsPlugin.EditSongForm', u'\xa9')) self.CCLILabel.setText( - translate(u'SongsPlugin.EditSongForm', u'CCLI Number:')) + translate('SongsPlugin.EditSongForm', 'CCLI Number:')) self.CommentsGroupBox.setTitle( - translate(u'SongsPlugin.EditSongForm', u'Comments')) + translate('SongsPlugin.EditSongForm', 'Comments')) self.SongTabWidget.setTabText( self.SongTabWidget.indexOf(self.ThemeTab), - translate(u'SongsPlugin.EditSongForm', - u'Theme, Copyright Info && Comments')) + translate('SongsPlugin.EditSongForm', + 'Theme, Copyright Info && Comments')) diff --git a/openlp/plugins/songs/forms/editsongform.py b/openlp/plugins/songs/forms/editsongform.py index e6c162d0b..0bdff1897 100644 --- a/openlp/plugins/songs/forms/editsongform.py +++ b/openlp/plugins/songs/forms/editsongform.py @@ -30,7 +30,7 @@ from PyQt4 import QtCore, QtGui from openlp.core.lib import SongXMLBuilder, SongXMLParser, Receiver, translate from openlp.plugins.songs.forms import EditVerseForm -from openlp.plugins.songs.lib.models import Song +from openlp.plugins.songs.lib.models import Song, Author, Topic, Book from editsongdialog import Ui_EditSongDialog log = logging.getLogger(__name__) @@ -126,12 +126,8 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): def loadAuthors(self): authors = self.songmanager.get_authors() - authorsCompleter = QtGui.QCompleter( - [author.display_name for author in authors], - self.AuthorsSelectionComboItem) - authorsCompleter.setCaseSensitivity(QtCore.Qt.CaseInsensitive) - self.AuthorsSelectionComboItem.setCompleter(authorsCompleter) self.AuthorsSelectionComboItem.clear() + self.AuthorsSelectionComboItem.addItem(u'') for author in authors: row = self.AuthorsSelectionComboItem.count() self.AuthorsSelectionComboItem.addItem(author.display_name) @@ -140,11 +136,8 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): def loadTopics(self): topics = self.songmanager.get_topics() - topicsCompleter = QtGui.QCompleter( - [topic.name for topic in topics], self.SongTopicCombo) - topicsCompleter.setCaseSensitivity(QtCore.Qt.CaseInsensitive) - self.SongTopicCombo.setCompleter(topicsCompleter) self.SongTopicCombo.clear() + self.SongTopicCombo.addItem(u'') for topic in topics: row = self.SongTopicCombo.count() self.SongTopicCombo.addItem(topic.name) @@ -152,25 +145,16 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): def loadBooks(self): books = self.songmanager.get_books() - booksCompleter = QtGui.QCompleter( - [book.name for book in books], self.SongbookCombo) - booksCompleter.setCaseSensitivity(QtCore.Qt.CaseInsensitive) - self.SongbookCombo.setCompleter(booksCompleter) self.SongbookCombo.clear() - self.SongbookCombo.addItem(u' ') + self.SongbookCombo.addItem(u'') for book in books: row = self.SongbookCombo.count() self.SongbookCombo.addItem(book.name) self.SongbookCombo.setItemData(row, QtCore.QVariant(book.id)) def loadThemes(self, theme_list): - themesCompleter = QtGui.QCompleter( - [theme for theme in theme_list], - self.ThemeSelectionComboItem) - themesCompleter.setCaseSensitivity(QtCore.Qt.CaseInsensitive) - self.ThemeSelectionComboItem.setCompleter(themesCompleter) self.ThemeSelectionComboItem.clear() - self.ThemeSelectionComboItem.addItem(u' ') + self.ThemeSelectionComboItem.addItem(u'') for theme in theme_list: self.ThemeSelectionComboItem.addItem(theme) @@ -244,6 +228,9 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): self.VerseListWidget.clear() self.VerseListWidget.setRowCount(0) self.VerseListWidget.setColumnWidth(0, self.width) + # This is just because occasionally the lyrics come back as a "buffer" + if isinstance(self.song.lyrics, buffer): + self.song.lyrics = unicode(self.song.lyrics) if self.song.lyrics.startswith(u' -1: + text = unicode(self.AuthorsSelectionComboItem.currentText()) + 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: + author = Author.populate(display_name=text) + self.songmanager.save_author(author) + self.song.authors.append(author) + author_item = QtGui.QListWidgetItem(unicode(author.display_name)) + author_item.setData(QtCore.Qt.UserRole, QtCore.QVariant(author.id)) + self.AuthorsListView.addItem(author_item) + self.loadAuthors() + self.AuthorsSelectionComboItem.setCurrentIndex(0) + else: + return + elif item > 0: item_id = (self.AuthorsSelectionComboItem.itemData(item)).toInt()[0] author = self.songmanager.get_author(item_id) self.song.authors.append(author) author_item = QtGui.QListWidgetItem(unicode(author.display_name)) author_item.setData(QtCore.Qt.UserRole, QtCore.QVariant(author.id)) self.AuthorsListView.addItem(author_item) + self.AuthorsSelectionComboItem.setCurrentIndex(0) + else: + QtGui.QMessageBox.warning(self, + translate('SongsPlugin.EditSongForm', 'No Author Selected'), + 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.'), + QtGui.QMessageBox.Ok, QtGui.QMessageBox.Ok) def onAuthorsListViewPressed(self): if self.AuthorsListView.count() > 1: @@ -322,13 +336,40 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): def onTopicAddButtonClicked(self): item = int(self.SongTopicCombo.currentIndex()) - if item > -1: + text = unicode(self.SongTopicCombo.currentText()) + if item == 0 and text: + 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) + self.songmanager.save_topic(topic) + self.song.topics.append(topic) + topic_item = QtGui.QListWidgetItem(unicode(topic.name)) + topic_item.setData(QtCore.Qt.UserRole, QtCore.QVariant(topic.id)) + self.TopicsListView.addItem(topic_item) + self.loadTopics() + self.SongTopicCombo.setCurrentIndex(0) + else: + return + elif item > 0: item_id = (self.SongTopicCombo.itemData(item)).toInt()[0] topic = self.songmanager.get_topic(item_id) self.song.topics.append(topic) topic_item = QtGui.QListWidgetItem(unicode(topic.name)) topic_item.setData(QtCore.Qt.UserRole, QtCore.QVariant(topic.id)) self.TopicsListView.addItem(topic_item) + self.SongTopicCombo.setCurrentIndex(0) + else: + QtGui.QMessageBox.warning(self, + translate('SongsPlugin.EditSongForm', 'No Topic Selected'), + 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.'), + QtGui.QMessageBox.Ok, QtGui.QMessageBox.Ok) def onTopicListViewPressed(self): self.TopicRemoveButton.setEnabled(True) @@ -343,12 +384,27 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): self.TopicsListView.takeItem(row) def onSongBookComboChanged(self, item): - if item == 0: - self.song.song_book_id = 0 - else: + item = int(self.SongbookCombo.currentIndex()) + text = unicode(self.SongbookCombo.currentText()) + if item == 0 and text: + 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) + self.songmanager.save_book(book) + self.song.book = book + self.loadBooks() + else: + return + elif item > 1: item = int(self.SongbookCombo.currentIndex()) self.song.song_book_id = \ (self.SongbookCombo.itemData(item)).toInt()[0] + else: + self.song.song_book_id = 0 def onThemeComboChanged(self, item): if item == 0: @@ -484,7 +540,7 @@ class EditSongForm(QtGui.QDialog, Ui_EditSongDialog): else: self.SongTabWidget.setCurrentIndex(0) self.VerseOrderEdit.setFocus() - return False, translate(u'SongsPlugin.EditSongForm', + return False, translate(u'SongsPlugin.EditSongForm', u'Invalid verse entry, values must be I,B,T,P,E,O,V,C ' u'followed by a number') return True, u'' diff --git a/openlp/plugins/songs/forms/songmaintenancedialog.py b/openlp/plugins/songs/forms/songmaintenancedialog.py index 68ae105ca..f86754e0c 100644 --- a/openlp/plugins/songs/forms/songmaintenancedialog.py +++ b/openlp/plugins/songs/forms/songmaintenancedialog.py @@ -211,28 +211,28 @@ class Ui_SongMaintenanceDialog(object): def retranslateUi(self, SongMaintenanceDialog): SongMaintenanceDialog.setWindowTitle( - translate(u'SongsPlugin.SongMaintenanceForm', u'Song Maintenance')) + translate('SongsPlugin.SongMaintenanceForm', 'Song Maintenance')) self.TypeListWidget.item(0).setText( - translate(u'SongsPlugin.SongMaintenanceForm', u'Authors')) + translate('SongsPlugin.SongMaintenanceForm', 'Authors')) self.TypeListWidget.item(1).setText( - translate(u'SongsPlugin.SongMaintenanceForm', u'Topics')) + translate('SongsPlugin.SongMaintenanceForm', 'Topics')) self.TypeListWidget.item(2).setText( - translate(u'SongsPlugin.SongMaintenanceForm', u'Books/Hymnals')) + translate('SongsPlugin.SongMaintenanceForm', 'Books/Hymnals')) self.AuthorAddButton.setText( - translate(u'SongsPlugin.SongMaintenanceForm', u'Add')) + translate('SongsPlugin.SongMaintenanceForm', '&Add')) self.AuthorEditButton.setText( - translate(u'SongsPlugin.SongMaintenanceForm', u'Edit')) + translate('SongsPlugin.SongMaintenanceForm', '&Edit')) self.AuthorDeleteButton.setText( - translate(u'SongsPlugin.SongMaintenanceForm', u'Delete')) + translate('SongsPlugin.SongMaintenanceForm', '&Delete')) self.TopicAddButton.setText( - translate(u'SongsPlugin.SongMaintenanceForm', u'Add')) + translate('SongsPlugin.SongMaintenanceForm', '&Add')) self.TopicEditButton.setText( - translate(u'SongsPlugin.SongMaintenanceForm', u'Edit')) + translate('SongsPlugin.SongMaintenanceForm', '&Edit')) self.TopicDeleteButton.setText( - translate(u'SongsPlugin.SongMaintenanceForm', u'Delete')) + translate('SongsPlugin.SongMaintenanceForm', '&Delete')) self.BookAddButton.setText( - translate(u'SongsPlugin.SongMaintenanceForm', u'Add')) + translate('SongsPlugin.SongMaintenanceForm', '&Add')) self.BookEditButton.setText( - translate(u'SongsPlugin.SongMaintenanceForm', u'Edit')) + translate('SongsPlugin.SongMaintenanceForm', '&Edit')) self.BookDeleteButton.setText( - translate(u'SongsPlugin.SongMaintenanceForm', u'Delete')) + translate('SongsPlugin.SongMaintenanceForm', '&Delete')) diff --git a/openlpcnv.pyw b/openlpcnv.pyw deleted file mode 100755 index f0c2748f0..000000000 --- a/openlpcnv.pyw +++ /dev/null @@ -1,163 +0,0 @@ -#!/usr/bin/env python -# -*- 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, Christian Richter, Maikel Stuivenberg, Martin # -# Thompson, Jon Tibble, Carsten Tinggaard # -# --------------------------------------------------------------------------- # -# 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 # -############################################################################### - -import os -import logging -import time -import subprocess -import codecs - -if os.name == u'nt': - import win32api - import win32con - from win32com.client import Dispatch - -from openlp.core.utils import AppLocation -from openlp.migration.display import * -from openlp.migration.migratefiles import * -from openlp.migration.migratebibles import * -from openlp.migration.migratesongs import * - -############################################################################### -# For Windows, requires SQLite ODBC Driver to be installed -# (uses sqlite.exe and sqlite3.exe) -# http://www.ch-werner.de/sqliteodbc/ -############################################################################### - -logging.basicConfig(level=logging.DEBUG, - format=u'%(asctime)s %(name)-12s %(levelname)-8s %(message)s', - datefmt=u'%m-%d %H:%M', - filename=u'openlp-migration.log', - filemode=u'w') - -class Migration(object): - """ - A class to take care of the migration process. - """ - def __init__(self): - """ - Initialise the process. - """ - self.display = Display() - self.stime = time.strftime(u'%Y-%m-%d-%H%M%S', time.localtime()) - self.display.output(u'OpenLp v1.9.0 Migration Utility Started') - - def process(self): - """ - Perform the conversion. - """ - #MigrateFiles(self.display).process() - MigrateSongs(self.display).process() - MigrateBibles(self.display).process() - - def move_log_file(self): - """ - Move the log file to a new location. - """ - fname = u'openlp-migration.log' - c = os.path.splitext(fname) - b = (c[0]+'-'+ unicode(self.stime) + c[1]) - self.display.output(u'Logfile ' + b + u' generated') - self.display.output(u'Migration Utility Finished ') - os.rename(fname, b) - - def convert_file(self, inname, outname): - """ - Convert a file from another encoding into UTF-8. - - ``inname`` - The name of the file to be opened and converted. - - ``outname`` - The output file name. - """ - infile = codecs.open(inname, u'r', encoding=u'CP1252') - writefile = codecs.open(outname, u'w', encoding=u'utf-8') - for line in infile: - writefile.write(line) - infile.close() - writefile.close() - - def convert_sqlite2_to_3(self, olddb, newdb): - print u'Converting sqlite2 ' + olddb + ' to sqlite3 ' + newdb - if os.name == u'nt': - # we can't make this a raw unicode string as the \U within it - # causes much confusion - hKey = win32api.RegOpenKey(win32con.HKEY_LOCAL_MACHINE, - u'SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\SQLite ODBC Driver') - value, type = win32api.RegQueryValueEx (hKey, u'UninstallString') - sqlitepath, temp = os.path.split(value) - sqliteexe = os.path.join(sqlitepath, u'sqlite.exe') - else: - sqliteexe = u'sqlite' - cmd = u'%s "%s" .dump' % (sqliteexe, olddb) - if os.name == u'nt': - subprocess.call(cmd, stdout=open(u'sqlite.dmp', u'w')) - else: - subprocess.call(cmd, stdout=open(u'sqlite.dmp', u'w'), shell=True) - self.convert_file(u'sqlite.dmp', u'sqlite3.dmp') - if os.name == u'nt': - sqlite3exe = os.path.join(sqlitepath, u'sqlite3.exe') - else: - sqlite3exe = u'sqlite3' - if os.path.isfile(newdb): - saveddb = newdb + self.stime - os.rename(newdb, saveddb) - cmd = '%s "%s"' % (sqlite3exe, newdb) - if os.name == u'nt': - subprocess.call(cmd, stdin=open(u'sqlite3.dmp', u'r')) - else: - subprocess.call(cmd, stdin=open(u'sqlite3.dmp', u'r'), shell=True) - os.remove(u'sqlite.dmp') - os.remove(u'sqlite3.dmp') - -if __name__ == u'__main__': - mig = Migration() - newsongpath = AppLocation.get_section_data_path(u'songs') - newbiblepath = AppLocation.get_section_data_path(u'bibles') - if os.name == u'nt': - if not os.path.isdir(newsongpath): - os.makedirs(newsongpath) - if not os.path.isdir(newbiblepath): - os.makedirs(newbiblepath) - ALL_USERS_APPLICATION_DATA = 35 - shell = Dispatch(u'Shell.Application') - folder = shell.Namespace(ALL_USERS_APPLICATION_DATA) - folderitem = folder.Self - oldsongdb = os.path.join(folderitem.path, u'openlp.org', u'Data', u'songs.olp') - oldbiblepath = os.path.join(folderitem.path, u'openlp.org', u'Data', u'Bibles') - else: - oldsongdb = os.path.join(newsongpath, u'songs.olp') - newsongdb = os.path.join(newsongpath, u'songs.sqlite') - mig.convert_sqlite2_to_3(oldsongdb, newsongdb) - files = os.listdir(oldbiblepath) - for file in files: - f = os.path.splitext(os.path.basename(file))[0] - if f != 'kjv': #kjv bible has an autoincrement key not supported in sqlite3 - mig.convert_sqlite2_to_3(os.path.join(oldbiblepath, file), - os.path.join(newbiblepath, f + u'.sqlite')) - mig.process() - #mig.move_log_file()