From af9b8edd6f26a12efc2b076579dc645b1ffe36cc Mon Sep 17 00:00:00 2001 From: Raoul Snyman Date: Thu, 23 Jul 2009 22:20:49 +0200 Subject: [PATCH] The new song maintenance dialog... getting there. --- openlp/core/lib/rendermanager.py | 5 +- openlp/plugins/songs/forms/__init__.py | 1 + .../songs/forms/songmaintenancedialog.py | 251 ++++++++++++++ .../songs/forms/songmaintenanceform.py | 181 +++++++++++ openlp/plugins/songs/lib/mediaitem.py | 35 +- resources/forms/songmaintenance.ui | 307 +++++++++++++++--- resources/images/author_add.png | Bin 0 -> 836 bytes resources/images/author_delete.png | Bin 0 -> 858 bytes resources/images/author_edit.png | Bin 0 -> 885 bytes resources/images/book_add.png | Bin 0 -> 670 bytes resources/images/book_delete.png | Bin 0 -> 744 bytes resources/images/book_edit.png | Bin 0 -> 776 bytes resources/images/book_maintenance.png | Bin 1906 -> 1722 bytes resources/images/openlp-2.qrc | 9 + resources/images/topic_add.png | Bin 0 -> 1007 bytes resources/images/topic_delete.png | Bin 0 -> 1038 bytes resources/images/topic_edit.png | Bin 0 -> 1024 bytes 17 files changed, 723 insertions(+), 66 deletions(-) create mode 100644 openlp/plugins/songs/forms/songmaintenancedialog.py create mode 100644 openlp/plugins/songs/forms/songmaintenanceform.py create mode 100644 resources/images/author_add.png create mode 100644 resources/images/author_delete.png create mode 100644 resources/images/author_edit.png create mode 100644 resources/images/book_add.png create mode 100644 resources/images/book_delete.png create mode 100644 resources/images/book_edit.png create mode 100644 resources/images/topic_add.png create mode 100644 resources/images/topic_delete.png create mode 100644 resources/images/topic_edit.png diff --git a/openlp/core/lib/rendermanager.py b/openlp/core/lib/rendermanager.py index 3efc03858..6cb117b2b 100644 --- a/openlp/core/lib/rendermanager.py +++ b/openlp/core/lib/rendermanager.py @@ -53,7 +53,10 @@ class RenderManager(object): self.screen_list = screen_list self.theme_manager = theme_manager self.displays = len(screen_list) - self.current_display = screen_number + if (screen_number + 1) > len(screen_list): + self.current_display = 0 + else: + self.current_display = screen_number self.renderer = Renderer() self.calculate_default(self.screen_list[self.current_display][u'size']) self.theme = u'' diff --git a/openlp/plugins/songs/forms/__init__.py b/openlp/plugins/songs/forms/__init__.py index 26b623778..4bc392b81 100644 --- a/openlp/plugins/songs/forms/__init__.py +++ b/openlp/plugins/songs/forms/__init__.py @@ -23,6 +23,7 @@ from topicsform import TopicsForm from songbookform import SongBookForm from editverseform import EditVerseForm from editsongform import EditSongForm +from songmaintenanceform import SongMaintenanceForm from openlpexportform import OpenLPExportForm from openlpimportform import OpenLPImportForm diff --git a/openlp/plugins/songs/forms/songmaintenancedialog.py b/openlp/plugins/songs/forms/songmaintenancedialog.py new file mode 100644 index 000000000..e91ce735c --- /dev/null +++ b/openlp/plugins/songs/forms/songmaintenancedialog.py @@ -0,0 +1,251 @@ +# -*- 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 +""" +from PyQt4 import QtCore, QtGui +from openlp.core.lib import translate + +class Ui_SongMaintenanceDialog(object): + def setupUi(self, SongMaintenanceDialog): + SongMaintenanceDialog.setObjectName("SongMaintenanceDialog") + SongMaintenanceDialog.setWindowModality(QtCore.Qt.ApplicationModal) + SongMaintenanceDialog.resize(486, 361) + self.DialogLayout = QtGui.QVBoxLayout(SongMaintenanceDialog) + self.DialogLayout.setSpacing(8) + self.DialogLayout.setMargin(8) + self.DialogLayout.setObjectName("DialogLayout") + self.ContentWidget = QtGui.QWidget(SongMaintenanceDialog) + self.ContentWidget.setObjectName("ContentWidget") + self.ContentLayout = QtGui.QHBoxLayout(self.ContentWidget) + self.ContentLayout.setSpacing(8) + self.ContentLayout.setMargin(0) + self.ContentLayout.setObjectName("ContentLayout") + self.TypeListWidget = QtGui.QListWidget(self.ContentWidget) + sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Expanding) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.TypeListWidget.sizePolicy().hasHeightForWidth()) + self.TypeListWidget.setSizePolicy(sizePolicy) + self.TypeListWidget.setProperty("showDropIndicator", QtCore.QVariant(False)) + #self.TypeListWidget.setFlow(QtGui.QListView.TopToBottom) + self.TypeListWidget.setSpacing(0) + self.TypeListWidget.setViewMode(QtGui.QListView.IconMode) + self.TypeListWidget.setIconSize(QtCore.QSize(128, 100)); + self.TypeListWidget.setMovement(QtGui.QListView.Static); + self.TypeListWidget.setMaximumWidth(128); + self.TypeListWidget.setSpacing(3); + self.TypeListWidget.setUniformItemSizes(True) + self.TypeListWidget.setObjectName("TypeListWidget") + icon = QtGui.QIcon() + icon.addPixmap(QtGui.QPixmap(":/songs/author_maintenance.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + item = QtGui.QListWidgetItem(self.TypeListWidget) + item.setIcon(icon) + icon1 = QtGui.QIcon() + icon1.addPixmap(QtGui.QPixmap(":/songs/topic_maintenance.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + item = QtGui.QListWidgetItem(self.TypeListWidget) + item.setIcon(icon1) + icon2 = QtGui.QIcon() + icon2.addPixmap(QtGui.QPixmap(":/songs/book_maintenance.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + item = QtGui.QListWidgetItem(self.TypeListWidget) + item.setIcon(icon2) + self.ContentLayout.addWidget(self.TypeListWidget) + self.TypeStackedWidget = QtGui.QStackedWidget(self.ContentWidget) + self.TypeStackedWidget.setObjectName("TypeStackedWidget") + self.AuthorsPage = QtGui.QWidget() + self.AuthorsPage.setObjectName("AuthorsPage") + self.AuthorsLayout = QtGui.QVBoxLayout(self.AuthorsPage) + self.AuthorsLayout.setSpacing(8) + self.AuthorsLayout.setMargin(0) + self.AuthorsLayout.setObjectName("AuthorsLayout") + self.AuthorsListWidget = QtGui.QListWidget(self.AuthorsPage) + self.AuthorsListWidget.setObjectName("AuthorsListWidget") + self.AuthorsLayout.addWidget(self.AuthorsListWidget) + self.AuthorsErrorLabel = QtGui.QLabel(self.AuthorsPage) + sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.MinimumExpanding, QtGui.QSizePolicy.Expanding) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.AuthorsErrorLabel.sizePolicy().hasHeightForWidth()) + self.AuthorsErrorLabel.setSizePolicy(sizePolicy) + self.AuthorsErrorLabel.setSize(QtCore.QSize(0, 0)) + self.AuthorsErrorLabel.setMargin(4) + self.AuthorsErrorLabel.setStyleSheet(u'background-color: #900; color: #fff;') + self.AuthorsErrorLabel.setObjectName("AuthorsErrorLabel") + self.AuthorsLayout.addWidget(self.AuthorsErrorLabel) + self.AuthorButtonWidget = QtGui.QWidget(self.AuthorsPage) + self.AuthorButtonWidget.setObjectName("AuthorButtonWidget") + self.AuthorButtonsLayout = QtGui.QHBoxLayout(self.AuthorButtonWidget) + self.AuthorButtonsLayout.setSpacing(8) + self.AuthorButtonsLayout.setMargin(0) + self.AuthorButtonsLayout.setObjectName("AuthorButtonsLayout") + spacerItem = QtGui.QSpacerItem(40, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) + self.AuthorButtonsLayout.addItem(spacerItem) + self.AuthorAddButton = QtGui.QPushButton(self.AuthorButtonWidget) + icon3 = QtGui.QIcon() + icon3.addPixmap(QtGui.QPixmap(":/songs/author_add.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.AuthorAddButton.setIcon(icon3) + self.AuthorAddButton.setObjectName("AuthorAddButton") + self.AuthorButtonsLayout.addWidget(self.AuthorAddButton) + self.AuthorEditButton = QtGui.QPushButton(self.AuthorButtonWidget) + icon4 = QtGui.QIcon() + icon4.addPixmap(QtGui.QPixmap(":/songs/author_edit.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.AuthorEditButton.setIcon(icon4) + self.AuthorEditButton.setObjectName("AuthorEditButton") + self.AuthorButtonsLayout.addWidget(self.AuthorEditButton) + self.AuthorDeleteButton = QtGui.QPushButton(self.AuthorButtonWidget) + icon5 = QtGui.QIcon() + icon5.addPixmap(QtGui.QPixmap(":/songs/author_delete.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.AuthorDeleteButton.setIcon(icon5) + self.AuthorDeleteButton.setObjectName("AuthorDeleteButton") + self.AuthorButtonsLayout.addWidget(self.AuthorDeleteButton) + self.AuthorsLayout.addWidget(self.AuthorButtonWidget) + self.AuthorsLine = QtGui.QFrame(self.AuthorsPage) + self.AuthorsLine.setFrameShape(QtGui.QFrame.HLine) + self.AuthorsLine.setFrameShadow(QtGui.QFrame.Sunken) + self.AuthorsLine.setObjectName("AuthorsLine") + self.AuthorsLayout.addWidget(self.AuthorsLine) + self.TypeStackedWidget.addWidget(self.AuthorsPage) + self.TopicsPage = QtGui.QWidget() + self.TopicsPage.setObjectName("TopicsPage") + self.TopicLayout = QtGui.QVBoxLayout(self.TopicsPage) + self.TopicLayout.setSpacing(4) + self.TopicLayout.setMargin(0) + self.TopicLayout.setObjectName("TopicLayout") + self.TopicsListWidget = QtGui.QListWidget(self.TopicsPage) + self.TopicsListWidget.setObjectName("TopicsListWidget") + self.TopicLayout.addWidget(self.TopicsListWidget) + self.TopicsErrorLabel = QtGui.QLabel(self.TopicsPage) + self.TopicsErrorLabel.setMaximumHeight(0) + self.TopicsErrorLabel.setMinimumHeight(0) + self.TopicsErrorLabel.setIndent(4) + self.TopicsErrorLabel.setStyleSheet(u'background-color: #900; color: #fff;') + self.TopicsErrorLabel.setObjectName("TopicsErrorLabel") + self.TopicLayout.addWidget(self.TopicsErrorLabel) + self.TopicButtonWidget = QtGui.QWidget(self.TopicsPage) + self.TopicButtonWidget.setObjectName("TopicButtonWidget") + self.TopicButtonLayout = QtGui.QHBoxLayout(self.TopicButtonWidget) + self.TopicButtonLayout.setSpacing(8) + self.TopicButtonLayout.setMargin(0) + self.TopicButtonLayout.setObjectName("TopicButtonLayout") + spacerItem1 = QtGui.QSpacerItem(54, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) + self.TopicButtonLayout.addItem(spacerItem1) + self.TopicAddButton = QtGui.QPushButton(self.TopicButtonWidget) + icon6 = QtGui.QIcon() + icon6.addPixmap(QtGui.QPixmap(":/songs/topic_add.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.TopicAddButton.setIcon(icon6) + self.TopicAddButton.setObjectName("TopicAddButton") + self.TopicButtonLayout.addWidget(self.TopicAddButton) + self.TopicEditButton = QtGui.QPushButton(self.TopicButtonWidget) + icon7 = QtGui.QIcon() + icon7.addPixmap(QtGui.QPixmap(":/songs/topic_edit.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.TopicEditButton.setIcon(icon7) + self.TopicEditButton.setObjectName("TopicEditButton") + self.TopicButtonLayout.addWidget(self.TopicEditButton) + self.TopicDeleteButton = QtGui.QPushButton(self.TopicButtonWidget) + icon8 = QtGui.QIcon() + icon8.addPixmap(QtGui.QPixmap(":/songs/topic_delete.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.TopicDeleteButton.setIcon(icon8) + self.TopicDeleteButton.setObjectName("TopicDeleteButton") + self.TopicButtonLayout.addWidget(self.TopicDeleteButton) + self.TopicLayout.addWidget(self.TopicButtonWidget) + self.TopicsLine = QtGui.QFrame(self.TopicsPage) + self.TopicsLine.setFrameShape(QtGui.QFrame.HLine) + self.TopicsLine.setFrameShadow(QtGui.QFrame.Sunken) + self.TopicsLine.setObjectName("TopicsLine") + self.TopicLayout.addWidget(self.TopicsLine) + self.TypeStackedWidget.addWidget(self.TopicsPage) + self.BooksPage = QtGui.QWidget() + self.BooksPage.setObjectName("BooksPage") + self.BookLayout = QtGui.QVBoxLayout(self.BooksPage) + self.BookLayout.setSpacing(4) + self.BookLayout.setMargin(0) + self.BookLayout.setObjectName("BookLayout") + self.BooksListWidget = QtGui.QListWidget(self.BooksPage) + self.BooksListWidget.setObjectName("BooksListWidget") + self.BookLayout.addWidget(self.BooksListWidget) + self.BooksErrorLabel = QtGui.QLabel(self.BooksPage) + self.BooksErrorLabel.setMaximumHeight(0) + self.BooksErrorLabel.setMinimumHeight(0) + self.BooksErrorLabel.setIndent(4) + self.BooksErrorLabel.setStyleSheet(u'background-color: #900; color: #fff;') + self.BooksErrorLabel.setObjectName("BooksErrorLabel") + self.BookLayout.addWidget(self.BooksErrorLabel) + self.BookButtonWidget = QtGui.QWidget(self.BooksPage) + self.BookButtonWidget.setObjectName("BookButtonWidget") + self.BookButtonLayout = QtGui.QHBoxLayout(self.BookButtonWidget) + self.BookButtonLayout.setSpacing(8) + self.BookButtonLayout.setMargin(0) + self.BookButtonLayout.setObjectName("BookButtonLayout") + spacerItem2 = QtGui.QSpacerItem(54, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum) + self.BookButtonLayout.addItem(spacerItem2) + self.BookAddButton = QtGui.QPushButton(self.BookButtonWidget) + icon9 = QtGui.QIcon() + icon9.addPixmap(QtGui.QPixmap(":/songs/book_add.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.BookAddButton.setIcon(icon9) + self.BookAddButton.setObjectName("BookAddButton") + self.BookButtonLayout.addWidget(self.BookAddButton) + self.BookEditButton = QtGui.QPushButton(self.BookButtonWidget) + icon10 = QtGui.QIcon() + icon10.addPixmap(QtGui.QPixmap(":/songs/book_edit.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.BookEditButton.setIcon(icon10) + self.BookEditButton.setObjectName("BookEditButton") + self.BookButtonLayout.addWidget(self.BookEditButton) + self.BookDeleteButton = QtGui.QPushButton(self.BookButtonWidget) + icon11 = QtGui.QIcon() + icon11.addPixmap(QtGui.QPixmap(":/songs/book_delete.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.BookDeleteButton.setIcon(icon11) + self.BookDeleteButton.setObjectName("BookDeleteButton") + self.BookButtonLayout.addWidget(self.BookDeleteButton) + self.BookLayout.addWidget(self.BookButtonWidget) + self.BooksLine = QtGui.QFrame(self.BooksPage) + self.BooksLine.setFrameShape(QtGui.QFrame.HLine) + self.BooksLine.setFrameShadow(QtGui.QFrame.Sunken) + self.BooksLine.setObjectName("BooksLine") + self.BookLayout.addWidget(self.BooksLine) + self.TypeStackedWidget.addWidget(self.BooksPage) + self.ContentLayout.addWidget(self.TypeStackedWidget) + self.DialogLayout.addWidget(self.ContentWidget) + self.MaintenanceButtonBox = QtGui.QDialogButtonBox(SongMaintenanceDialog) + self.MaintenanceButtonBox.setOrientation(QtCore.Qt.Horizontal) + self.MaintenanceButtonBox.setStandardButtons(QtGui.QDialogButtonBox.Close) + self.MaintenanceButtonBox.setObjectName("MaintenanceButtonBox") + self.DialogLayout.addWidget(self.MaintenanceButtonBox) + + self.retranslateUi(SongMaintenanceDialog) + self.TypeStackedWidget.setCurrentIndex(2) + QtCore.QObject.connect(self.MaintenanceButtonBox, QtCore.SIGNAL("rejected()"), SongMaintenanceDialog.accept) + QtCore.QObject.connect(self.TypeListWidget, QtCore.SIGNAL("currentRowChanged(int)"), self.TypeStackedWidget.setCurrentIndex) + QtCore.QMetaObject.connectSlotsByName(SongMaintenanceDialog) + + def retranslateUi(self, SongMaintenanceDialog): + SongMaintenanceDialog.setWindowTitle(QtGui.QApplication.translate("SongMaintenanceDialog", "Song Maintenance", None, QtGui.QApplication.UnicodeUTF8)) + __sortingEnabled = self.TypeListWidget.isSortingEnabled() + self.TypeListWidget.setSortingEnabled(False) + self.TypeListWidget.item(0).setText(QtGui.QApplication.translate("SongMaintenanceDialog", "Authors", None, QtGui.QApplication.UnicodeUTF8)) + self.TypeListWidget.item(1).setText(QtGui.QApplication.translate("SongMaintenanceDialog", "Topics", None, QtGui.QApplication.UnicodeUTF8)) + self.TypeListWidget.item(2).setText(QtGui.QApplication.translate("SongMaintenanceDialog", "Books/Hymnals", None, QtGui.QApplication.UnicodeUTF8)) + self.TypeListWidget.setSortingEnabled(__sortingEnabled) + self.AuthorAddButton.setText(QtGui.QApplication.translate("SongMaintenanceDialog", "Add", None, QtGui.QApplication.UnicodeUTF8)) + self.AuthorEditButton.setText(QtGui.QApplication.translate("SongMaintenanceDialog", "Edit", None, QtGui.QApplication.UnicodeUTF8)) + self.AuthorDeleteButton.setText(QtGui.QApplication.translate("SongMaintenanceDialog", "Delete", None, QtGui.QApplication.UnicodeUTF8)) + self.TopicAddButton.setText(QtGui.QApplication.translate("SongMaintenanceDialog", "Add", None, QtGui.QApplication.UnicodeUTF8)) + self.TopicEditButton.setText(QtGui.QApplication.translate("SongMaintenanceDialog", "Edit", None, QtGui.QApplication.UnicodeUTF8)) + self.TopicDeleteButton.setText(QtGui.QApplication.translate("SongMaintenanceDialog", "Delete", None, QtGui.QApplication.UnicodeUTF8)) + self.BookAddButton.setText(QtGui.QApplication.translate("SongMaintenanceDialog", "Add", None, QtGui.QApplication.UnicodeUTF8)) + self.BookEditButton.setText(QtGui.QApplication.translate("SongMaintenanceDialog", "Edit", None, QtGui.QApplication.UnicodeUTF8)) + self.BookDeleteButton.setText(QtGui.QApplication.translate("SongMaintenanceDialog", "Delete", None, QtGui.QApplication.UnicodeUTF8)) + diff --git a/openlp/plugins/songs/forms/songmaintenanceform.py b/openlp/plugins/songs/forms/songmaintenanceform.py new file mode 100644 index 000000000..c39bcd5ec --- /dev/null +++ b/openlp/plugins/songs/forms/songmaintenanceform.py @@ -0,0 +1,181 @@ +# -*- coding: utf-8 -*- +""" +OpenLP - Open Source Lyrics Projection +Copyright (c) 2008 Raoul Snyman +Portions copyright (c) 2008-2009 Martin Thompson, Tim Bentley, 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 +""" + +from PyQt4 import QtGui, QtCore +from openlp.core.lib import translate +from openlp.plugins.songs.forms import SongBookForm +from openlp.plugins.songs.lib.classes import Author, Book, Topic +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.timer = QtCore.QTimer() + QtCore.QObject.connect(self.timer, + QtCore.SIGNAL(u'timeout()'), self._hideErrors) + 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.resetAuthors() + self.resetTopics() + self.resetBooks() + return QtGui.QDialog.exec_(self) + + def _getCurrentItemId(self, ListWidget): + item = ListWidget.currentItem() + print item + if item is not None: + item_id = (item.data(QtCore.Qt.UserRole)).toInt()[0] + return item_id + else: + return -1 + + def _showError(self, error): + self.AuthorsErrorLabel.setSize(QtCore.QSize(0, 32)) + self.AuthorsErrorLabel.setText(error) + self.TopicsErrorLabel.setMaximumHeight(32) + self.TopicsErrorLabel.setMinimumHeight(32) + self.TopicsErrorLabel.setText(error) + self.BooksErrorLabel.setMaximumHeight(32) + self.BooksErrorLabel.setMinimumHeight(32) + self.BooksErrorLabel.setText(error) + self.timer.start(2000) + + def _hideErrors(self): + self.timer.stop() + self.AuthorsErrorLabel.setMaximumHeight(0) + self.AuthorsErrorLabel.setMinimumHeight(0) + self.AuthorsErrorLabel.clear() + self.TopicsErrorLabel.setMaximumHeight(0) + self.TopicsErrorLabel.setMinimumHeight(0) + self.TopicsErrorLabel.clear() + self.BooksErrorLabel.setMaximumHeight(0) + self.BooksErrorLabel.setMinimumHeight(0) + self.BooksErrorLabel.clear() + + def resetAuthors(self): + self.AuthorsListWidget.clear() + authors = self.songmanager.get_authors() + for author in authors: + if author.display_name is not None and author.display_name != u'': + 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) + + def resetTopics(self): + self.TopicsListWidget.clear() + topics = self.songmanager.get_topics() + 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) + + def resetBooks(self): + self.BooksListWidget.clear() + books = self.songmanager.get_books() + for book in books: + book_name = QtGui.QListWidgetItem(book.name) + book_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(book.id)) + self.BooksListWidget.addItem(book_name) + + def onAuthorDeleteButtonClick(self): + """ + Delete the author if the author is not attached to any songs + """ + author_id = self._getCurrentItemId(self.AuthorsListWidget) + if author_id != -1: + author = self.songmanager.get_author(author_id) + if QtGui.QMessageBox.warning(None, + translate(u'SongMaintenanceForm', u'Delete Author'), + translate(u'SongMaintenanceForm', u'Are you sure you want to delete the selected author?'), + QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.No | QtGui.QMessageBox.Yes) + ) == QtGui.QMessageBox.Yes: + if len(author.songs) == 0: + self.songmanager.delete_author(author.id) + self.resetAuthors() + else: + QtGui.QMessageBox.critical(None, + translate(u'SongMaintenanceForm', u'Delete Author'), + translate(u'SongMaintenanceForm', u'This author can\'t be deleted, they are currently assigned to at least one song!'), + QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok)) + else: + self._showError(translate(u'SongMaintenanceForm', u'No author selected!')) + + def onTopicDeleteButtonClick(self): + """ + Delete the Book is the Book is not attached to any songs + """ + topic_id = self._getCurrentItemId(self.TopicsListWidget) + if topic_id != -1: + topic = self.songmanager.get_topic(topic_id) + if QtGui.QMessageBox.warning(None, + translate(u'SongMaintenanceForm', u'Delete Topic'), + translate(u'SongMaintenanceForm', u'Are you sure you want to delete the selected topic?'), + QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.No | QtGui.QMessageBox.Yes) + ) == QtGui.QMessageBox.Yes: + if len(topic.songs) == 0: + self.songmanager.delete_topic(topic.id) + self.resetTopics() + else: + #QtGui.QMessageBox.critical(None, + # translate(u'SongMaintenanceForm', u'Delete Topic'), + # translate(u'SongMaintenanceForm', u'This topic can\'t be deleted, it is currently assigned to at least one song!'), + # QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok)) + self._showError(translate(u'SongMaintenanceForm', u'This topic can\'t be deleted, it is currently assigned to at least one song!')) + else: + self._showError(translate(u'SongMaintenanceForm', u'No topic selected!')) + + def onBookDeleteButtonClick(self): + """ + Delete the Book is the Book is not attached to any songs + """ + book_id = self._getCurrentItemId(self.BooksListWidget) + if book_id != -1: + book = self.songmanager.get_book(book_id) + if QtGui.QMessageBox.warning(None, + translate(u'SongMaintenanceForm', u'Delete Book'), + translate(u'SongMaintenanceForm', u'Are you sure you want to delete the selected book?'), + QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.No | QtGui.QMessageBox.Yes) + ) == QtGui.QMessageBox.Yes: + if len(book.songs) == 0: + self.songmanager.delete_book(book.id) + self.resetBooks() + else: + QtGui.QMessageBox.critical(None, + translate(u'SongMaintenanceForm', u'Delete Book'), + translate(u'SongMaintenanceForm', u'This book can\'t be deleted, it is currently assigned to at least one song!'), + QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok)) + else: + self._showError(translate(u'SongMaintenanceForm', u'No book selected!')) diff --git a/openlp/plugins/songs/lib/mediaitem.py b/openlp/plugins/songs/lib/mediaitem.py index b49bcac95..5b9dbae38 100644 --- a/openlp/plugins/songs/lib/mediaitem.py +++ b/openlp/plugins/songs/lib/mediaitem.py @@ -20,9 +20,10 @@ Place, Suite 330, Boston, MA 02111-1307 USA import logging from PyQt4 import QtCore, QtGui -from openlp.core.lib import MediaManagerItem, translate, ServiceItem, SongXMLParser , contextMenuAction, contextMenuSeparator - -from openlp.plugins.songs.forms import EditSongForm, AuthorsForm, TopicsForm, SongBookForm +from openlp.core.lib import MediaManagerItem, translate, ServiceItem, \ + SongXMLParser, contextMenuAction, contextMenuSeparator +from openlp.plugins.songs.forms import EditSongForm, AuthorsForm, \ + TopicsForm, SongBookForm, SongMaintenanceForm class SongList(QtGui.QListWidget): @@ -62,6 +63,7 @@ class SongMediaItem(MediaManagerItem): self.authors_form = AuthorsForm(self.parent.songmanager) self.topics_form = TopicsForm(self.parent.songmanager) self.song_book_form = SongBookForm(self.parent.songmanager) + self.song_maintenance_form = SongMaintenanceForm(self.parent.songmanager) def setupUi(self): # Add a toolbar @@ -95,17 +97,21 @@ class SongMediaItem(MediaManagerItem): ':/system/system_add.png', self.onSongAddClick, 'SongAddItem') self.addToolbarSeparator() ## Author Edit Button ## - self.addToolbarButton(translate(u'SongMediaItem', u'Edit Authors'), - translate(u'SongMediaItem', u'Maintain the list of Song Authors'), - ':/songs/song_author_edit.png', self.onEditAuthorClick, 'SongAuthorEditItem') + #self.addToolbarButton(translate(u'SongMediaItem', u'Edit Authors'), + # translate(u'SongMediaItem', u'Maintain the list of Song Authors'), + # ':/songs/song_author_edit.png', self.onEditAuthorClick, 'SongAuthorEditItem') ## Author Edit Button ## - self.addToolbarButton(translate(u'SongMediaItem', u'Edit Books'), - translate(u'SongMediaItem', u'Maintain the list of Song Books'), - ':/songs/song_book_edit.png', self.onEditBookClick, 'SongAuthorEditItem') - ## Author Edit Button ## - self.addToolbarButton(translate(u'SongMediaItem', u'Edit Topics'), - translate(u'SongMediaItem', u'Maintain the list of Song Topics'), - ':/songs/song_topic_edit.png', self.onEditTopicClick, 'SongAuthorEditItem') + #self.addToolbarButton(translate(u'SongMediaItem', u'Edit Books'), + # translate(u'SongMediaItem', u'Maintain the list of Song Books'), + # ':/songs/song_book_edit.png', self.onEditBookClick, 'SongAuthorEditItem') + # ## Author Edit Button ## + #self.addToolbarButton(translate(u'SongMediaItem', u'Edit Topics'), + # translate(u'SongMediaItem', u'Maintain the list of Song Topics'), + # ':/songs/song_topic_edit.png', self.onEditTopicClick, 'SongAuthorEditItem') + ## Song Maintenance Button ## + self.addToolbarButton(translate(u'SongMediaItem', u'Song Maintenance'), + translate(u'SongMediaItem', u'Maintain the lists of authors, topics and books'), + ':/songs/song_author_edit.png', self.onSongMaintenanceClick, 'SongMaintenanceItem') ## Add the songlist widget ## # Create the tab widget self.SongWidget = QtGui.QWidget(self) @@ -250,6 +256,9 @@ class SongMediaItem(MediaManagerItem): self.song_book_form.load_form() self.song_book_form.exec_() + def onSongMaintenanceClick(self): + self.song_maintenance_form.exec_() + def onSongEditClick(self): item = self.ListView.currentItem() if item is not None: diff --git a/resources/forms/songmaintenance.ui b/resources/forms/songmaintenance.ui index 444e444ec..dd06797fb 100644 --- a/resources/forms/songmaintenance.ui +++ b/resources/forms/songmaintenance.ui @@ -2,6 +2,9 @@ SongMaintenanceDialog + + Qt::ApplicationModal + 0 @@ -13,7 +16,7 @@ Song Maintenance - + 8 @@ -22,7 +25,7 @@ - + 8 @@ -30,37 +33,94 @@ 0 - + + + + 0 + 0 + + + + + 130 + 0 + + - 150 + 130 16777215 false + + false + + + QAbstractItemView::SingleSelection + 32 32 - - QListView::TopToBottom + + false - - 0 + + false - - QListView::IconMode - - + + false + + true - - + + + false + + + false + + + false + + + true + + + false + + + false + + - Authors + New Row + + + + + New Row + + + + + New Row + + + + + Types + + + + + +Authors AlignHCenter|AlignVCenter|AlignCenter @@ -69,13 +129,11 @@ :/songs/author_maintenance.png:/songs/author_maintenance.png - - ItemIsSelectable|ItemIsEnabled - - + - Topics + +Topics AlignHCenter|AlignVCenter|AlignCenter @@ -84,13 +142,11 @@ :/songs/topic_maintenance.png:/songs/topic_maintenance.png - - ItemIsSelectable|ItemIsEnabled - - + - Books/Hymnals + +Books/Hymnals AlignHCenter|AlignVCenter|AlignCenter @@ -99,19 +155,16 @@ :/songs/book_maintenance.png:/songs/book_maintenance.png - - ItemIsSelectable|ItemIsEnabled - - 0 + 2 - + 8 @@ -122,8 +175,8 @@ - - + + 8 @@ -131,7 +184,7 @@ 0 - + Qt::Horizontal @@ -150,7 +203,7 @@ - :/songs/song_author_edit.png:/songs/song_author_edit.png + :/songs/author_add.png:/songs/author_add.png @@ -161,7 +214,7 @@ - :/songs/song_edit.png:/songs/song_edit.png + :/songs/author_edit.png:/songs/author_edit.png @@ -172,27 +225,177 @@ - :/songs/song_delete.png:/songs/song_delete.png + :/songs/author_delete.png:/songs/author_delete.png + + + + Qt::Horizontal + + + - - - - - - 30 - 20 - 256 - 192 - + + + + 8 - + + 0 + + + + + + + + + 8 + + + 0 + + + + + Qt::Horizontal + + + + 54 + 20 + + + + + + + + Add + + + + :/songs/topic_add.png:/songs/topic_add.png + + + + + + + Edit + + + + :/songs/topic_edit.png:/songs/topic_edit.png + + + + + + + Delete + + + + :/songs/topic_delete.png:/songs/topic_delete.png + + + + + + + + + + Qt::Horizontal + + + + + + + + + 8 + + + 0 + + + + + + + + + 8 + + + 0 + + + + + Qt::Horizontal + + + + 54 + 20 + + + + + + + + Add + + + + :/songs/book_add.png:/songs/book_add.png + + + + + + + Edit + + + + :/songs/book_edit.png:/songs/book_edit.png + + + + + + + Delete + + + + :/songs/book_delete.png:/songs/book_delete.png + + + + + + + + + + Qt::Horizontal + + + + @@ -217,7 +420,7 @@ MaintenanceButtonBox - accepted() + rejected() SongMaintenanceDialog accept() @@ -232,17 +435,17 @@ - TypeListWidget - currentRowChanged(int) + TypeTableWidget + cellClicked(int,int) TypeStackedWidget setCurrentIndex(int) - 82 + 72 163 - 321 + 311 163 diff --git a/resources/images/author_add.png b/resources/images/author_add.png new file mode 100644 index 0000000000000000000000000000000000000000..a12a384672d5a059f4b8bbbf090e185ac87c2bd5 GIT binary patch literal 836 zcmV-K1H1f*P)Mc{K~#9!g^^!KQ(+j!pYQB!JMO=3IT>y$h=>?Wy+|kt?Ixl? z!n%>V3G23QL`uqa5fqqGL?juJL8erqSX>+WM`ZEd(PJprv!oi z;Jf+W=Xt;9{a#Q?_dR%mliAMfuT`T}zO44FDLg{uPHlhl9h|qnwF?bX4KyyqX~T2_ zwY%&BZsXimoxvUuLX^;>o@aPwaHR_rA{IBgz_L684Q>*Ny6g(tp8o z1OaFm?2Q0|0N15Jg>zf#_(D+nfdCYK0Nj2JWSGWdQ2}vA+`e#b0wXbqn3b{tJV{2y z{hIPpjWJ^|xEW^5W~2A)wN_j5A9T2a>*jpL#KjVo#$YfoXQ~}gYE0;8dul@xc6V5r_>0Kc90np1u@HQJJTH*MVq&9} z$4}6lf+E6Y{#NBH#aWyRFk7!tuX3=a&%ZuPEtkmQEb?+b?lUMj>9UY&<~ z+`aN&gXUo@GDa&pUiU(!)5beHI~CZ$;b3?lKQ#Ys6rcOLG3S}&kc50DtwT?H2Sx|`P;;+G9DjAUj=bsa zUn{Z~m{Rqs?MMtkA|W6lh}aBND1O}d1*a7_kHqXzD-@M)vD8!oJtXiMucc2!v9|NEx7uB)cytDS%KKql}#4_ O0000Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L02{9W02{9XUK)`c00007bV*G`2iOcA z5F{5Vl0IGl00P=cL_t(I%Y~6^Xj69>#()2FlIG;r#&)*NB3+tl({;EyFLMa<_Hk=eHA6LkG!?)OYZX|mK;YQ_kl(dcG&bzfED)H;D80(5(NH$WfBA|;I~1m0$TtC@6d5Thy4a@&CLX~%CP=x(B2CG zI0qkQ;11vd)I9j?tCya)PS`x(BsR~Jm7MPYw;3+lz-5E51I!AvcRgsB% ztMqI|Wp$Z``b$OA(LE{zbnr{idTfre*E=fO>=TA(!B8rmud}=c!loRcuyn>xa~Cc3 zrm_;L^jO2A0<+7VRQ&>4&->)>;}&zTeWtCXKfjDb*DZHlf2t8^d=1Aw zxM@5MwHb#Sme)q0J_7QOUlz>Tvvrj*{!fST{9%`|ZN=lqT1$tX1Va2eQe;Hyi4DeUP05`1|UW-HE|SCOh0mtS5N7vE_Py zZnynJ>R;ob>Pm+S<*93bN&bN zzp*|}{r+>NZr6zikFK;dnd;Zo@BCuXye6l^0zyz#Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L02{9W02{9XUK)`c00007bV*G`2iOcA z5F{<{p6BcU00Q+%L_t(I%axI9NK*k6$NzV`d)(`$tLZj%nY#6GrC1tHO=blaMcIRp z!~~@*42ww1EHto;=u06{WxKYPUI8JuXoaGh_Vc^2Ah@pLjKo$a?Jis@WXpJbwv3``IP-F#o}A)BkBm^I+FyU?THB!KyIzlC?20 z;Ce}6GaBF=sZ8SW>B6kD-EcdsNJ!S<=#hMINC66u9|}Wj3jkpDjZ$y=i-(zn$K`;> zX<>D-W2Y|OWyCGtOgNFsV&B&7;POS_kUXUC+hdvGW(6PLzAhdg?quA?0SH}piN+ry z-`h{D*sF6PVj1_#?}3inZuGBqOi8Ub~H3n__C zhsD^JVm4YDCPoG^(9?nD#`mJxBW~M~$vcpdnyCs2JS>w^iuPt2Z4(lRDLsxQn_+Wr z=n6_WSt)UJgbF3Tu-YA1qh6ME>Hec6!|U<_GHrj_Ic;22fmkE}N%FxX$04J7a6Tsp zly3?fB8!e(q+UU|x&{Ha6T{u#G1Sw;7fYne+2EDeIR5^A=>XuK^1yDlBlmO(#vC$) z#Fs*)Eg%RVCBb+&@Q4H9@m9h-O+gm10oHL7gcL33u8ZBw0N~ne4&p;&69K-Q(QZ6w zopf`02L^}g8ycGKj9Z6MZEN0N;Jh;0f**O200000 LNkvXXu0mjf=h2y| literal 0 HcmV?d00001 diff --git a/resources/images/book_add.png b/resources/images/book_add.png new file mode 100644 index 0000000000000000000000000000000000000000..a2d5c841335d19c0f64b9b6aafdc275dd09a2bb7 GIT binary patch literal 670 zcmV;P0%84$P)Xv3uhk}A4@St@FDuqBY z@z6!Pbq@8?B?>%skB*%Tx^+@hT?sgPKY=)=c>=-o~w@3}lakcL_nQWH%g^d^b{^F3LLZ7_cKfv7w z52+_M2aGKZGIHhyqg|uCX?{g}>&xrnsko!Cetz8gu-wAU!7G%~Jv5xZ#X(6^j1AWA z;nx%|tTUILWu$$8_3T@scm$w8fUV4YA&MC(G z#<6;j^kcPsYU^^SqT?9pIB4UPpAPMZe0*2Ys82BQb%N8+1@G2oxHo%|OEZGa^yXSJ zpi4+8@m!aD>=2aCzUR`pGf3bcBNM`239=!)_W+MaiGckh%5m&dD@U;;=&&o4PtTWW z!reZu&5!czSB7wDXw?jx$BG1ll#X3cbp@INS&ntnyE={K2v}KO_zsW=IDk@;hQOnm zuLPbpXibF>0@w4Y4OHfPG=%}xgfIj`U^Hkz0A9U-a$Qn%_U#~4E2BPsbh7=c@FfmD)we&2q`e+T~F>(&Mk4*5c! zLh*ovx=UmtklEeYBHG(#Be%`x)o=Vyu@ti(MLz(31JF;k9rOM+qW}N^07*qoM6N<$ Ef@xJQ3IG5A literal 0 HcmV?d00001 diff --git a/resources/images/book_delete.png b/resources/images/book_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..293cf966689f34c9266bb2f94fba82593622d570 GIT binary patch literal 744 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 A7XSbN delta 1891 zcmV-p2b}o24e}0= z=q_1z*$&v)U?4H(5|@^gCWX?FkWSK;>5aT((&s+(U-T(&X@C3LJhcx^A9@{Tn$T&d zBn)+NfsimT0b_i@vMn7Q9Z5%*bIW2|$6!g8JCko_&E98pw7+%Mx4!R4!gXDInGiyN zp%8-b5q=^#tsr;y$dO~CV`B#|UcC654{W!99w78y60)s$}FZ9|O=5o*x{vJt(vf1p< z2L}ho9LLEq_WaDXvJ(Qqi0i~cjuQzOWrS-9)UJL6r_}@)=~vD{yLBC|Y07I`Vk2^{ zc$Q0usP`qn2!+GpcTS!>`O|zp4^7iRB2aG5x~XPepnn}EG4$g%QTg9Bcv1W8Q$(i@ zqjvKKIwK2YxI}vqP&%#y#E7CO@cDdbHk)WP8c+j4mI@#?!&Hk%e)AN(XysQB-n$RI zA|u?uw|zJP#!du+Od2KuSq_tOwpuNe!x1T`L)h*Hv@2JT`R;id;#H8CWGDE&UJ)aP zftUXu0)G~bQe#rINk|2%0|Oh$36Dta!5r59{6{27ApO1bup!`pa3SG7flM+eFew;2 zdB7ypN~IzR(155`t1vRDO+$&NR`uhL;LGNaJn;fVI1Go1Ie`FZ#4Y#1r2;}saN`4D z^;Lja_XtEH5m^HL=@NKr8>@f$6V^ZcJ0g>l5`X?(yL;Z35!l5gxKjyiBG0Fm@>`Y# z+qO}3T*=J#(2<~U`QLc-{_kP)$%lV(0jZbI0^#tM`x363OaQ5!2)M)pD&SB7NkIC5 zD&&O%yIo(dU7pbI-a+mDeKb`Sv7^WE%v*0GdgLfvo?~wq(f6W)Z}cVLGPtbOYPG88 z7k{r49xA@A(t1RmT9tSl3%~m<@_+j)Ov6Cx#g~vf{{sYek07v7hEttB^rJh9hGA5w zK*DQ9wkGO+KWs~y%ZskPBd8kh)$iRyb#4v=lZTL;o<@cxsXu&(J)hj1LP1jiIK33` zLZc8BuND1FOcJPv!X2`A?;R5Kt}Vxbc7OXbEdAkqj_6wm4i95$`uHRO|4s@RgzgzJ zkx0lAR34kE-22JpLHxYQ?yA0r$C+1SO%{Zr2>^;X!|E8 zlw=Z3P3vkw53PC~&isSu5xzOQP1rpP3N)g3EfvuG0UAxfZo}JqiGt7ULZejbN`LN= zOTX}S?0xM!;zTBWZl@BM#5xrKy#USu2^E0d%Y5#}Re0A3v`=qIQr_p0;X$O>iqYM> z(IPqZzcXkpE*)cO<=NX2aEXQbW62z6a~M@vhIKsT8fPwLGWTwA@ z$j}f>UB}vgW}tumIRulYAtsqZc7MWl1RP?XFCm)*d~Fi440H6vxMO!ESJ)|mOa_s$ zG337bHH6Y>SX6NB+BJ5-C+rSu^Zv9@CICACpxKLnl!g+mb2ZriajxKR14$r8AJ{D$ zqC;n*#;wAkY;mQD?-#U?)fwTz@8UT3ZiI zA3B8nKl~9K5-qUb^DIM)vWsnoRmgQ?QvzcEZuKLe6EzY*C=`+ka1Sj=1>7fxjeP42 z#$J6z_WJGj-a~C^u{&wU8XzWwIJFZ2gQ&0sauRwzCnC`PR!FJBmCF=8wgo zFZM|;2>M5~OU$|+_c}pA?|*0zW!By60*M0Q02qJ$4Mges*>~TC%|n*2e7vRqMKmgZ zpa_-@Bn=KRm;RAZd^Dmse89{j#! z>%f5n{$a`-=izB4%YTwkiG4plH6?$vW-=L>Ajl`RSdwa?fLgJL{LBpU3k!C+RH_$O zSM`;J1x>HlHPtZGJG%Z(ze(r~qr%Y8kapq1g&hAK$wXl)5C`C6cNCVF@!&Due zp{igrO_H1Cy6a}GehouJZA&?2lh+{b}F(T{+S%YGtDsDw_`+X+n1 d^k4Sx{TK6P+-A`=TH*iz002ovPDHLkV1n>;gTnv- diff --git a/resources/images/openlp-2.qrc b/resources/images/openlp-2.qrc index de5da6a9f..98480206a 100644 --- a/resources/images/openlp-2.qrc +++ b/resources/images/openlp-2.qrc @@ -1,5 +1,14 @@ + topic_edit.png + author_add.png + author_delete.png + book_add.png + topic_add.png + book_delete.png + book_edit.png + author_edit.png + topic_delete.png book_maintenance.png author_maintenance.png topic_maintenance.png diff --git a/resources/images/topic_add.png b/resources/images/topic_add.png new file mode 100644 index 0000000000000000000000000000000000000000..3754fc60e88139f15b3141c42ed61d089c644939 GIT binary patch literal 1007 zcmVPx#24YJ`L;(K){{a7>y{D4^000SaNLh0L05@C!05@C#%g3a-00007bV*G`2iXS} z5)CEazwQ7400VDHL_t(I%T1C?Oq^95#n1iUJKx8=Dbt~J1`0xp2$+~Lg+e2y;-e%k znwYl6G*J|dw#Jpl#6**Jp)8C|6Be47E^J-+NF^~%p|+t+N&?K3#1_*kT3(fh6gn_7 z4BzA4>!Ky?S)Ikn@0`V9EeBiSm=;)pz&1E$`wKA3-C*m%U585I{^x{A;Zb*7E>vY| z6Xj2DOZ}Nzm|mU!r29;F??+v)gU=>saQ^Bq2>85AS-_SmZ}r~Jn%?-6;iLXCYP^ZR zcHQ0X)E%yVb?d2yQ{Jp68_lrHp|jz$lb3%Qx=!tHy@1;T8T|T9zaBhyotL(IzNHF# zPgdmIj9%Bt{0+87YZ#jEg@(e+yPY4x;ed1_TK(#;_^&JKK~T^RK$d6DXK083V}=k~aL#I`x8Y{^Urea`&3)@Y+J?g4 z_-=GA0pXqBg508`Ze1n#Acosoa^wC8HFDyL5o67wQqzQH8FK}VJ#hdr7`Ntn%=7*e zyT9xQt4A01_Wc2Eagwf9*?*|BYM*gB=nE>XG!;}HD;Z0;Y?wnif)xKQqD z34XtE1rML`K*!#Bmq(*fIhszLZf$PvjKwSE_IONoyu7~=z=YQ`Q~+E6u-y$*RKy=X@{w{5z~G!0Nhx`0X>>;-k@z7T zF5WpcHQhZjGJMiBO<0yy0AK-d0BHUQzyrXiwGI+dB$vx;(=dlhA|(UKWb%@fG9;zk d%*zLh^#4=LdgeE|-46f&002ovPDHLkV1ms(&fWk3 literal 0 HcmV?d00001 diff --git a/resources/images/topic_delete.png b/resources/images/topic_delete.png new file mode 100644 index 0000000000000000000000000000000000000000..38a2ad5b5edee7122e5f290a347d97de721feccd GIT binary patch literal 1038 zcmV+p1o8WcP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L05@C!05@C#%g3a-00007bV*G`2iXS} z5)>DVXcm|N00WLmL_t(I%T113Oq*o@hTre|{`PN6PirYcIggF7j1jGYt&kDj76yhz z6EmYRF=HNKb0&+27*B~8W*2135)+LVx_Ciivc+++Yy&p73JGX!M3J#zI29-d0b6?d z`~Tnfc`-4(SMSA}=Y2@`pRN7eP+%WJ0{!_#@LiG>Q~ zMCl<%t?QLo@1#;XGTY67CoO<@XLI-_`|05@7QzV(-M){x2MJc+S$fq`sT@un$T!rC zLEMpLVjr4EuFj=YeHVFJ-OA;gfu5y?lCF45ks!gd^&qOGT$6$ttl8B-@2ghEDOIRq zrlju5U)a+d#dczQ-O4J#df8x5Vd)Q4{rDBckLUKhHlS33XC?n0m)1jV0O$t;ZGGj^ zb+qWWWii=qCrcYC@FXE?!+M*&5Vr(C4GqHkYYoVYPrZtTFi`XP63iY+IdWnvCXNQ5 zEg!I(oN`TH603^tM^wvpVe|kRYi?*>B5(XbVDD__j#$p6k)_Y82jViBf!p_dE+hS^ZEGC;a|RO zJb19fUtG?Miv7H;y|os=lvTBmjFy$#d%9ix{zAO|+9?QTU?cH2z(g{wr=VCVnOm3< z01N=g8CjH;7XN>^(|`dmGsY~Ob5>B`D+>eyKe$}(J+rfO7e+@%E~%;tP17;}GypmP z$#wut0Bll92c^`TOs1r2R);-a&tNDN8sMBeIp^DZ{-2Tj7rAtgxH|zI+yDRo07*qo IM6N<$g3FNLR{#J2 literal 0 HcmV?d00001 diff --git a/resources/images/topic_edit.png b/resources/images/topic_edit.png new file mode 100644 index 0000000000000000000000000000000000000000..03b8167d0ffadaafea18f3f3547306eea7e03153 GIT binary patch literal 1024 zcmV+b1poVqP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L05@C!05@C#%g3a-00007bV*G`2iXS} z5*Y!_65WIV00V$YL_t(I%UzFcOqFE-hOg&&U(PEB4ip3)KBY#A2#jTjkf3#ze7R{E z;#|2Xe?(<#&8=n5K4vs)jONx>i>d45Pua#6F-^)yYO@i}rbU1sd`K!1aDa2p`=0ka zPe07fb#M1}|G2mNxWsCcY8vI|RW+$vQETxr*qLmim zU@ROObq>5&+S~m8uEqSUNd>0SZJhq=XD0fC^quHs^v|GC){=9~cduFHnlU#bqQcct zTIy;i&tlhTx?M+zZ@ zmRg8)W>8h=LV1-Ymiqk|6K~8+U;3uhbP_^HuSP3i!IQffb6K=Ch9O0qHV_DrAslw* zual3xaE2RGeRLeG(Ko%Xyu80HJZ4&p77~Syg0$l%y&jF3D1^r}wP_f_qcv~lmeO`~ zilNK%eEgc1r0A(bUv299?AOU!L||)xh3ioU`y^gWZ}sO3XA-hyks%Ewq>wwTM4XFx z?B3f=iQneY^2N|UW8vJ>)x|STG^Ru$yLjmM1+;C*n5)(NMcJJ9u;;LM##F0PU0EH; zpr+*_d1B**i?sZ0wTXXT0{l9ri>2R2sVizPAe{WSCR1ISl<>b@%s5qLZ!$c}w3 zBO}*%YI8AX6X)s@{Tx>yT^p79TLEJGhG&`Rhk~~!@uX-O!%_2ptH8n1k)Dq3rF3-8 z@z&E0f%UJG7Z?!3+z`vf6%G4Yv!xXQP+3z&@RFD7W7AC8{mlMYr~7^%;<+}-6IBuF z>*F~(k=c@*CqB|jODCjMdh<`5zw0GTfZ)jzN}nI+nLRtvCs*s~>0|8q@NV)mZMIfB zoDVnh%i%B2M%^g)q@`jSCT{x%&dnXVMR2EjI*;i2xj|anzh>|DYs4jQ(MHab(Yj5w zMZj>pwM2yNh`!x7Z->lGKMnP@#F?|C$B%GecP>j(w=o)Au0s=-72pCmZiJkiEXK#L z{(l<-h%YNn)160J^w8i1U0Yi-+|<;h%gfik3#40?l@9m-58R@^^MVIR0DMx)B&C#G uRalr+u(BYttLxhV+qMA~f%*R&0@S~%CVK9AjxSvR0000