diff --git a/openlp/core/lib/__init__.py b/openlp/core/lib/__init__.py index 687c49094..cc2a2d9ae 100644 --- a/openlp/core/lib/__init__.py +++ b/openlp/core/lib/__init__.py @@ -37,6 +37,7 @@ log = logging.getLogger(__name__) base_html_expands = [] +# Hex Color tags from http://www.w3schools.com/html/html_colornames.asp base_html_expands.append({u'desc': u'Red', u'start tag': u'{r}', u'start html': u'', u'end tag': u'{/r}', u'end html': u'', u'protected': True}) @@ -53,13 +54,13 @@ base_html_expands.append({u'desc': u'Green', u'start tag': u'{g}', u'start html': u'', u'end tag': u'{/g}', u'end html': u'', u'protected': True}) base_html_expands.append({u'desc': u'Pink', u'start tag': u'{pk}', - u'start html': u'', + u'start html': u'', u'end tag': u'{/pk}', u'end html': u'', u'protected': True}) base_html_expands.append({u'desc': u'Orange', u'start tag': u'{o}', - u'start html': u'', + u'start html': u'', u'end tag': u'{/o}', u'end html': u'', u'protected': True}) base_html_expands.append({u'desc': u'Purple', u'start tag': u'{pp}', - u'start html': u'', + u'start html': u'', u'end tag': u'{/pp}', u'end html': u'', u'protected': True}) base_html_expands.append({u'desc': u'White', u'start tag': u'{w}', u'start html': u'', diff --git a/openlp/core/lib/mediamanageritem.py b/openlp/core/lib/mediamanageritem.py index 8b63963a0..e5e8ed3b1 100644 --- a/openlp/core/lib/mediamanageritem.py +++ b/openlp/core/lib/mediamanageritem.py @@ -34,7 +34,7 @@ from PyQt4 import QtCore, QtGui from openlp.core.lib import SettingsManager, OpenLPToolbar, ServiceItem, \ StringContent, build_icon, translate, Receiver, ListWidgetWithDnD from openlp.core.lib.ui import UiStrings, context_menu_action, \ - context_menu_separator + context_menu_separator, critical_error_message_box log = logging.getLogger(__name__) @@ -333,7 +333,21 @@ class MediaManagerItem(QtGui.QWidget): log.info(u'New files(s) %s', unicode(files)) if files: Receiver.send_message(u'cursor_busy') - self.loadList(files) + 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 file name %s.\nFilename already exists in ' + '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, diff --git a/openlp/core/lib/ui.py b/openlp/core/lib/ui.py index b544efab9..47776a64b 100644 --- a/openlp/core/lib/ui.py +++ b/openlp/core/lib/ui.py @@ -67,6 +67,7 @@ class UiStrings(object): self.Default = unicode(translate('OpenLP.Ui', 'Default')) self.Delete = translate('OpenLP.Ui', '&Delete') self.DisplayStyle = translate('OpenLP.Ui', 'Display style:') + self.Duplicate = translate('OpenLP.Ui', 'Duplicate Error') self.Edit = translate('OpenLP.Ui', '&Edit') self.EmptyField = translate('OpenLP.Ui', 'Empty Field') self.Error = translate('OpenLP.Ui', 'Error') @@ -124,6 +125,7 @@ class UiStrings(object): self.Themes = translate('OpenLP.Ui', 'Themes', 'Plural') self.Tools = translate('OpenLP.Ui', 'Tools') self.Top = translate('OpenLP.Ui', 'Top') + self.UnsupportedFile = translate('OpenLP.Ui', 'Unsupported File') self.VersePerSlide = translate('OpenLP.Ui', 'Verse Per Slide') self.VersePerLine = translate('OpenLP.Ui', 'Verse Per Line') self.Version = translate('OpenLP.Ui', 'Version') diff --git a/openlp/core/ui/shortcutlistdialog.py b/openlp/core/ui/shortcutlistdialog.py index 288086cba..e22bf1241 100644 --- a/openlp/core/ui/shortcutlistdialog.py +++ b/openlp/core/ui/shortcutlistdialog.py @@ -28,6 +28,24 @@ from PyQt4 import QtCore, QtGui from openlp.core.lib import translate, build_icon +class CaptureShortcutButton(QtGui.QPushButton): + """ + A class to encapsulate a ``QPushButton``. + """ + def __init__(self, *args): + QtGui.QPushButton.__init__(self, *args) + self.setCheckable(True) + + def keyPressEvent(self, event): + """ + Block the ``Key_Space`` key, so that the button will not change the + checked state. + """ + if event.key() == QtCore.Qt.Key_Space and self.isChecked(): + # Ignore the event, so that the parent can take care of this. + event.ignore() + + class Ui_ShortcutListDialog(object): def setupUi(self, shortcutListDialog): shortcutListDialog.setObjectName(u'shortcutListDialog') @@ -56,12 +74,11 @@ class Ui_ShortcutListDialog(object): self.detailsLayout.addWidget(self.customRadioButton, 1, 0, 1, 1) self.primaryLayout = QtGui.QHBoxLayout() self.primaryLayout.setObjectName(u'primaryLayout') - self.primaryPushButton = QtGui.QPushButton(shortcutListDialog) + self.primaryPushButton = CaptureShortcutButton(shortcutListDialog) self.primaryPushButton.setObjectName(u'primaryPushButton') self.primaryPushButton.setMinimumSize(QtCore.QSize(84, 0)) self.primaryPushButton.setIcon( build_icon(u':/system/system_configure_shortcuts.png')) - self.primaryPushButton.setCheckable(True) self.primaryLayout.addWidget(self.primaryPushButton) self.clearPrimaryButton = QtGui.QToolButton(shortcutListDialog) self.clearPrimaryButton.setObjectName(u'clearPrimaryButton') @@ -72,9 +89,8 @@ class Ui_ShortcutListDialog(object): self.detailsLayout.addLayout(self.primaryLayout, 1, 1, 1, 1) self.alternateLayout = QtGui.QHBoxLayout() self.alternateLayout.setObjectName(u'alternateLayout') - self.alternatePushButton = QtGui.QPushButton(shortcutListDialog) + self.alternatePushButton = CaptureShortcutButton(shortcutListDialog) self.alternatePushButton.setObjectName(u'alternatePushButton') - self.alternatePushButton.setCheckable(True) self.alternatePushButton.setIcon( build_icon(u':/system/system_configure_shortcuts.png')) self.alternateLayout.addWidget(self.alternatePushButton) diff --git a/openlp/core/ui/shortcutlistform.py b/openlp/core/ui/shortcutlistform.py index 3136c9b1f..8e38ebff5 100644 --- a/openlp/core/ui/shortcutlistform.py +++ b/openlp/core/ui/shortcutlistform.py @@ -71,7 +71,9 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog): QtCore.SIGNAL(u'clicked(bool)'), self.onCustomRadioButtonClicked) def keyPressEvent(self, event): - if self.primaryPushButton.isChecked() or \ + if event.key() == QtCore.Qt.Key_Space: + self.keyReleaseEvent(event) + elif self.primaryPushButton.isChecked() or \ self.alternatePushButton.isChecked(): event.ignore() elif event.key() == QtCore.Qt.Key_Escape: @@ -163,6 +165,7 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog): self.customRadioButton.setChecked(True) if toggled: self.alternatePushButton.setChecked(False) + self.primaryPushButton.setText(u'') return action = self._currentItemAction() if action is None: @@ -181,6 +184,7 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog): self.customRadioButton.setChecked(True) if toggled: self.primaryPushButton.setChecked(False) + self.alternatePushButton.setText(u'') return action = self._currentItemAction() if action is None: @@ -211,10 +215,11 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog): self.primaryPushButton.setChecked(column in [0, 1]) self.alternatePushButton.setChecked(column not in [0, 1]) if column in [0, 1]: + self.primaryPushButton.setText(u'') self.primaryPushButton.setFocus(QtCore.Qt.OtherFocusReason) else: + self.alternatePushButton.setText(u'') self.alternatePushButton.setFocus(QtCore.Qt.OtherFocusReason) - self.onCurrentItemChanged(item) def onCurrentItemChanged(self, item=None, previousItem=None): """ @@ -247,6 +252,12 @@ class ShortcutListForm(QtGui.QDialog, Ui_ShortcutListDialog): elif len(shortcuts) == 2: primary_text = shortcuts[0].toString() alternate_text = shortcuts[1].toString() + # When we are capturing a new shortcut, we do not want, the buttons to + # display the current shortcut. + if self.primaryPushButton.isChecked(): + primary_text = u'' + if self.alternatePushButton.isChecked(): + alternate_text = u'' self.primaryPushButton.setText(primary_text) self.alternatePushButton.setText(alternate_text) self.primaryLabel.setText(primary_label_text) diff --git a/openlp/plugins/bibles/lib/mediaitem.py b/openlp/plugins/bibles/lib/mediaitem.py index c7e1f0bc2..7d21b57c4 100644 --- a/openlp/plugins/bibles/lib/mediaitem.py +++ b/openlp/plugins/bibles/lib/mediaitem.py @@ -72,76 +72,85 @@ class BibleMediaItem(MediaManagerItem): self.hasDeleteIcon = False self.addToServiceItem = False + def addSearchTab(self, prefix, name): + """ + Creates and adds generic search tab. + + ``prefix`` + The prefix of the tab, this is either ``quick`` or ``advanced``. + + ``name`` + The translated string to display. + """ + tab = QtGui.QWidget() + tab.setObjectName(prefix + u'Tab') + layout = QtGui.QGridLayout(tab) + layout.setObjectName(prefix + u'Layout') + versionLabel = QtGui.QLabel(tab) + versionLabel.setObjectName(prefix + u'VersionLabel') + layout.addWidget(versionLabel, 0, 0, QtCore.Qt.AlignRight) + versionComboBox = media_item_combo_box(tab, prefix + u'VersionComboBox') + versionLabel.setBuddy(versionComboBox) + layout.addWidget(versionComboBox, 0, 1, 1, 2) + secondLabel = QtGui.QLabel(tab) + secondLabel.setObjectName(prefix + u'SecondLabel') + layout.addWidget(secondLabel, 1, 0, QtCore.Qt.AlignRight) + secondComboBox = media_item_combo_box(tab, prefix + u'SecondComboBox') + versionLabel.setBuddy(secondComboBox) + layout.addWidget(secondComboBox, 1, 1, 1, 2) + searchButtonLayout = QtGui.QHBoxLayout() + searchButtonLayout.setObjectName(prefix + u'SearchButtonLayout') + searchButtonLayout.addStretch() + searchButton = QtGui.QPushButton(tab) + searchButton.setObjectName(prefix + u'SearchButton') + searchButtonLayout.addWidget(searchButton) + self.searchTabWidget.addTab(tab, name) + setattr(self, prefix + u'Tab', tab) + setattr(self, prefix + u'Layout', layout) + setattr(self, prefix + u'VersionLabel', versionLabel) + setattr(self, prefix + u'VersionComboBox', versionComboBox) + setattr(self, prefix + u'SecondLabel', secondLabel) + setattr(self, prefix + u'SecondComboBox', secondComboBox) + setattr(self, prefix + u'SearchButtonLayout', searchButtonLayout) + setattr(self, prefix + u'SearchButton', searchButton) + def addEndHeaderBar(self): self.searchTabWidget = QtGui.QTabWidget(self) self.searchTabWidget.setSizePolicy( QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Minimum) - self.searchTabWidget.setObjectName(u'SearchTabWidget') + self.searchTabWidget.setObjectName(u'searchTabWidget') # Add the Quick Search tab. - self.quickTab = QtGui.QWidget() - self.quickTab.setObjectName(u'quickTab') - self.quickLayout = QtGui.QFormLayout(self.quickTab) - self.quickLayout.setObjectName(u'quickLayout') - self.quickVersionLabel = QtGui.QLabel(self.quickTab) - self.quickVersionLabel.setObjectName(u'quickVersionLabel') - self.quickVersionComboBox = media_item_combo_box(self.quickTab, - u'quickVersionComboBox') - self.quickVersionLabel.setBuddy(self.quickVersionComboBox) - self.quickLayout.addRow(self.quickVersionLabel, - self.quickVersionComboBox) - self.quickSecondLabel = QtGui.QLabel(self.quickTab) - self.quickSecondLabel.setObjectName(u'quickSecondLabel') - self.quickSecondComboBox = media_item_combo_box(self.quickTab, - u'quickSecondComboBox') - self.quickSecondLabel.setBuddy(self.quickSecondComboBox) - self.quickLayout.addRow(self.quickSecondLabel, self.quickSecondComboBox) + self.addSearchTab( + u'quick', translate('BiblesPlugin.MediaItem', 'Quick')) self.quickSearchLabel = QtGui.QLabel(self.quickTab) self.quickSearchLabel.setObjectName(u'quickSearchLabel') + self.quickLayout.addWidget( + self.quickSearchLabel, 2, 0, QtCore.Qt.AlignRight) self.quickSearchEdit = SearchEdit(self.quickTab) self.quickSearchEdit.setObjectName(u'quickSearchEdit') self.quickSearchLabel.setBuddy(self.quickSearchEdit) - self.quickLayout.addRow(self.quickSearchLabel, self.quickSearchEdit) + self.quickLayout.addWidget(self.quickSearchEdit, 2, 1, 1, 2) self.quickLayoutLabel = QtGui.QLabel(self.quickTab) self.quickLayoutLabel.setObjectName(u'quickClearLabel') + self.quickLayout.addWidget( + self.quickLayoutLabel, 3, 0, QtCore.Qt.AlignRight) self.quickLayoutComboBox = media_item_combo_box(self.quickTab, u'quickLayoutComboBox') self.quickLayoutComboBox.addItems([u'', u'', u'']) - self.quickLayout.addRow(self.quickLayoutLabel, self.quickLayoutComboBox) + self.quickLayout.addWidget(self.quickLayoutComboBox, 3, 1, 1, 2) self.quickClearLabel = QtGui.QLabel(self.quickTab) self.quickClearLabel.setObjectName(u'quickClearLabel') + self.quickLayout.addWidget( + self.quickClearLabel, 4, 0, QtCore.Qt.AlignRight) self.quickClearComboBox = media_item_combo_box(self.quickTab, u'quickClearComboBox') - self.quickLayout.addRow(self.quickClearLabel, self.quickClearComboBox) - self.quickSearchButtonLayout = QtGui.QHBoxLayout() - self.quickSearchButtonLayout.setObjectName(u'quickSearchButtonLayout') - self.quickSearchButtonLayout.addStretch() - self.quickSearchButton = QtGui.QPushButton(self.quickTab) - self.quickSearchButton.setObjectName(u'quickSearchButton') - self.quickSearchButtonLayout.addWidget(self.quickSearchButton) - self.quickLayout.addRow(self.quickSearchButtonLayout) - self.searchTabWidget.addTab(self.quickTab, - translate('BiblesPlugin.MediaItem', 'Quick')) + self.quickLayout.addWidget(self.quickClearComboBox, 4, 1, 1, 2) + self.quickLayout.addLayout(self.quickSearchButtonLayout, 6, 1, 1, 2) + # Add a QWidget, so that the quick tab has as many rows as the advanced + # tab. + self.quickLayout.addWidget(QtGui.QWidget(), 7, 0) # Add the Advanced Search tab. - self.advancedTab = QtGui.QWidget() - self.advancedTab.setObjectName(u'advancedTab') - self.advancedLayout = QtGui.QGridLayout(self.advancedTab) - self.advancedLayout.setObjectName(u'advancedLayout') - self.advancedVersionLabel = QtGui.QLabel(self.advancedTab) - self.advancedVersionLabel.setObjectName(u'advancedVersionLabel') - self.advancedLayout.addWidget(self.advancedVersionLabel, 0, 0, - QtCore.Qt.AlignRight) - self.advancedVersionComboBox = media_item_combo_box(self.advancedTab, - u'advancedVersionComboBox') - self.advancedVersionLabel.setBuddy(self.advancedVersionComboBox) - self.advancedLayout.addWidget(self.advancedVersionComboBox, 0, 1, 1, 2) - self.advancedSecondLabel = QtGui.QLabel(self.advancedTab) - self.advancedSecondLabel.setObjectName(u'advancedSecondLabel') - self.advancedLayout.addWidget(self.advancedSecondLabel, 1, 0, - QtCore.Qt.AlignRight) - self.advancedSecondComboBox = media_item_combo_box(self.advancedTab, - u'advancedSecondComboBox') - self.advancedSecondLabel.setBuddy(self.advancedSecondComboBox) - self.advancedLayout.addWidget(self.advancedSecondComboBox, 1, 1, 1, 2) + self.addSearchTab(u'advanced', UiStrings().Advanced) self.advancedBookLabel = QtGui.QLabel(self.advancedTab) self.advancedBookLabel.setObjectName(u'advancedBookLabel') self.advancedLayout.addWidget(self.advancedBookLabel, 2, 0, @@ -152,7 +161,7 @@ class BibleMediaItem(MediaManagerItem): self.advancedLayout.addWidget(self.advancedBookComboBox, 2, 1, 1, 2) self.advancedChapterLabel = QtGui.QLabel(self.advancedTab) self.advancedChapterLabel.setObjectName(u'advancedChapterLabel') - self.advancedLayout.addWidget(self.advancedChapterLabel, 3, 1) + self.advancedLayout.addWidget(self.advancedChapterLabel, 3, 1, 1, 2) self.advancedVerseLabel = QtGui.QLabel(self.advancedTab) self.advancedVerseLabel.setObjectName(u'advancedVerseLabel') self.advancedLayout.addWidget(self.advancedVerseLabel, 3, 2) @@ -184,16 +193,8 @@ class BibleMediaItem(MediaManagerItem): u'advancedClearComboBox') self.advancedClearLabel.setBuddy(self.advancedClearComboBox) self.advancedLayout.addWidget(self.advancedClearComboBox, 6, 1, 1, 2) - self.advancedSearchButtonLayout = QtGui.QHBoxLayout() - self.advancedSearchButtonLayout.setObjectName( - u'advancedSearchButtonLayout') - self.advancedSearchButtonLayout.addStretch() - self.advancedSearchButton = QtGui.QPushButton(self.advancedTab) - self.advancedSearchButton.setObjectName(u'advancedSearchButton') - self.advancedSearchButtonLayout.addWidget(self.advancedSearchButton) self.advancedLayout.addLayout( self.advancedSearchButtonLayout, 7, 0, 1, 3) - self.searchTabWidget.addTab(self.advancedTab, UiStrings().Advanced) # Add the search tab widget to the page layout. self.pageLayout.addWidget(self.searchTabWidget) # Combo Boxes @@ -213,7 +214,7 @@ class BibleMediaItem(MediaManagerItem): QtCore.SIGNAL(u'activated(int)'), self.updateAutoCompleter) QtCore.QObject.connect( self.quickLayoutComboBox, QtCore.SIGNAL(u'activated(int)'), - self.onlayoutStyleComboBoxChanged) + self.onLayoutStyleComboBoxChanged) # Buttons QtCore.QObject.connect(self.advancedSearchButton, QtCore.SIGNAL(u'pressed()'), self.onAdvancedSearchButton) @@ -844,7 +845,7 @@ class BibleMediaItem(MediaManagerItem): return u'{su}[%s]{/su}' % verse_text return u'{su}%s{/su}' % verse_text - def onlayoutStyleComboBoxChanged(self): + def onLayoutStyleComboBoxChanged(self): self.settings.layout_style = self.quickLayoutComboBox.currentIndex() self.settings.layoutStyleComboBox.setCurrentIndex( self.settings.layout_style) diff --git a/openlp/plugins/images/lib/mediaitem.py b/openlp/plugins/images/lib/mediaitem.py index 68da7fbe1..21b81128d 100644 --- a/openlp/plugins/images/lib/mediaitem.py +++ b/openlp/plugins/images/lib/mediaitem.py @@ -108,7 +108,6 @@ class ImageMediaItem(MediaManagerItem): self.settingsSection, self.getFileList()) def loadList(self, list, initialLoad=False): - Receiver.send_message(u'cursor_busy') if not initialLoad: self.parent.formparent.displayProgressBar(len(list)) for imageFile in list: @@ -127,7 +126,6 @@ class ImageMediaItem(MediaManagerItem): item_name.setIcon(icon) item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(imageFile)) self.listView.addItem(item_name) - Receiver.send_message(u'cursor_normal') if not initialLoad: self.parent.formparent.finishedProgressBar() diff --git a/openlp/plugins/media/lib/mediaitem.py b/openlp/plugins/media/lib/mediaitem.py index e494b9e5e..aa574d029 100644 --- a/openlp/plugins/media/lib/mediaitem.py +++ b/openlp/plugins/media/lib/mediaitem.py @@ -138,10 +138,8 @@ class MediaMediaItem(MediaManagerItem): if not self.mediaStateWait(Phonon.StoppedState): # Due to string freeze, borrow a message from presentations # This will be corrected in 1.9.6 - critical_error_message_box( - translate('PresentationPlugin.MediaItem', 'Unsupported File'), - unicode(translate('PresentationPlugin.MediaItem', - 'Unsupported File'))) + critical_error_message_box(UiStrings().UnsupportedFile, + UiStrings().UnsupportedFile) return False # File too big for processing if os.path.getsize(filename) <= 52428800: # 50MiB @@ -152,15 +150,11 @@ class MediaMediaItem(MediaManagerItem): # Due to string freeze, borrow a message from presentations # This will be corrected in 1.9.6 self.mediaObject.stop() - critical_error_message_box( - translate('PresentationPlugin.MediaItem', - 'Unsupported File'), - unicode(translate('PresentationPlugin.MediaItem', - 'Unsupported File'))) + critical_error_message_box(UiStrings().UnsupportedFile, + UiStrings().UnsupportedFile) return False - self.mediaLength = self.mediaObject.totalTime() / 1000 self.mediaObject.stop() - service_item.media_length = self.mediaLength + service_item.media_length = self.mediaObject.totalTime() / 1000 service_item.add_capability( ItemCapabilities.AllowsVariableStartTime) service_item.title = unicode(self.plugin.nameStrings[u'singular']) diff --git a/openlp/plugins/presentations/lib/mediaitem.py b/openlp/plugins/presentations/lib/mediaitem.py index 22db8f39f..65b85454d 100644 --- a/openlp/plugins/presentations/lib/mediaitem.py +++ b/openlp/plugins/presentations/lib/mediaitem.py @@ -193,9 +193,7 @@ class PresentationMediaItem(MediaManagerItem): if initialLoad: icon = build_icon(u':/general/general_delete.png') else: - critical_error_message_box( - translate('PresentationPlugin.MediaItem', - 'Unsupported File'), + critical_error_message_box(UiStrings().UnsupportedFile, translate('PresentationPlugin.MediaItem', 'This type of presentation is not supported.')) continue @@ -293,7 +291,7 @@ class PresentationMediaItem(MediaManagerItem): "supports" the extension. If none found, then look for a controller which "also supports" it instead. """ - filetype = os.path.splitext(filename)[1] + filetype = os.path.splitext(filename)[1][1:] if not filetype: return None for controller in self.controllers: