diff --git a/documentation/api/source/plugins/remotes.rst b/documentation/api/source/plugins/remotes.rst index 0bcd37119..0bb05b8b9 100644 --- a/documentation/api/source/plugins/remotes.rst +++ b/documentation/api/source/plugins/remotes.rst @@ -17,3 +17,9 @@ Helper Classes & Functions .. automodule:: openlp.plugins.remotes.lib :members: + +.. autoclass:: openlp.plugins.remotes.lib.httpserver.HttpConnection + :members: + +.. autoclass:: openlp.plugins.remotes.lib.httpserver.HttpResponse + :members: diff --git a/openlp/core/lib/serviceitem.py b/openlp/core/lib/serviceitem.py index 2d7f542d6..b360ab13d 100644 --- a/openlp/core/lib/serviceitem.py +++ b/openlp/core/lib/serviceitem.py @@ -62,7 +62,7 @@ class ItemCapabilities(object): AddIfNewItem = 9 ProvidesOwnDisplay = 10 AllowsDetailedTitleDisplay = 11 - AllowsVarableStartTime = 12 + AllowsVariableStartTime = 12 class ServiceItem(object): @@ -447,4 +447,4 @@ class ServiceItem(object): elif not start and end: return end else: - return u'%s : %s' % (start, end) + return u'%s : %s' % (start, end) \ No newline at end of file diff --git a/openlp/core/ui/firsttimeform.py b/openlp/core/ui/firsttimeform.py index 08e240b5c..708571f8d 100644 --- a/openlp/core/ui/firsttimeform.py +++ b/openlp/core/ui/firsttimeform.py @@ -160,6 +160,16 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard): self._performWizard() self._postWizard() + def _getFileSize(self, url): + site = urllib.urlopen(url) + meta = site.info() + return int(meta.getheaders("Content-Length")[0]) + + def _downloadProgress(self, count, block_size, total_size): + increment = (count * block_size) - self.previous_size + self._incrementProgressBar(None, increment) + self.previous_size = count * block_size + def _incrementProgressBar(self, status_text, increment=1): """ Update the wizard progress page. @@ -184,19 +194,27 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard): max_progress = 2 # Loop through the songs list and increase for each selected item for i in xrange(self.songsListWidget.count()): - if self.songsListWidget.item(i).checkState() == QtCore.Qt.Checked: - max_progress += 1 + item = self.songsListWidget.item(i) + if item.checkState() == QtCore.Qt.Checked: + filename = item.data(QtCore.Qt.UserRole).toString() + size = self._getFileSize(u'%s%s' % (self.web, filename)) + max_progress += size # Loop through the Bibles list and increase for each selected item iterator = QtGui.QTreeWidgetItemIterator(self.biblesTreeWidget) while iterator.value(): item = iterator.value() if item.parent() and item.checkState(0) == QtCore.Qt.Checked: - max_progress += 1 + filename = item.data(0, QtCore.Qt.UserRole).toString() + size = self._getFileSize(u'%s%s' % (self.web, filename)) + max_progress += size iterator += 1 # Loop through the themes list and increase for each selected item for i in xrange(self.themesListWidget.count()): - if self.themesListWidget.item(i).checkState() == QtCore.Qt.Checked: - max_progress += 1 + item = self.themesListWidget.item(i) + if item.checkState() == QtCore.Qt.Checked: + filename = item.data(QtCore.Qt.UserRole).toString() + size = self._getFileSize(u'%s%s' % (self.web, filename)) + max_progress += size self.finishButton.setVisible(False) self.progressBar.setValue(0) self.progressBar.setMinimum(0) @@ -241,27 +259,33 @@ class FirstTimeForm(QtGui.QWizard, Ui_FirstTimeWizard): item = self.songsListWidget.item(i) if item.checkState() == QtCore.Qt.Checked: filename = item.data(QtCore.Qt.UserRole).toString() - self._incrementProgressBar(self.downloading % filename) + self._incrementProgressBar(self.downloading % filename, 0) + self.previous_size = 0 destination = os.path.join(songs_destination, unicode(filename)) - urllib.urlretrieve(u'%s%s' % (self.web, filename), destination) + urllib.urlretrieve(u'%s%s' % (self.web, filename), destination, + self._downloadProgress) # Download Bibles bibles_iterator = QtGui.QTreeWidgetItemIterator(self.biblesTreeWidget) while bibles_iterator.value(): item = bibles_iterator.value() if item.parent() and item.checkState(0) == QtCore.Qt.Checked: bible = unicode(item.data(0, QtCore.Qt.UserRole).toString()) - self._incrementProgressBar(self.downloading % bible) + self._incrementProgressBar(self.downloading % bible, 0) + self.previous_size = 0 urllib.urlretrieve(u'%s%s' % (self.web, bible), - os.path.join(bibles_destination, bible)) + os.path.join(bibles_destination, bible), + self._downloadProgress) bibles_iterator += 1 # Download themes for i in xrange(self.themesListWidget.count()): item = self.themesListWidget.item(i) if item.checkState() == QtCore.Qt.Checked: theme = unicode(item.data(QtCore.Qt.UserRole).toString()) - self._incrementProgressBar(self.downloading % theme) + self._incrementProgressBar(self.downloading % theme, 0) + self.previous_size = 0 urllib.urlretrieve(u'%s%s' % (self.web, theme), - os.path.join(themes_destination, theme)) + os.path.join(themes_destination, theme), + self._downloadProgress) # Set Default Display if self.displayComboBox.currentIndex() != -1: QtCore.QSettings().setValue(u'General/monitor', diff --git a/openlp/core/ui/generaltab.py b/openlp/core/ui/generaltab.py index e705d5ec3..1dbbb3559 100644 --- a/openlp/core/ui/generaltab.py +++ b/openlp/core/ui/generaltab.py @@ -237,6 +237,12 @@ class GeneralTab(SettingsTab): # Reload the tab, as the screen resolution/count may have changed. QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'config_screen_changed'), self.load) + # Remove for now + self.usernameLabel.setVisible(False) + self.usernameEdit.setVisible(False) + self.passwordLabel.setVisible(False) + self.passwordEdit.setVisible(False) + def retranslateUi(self): """ diff --git a/openlp/core/ui/maindisplay.py b/openlp/core/ui/maindisplay.py index 79d3890a9..76c891636 100644 --- a/openlp/core/ui/maindisplay.py +++ b/openlp/core/ui/maindisplay.py @@ -153,7 +153,7 @@ class MainDisplay(DisplayWidget): self.initialFrame = QtGui.QImage( self.screens.current[u'size'].width(), self.screens.current[u'size'].height(), - QtGui.QImage.Format_ARGB32_Premultiplied) + QtGui.QImage.Format_ARGB32_Premultiplied) painter_image = QtGui.QPainter() painter_image.begin(self.initialFrame) painter_image.fillRect(self.initialFrame.rect(), background_color) @@ -166,7 +166,7 @@ class MainDisplay(DisplayWidget): serviceItem.bg_image_bytes = image_to_byte(self.initialFrame) self.webView.setHtml(build_html(serviceItem, self.screen, self.alertTab, self.isLive, None)) - self.__hideMouse() + self.__hideMouse() # To display or not to display? if not self.screen[u'primary']: self.show() @@ -199,7 +199,7 @@ class MainDisplay(DisplayWidget): `slide` The slide text to be displayed """ - log.debug(u'alert to display') + log.debug(u'alert to display') if self.height() != self.screen[u'size'].height() \ or not self.isVisible() or self.videoWidget.isVisible(): shrink = True @@ -434,7 +434,14 @@ class MainDisplay(DisplayWidget): if self.hideMode: self.hideDisplay(self.hideMode) else: - self.setVisible(True) + # Single screen active + if self.screens.monitor_number == 0: + # Only make visible if setting enabled + if QtCore.QSettings().value(u'general/display on monitor', + QtCore.QVariant(True)).toBool(): + self.setVisible(True) + else: + self.setVisible(True) preview = QtGui.QImage(self.screen[u'size'].width(), self.screen[u'size'].height(), QtGui.QImage.Format_ARGB32_Premultiplied) diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index 06b809a20..294cca49b 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -217,8 +217,6 @@ class Ui_MainWindow(object): self.ModeDefaultItem.setChecked(True) self.ToolsAddToolItem = icon_action(mainWindow, u'ToolsAddToolItem', u':/tools/tools_add.png') - # Hide the entry, as it does not have any functionality yet. - self.ToolsAddToolItem.setVisible(False) mainWindow.actionList.add_action(self.ToolsAddToolItem, u'Tools') self.ToolsOpenDataFolder = icon_action(mainWindow, u'ToolsOpenDataFolder', u':/general/general_open.png') @@ -300,6 +298,13 @@ class Ui_MainWindow(object): QtCore.QObject.connect(self.FileExitItem, QtCore.SIGNAL(u'triggered()'), mainWindow.close) QtCore.QMetaObject.connectSlotsByName(mainWindow) + # Hide the entry, as it does not have any functionality yet. + self.ToolsAddToolItem.setVisible(False) + self.ImportLanguageItem.setVisible(False) + self.ExportLanguageItem.setVisible(False) + self.SettingsShortcutsItem.setVisible(False) + self.HelpDocumentationItem.setVisible(False) + self.HelpOnlineHelpItem.setVisible(False) def retranslateUi(self, mainWindow): """ diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py index fa2bc50f5..56aa1bea1 100644 --- a/openlp/core/ui/servicemanager.py +++ b/openlp/core/ui/servicemanager.py @@ -49,6 +49,19 @@ class ServiceManagerList(QtGui.QTreeWidget): QtGui.QTreeWidget.__init__(self, parent) self.mainwindow = mainwindow + def keyPressEvent(self, event): + if isinstance(event, QtGui.QKeyEvent): + # here accept the event and do something + if event.key() == QtCore.Qt.Key_Up: + self.mainwindow.onMoveSelectionUp() + event.accept() + elif event.key() == QtCore.Qt.Key_Down: + self.mainwindow.onMoveSelectionDown() + event.accept() + event.ignore() + else: + event.ignore() + def mouseMoveEvent(self, event): """ Drag and drop event does not care what data is selected @@ -197,13 +210,13 @@ class ServiceManager(QtGui.QWidget): u':/services/service_expand_all.png', translate('OpenLP.ServiceManager', 'Expand all the service items.'), - self.onExpandAll) + self.onExpandAll, shortcut=QtCore.Qt.Key_Plus) self.serviceManagerList.collapse = self.orderToolbar.addToolbarButton( translate('OpenLP.ServiceManager', '&Collapse all'), u':/services/service_collapse_all.png', translate('OpenLP.ServiceManager', 'Collapse all the service items.'), - self.onCollapseAll) + self.onCollapseAll, shortcut=QtCore.Qt.Key_Minus) self.orderToolbar.addSeparator() self.serviceManagerList.makeLive = self.orderToolbar.addToolbarButton( translate('OpenLP.ServiceManager', 'Go Live'), @@ -293,7 +306,9 @@ class ServiceManager(QtGui.QWidget): self.serviceManagerList.moveTop, self.serviceManagerList.moveBottom, self.serviceManagerList.up, - self.serviceManagerList.down + self.serviceManagerList.down, + self.serviceManagerList.expand, + self.serviceManagerList.collapse ]) self.configUpdated() @@ -306,6 +321,9 @@ class ServiceManager(QtGui.QWidget): actionList.add_action(self.serviceManagerList.makeLive, u'Service') actionList.add_action(self.serviceManagerList.up, u'Service') actionList.add_action(self.serviceManagerList.down, u'Service') + actionList.add_action(self.serviceManagerList.expand, u'Service') + actionList.add_action(self.serviceManagerList.collapse, u'Service') + def setModified(self, modified=True): """ @@ -600,7 +618,7 @@ class ServiceManager(QtGui.QWidget): if item.parent() is None: self.notesAction.setVisible(True) if serviceItem[u'service_item']\ - .is_capable(ItemCapabilities.AllowsVarableStartTime): + .is_capable(ItemCapabilities.AllowsVariableStartTime): self.timeAction.setVisible(True) self.themeMenu.menuAction().setVisible(False) if serviceItem[u'service_item'].is_text(): @@ -887,7 +905,7 @@ class ServiceManager(QtGui.QWidget): child.setText(0, text[:40]) child.setData(0, QtCore.Qt.UserRole, QtCore.QVariant(count)) if item[u'service_item'] \ - .is_capable(ItemCapabilities.AllowsVarableStartTime): + .is_capable(ItemCapabilities.AllowsVariableStartTime): tip = item[u'service_item'].get_media_time() if tip: child.setToolTip(0, tip) @@ -1238,4 +1256,4 @@ class ServiceManager(QtGui.QWidget): Print a Service Order Sheet. """ settingDialog = PrintServiceForm(self.mainwindow, self) - settingDialog.exec_() + settingDialog.exec_() \ No newline at end of file diff --git a/openlp/plugins/bibles/bibleplugin.py b/openlp/plugins/bibles/bibleplugin.py index 61bca84aa..e4dd2f768 100644 --- a/openlp/plugins/bibles/bibleplugin.py +++ b/openlp/plugins/bibles/bibleplugin.py @@ -50,7 +50,8 @@ class BiblePlugin(Plugin): self.manager = BibleManager(self) Plugin.initialise(self) self.importBibleItem.setVisible(True) - self.exportBibleItem.setVisible(True) + # Set to invisible until we can export bibles + self.exportBibleItem.setVisible(False) def finalise(self): """ diff --git a/openlp/plugins/media/lib/mediaitem.py b/openlp/plugins/media/lib/mediaitem.py index 40ea7abb1..9511fabee 100644 --- a/openlp/plugins/media/lib/mediaitem.py +++ b/openlp/plugins/media/lib/mediaitem.py @@ -132,14 +132,18 @@ class MediaMediaItem(MediaManagerItem): self.mediaObject.play() service_item.title = unicode(self.plugin.nameStrings[u'singular']) service_item.add_capability(ItemCapabilities.RequiresMedia) - service_item.add_capability(ItemCapabilities.AllowsVarableStartTime) # force a nonexistent theme service_item.theme = -1 frame = u':/media/image_clapperboard.png' (path, name) = os.path.split(filename) - while not self.mediaState: - Receiver.send_message(u'openlp_process_events') - service_item.media_length = self.mediaLength + file_size = os.path.getsize(filename) + # File too big for processing + if file_size <= 52428800: # 50MiB + while not self.mediaState: + Receiver.send_message(u'openlp_process_events') + service_item.media_length = self.mediaLength + service_item.add_capability( + ItemCapabilities.AllowsVariableStartTime) service_item.add_from_command(path, name, frame) return True else: @@ -185,4 +189,4 @@ class MediaMediaItem(MediaManagerItem): if newState == Phonon.PlayingState: self.mediaState = newState self.mediaLength = self.mediaObject.totalTime()/1000 - self.mediaObject.stop() + self.mediaObject.stop() \ No newline at end of file diff --git a/openlp/plugins/media/mediaplugin.py b/openlp/plugins/media/mediaplugin.py index 06936cd44..683875e95 100644 --- a/openlp/plugins/media/mediaplugin.py +++ b/openlp/plugins/media/mediaplugin.py @@ -49,11 +49,13 @@ class MediaPlugin(Plugin): u'audio/ac3': [u'.ac3'], u'audio/flac': [u'.flac'], u'audio/x-m4a': [u'.m4a'], + u'audio/midi': [u'.mid', u'.midi'], u'audio/x-mp3': [u'.mp3'], u'audio/mpeg': [u'.mp3', u'.mp2', u'.mpga', u'.mpega', u'.m4a'], u'audio/qcelp': [u'.qcp'], u'audio/x-wma': [u'.wma'], u'audio/x-ms-wma': [u'.wma'], + u'video/x-flv': [u'.flv'], u'video/x-matroska': [u'.mpv', u'.mkv'], u'video/x-wmv': [u'.wmv'], u'video/x-ms-wmv': [u'.wmv']} diff --git a/openlp/plugins/remotes/__init__.py b/openlp/plugins/remotes/__init__.py index b5077f435..70445293a 100644 --- a/openlp/plugins/remotes/__init__.py +++ b/openlp/plugins/remotes/__init__.py @@ -26,4 +26,68 @@ """ The :mod:`remotes` plugin allows OpenLP to be controlled from another machine over a network connection. + +Routes: + +``/`` + Go to the web interface. + +``/files/{filename}`` + Serve a static file. + +``/api/poll`` + Poll to see if there are any changes. Returns a JSON-encoded dict of + any changes that occurred:: + + {"results": {"type": "controller"}} + + Or, if there were no results, False:: + + {"results": False} + +``/api/controller/{live|preview}/{action}`` + Perform ``{action}`` on the live or preview controller. Valid actions + are: + + ``next`` + Load the next slide. + + ``previous`` + Load the previous slide. + + ``jump`` + Jump to a specific slide. Requires an id return in a JSON-encoded + dict like so:: + + {"request": {"id": 1}} + + ``first`` + Load the first slide. + + ``last`` + Load the last slide. + + ``text`` + Request the text of the current slide. + +``/api/service/{action}`` + Perform ``{action}`` on the service manager (e.g. go live). Data is + passed as a json-encoded ``data`` parameter. Valid actions are: + + ``next`` + Load the next item in the service. + + ``previous`` + Load the previews item in the service. + + ``jump`` + Jump to a specific item in the service. Requires an id returned in + a JSON-encoded dict like so:: + + {"request": {"id": 1}} + + ``list`` + Request a list of items in the service. + + """ diff --git a/openlp/plugins/remotes/html/images/ajax-loader.png b/openlp/plugins/remotes/html/images/ajax-loader.png new file mode 100644 index 000000000..811a2cdd1 Binary files /dev/null and b/openlp/plugins/remotes/html/images/ajax-loader.png differ diff --git a/openlp/plugins/remotes/html/images/form-check-off.png b/openlp/plugins/remotes/html/images/form-check-off.png new file mode 100644 index 000000000..54e2fe0f8 Binary files /dev/null and b/openlp/plugins/remotes/html/images/form-check-off.png differ diff --git a/openlp/plugins/remotes/html/images/form-check-on.png b/openlp/plugins/remotes/html/images/form-check-on.png new file mode 100644 index 000000000..e6daaaf8b Binary files /dev/null and b/openlp/plugins/remotes/html/images/form-check-on.png differ diff --git a/openlp/plugins/remotes/html/images/form-radio-off.png b/openlp/plugins/remotes/html/images/form-radio-off.png new file mode 100644 index 000000000..32bd43392 Binary files /dev/null and b/openlp/plugins/remotes/html/images/form-radio-off.png differ diff --git a/openlp/plugins/remotes/html/images/form-radio-on.png b/openlp/plugins/remotes/html/images/form-radio-on.png new file mode 100644 index 000000000..ddc404970 Binary files /dev/null and b/openlp/plugins/remotes/html/images/form-radio-on.png differ diff --git a/openlp/plugins/remotes/html/images/icon-search-black.png b/openlp/plugins/remotes/html/images/icon-search-black.png new file mode 100644 index 000000000..5721120f8 Binary files /dev/null and b/openlp/plugins/remotes/html/images/icon-search-black.png differ diff --git a/openlp/plugins/remotes/html/images/icons-18-black.png b/openlp/plugins/remotes/html/images/icons-18-black.png new file mode 100644 index 000000000..3657baea8 Binary files /dev/null and b/openlp/plugins/remotes/html/images/icons-18-black.png differ diff --git a/openlp/plugins/remotes/html/images/icons-18-white.png b/openlp/plugins/remotes/html/images/icons-18-white.png new file mode 100644 index 000000000..ccca7b44b Binary files /dev/null and b/openlp/plugins/remotes/html/images/icons-18-white.png differ diff --git a/openlp/plugins/remotes/html/images/icons-36-black.png b/openlp/plugins/remotes/html/images/icons-36-black.png new file mode 100644 index 000000000..79b6d601b Binary files /dev/null and b/openlp/plugins/remotes/html/images/icons-36-black.png differ diff --git a/openlp/plugins/remotes/html/images/icons-36-white.png b/openlp/plugins/remotes/html/images/icons-36-white.png new file mode 100644 index 000000000..e1b9c04ea Binary files /dev/null and b/openlp/plugins/remotes/html/images/icons-36-white.png differ diff --git a/openlp/plugins/remotes/html/images/ui-icon-blank.png b/openlp/plugins/remotes/html/images/ui-icon-blank.png new file mode 100644 index 000000000..a685fe537 Binary files /dev/null and b/openlp/plugins/remotes/html/images/ui-icon-blank.png differ diff --git a/openlp/plugins/remotes/html/images/ui-icon-unblank.png b/openlp/plugins/remotes/html/images/ui-icon-unblank.png new file mode 100644 index 000000000..590361f44 Binary files /dev/null and b/openlp/plugins/remotes/html/images/ui-icon-unblank.png differ diff --git a/openlp/plugins/remotes/html/index.html b/openlp/plugins/remotes/html/index.html index 94bb24d32..bb3352f1f 100644 --- a/openlp/plugins/remotes/html/index.html +++ b/openlp/plugins/remotes/html/index.html @@ -1,57 +1,73 @@ - - -
- -Quick Links: Service Manager | Slide Controller | Miscellaneous
-(Click service item to go live.)
- -(Click verse to display.)
- -