diff --git a/openlp/core/lib/mediamanageritem.py b/openlp/core/lib/mediamanageritem.py index cedf86f6a..936a2ef0a 100644 --- a/openlp/core/lib/mediamanageritem.py +++ b/openlp/core/lib/mediamanageritem.py @@ -383,7 +383,6 @@ class MediaManagerItem(QtGui.QWidget): self.loadList(full_list) last_dir = os.path.split(unicode(files[0]))[0] Settings().setValue(self.settingsSection + u'/last directory', last_dir) - Settings().setValue(u'%s/%s files' % (self.settingsSection, self.settingsSection), self.getFileList()) if duplicates_found: critical_error_message_box(UiStrings().Duplicate, translate('OpenLP.MediaManagerItem', 'Duplicate files were found on import and were ignored.')) diff --git a/openlp/plugins/images/imageplugin.py b/openlp/plugins/images/imageplugin.py index 11e542e60..cbbdc39ec 100644 --- a/openlp/plugins/images/imageplugin.py +++ b/openlp/plugins/images/imageplugin.py @@ -32,11 +32,14 @@ from PyQt4 import QtCore, QtGui import logging from openlp.core.lib import Plugin, StringContent, build_icon, translate, Receiver, ImageSource, Settings +from openlp.core.lib.db import Manager from openlp.plugins.images.lib import ImageMediaItem, ImageTab +from openlp.plugins.images.lib.db import init_schema log = logging.getLogger(__name__) __default_settings__ = { + u'images/db type': u'sqlite', u'images/background color': u'#000000', u'images/images files': [] } @@ -47,6 +50,7 @@ class ImagePlugin(Plugin): def __init__(self): Plugin.__init__(self, u'images', __default_settings__, ImageMediaItem, ImageTab) + self.manager = Manager(u'images', init_schema) self.weight = -7 self.iconPath = u':/plugins/plugin_images.png' self.icon = build_icon(self.iconPath) diff --git a/openlp/plugins/images/lib/db.py b/openlp/plugins/images/lib/db.py new file mode 100644 index 000000000..a5716f648 --- /dev/null +++ b/openlp/plugins/images/lib/db.py @@ -0,0 +1,97 @@ +# -*- coding: utf-8 -*- +# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4 + +############################################################################### +# OpenLP - Open Source Lyrics Projection # +# --------------------------------------------------------------------------- # +# Copyright (c) 2008-2013 Raoul Snyman # +# Portions copyright (c) 2008-2013 Tim Bentley, Gerald Britton, Jonathan # +# Corwin, Samuel Findlay, Michael Gorven, Scott Guerrieri, Matthias Hub, # +# Meinert Jordan, Armin Köhler, Erik Lundin, Edwin Lunando, Brian T. Meyer. # +# Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias Põldaru, # +# Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, # +# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Dave Warnock, # +# Frode Woldsund, Martin Zibricky, Patrick Zimmermann # +# --------------------------------------------------------------------------- # +# 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 # +############################################################################### +""" +The :mod:`db` module provides the database and schema that is the backend for the Images plugin +""" + +from sqlalchemy import Column, ForeignKey, Table, types +from sqlalchemy.orm import mapper, relation, reconstructor + +from openlp.core.lib.db import BaseModel, init_db + + +class ImageGroups(BaseModel): + """ + ImageGroups model + """ + pass + +class ImageFilenames(BaseModel): + """ + ImageFilenames model + """ + pass + +def init_schema(url): + """ + Setup the images database connection and initialise the database schema. + + ``url`` + The database to setup + + The images database contains the following tables: + + * image_groups + * image_filenames + + **image_groups Table** + This table holds the names of the images groups. It has the following columns: + + * id + * parent_id + * group_name + + **image_filenames Table** + This table holds the filenames of the images and the group they belong to. It has the following columns: + + * id + * group_id + * filename + """ + session, metadata = init_db(url) + + # Definition of the "image_groups" table + image_groups_table = Table(u'image_groups', metadata, + Column(u'id', types.Integer(), primary_key=True), + Column(u'parent_id', types.Integer()), + Column(u'group_name', types.Unicode(128)) + ) + + # Definition of the "image_filenames" table + image_filenames_table = Table(u'image_filenames', metadata, + Column(u'id', types.Integer(), primary_key=True), + Column(u'group_id', types.Integer(), ForeignKey(u'image_groups.id'), default=None), + Column(u'filename', types.Unicode(255), nullable=False) + ) + + mapper(ImageGroups, image_groups_table) + mapper(ImageFilenames, image_filenames_table) + + metadata.create_all(checkfirst=True) + return session diff --git a/openlp/plugins/images/lib/mediaitem.py b/openlp/plugins/images/lib/mediaitem.py index c3904b2b7..37036c668 100644 --- a/openlp/plugins/images/lib/mediaitem.py +++ b/openlp/plugins/images/lib/mediaitem.py @@ -37,6 +37,7 @@ from openlp.core.lib import MediaManagerItem, build_icon, ItemCapabilities, Sett UiStrings from openlp.core.lib.ui import critical_error_message_box from openlp.core.utils import AppLocation, delete_file, locale_compare, get_images_filter +from openlp.plugins.images.lib.db import ImageFilenames log = logging.getLogger(__name__) @@ -51,6 +52,7 @@ class ImageMediaItem(MediaManagerItem): MediaManagerItem.__init__(self, parent, plugin, icon) self.quickPreviewAllowed = True self.hasSearch = True + self.manager = plugin.manager QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'live_theme_changed'), self.liveThemeChanged) # Allow DnD from the desktop self.listView.activateDnD() @@ -78,7 +80,19 @@ class ImageMediaItem(MediaManagerItem): self.listView.setIconSize(QtCore.QSize(88, 50)) self.servicePath = os.path.join(AppLocation.get_section_data_path(self.settingsSection), u'thumbnails') check_directory_exists(self.servicePath) - self.loadList(Settings().value(self.settingsSection + u'/images files'), True) + # Import old images list + images_old = Settings().value(self.settingsSection + u'/images files') + if len(images_old) > 0: + for imageFile in images_old: + imagefilename = ImageFilenames() + imagefilename.group_id = 0 + imagefilename.filename = imageFile + success = self.manager.save_object(imagefilename) + Settings().setValue(self.settingsSection + u'/images files', []) + Settings().remove(self.settingsSection + u'/images files') + Settings().remove(self.settingsSection + u'/images count') + # Load images from the database + self.loadList(self.manager.get_all_objects(ImageFilenames, order_by_ref=ImageFilenames.filename)) def addListViewToToolBar(self): MediaManagerItem.addListViewToToolBar(self) @@ -102,11 +116,12 @@ class ImageMediaItem(MediaManagerItem): Receiver.send_message(u'cursor_busy') self.main_window.displayProgressBar(len(row_list)) for row in row_list: - text = self.listView.topLevelItem(row) - if text: - delete_file(os.path.join(self.servicePath, text.text(0))) + row_item = self.listView.topLevelItem(row) + if row_item: + delete_file(os.path.join(self.servicePath, row_item.text(0))) self.listView.takeTopLevelItem(row) self.main_window.incrementProgressBar() + self.manager.delete_object(ImageFilenames, row_item.data(0, QtCore.Qt.UserRole).id) SettingsManager.setValue(self.settingsSection + u'/images files', self.getFileList()) self.main_window.finishedProgressBar() Receiver.send_message(u'cursor_normal') @@ -120,19 +135,26 @@ class ImageMediaItem(MediaManagerItem): # characters. images.sort(cmp=locale_compare, key=lambda filename: os.path.split(unicode(filename))[1]) for imageFile in images: - filename = os.path.split(unicode(imageFile))[1] + if type(imageFile) is str or type(imageFile) is unicode: + filename = imageFile + imageFile = ImageFilenames() + imageFile.group_id = 0 + imageFile.filename = unicode(filename) + success = self.manager.save_object(imageFile) + filename = os.path.split(imageFile.filename)[1] thumb = os.path.join(self.servicePath, filename) - if not os.path.exists(unicode(imageFile)): + if not os.path.exists(imageFile.filename): icon = build_icon(u':/general/general_delete.png') else: - if validate_thumb(unicode(imageFile), thumb): + if validate_thumb(imageFile.filename, thumb): icon = build_icon(thumb) else: - icon = create_thumb(unicode(imageFile), thumb) + icon = create_thumb(imageFile.filename, thumb) + log.debug(u'Loading image: %s', imageFile.filename) item_name = QtGui.QTreeWidgetItem(filename) item_name.setText(0, filename) item_name.setIcon(0, icon) - item_name.setToolTip(0, imageFile) + item_name.setToolTip(0, imageFile.filename) item_name.setData(0, QtCore.Qt.UserRole, imageFile) self.listView.addTopLevelItem(item_name) if not initialLoad: @@ -160,7 +182,7 @@ class ImageMediaItem(MediaManagerItem): missing_items = [] missing_items_filenames = [] for bitem in items: - filename = bitem.data(0, QtCore.Qt.UserRole) + filename = bitem.data(0, QtCore.Qt.UserRole).filename if not os.path.exists(filename): missing_items.append(bitem) missing_items_filenames.append(filename) @@ -183,7 +205,7 @@ class ImageMediaItem(MediaManagerItem): return False # Continue with the existing images. for bitem in items: - filename = bitem.data(0, QtCore.Qt.UserRole) + filename = bitem.data(0, QtCore.Qt.UserRole).filename name = os.path.split(filename)[1] service_item.add_from_image(filename, name, background) return True @@ -210,7 +232,7 @@ class ImageMediaItem(MediaManagerItem): background = QtGui.QColor(Settings().value(self.settingsSection + u'/background color')) item = self.listView.selectedIndexes()[0] bitem = self.listView.topLevelItem(item.row()) - filename = bitem.data(QtCore.Qt.UserRole) + filename = bitem.data(QtCore.Qt.UserRole).filename if os.path.exists(filename): if self.plugin.liveController.display.directImage(filename, background): self.resetAction.setVisible(True) diff --git a/openlp/plugins/media/lib/mediaitem.py b/openlp/plugins/media/lib/mediaitem.py index e6ae464b3..4fa94e2a2 100644 --- a/openlp/plugins/media/lib/mediaitem.py +++ b/openlp/plugins/media/lib/mediaitem.py @@ -285,6 +285,7 @@ class MediaMediaItem(MediaManagerItem): item_name.setData(0, QtCore.Qt.UserRole, track) item_name.setToolTip(0, track) self.listView.addTopLevelItem(item_name) + Settings().setValue(self.settingsSection + u'/media files', self.getFileList()) def getList(self, type=MediaType.Audio): media = Settings().value(self.settingsSection + u'/media files') diff --git a/openlp/plugins/presentations/lib/mediaitem.py b/openlp/plugins/presentations/lib/mediaitem.py index 79868e9ed..cd2628cf1 100644 --- a/openlp/plugins/presentations/lib/mediaitem.py +++ b/openlp/plugins/presentations/lib/mediaitem.py @@ -208,6 +208,7 @@ class PresentationMediaItem(MediaManagerItem): item_name.setIcon(0, icon) item_name.setToolTip(0, file) self.listView.addTopLevelItem(item_name) + Settings().setValue(self.settingsSection + u'/presentations files', self.getFileList()) Receiver.send_message(u'cursor_normal') if not initialLoad: self.main_window.finishedProgressBar()