diff --git a/openlp.pyw b/openlp.pyw index a39f6cf65..9d291bbca 100755 --- a/openlp.pyw +++ b/openlp.pyw @@ -93,7 +93,7 @@ class OpenLP(QtGui.QApplication): # On Windows, the args passed into the constructor are # ignored. Not very handy, so set the ones we want to use. self.args = args - # provide a listener for widgets to reqest a screen update. + # provide a listener for widgets to request a screen update. QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'openlp_process_events'), self.processEvents) QtCore.QObject.connect(Receiver.get_receiver(), @@ -125,6 +125,8 @@ class OpenLP(QtGui.QApplication): # now kill the splashscreen self.splash.finish(self.mainWindow) log.debug(u'Splashscreen closed') + # make sure Qt really display the splash screen + self.processEvents() self.mainWindow.repaint() self.processEvents() if not has_run_wizard: diff --git a/openlp/core/lib/__init__.py b/openlp/core/lib/__init__.py index 7fbd5243c..cc2c170e5 100644 --- a/openlp/core/lib/__init__.py +++ b/openlp/core/lib/__init__.py @@ -233,9 +233,9 @@ def check_directory_exists(dir): except IOError: pass +from eventreceiver import Receiver from listwidgetwithdnd import ListWidgetWithDnD from displaytags import DisplayTags -from eventreceiver import Receiver from spelltextedit import SpellTextEdit from settingsmanager import SettingsManager from plugin import PluginStatus, StringContent, Plugin diff --git a/openlp/core/lib/listwidgetwithdnd.py b/openlp/core/lib/listwidgetwithdnd.py index 48793c12e..69bd67fdd 100644 --- a/openlp/core/lib/listwidgetwithdnd.py +++ b/openlp/core/lib/listwidgetwithdnd.py @@ -27,8 +27,12 @@ """ Extend QListWidget to handle drag and drop functionality """ +import os.path + from PyQt4 import QtCore, QtGui +from openlp.core.lib import Receiver + class ListWidgetWithDnD(QtGui.QListWidget): """ Provide a list widget to store objects and handle drag and drop events @@ -41,6 +45,13 @@ class ListWidgetWithDnD(QtGui.QListWidget): self.mimeDataText = name assert(self.mimeDataText) + def activateDnD(self): + """ + Activate DnD of widget + """ + self.setAcceptDrops(True) + self.setDragDropMode(QtGui.QAbstractItemView.DragDrop) + def mouseMoveEvent(self, event): """ Drag and drop event does not care what data is selected @@ -58,3 +69,33 @@ class ListWidgetWithDnD(QtGui.QListWidget): 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() + for url in event.mimeData().urls(): + if os.path.isfile(url.toLocalFile()): + Receiver.send_message(u'%s_dnd' % self.mimeDataText, + url.toLocalFile()) + else: + event.ignore() diff --git a/openlp/core/lib/mediamanageritem.py b/openlp/core/lib/mediamanageritem.py index 66bf89f49..2b2e8c6e3 100644 --- a/openlp/core/lib/mediamanageritem.py +++ b/openlp/core/lib/mediamanageritem.py @@ -252,7 +252,6 @@ class MediaManagerItem(QtGui.QWidget): self.listView.setSelectionMode( QtGui.QAbstractItemView.ExtendedSelection) self.listView.setAlternatingRowColors(True) - self.listView.setDragEnabled(True) self.listView.setObjectName(u'%sListView' % self.plugin.name) # Add to pageLayout self.pageLayout.addWidget(self.listView) @@ -339,27 +338,57 @@ class MediaManagerItem(QtGui.QWidget): log.info(u'New files(s) %s', unicode(files)) if files: Receiver.send_message(u'cursor_busy') - names = [] - for count in range(0, self.listView.count()): - names.append(self.listView.item(count).text()) - newFiles = [] - for file in files: - filename = os.path.split(unicode(file))[1] - if filename in names: - critical_error_message_box( - UiStrings().Duplicate, - unicode(translate('OpenLP.MediaManagerItem', - 'Duplicate filename %s.\nThis filename is already in ' - 'the list')) % filename) - else: - newFiles.append(file) - self.loadList(newFiles) - lastDir = os.path.split(unicode(files[0]))[0] - SettingsManager.set_last_dir(self.settingsSection, lastDir) - SettingsManager.set_list(self.settingsSection, - self.settingsSection, self.getFileList()) + self.validateAndLoad(files) Receiver.send_message(u'cursor_normal') + def loadFile(self, filename): + """ + Turn file from Drag and Drop into a array so the Validate code + can runn it. + + ``filename`` + The file to be loaded + """ + filename = unicode(filename) + type = filename.split(u'.')[-1] + if type.lower() not in self.onNewFileMasks: + critical_error_message_box( + translate('OpenLP.MediaManagerItem', + 'Invalid File Type'), + unicode(translate('OpenLP.MediaManagerItem', + 'Invalid File %s.\nSuffix not supported')) + % filename) + else: + self.validateAndLoad([filename]) + + def validateAndLoad(self, files): + """ + Process a list for files either from the File Dialog or from Drag and + Drop + + ``files`` + The files to be loaded + """ + names = [] + for count in range(0, self.listView.count()): + names.append(self.listView.item(count).text()) + newFiles = [] + for file in files: + filename = os.path.split(unicode(file))[1] + if filename in names: + critical_error_message_box( + UiStrings().Duplicate, + unicode(translate('OpenLP.MediaManagerItem', + 'Duplicate filename %s.\nThis filename is already in ' + 'the list')) % filename) + else: + newFiles.append(file) + self.loadList(newFiles) + lastDir = os.path.split(unicode(files[0]))[0] + SettingsManager.set_last_dir(self.settingsSection, lastDir) + SettingsManager.set_list(self.settingsSection, + self.settingsSection, self.getFileList()) + def contextMenu(self, point): item = self.listView.itemAt(point) # Decide if we have to show the context menu or not. diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py index 351e5bbc6..6d86097f2 100644 --- a/openlp/core/ui/servicemanager.py +++ b/openlp/core/ui/servicemanager.py @@ -1239,7 +1239,14 @@ class ServiceManager(QtGui.QWidget): Handle of the event pint passed """ link = event.mimeData() - if link.hasText(): + if event.mimeData().hasUrls(): + event.setDropAction(QtCore.Qt.CopyAction) + event.accept() + for url in event.mimeData().urls(): + filename = unicode(url.toLocalFile()) + if filename.endswith(u'.osz'): + self.loadFile(filename) + elif event.mimeData().hasText(): plugin = unicode(event.mimeData().text()) item = self.serviceManagerList.itemAt(event.pos()) # ServiceManager started the drag and drop diff --git a/openlp/plugins/images/lib/mediaitem.py b/openlp/plugins/images/lib/mediaitem.py index 3c4489bbc..09811ead7 100644 --- a/openlp/plugins/images/lib/mediaitem.py +++ b/openlp/plugins/images/lib/mediaitem.py @@ -52,6 +52,10 @@ class ImageMediaItem(MediaManagerItem): self.hasSearch = True QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'live_theme_changed'), self.liveThemeChanged) + # Allow DnD from the desktop + self.listView.activateDnD() + QtCore.QObject.connect(Receiver.get_receiver(), + QtCore.SIGNAL(u'images_dnd'), self.loadFile) def retranslateUi(self): self.onNewPrompt = translate('ImagePlugin.MediaItem', @@ -131,6 +135,7 @@ class ImageMediaItem(MediaManagerItem): icon = self.iconFromFile(imageFile, thumb) item_name = QtGui.QListWidgetItem(filename) item_name.setIcon(icon) + item_name.setToolTip(imageFile) item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(imageFile)) self.listView.addItem(item_name) if not initialLoad: diff --git a/openlp/plugins/media/lib/mediaitem.py b/openlp/plugins/media/lib/mediaitem.py index 77f91a529..54682dbf6 100644 --- a/openlp/plugins/media/lib/mediaitem.py +++ b/openlp/plugins/media/lib/mediaitem.py @@ -39,6 +39,8 @@ from PyQt4.phonon import Phonon log = logging.getLogger(__name__) +CLAPPERBOARD = QtGui.QPixmap(u':/media/media_video.png').toImage() + class MediaMediaItem(MediaManagerItem): """ This is the custom media manager item for Media Slides. @@ -48,8 +50,7 @@ class MediaMediaItem(MediaManagerItem): def __init__(self, parent, plugin, icon): self.IconPath = u'images/image' self.background = False - self.PreviewFunction = QtGui.QPixmap( - u':/media/media_video.png').toImage() + self.PreviewFunction = CLAPPERBOARD MediaManagerItem.__init__(self, parent, plugin, icon) self.singleServiceItem = False self.hasSearch = True @@ -60,6 +61,10 @@ class MediaMediaItem(MediaManagerItem): QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'openlp_phonon_creation'), self.createPhonon) + # Allow DnD from the desktop + self.listView.activateDnD() + QtCore.QObject.connect(Receiver.get_receiver(), + QtCore.SIGNAL(u'media_dnd'), self.loadFile) def retranslateUi(self): self.onNewPrompt = translate('MediaPlugin.MediaItem', 'Select Media') @@ -201,17 +206,17 @@ class MediaMediaItem(MediaManagerItem): SettingsManager.set_list(self.settingsSection, u'media', self.getFileList()) - def loadList(self, files): + def loadList(self, media): # Sort the themes by its filename considering language specific # characters. lower() is needed for windows! - files.sort(cmp=locale.strcoll, + media.sort(cmp=locale.strcoll, key=lambda filename: os.path.split(unicode(filename))[1].lower()) - for file in files: - filename = os.path.split(unicode(file))[1] + for track in media: + filename = os.path.split(unicode(track))[1] item_name = QtGui.QListWidgetItem(filename) - img = QtGui.QPixmap(u':/media/media_video.png').toImage() - item_name.setIcon(build_icon(img)) - item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(file)) + item_name.setIcon(build_icon(CLAPPERBOARD)) + item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(track)) + item_name.setToolTip(track) self.listView.addItem(item_name) def createPhonon(self): diff --git a/openlp/plugins/presentations/lib/mediaitem.py b/openlp/plugins/presentations/lib/mediaitem.py index 07b490d83..abd597c6c 100644 --- a/openlp/plugins/presentations/lib/mediaitem.py +++ b/openlp/plugins/presentations/lib/mediaitem.py @@ -58,6 +58,10 @@ class PresentationMediaItem(MediaManagerItem): self.hasSearch = True QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'mediaitem_presentation_rebuild'), self.rebuild) + # Allow DnD from the desktop + self.listView.activateDnD() + QtCore.QObject.connect(Receiver.get_receiver(), + QtCore.SIGNAL(u'presentations_dnd'), self.loadFile) def retranslateUi(self): """ @@ -205,6 +209,7 @@ class PresentationMediaItem(MediaManagerItem): item_name = QtGui.QListWidgetItem(filename) item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(file)) item_name.setIcon(icon) + item_name.setToolTip(file) self.listView.addItem(item_name) Receiver.send_message(u'cursor_normal') if not initialLoad: