From 6224795661f5fd612a697cbdf581d4dcca56034f Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Fri, 13 Mar 2009 06:13:11 +0000 Subject: [PATCH] Add Classes for songxml, video tidy up and custom plugins bzr-revno: 413 --- openlp/core/lib/songxmlhandler.py | 69 ++++++++ openlp/plugins/custom/lib/mediaitem.py | 194 ++++++++++++++++++++++ openlp/plugins/custom/lib/textlistdata.py | 63 +++++++ openlp/plugins/videos/lib/mediaitem.py | 128 ++++++++++++++ 4 files changed, 454 insertions(+) create mode 100644 openlp/core/lib/songxmlhandler.py create mode 100644 openlp/plugins/custom/lib/mediaitem.py create mode 100644 openlp/plugins/custom/lib/textlistdata.py create mode 100644 openlp/plugins/videos/lib/mediaitem.py diff --git a/openlp/core/lib/songxmlhandler.py b/openlp/core/lib/songxmlhandler.py new file mode 100644 index 000000000..51fb9af83 --- /dev/null +++ b/openlp/core/lib/songxmlhandler.py @@ -0,0 +1,69 @@ +from xml.dom.minidom import Document +from xml.etree.ElementTree import ElementTree, XML, dump +""" + + + + + + + + + +""" +class SongXMLBuilder(): + def __init__(self): + # Create the minidom document + self.song_xml = Document() + + def new_document(self): + # Create the base element + self.song = self.song_xml.createElement("song") + self.song_xml.appendChild(self.song) + self.song.setAttribute("version", "1.0") + + def add_lyrics_to_song(self): + # Create the main element + self.lyrics = self.song_xml.createElement("lyrics") + self.lyrics.setAttribute("language", "en") + self.song.appendChild(self.lyrics) + + def add_verse_to_lyrics(self, type, number, content): + """ + type - type of verse (Chorus, Verse , Bridge, Custom etc + number - number of item eg verse 1 + content - the text to be stored + """ + verse = self.song_xml.createElement("verse") + verse.setAttribute("type", type) + verse.setAttribute('label', number) + self.lyrics.appendChild(verse) + + # add data as a CDATA section + cds = self.song_xml.createCDATASection(content) + verse.appendChild(cds) + + def dump_xml(self): + # Debugging aid to see what we have + print self.song_xml.toprettyxml(indent=" ") + + def extract_xml(self): + # Print our newly created XML + return self.song_xml.toxml() + +class SongXMLParser(): + def __init__(self, xml): + self.song_xml = ElementTree(element=XML(xml)) + + def get_verses(self): + #return a list of verse's and attributes + iter=self.song_xml.getiterator() + verse_list = [] + for element in iter: + if element.tag == 'verse': + verse_list.append([element.attrib, element.text]) + return verse_list + + def dump_xml(self): + # Debugging aid to see what we have + print dump(self.song_xml) diff --git a/openlp/plugins/custom/lib/mediaitem.py b/openlp/plugins/custom/lib/mediaitem.py new file mode 100644 index 000000000..77a18c7f3 --- /dev/null +++ b/openlp/plugins/custom/lib/mediaitem.py @@ -0,0 +1,194 @@ +# -*- coding: utf-8 -*- +# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 +""" +OpenLP - Open Source Lyrics Projection +Copyright (c) 2008 Raoul Snyman +Portions copyright (c) 2008-2009 Martin Thompson, Tim Bentley + +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 logging + +from PyQt4 import QtCore, QtGui + +from openlp.core.lib import MediaManagerItem +from openlp.core.resources import * + +#from openlp.plugins.custom.lib import TextListData + +class CustomMediaItem(MediaManagerItem): + """ + This is the custom media manager item for Custom Slides. + """ + global log + log=logging.getLogger("CustomMediaItem") + log.info("Custom Media Item loaded") + + def __init__(self, parent, icon, title): + MediaManagerItem.__init__(self, parent, icon, title) + + def setupUi(self): + # Add a toolbar + self.addToolbar() + # Create buttons for the toolbar + ## New Custom Button ## + self.addToolbarButton('New Custom', 'Add a new Custom Item', + ':/custom/custom_new.png', self.onCustomNewClick, 'CustomNewItem') + ## Edit Custom Button ## + self.addToolbarButton('Edit Custom', 'Edit the selected Custom Item', + ':/custom/custom_edit.png', self.onCustomEditClick, 'CustomEditItem') + ## Delete Custom Button ## + self.addToolbarButton('Delete Custom', 'Delete the selected Custom Item', + ':/custom/custom_delete.png', self.onCustomDeleteClick, 'CustomDeleteItem') + ## Separator Line ## + self.addToolbarSeparator() + ## Preview Custom Button ## + self.addToolbarButton('Preview Custom', 'Preview the selected Custom', + ':/system/system_preview.png', self.onCustomPreviewClick, 'CustomPreviewItem') + ## Live Custom Button ## + self.addToolbarButton('Go Live', 'Send the selected Custom live', + ':/system/system_live.png', self.onCustomLiveClick, 'CustomLiveItem') + ## Add Custom Button ## + self.addToolbarButton('Add Custom To Service', + 'Add the selected Custom(s) to the service', ':/system/system_add.png', + self.onCustomAddClick, 'CustomAddItem') + ## Add the Customlist widget ## + # Create the tab widget + self.CustomWidget = QtGui.QWidget(self) + sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.CustomWidget.sizePolicy().hasHeightForWidth()) + self.CustomWidget.setSizePolicy(sizePolicy) + self.CustomWidget.setObjectName('CustomWidget') + self.SearchLayout = QtGui.QGridLayout(self.CustomWidget) + self.SearchLayout.setObjectName('SearchLayout') + + self.SearchTextLabel = QtGui.QLabel(self.CustomWidget) + self.SearchTextLabel.setObjectName('SearchTextLabel') + self.SearchTextLabel.setText('Search Text:') + self.SearchLayout.addWidget(self.SearchTextLabel, 2, 0, 1, 1) + self.SearchTextEdit = QtGui.QLineEdit(self.CustomWidget) + self.SearchTextEdit.setObjectName('SearchTextEdit') + self.SearchLayout.addWidget(self.SearchTextEdit, 2, 1, 1, 2) + self.ClearTextButton = QtGui.QPushButton(self.CustomWidget) + self.ClearTextButton.setObjectName('ClearTextButton') + self.ClearTextButton.setText('Clear') + self.SearchLayout.addWidget(self.ClearTextButton, 3, 1, 1, 1) + self.SearchTextButton = QtGui.QPushButton(self.CustomWidget) + self.SearchTextButton.setObjectName('SearchTextButton') + self.SearchTextButton.setText('Search') + self.SearchLayout.addWidget(self.SearchTextButton, 3, 2, 1, 1) + # Add the Custom widget to the page layout + self.PageLayout.addWidget(self.CustomWidget) + + self.CustomListView = QtGui.QListView() + self.CustomListView.setAlternatingRowColors(True) +# self.CustomListData = TextListData() +# self.CustomListView.setModel(self.CustomListData) + + self.PageLayout.addWidget(self.CustomListView) + + # Signals + QtCore.QObject.connect(self.SearchTextButton, + QtCore.SIGNAL("pressed()"), self.onSearchTextButtonClick) + QtCore.QObject.connect(self.ClearTextButton, + QtCore.SIGNAL("pressed()"), self.onClearTextButtonClick) + QtCore.QObject.connect(self.SearchTextEdit, + QtCore.SIGNAL("textChanged(const QString&)"), self.onSearchTextEditChanged) + QtCore.QObject.connect(self.CustomListView, + QtCore.SIGNAL("itemPressed(QTableWidgetItem * item)"), self.onCustomSelected) + +# #define and add the context menu + self.CustomListView.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu) +# + self.CustomListView.addAction(self.contextMenuAction( + self.CustomListView, ':/system/system_preview.png', + "&Preview Custom", self.onCustomPreviewClick)) + self.CustomListView.addAction(self.contextMenuAction( + self.CustomListView, ':/system/system_live.png', + "&Show Live", self.onCustomLiveClick)) + self.CustomListView.addAction(self.contextMenuAction( + self.CustomListView, ':/system/system_add.png', + "&Add to Service", self.onCustomEditClick)) + + def initialise(self): + self.loadCustomList(self.parent.custommanager.get_all_slides()) + + def loadCustomList(self, list): + for CustomSlide in list: + print CustomSlide.title +# for CustomSlide in list: + # self.TextListData.addRow(CustomSlide.id,CustomSlide.title) + + def onClearTextButtonClick(self): + """ + Clear the search text. + """ + self.SearchTextEdit.clear() + + def onSearchTextEditChanged(self, text): + if len(text) > 3: # only search if > 3 characters + self.onSearchTextButtonClick() + + def onSearchTextButtonClick(self): + search_keywords = str(self.SearchTextEdit.displayText()) + search_results = [] + search_type = self.SearchTypeComboBox.currentText() + search_results = self.Custommanager.search_Custom_lyrics(search_keywords) + self._display_results(search_results) + + def onCustomSelected(self, item): + print item + + def onCustomNewClick(self): + self.parent.edit_custom_form.exec_() + + def onCustomEditClick(self): + current_row = self.CustomListView.currentRow() + id = int(self.CustomListView.item(current_row, 0).text()) + self.edit_Custom_form.loadCustom(id) + self.edit_Custom_form.exec_() + + def onCustomDeleteClick(self): + pass + + def onCustomPreviewClick(self): + pass + + def onCustomLiveClick(self): + pass + + def onCustomAddClick(self): + pass + + def _display_results(self, searchresults): + log.debug("_search results") + self.CustomListView.clear() # clear the results + self.CustomListView.setHorizontalHeaderLabels(QtCore.QStringList(['', u'Custom Name'])) + self.CustomListView.horizontalHeader().setVisible(False) + self.CustomListView.verticalHeader().setVisible(False) + self.CustomListView.setRowCount(0) + #log.debug("Records returned from search %s", len(searchresults)) + for Custom in searchresults: + for author in Custom.authors: + c = self.CustomListView.rowCount() + self.CustomListView.setRowCount(c + 1) + Custom_index = QtGui.QTableWidgetItem(str(Custom.id)) + self.CustomListView.setItem(c , 0, Custom_index) + Custom_detail = QtGui.QTableWidgetItem(u'%s (%s)' % (str(Custom.title), str(author.display_name))) + self.CustomListView.setItem(c , 1, Custom_detail) + #twi = QtGui.QTableWidgetItem() + #self.CustomListView.setItem(c , 2, twi) + self.CustomListView.setRowHeight(c, 20) + diff --git a/openlp/plugins/custom/lib/textlistdata.py b/openlp/plugins/custom/lib/textlistdata.py new file mode 100644 index 000000000..0cb165a6a --- /dev/null +++ b/openlp/plugins/custom/lib/textlistdata.py @@ -0,0 +1,63 @@ +import logging + +from PyQt4.QtCore import * +from PyQt4.QtGui import * + + +class TextListData(QAbstractListModel): + """ + An abstract list of strings + """ + global log + log=logging.getLogger("ListData") + log.info("started") + + def __init__(self): + QAbstractListModel.__init__(self) + self.items=[] # will be a list of (database id , title) tuples + + def rowCount(self, parent): + return len(self.items) + + def insertRow(self, row, id, title): + self.beginInsertRows(QModelIndex(),row,row) + log.debug("insert row %d:%s for id %d"%(row,title, id)) + self.items.insert(row, (id, title)) + self.endInsertRows() + + def removeRow(self, row): + self.beginRemoveRows(QModelIndex(), row,row) + self.items.pop(row) + self.endRemoveRows() + + def addRow(self, id, title): + self.insertRow(len(self.items), id, title) + + def data(self, index, role): + row=index.row() + if row > len(self.items): # if the last row is selected and deleted, we then get called with an empty row! + return QVariant() + if role==Qt.DisplayRole: + retval= self.items[row][2] + elif role == Qt.DecorationRole: + retval= self.items[row][1] + elif role == Qt.ToolTipRole: + retval= self.items[row][0] + else: + retval= QVariant() +# log.info("Returning"+ str(retval)) + if type(retval) is not type(QVariant): + return QVariant(retval) + else: + return retval + + def getIdList(self): + filelist = [item[0] for item in self.items]; + return filelist + + def getId(self, index): + row = index.row() + return self.item[row][0] + +if __name__=="__main__": + sxml=TextListData() diff --git a/openlp/plugins/videos/lib/mediaitem.py b/openlp/plugins/videos/lib/mediaitem.py new file mode 100644 index 000000000..c402bc95c --- /dev/null +++ b/openlp/plugins/videos/lib/mediaitem.py @@ -0,0 +1,128 @@ +# -*- coding: utf-8 -*- +# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 +""" +OpenLP - Open Source Lyrics Projection +Copyright (c) 2008 Raoul Snyman +Portions copyright (c) 2008-2009 Martin Thompson, Tim Bentley + +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 logging +import os + +from PyQt4 import QtCore, QtGui + +from openlp.core import translate +from openlp.core.lib import MediaManagerItem +from openlp.core.resources import * + +from openlp.plugins.videos.lib import VideoTab + +class VideoMediaItem(MediaManagerItem): + """ + This is the custom media manager item for Custom Slides. + """ + global log + log=logging.getLogger("CustomMediaItem") + log.info("Custom Media Item loaded") + + def __init__(self, parent, icon, title): + MediaManagerItem.__init__(self, parent, icon, title) + + def setupUi(self): + # Add a toolbar + self.addToolbar() + # Create buttons for the toolbar + ## New Song Button ## + self.addToolbarButton('New Video', 'Load videos into openlp.org', + ':/videos/video_load.png', self.onVideoNewClick, 'VideoNewItem') + ## Delete Song Button ## + self.addToolbarButton('Delete Video', 'Delete the selected video', + ':/videos/video_delete.png', self.onVideoDeleteClick, 'VideoDeleteItem') + ## Separator Line ## + self.addToolbarSeparator() + ## Preview Song Button ## + self.addToolbarButton('Preview Video', 'Preview the selected video', + ':/system/system_preview.png', self.onVideoPreviewClick, 'VideoPreviewItem') + ## Live Song Button ## + self.addToolbarButton('Go Live', 'Send the selected video live', + ':/system/system_live.png', self.onVideoLiveClick, 'VideoLiveItem') + ## Add Song Button ## + self.addToolbarButton('Add Video To Service', + 'Add the selected video(s) to the service', ':/system/system_add.png', + self.onVideoAddClick, 'VideoAddItem') + ## Add the videolist widget ## + self.VideoListView = QtGui.QTableWidget() + self.VideoListView.setColumnCount(2) + self.VideoListView.setColumnHidden(0, True) + self.VideoListView.setColumnWidth(1, 275) + self.VideoListView.setShowGrid(False) + self.VideoListView.setSortingEnabled(False) + self.VideoListView.setAlternatingRowColors(True) + self.VideoListView.verticalHeader().setVisible(False) + self.VideoListView.horizontalHeader().setVisible(False) + self.VideoListView.setAlternatingRowColors(True) + self.VideoListView.setGeometry(QtCore.QRect(10, 100, 256, 591)) + self.VideoListView.setObjectName("VideoListView") + self.PageLayout.addWidget(self.VideoListView) + + #define and add the context menu + self.VideoListView.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu) + + self.VideoListView.addAction(self.contextMenuAction(self.VideoListView, ':/system/system_preview.png', "&Preview Video", self.onVideoPreviewClick)) + self.VideoListView.addAction(self.contextMenuAction(self.VideoListView, ':/system/system_live.png', "&Show Live", self.onVideoLiveClick)) + self.VideoListView.addAction(self.contextMenuAction(self.VideoListView, ':/system/system_add.png', "&Add to Service", self.onVideoAddClick)) + + def initialise(self): + list = self.parent.config.load_list('videos') + self.loadVideoList(list) + + def onVideoNewClick(self): + files = QtGui.QFileDialog.getOpenFileNames(None, "Select Image(s)", + self.parent.config.get_last_dir(), "Images (*.avi *.mpeg)") + if len(files) > 0: + self.loadVideoList(files) + print files[0] + dir, filename = os.path.split(str(files[0])) + print dir , filename + self.parent.config.set_last_dir(dir) + #self.parent.config.set_list('videos', self.getFileList()) + + def getFileList(self): + filelist = [item[0] for item in self.VideoListView]; + return filelist + + def loadVideoList(self, list): + for f in list: + file_path , file_name = os.path.split(str(f)) + count = self.VideoListView.rowCount() + self.VideoListView.setRowCount(count+1) + row_item = QtGui.QTableWidgetItem(str(f)) + self.VideoListView.setItem(count , 0, row_item) + row_item = QtGui.QTableWidgetItem(str(file_name)) + self.VideoListView.setItem(count , 1, row_item) + self.VideoListView.setRowHeight(count, 20) + + def onVideoDeleteClick(self): + cr = self.VideoListView.currentRow() + self.VideoListView.removeRow(int(cr)) + self._save_display_list(self.VideoListView) + + def onVideoPreviewClick(self): + pass + + def onVideoLiveClick(self): + pass + + def onVideoAddClick(self): + pass