From dbce056688adcfe14f94bfdaba09e63c788eaca3 Mon Sep 17 00:00:00 2001 From: Arjan Schrijver Date: Fri, 25 Jan 2013 12:29:32 +0100 Subject: [PATCH] Change QListWidget to QTreeWidget in media manager --- openlp/core/lib/__init__.py | 2 +- openlp/core/lib/mediamanageritem.py | 22 ++-- openlp/core/lib/treewidgetwithdnd.py | 113 ++++++++++++++++++ openlp/plugins/bibles/lib/mediaitem.py | 11 +- openlp/plugins/custom/lib/mediaitem.py | 7 +- openlp/plugins/images/lib/mediaitem.py | 15 +-- openlp/plugins/media/lib/mediaitem.py | 27 +++-- openlp/plugins/presentations/lib/mediaitem.py | 22 ++-- openlp/plugins/songs/lib/mediaitem.py | 23 ++-- 9 files changed, 183 insertions(+), 59 deletions(-) create mode 100644 openlp/core/lib/treewidgetwithdnd.py diff --git a/openlp/core/lib/__init__.py b/openlp/core/lib/__init__.py index 5cbfec11f..c18e3d0a1 100644 --- a/openlp/core/lib/__init__.py +++ b/openlp/core/lib/__init__.py @@ -391,7 +391,7 @@ from uistrings import UiStrings from eventreceiver import Receiver from screen import ScreenList from settings import Settings -from listwidgetwithdnd import ListWidgetWithDnD +from treewidgetwithdnd import TreeWidgetWithDnD from formattingtags import FormattingTags from spelltextedit import SpellTextEdit from settingsmanager import SettingsManager diff --git a/openlp/core/lib/mediamanageritem.py b/openlp/core/lib/mediamanageritem.py index 100f248c0..3c4507280 100644 --- a/openlp/core/lib/mediamanageritem.py +++ b/openlp/core/lib/mediamanageritem.py @@ -36,7 +36,7 @@ import re from PyQt4 import QtCore, QtGui from openlp.core.lib import OpenLPToolbar, ServiceItem, StringContent, build_icon, translate, Receiver, \ - ListWidgetWithDnD, ServiceItemContext, Settings, Registry, UiStrings + TreeWidgetWithDnD, ServiceItemContext, Settings, Registry, UiStrings from openlp.core.lib.searchedit import SearchEdit from openlp.core.lib.ui import create_widget_action, critical_error_message_box @@ -213,8 +213,7 @@ class MediaManagerItem(QtGui.QWidget): Creates the main widget for listing items the media item is tracking """ # Add the List widget - self.listView = ListWidgetWithDnD(self, self.plugin.name) - self.listView.setSpacing(1) + self.listView = TreeWidgetWithDnD(self, self.plugin.name) self.listView.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection) self.listView.setAlternatingRowColors(True) self.listView.setObjectName(u'%sListView' % self.plugin.name) @@ -404,7 +403,7 @@ class MediaManagerItem(QtGui.QWidget): """ count = 0 file_list = [] - while count < self.listView.count(): + while count < self.listView.topLevelItemCount(): bitem = self.listView.item(count) filename = bitem.data(QtCore.Qt.UserRole) file_list.append(filename) @@ -571,15 +570,16 @@ class MediaManagerItem(QtGui.QWidget): """ Checks if the listView is empty and adds a "No Search Results" item. """ - if self.listView.count(): + if self.listView.topLevelItemCount(): return message = translate('OpenLP.MediaManagerItem', 'No Search Results') - item = QtGui.QListWidgetItem(message) + item = QtGui.QTreeWidgetItem(message) + item.setText(0, message) item.setFlags(QtCore.Qt.NoItemFlags) font = QtGui.QFont() font.setItalic(True) - item.setFont(font) - self.listView.addItem(item) + item.setFont(0, font) + self.listView.addTopLevelItem(item) def _getIdOfItemToGenerate(self, item, remoteItem): """ @@ -596,7 +596,7 @@ class MediaManagerItem(QtGui.QWidget): item = self.listView.currentItem() if item is None: return False - item_id = item.data(QtCore.Qt.UserRole) + item_id = item.data(0, QtCore.Qt.UserRole) else: item_id = remoteItem else: @@ -611,7 +611,7 @@ class MediaManagerItem(QtGui.QWidget): if self.autoSelectId == -1: item = self.listView.currentItem() if item: - self.autoSelectId = item.data(QtCore.Qt.UserRole) + self.autoSelectId = item.data(0, QtCore.Qt.UserRole) def search(self, string, showError=True): """ @@ -687,4 +687,4 @@ class MediaManagerItem(QtGui.QWidget): self._service_manager = Registry().get(u'service_manager') return self._service_manager - service_manager = property(_get_service_manager) \ No newline at end of file + service_manager = property(_get_service_manager) diff --git a/openlp/core/lib/treewidgetwithdnd.py b/openlp/core/lib/treewidgetwithdnd.py new file mode 100644 index 000000000..b62246dc3 --- /dev/null +++ b/openlp/core/lib/treewidgetwithdnd.py @@ -0,0 +1,113 @@ +# -*- 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 # +############################################################################### +""" +Extend QTreeWidget to handle drag and drop functionality +""" +import os + +from PyQt4 import QtCore, QtGui + +from openlp.core.lib import Receiver + +class TreeWidgetWithDnD(QtGui.QTreeWidget): + """ + Provide a list widget to store objects and handle drag and drop events + """ + def __init__(self, parent=None, name=u''): + """ + Initialise the list widget + """ + QtGui.QTreeWidget.__init__(self, parent) + self.mimeDataText = name + self.header().close() + self.setIndentation(0) + assert(self.mimeDataText) + + def activateDnD(self): + """ + Activate DnD of widget + """ + self.setAcceptDrops(True) + self.setDragDropMode(QtGui.QAbstractItemView.DragDrop) + QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'%s_dnd' % self.mimeDataText), + self.parent().loadFile) + + def mouseMoveEvent(self, event): + """ + Drag and drop event does not care what data is selected + as the recipient will use events to request the data move + just tell it what plugin to call + """ + if event.buttons() != QtCore.Qt.LeftButton: + event.ignore() + return + if not self.selectedItems(): + event.ignore() + return + drag = QtGui.QDrag(self) + mimeData = QtCore.QMimeData() + drag.setMimeData(mimeData) + mimeData.setText(self.mimeDataText) + drag.start(QtCore.Qt.CopyAction) + + def dragEnterEvent(self, event): + if event.mimeData().hasUrls(): + event.accept() + else: + event.ignore() + + def dragMoveEvent(self, event): + if event.mimeData().hasUrls(): + event.setDropAction(QtCore.Qt.CopyAction) + event.accept() + else: + event.ignore() + + def dropEvent(self, event): + """ + Receive drop event check if it is a file and process it if it is. + + ``event`` + Handle of the event pint passed + """ + if event.mimeData().hasUrls(): + event.setDropAction(QtCore.Qt.CopyAction) + event.accept() + files = [] + for url in event.mimeData().urls(): + localFile = url.toLocalFile() + if os.path.isfile(localFile): + files.append(localFile) + elif os.path.isdir(localFile): + listing = os.listdir(localFile) + for file in listing: + files.append(os.path.join(localFile, file)) + Receiver.send_message(u'%s_dnd' % self.mimeDataText, files) + else: + event.ignore() diff --git a/openlp/plugins/bibles/lib/mediaitem.py b/openlp/plugins/bibles/lib/mediaitem.py index fd1109221..3d616181a 100644 --- a/openlp/plugins/bibles/lib/mediaitem.py +++ b/openlp/plugins/bibles/lib/mediaitem.py @@ -95,7 +95,7 @@ class BibleMediaItem(MediaManagerItem): self.displayResults(bible, second_bible) def _decodeQtObject(self, bitem, key): - reference = bitem.data(QtCore.Qt.UserRole) + reference = bitem.data(0, QtCore.Qt.UserRole) obj = reference[unicode(key)] return unicode(obj).strip() @@ -691,7 +691,7 @@ class BibleMediaItem(MediaManagerItem): self.second_search_results = bibles[second_bible].get_verses(text) if not self.quickLockButton.isChecked(): self.listView.clear() - if self.listView.count() != 0 and self.search_results: + if self.listView.topLevelItemCount() != 0 and self.search_results: self.__checkSecondBible(bible, second_bible) elif self.search_results: self.displayResults(bible, second_bible) @@ -707,7 +707,7 @@ class BibleMediaItem(MediaManagerItem): """ items = self.buildDisplayResults(bible, second_bible, self.search_results) for bible_verse in items: - self.listView.addItem(bible_verse) + self.listView.addTopLevelItem(bible_verse) self.listView.selectAll() self.search_results = {} self.second_search_results = {} @@ -766,8 +766,9 @@ class BibleMediaItem(MediaManagerItem): second_version) else: bible_text = u'%s %d%s%d (%s)' % (book, verse.chapter, verse_separator, verse.verse, version) - bible_verse = QtGui.QListWidgetItem(bible_text) - bible_verse.setData(QtCore.Qt.UserRole, data) + bible_verse = QtGui.QTreeWidgetItem(bible_text) + bible_verse.setText(0, bible_text) + bible_verse.setData(0, QtCore.Qt.UserRole, data) items.append(bible_verse) return items diff --git a/openlp/plugins/custom/lib/mediaitem.py b/openlp/plugins/custom/lib/mediaitem.py index b4938e929..2cf6bd92e 100644 --- a/openlp/plugins/custom/lib/mediaitem.py +++ b/openlp/plugins/custom/lib/mediaitem.py @@ -105,9 +105,10 @@ class CustomMediaItem(MediaManagerItem): self.listView.clear() custom_slides.sort() for custom_slide in custom_slides: - custom_name = QtGui.QListWidgetItem(custom_slide.title) - custom_name.setData(QtCore.Qt.UserRole, custom_slide.id) - self.listView.addItem(custom_name) + custom_name = QtGui.QTreeWidgetItem(custom_slide.title) + custom_name.setText(0, custom_slide.title) + custom_name.setData(0, QtCore.Qt.UserRole, custom_slide.id) + self.listView.addTopLevelItem(custom_name) # Auto-select the custom. if custom_slide.id == self.autoSelectId: self.listView.setCurrentItem(custom_name) diff --git a/openlp/plugins/images/lib/mediaitem.py b/openlp/plugins/images/lib/mediaitem.py index 092103c86..4924092e2 100644 --- a/openlp/plugins/images/lib/mediaitem.py +++ b/openlp/plugins/images/lib/mediaitem.py @@ -129,11 +129,12 @@ class ImageMediaItem(MediaManagerItem): icon = build_icon(thumb) else: icon = create_thumb(unicode(imageFile), thumb) - item_name = QtGui.QListWidgetItem(filename) - item_name.setIcon(icon) - item_name.setToolTip(imageFile) - item_name.setData(QtCore.Qt.UserRole, imageFile) - self.listView.addItem(item_name) + item_name = QtGui.QTreeWidgetItem(filename) + item_name.setText(0, filename) + item_name.setIcon(0, icon) + item_name.setToolTip(0, imageFile) + item_name.setData(0, QtCore.Qt.UserRole, imageFile) + self.listView.addTopLevelItem(item_name) if not initialLoad: self.main_window.incrementProgressBar() if not initialLoad: @@ -159,7 +160,7 @@ class ImageMediaItem(MediaManagerItem): missing_items = [] missing_items_filenames = [] for bitem in items: - filename = bitem.data(QtCore.Qt.UserRole) + filename = bitem.data(0, QtCore.Qt.UserRole) if not os.path.exists(filename): missing_items.append(bitem) missing_items_filenames.append(filename) @@ -182,7 +183,7 @@ class ImageMediaItem(MediaManagerItem): return False # Continue with the existing images. for bitem in items: - filename = bitem.data(QtCore.Qt.UserRole) + filename = bitem.data(0, QtCore.Qt.UserRole) name = os.path.split(filename)[1] service_item.add_from_image(filename, name, background) return True diff --git a/openlp/plugins/media/lib/mediaitem.py b/openlp/plugins/media/lib/mediaitem.py index 443087a09..773027847 100644 --- a/openlp/plugins/media/lib/mediaitem.py +++ b/openlp/plugins/media/lib/mediaitem.py @@ -264,24 +264,27 @@ class MediaMediaItem(MediaManagerItem): track_info = QtCore.QFileInfo(track) if not os.path.exists(track): filename = os.path.split(unicode(track))[1] - item_name = QtGui.QListWidgetItem(filename) - item_name.setIcon(ERROR) - item_name.setData(QtCore.Qt.UserRole, track) + item_name = QtGui.QTreeWidgetItem(filename) + item_name.setText(0, filename) + item_name.setIcon(0, ERROR) + item_name.setData(0, QtCore.Qt.UserRole, track) elif track_info.isFile(): filename = os.path.split(unicode(track))[1] - item_name = QtGui.QListWidgetItem(filename) + item_name = QtGui.QTreeWidgetItem(filename) + item_name.setText(0, filename) if u'*.%s' % (filename.split(u'.')[-1].lower()) in self.media_controller.audio_extensions_list: - item_name.setIcon(AUDIO) + item_name.setIcon(0, AUDIO) else: - item_name.setIcon(VIDEO) - item_name.setData(QtCore.Qt.UserRole, track) + item_name.setIcon(0, VIDEO) + item_name.setData(0, QtCore.Qt.UserRole, track) else: filename = os.path.split(unicode(track))[1] - item_name = QtGui.QListWidgetItem(filename) - item_name.setIcon(build_icon(DVDICON)) - item_name.setData(QtCore.Qt.UserRole, track) - item_name.setToolTip(track) - self.listView.addItem(item_name) + item_name = QtGui.QTreeWidgetItem(filename) + item_name.setText(0, filename) + item_name.setIcon(0, build_icon(DVDICON)) + item_name.setData(0, QtCore.Qt.UserRole, track) + item_name.setToolTip(0, track) + self.listView.addTopLevelItem(item_name) 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 fe533a791..f7358e8f0 100644 --- a/openlp/plugins/presentations/lib/mediaitem.py +++ b/openlp/plugins/presentations/lib/mediaitem.py @@ -164,11 +164,12 @@ class PresentationMediaItem(MediaManagerItem): continue filename = os.path.split(unicode(file))[1] if not os.path.exists(file): - item_name = QtGui.QListWidgetItem(filename) - item_name.setIcon(build_icon(ERROR)) - item_name.setData(QtCore.Qt.UserRole, file) - item_name.setToolTip(file) - self.listView.addItem(item_name) + item_name = QtGui.QTreeWidgetItem(filename) + item_name.setText(0, filename) + item_name.setIcon(0, build_icon(ERROR)) + item_name.setData(0, QtCore.Qt.UserRole, file) + item_name.setToolTip(0, file) + self.listView.addTopLevelItem(item_name) else: if titles.count(filename) > 0: if not initialLoad: @@ -201,11 +202,12 @@ class PresentationMediaItem(MediaManagerItem): critical_error_message_box(UiStrings().UnsupportedFile, translate('PresentationPlugin.MediaItem', 'This type of presentation is not supported.')) continue - item_name = QtGui.QListWidgetItem(filename) - item_name.setData(QtCore.Qt.UserRole, file) - item_name.setIcon(icon) - item_name.setToolTip(file) - self.listView.addItem(item_name) + item_name = QtGui.QTreeWidgetItem(filename) + item_name.setText(0, filename) + item_name.setData(0, QtCore.Qt.UserRole, file) + item_name.setIcon(0, icon) + item_name.setToolTip(0, file) + self.listView.addTopLevelItem(item_name) Receiver.send_message(u'cursor_normal') if not initialLoad: self.main_window.finishedProgressBar() diff --git a/openlp/plugins/songs/lib/mediaitem.py b/openlp/plugins/songs/lib/mediaitem.py index cd23ad731..d974f79e8 100644 --- a/openlp/plugins/songs/lib/mediaitem.py +++ b/openlp/plugins/songs/lib/mediaitem.py @@ -236,9 +236,10 @@ class SongMediaItem(MediaManagerItem): author_list = [author.display_name for author in song.authors] song_title = unicode(song.title) song_detail = u'%s (%s)' % (song_title, create_separated_list(author_list)) - song_name = QtGui.QListWidgetItem(song_detail) - song_name.setData(QtCore.Qt.UserRole, song.id) - self.listView.addItem(song_name) + song_name = QtGui.QTreeWidgetItem(song_detail) + song_name.setText(0, song_detail) + song_name.setData(0, QtCore.Qt.UserRole, song.id) + self.listView.addTopLevelItem(song_name) # Auto-select the item if name has been set if song.id == self.autoSelectId: self.listView.setCurrentItem(song_name) @@ -253,9 +254,10 @@ class SongMediaItem(MediaManagerItem): if song.temporary: continue song_detail = u'%s (%s)' % (author.display_name, song.title) - song_name = QtGui.QListWidgetItem(song_detail) - song_name.setData(QtCore.Qt.UserRole, song.id) - self.listView.addItem(song_name) + song_name = QtGui.QTreeWidgetItem(song_detail) + song_name.setText(0, song_detail) + song_name.setData(0, QtCore.Qt.UserRole, song.id) + self.listView.addTopLevelItem(song_name) def displayResultsBook(self, searchresults, song_number=False): log.debug(u'display results Book') @@ -270,9 +272,10 @@ class SongMediaItem(MediaManagerItem): if song_number and not song_number in song.song_number: continue song_detail = u'%s - %s (%s)' % (book.name, song.song_number, song.title) - song_name = QtGui.QListWidgetItem(song_detail) - song_name.setData(QtCore.Qt.UserRole, song.id) - self.listView.addItem(song_name) + song_name = QtGui.QTreeWidgetItem(song_detail) + song_name.setText(0, song_detail) + song_name.setData(0, QtCore.Qt.UserRole, song.id) + self.listView.addTopLevelItem(song_name) def onClearTextButtonClick(self): """ @@ -351,7 +354,7 @@ class SongMediaItem(MediaManagerItem): log.debug(u'onEditClick') if check_item_selected(self.listView, UiStrings().SelectEdit): self.editItem = self.listView.currentItem() - item_id = self.editItem.data(QtCore.Qt.UserRole) + item_id = self.editItem.data(0, QtCore.Qt.UserRole) self.editSongForm.loadSong(item_id, False) self.editSongForm.exec_() self.autoSelectId = -1