Add min user requirement to autoplay, make settings persistent (and settable via INI), and tooltips

This commit is contained in:
Et0h 2015-02-02 00:24:33 +00:00
parent 31c83fbc8a
commit a8275032a2
5 changed files with 141 additions and 37 deletions

View File

@ -11,7 +11,6 @@ from syncplay.messages import getMissingStrings, getMessage
from syncplay.constants import PRIVACY_SENDHASHED_MODE, PRIVACY_DONTSEND_MODE, \ from syncplay.constants import PRIVACY_SENDHASHED_MODE, PRIVACY_DONTSEND_MODE, \
PRIVACY_HIDDENFILENAME PRIVACY_HIDDENFILENAME
import collections import collections
class SyncClientFactory(ClientFactory): class SyncClientFactory(ClientFactory):
def __init__(self, client, retry=constants.RECONNECT_RETRIES): def __init__(self, client, retry=constants.RECONNECT_RETRIES):
self._client = client self._client = client
@ -106,6 +105,7 @@ class SyncplayClient(object):
self._speedChanged = False self._speedChanged = False
self.behindFirstDetected = None self.behindFirstDetected = None
self.autoPlay = False self.autoPlay = False
self.autoPlayThreshold = None
self._warnings = self._WarningManager(self._player, self.userlist, self.ui, self) self._warnings = self._WarningManager(self._player, self.userlist, self.ui, self)
if constants.LIST_RELATIVE_CONFIGS and self._config.has_key('loadedRelativePaths') and self._config['loadedRelativePaths']: if constants.LIST_RELATIVE_CONFIGS and self._config.has_key('loadedRelativePaths') and self._config['loadedRelativePaths']:
@ -319,7 +319,6 @@ class SyncplayClient(object):
self.ui.showMessage(getMessage("current-offset-notification").format(self._userOffset)) self.ui.showMessage(getMessage("current-offset-notification").format(self._userOffset))
def onDisconnect(self): def onDisconnect(self):
self.resetAutoPlayState()
if self._config['pauseOnLeave']: if self._config['pauseOnLeave']:
self.setPaused(True) self.setPaused(True)
self.lastPausedOnLeaveTime = time.time() self.lastPausedOnLeaveTime = time.time()
@ -404,9 +403,10 @@ class SyncplayClient(object):
def getUsername(self): def getUsername(self):
return self.userlist.currentUser.username return self.userlist.currentUser.username
def setRoom(self, roomName): def setRoom(self, roomName, resetAutoplay=False):
self.userlist.currentUser.room = roomName self.userlist.currentUser.room = roomName
self.resetAutoPlayState() if resetAutoplay:
self.resetAutoPlayState()
def sendRoom(self): def sendRoom(self):
room = self.userlist.currentUser.room room = self.userlist.currentUser.room
@ -493,12 +493,16 @@ class SyncplayClient(object):
return wrapper return wrapper
return requireMinVersionDecorator return requireMinVersionDecorator
def changeAutoPlayState(self, newState): def changeAutoplayState(self, newState):
self.autoPlay = newState self.autoPlay = newState
self.autoPlayCheck() self.autoplayCheck()
def autoPlayCheck(self): def changeAutoPlayThrehsold(self, newThreshold):
if self.autoPlay and self.userlist.currentUser.canControl() and self.userlist.isReadinessSupported() and self.userlist.areAllUsersInRoomReady(): self.autoPlayThreshold = newThreshold
self.autoplayCheck()
def autoplayCheck(self):
if self.autoPlay and self.userlist.currentUser.canControl() and self.userlist.isReadinessSupported() and self.userlist.areAllUsersInRoomReady() and self.autoPlayThreshold and self.userlist.usersInRoomCount() >= self.autoPlayThreshold:
self.setPaused(False) self.setPaused(False)
def resetAutoPlayState(self): def resetAutoPlayState(self):
@ -532,7 +536,7 @@ class SyncplayClient(object):
def controlledRoomCreated(self, roomName, controlPassword): def controlledRoomCreated(self, roomName, controlPassword):
self.ui.showMessage(getMessage("created-controlled-room-notification").format(roomName, controlPassword)) self.ui.showMessage(getMessage("created-controlled-room-notification").format(roomName, controlPassword))
self.setRoom(roomName) self.setRoom(roomName, resetAutoplay=True)
self.sendRoom() self.sendRoom()
self._protocol.requestControlledRoom(roomName, controlPassword) self._protocol.requestControlledRoom(roomName, controlPassword)
self.ui.updateRoomName(roomName) self.ui.updateRoomName(roomName)
@ -912,6 +916,13 @@ class SyncplayUserlist(object):
readyCount += 1 readyCount += 1
return readyCount return readyCount
def usersInRoomCount(self):
userCount = 1
for user in self._users.itervalues():
if user.room == self.currentUser.room and user.isReady():
userCount += 1
return userCount
def usersInRoomNotReady(self): def usersInRoomNotReady(self):
notReady = [] notReady = []
if not self.currentUser.isReady(): if not self.currentUser.isReady():
@ -970,7 +981,7 @@ class SyncplayUserlist(object):
self.currentUser.setReady(isReady) self.currentUser.setReady(isReady)
elif self._users.has_key(username): elif self._users.has_key(username):
self._users[username].setReady(isReady) self._users[username].setReady(isReady)
self._client.autoPlayCheck() self._client.autoplayCheck()
def userListChange(self, room = None): def userListChange(self, room = None):
if room is not None and self.isRoomSame(room): if room is not None and self.isRoomSame(room):
@ -994,7 +1005,7 @@ class SyncplayUserlist(object):
rooms[self.currentUser.room].append(self.currentUser) rooms[self.currentUser.room].append(self.currentUser)
rooms = self.sortList(rooms) rooms = self.sortList(rooms)
self.ui.showUserList(self.currentUser, rooms) self.ui.showUserList(self.currentUser, rooms)
self._client.autoPlayCheck() self._client.autoplayCheck()
def clearList(self): def clearList(self):
self._users = {} self._users = {}

View File

@ -219,7 +219,8 @@ en = {
"pause-menu-label" : "Pause", "pause-menu-label" : "Pause",
"playbackbuttons-menu-label" : u"Show playback buttons", "playbackbuttons-menu-label" : u"Show playback buttons",
"autoplay-menu-label" : u"Show auto-play button", "autoplay-menu-label" : u"Show auto-play button",
"autoplay-guipushbuttonlabel" : u"Auto-play when everyone is ready", "autoplay-guipushbuttonlabel" : u"Play when all ready",
"autoplay-minimum-label" : u"Min users:",
"ready-guipushbuttonlabel" : u"I'm ready to watch!", "ready-guipushbuttonlabel" : u"I'm ready to watch!",
@ -304,6 +305,8 @@ en = {
"joinroom-tooltip" : "Leave current room and joins specified room.", "joinroom-tooltip" : "Leave current room and joins specified room.",
"seektime-msgbox-label" : "Jump to specified time (in seconds / min:sec). Use +/- for relative seek.", "seektime-msgbox-label" : "Jump to specified time (in seconds / min:sec). Use +/- for relative seek.",
"ready-tooltip" : "Indicates whether you are ready to watch.",
"autoplay-tooltip" : "Auto-play when all users who have readiness indicator are ready and minimum user threshold met.",
# In-userlist notes (GUI) # In-userlist notes (GUI)
"differentsize-note" : "Different size!", "differentsize-note" : "Different size!",
@ -562,6 +565,7 @@ ru = {
"playbackbuttons-menu-label" : u"Show playback buttons", # TODO: Translate into Russian "playbackbuttons-menu-label" : u"Show playback buttons", # TODO: Translate into Russian
"autoplay-menu-label" : u"Show auto-play button", # TODO: Translate into Russian "autoplay-menu-label" : u"Show auto-play button", # TODO: Translate into Russian
"autoplay-guipushbuttonlabel" : u"Auto-play when everyone is ready", # TODO: Translate into Russian "autoplay-guipushbuttonlabel" : u"Auto-play when everyone is ready", # TODO: Translate into Russian
"autoplay-minimum-label" : u"Min users:", # TODO: Translate into Russian
"ready-guipushbuttonlabel" : u"I'm ready to watch!", # TODO: Translate into Russian "ready-guipushbuttonlabel" : u"I'm ready to watch!", # TODO: Translate into Russian
@ -647,6 +651,8 @@ ru = {
"joinroom-tooltip" : u"Покинуть комнату и зайти в другую, указанную комнату.", "joinroom-tooltip" : u"Покинуть комнату и зайти в другую, указанную комнату.",
"seektime-msgbox-label" : u"Перемотать к определенному моменту времени (указывать в секундах или мин:сек). Используйте +/-, чтобы перемотать вперед/назад относительно настоящего момента.", "seektime-msgbox-label" : u"Перемотать к определенному моменту времени (указывать в секундах или мин:сек). Используйте +/-, чтобы перемотать вперед/назад относительно настоящего момента.",
"ready-tooltip" : "Indicates whether you are ready to watch.", # TODO: Translate into Russian
"autoplay-tooltip" : "Auto-play when all users who have readiness indicator are ready and minimum user threshold met.", # TODO: Translate into Russian
# In-userlist notes (GUI) # In-userlist notes (GUI)
"differentsize-note" : u"Размер файла не совпадает!", "differentsize-note" : u"Размер файла не совпадает!",
@ -903,6 +909,7 @@ de = {
"playbackbuttons-menu-label" : u"Show playback buttons", # TODO: Translate into German "playbackbuttons-menu-label" : u"Show playback buttons", # TODO: Translate into German
"autoplay-menu-label" : u"Show auto-play button", # TODO: Translate into German "autoplay-menu-label" : u"Show auto-play button", # TODO: Translate into German
"autoplay-guipushbuttonlabel" : u"Auto-play when everyone is ready", # TODO: Translate into German "autoplay-guipushbuttonlabel" : u"Auto-play when everyone is ready", # TODO: Translate into German
"autoplay-minimum-label" : u"Min users:", # TODO: Translate into German
"ready-guipushbuttonlabel" : u"I'm ready to watch!", # TODO: Translate into German "ready-guipushbuttonlabel" : u"I'm ready to watch!", # TODO: Translate into German
@ -989,6 +996,8 @@ de = {
"joinroom-tooltip" : u"Den aktuellen Raum verlassen und stattdessen den angegebenen betreten.", "joinroom-tooltip" : u"Den aktuellen Raum verlassen und stattdessen den angegebenen betreten.",
"seektime-msgbox-label" : u"Springe zur angegebenen Zeit (in Sekunden oder min:sek). Verwende +/- zum relativen Springen.", "seektime-msgbox-label" : u"Springe zur angegebenen Zeit (in Sekunden oder min:sek). Verwende +/- zum relativen Springen.",
"ready-tooltip" : "Indicates whether you are ready to watch.", # TODO: Translate into German
"autoplay-tooltip" : "Auto-play when all users who have readiness indicator are ready and minimum user threshold met.", # TODO: Translate into German
# In-userlist notes (GUI) # In-userlist notes (GUI)
"differentsize-note" : u"Verschiedene Größe!", "differentsize-note" : u"Verschiedene Größe!",

View File

@ -45,6 +45,8 @@ class ConfigurationGetter(object):
"filesizePrivacyMode": constants.PRIVACY_SENDRAW_MODE, "filesizePrivacyMode": constants.PRIVACY_SENDRAW_MODE,
"pauseOnLeave": False, "pauseOnLeave": False,
"readyAtStart": False, "readyAtStart": False,
"autoplayInitialState" : None,
"autoplayInitialThreshold" : -1,
"clearGUIData": False, "clearGUIData": False,
"language" : "", "language" : "",
"checkForUpdatesAutomatically" : None, "checkForUpdatesAutomatically" : None,
@ -97,18 +99,20 @@ class ConfigurationGetter(object):
"showDurationNotification" "showDurationNotification"
] ]
self._tristate = [ self._tristate = [
"checkForUpdatesAutomatically" "checkForUpdatesAutomatically",
"autoplayInitialState",
] ]
self._numeric = [ self._numeric = [
"slowdownThreshold", "slowdownThreshold",
"rewindThreshold", "rewindThreshold",
"fastforwardThreshold", "fastforwardThreshold",
"autoplayInitialThreshold",
] ]
self._iniStructure = { self._iniStructure = {
"server_data": ["host", "port", "password"], "server_data": ["host", "port", "password"],
"client_settings": ["name", "room", "playerPath", "slowdownThreshold", "rewindThreshold", "fastforwardThreshold", "slowOnDesync", "rewindOnDesync", "fastforwardOnDesync", "dontSlowDownWithMe", "forceGuiPrompt", "filenamePrivacyMode", "filesizePrivacyMode", "pauseOnLeave", "readyAtStart"], "client_settings": ["name", "room", "playerPath", "slowdownThreshold", "rewindThreshold", "fastforwardThreshold", "slowOnDesync", "rewindOnDesync", "fastforwardOnDesync", "dontSlowDownWithMe", "forceGuiPrompt", "filenamePrivacyMode", "filesizePrivacyMode", "pauseOnLeave", "readyAtStart", "autoplayInitialThreshold", "autoplayInitialState"],
"gui": ["showOSD", "showOSDWarnings", "showSlowdownOSD", "showDifferentRoomOSD", "showSameRoomOSD", "showNonControllerOSD", "showDurationNotification"], "gui": ["showOSD", "showOSDWarnings", "showSlowdownOSD", "showDifferentRoomOSD", "showSameRoomOSD", "showNonControllerOSD", "showDurationNotification"],
"general": ["language", "checkForUpdatesAutomatically", "lastCheckedForUpdates"] "general": ["language", "checkForUpdatesAutomatically", "lastCheckedForUpdates"]
} }

View File

@ -144,7 +144,7 @@ class ConsoleUI(threading.Thread):
else: else:
room = self._syncplayClient.defaultRoom room = self._syncplayClient.defaultRoom
self._syncplayClient.setRoom(room) self._syncplayClient.setRoom(room, resetAutoplay=True)
self._syncplayClient.sendRoom() self._syncplayClient.sendRoom()
elif command.group('command') in constants.COMMANDS_CREATE: elif command.group('command') in constants.COMMANDS_CREATE:
roombasename = command.group('parameter') roombasename = command.group('parameter')

View File

@ -8,6 +8,7 @@ from datetime import datetime
import re import re
import os import os
from syncplay.utils import formatTime, sameFilename, sameFilesize, sameFileduration, RoomPasswordProvider, formatSize from syncplay.utils import formatTime, sameFilename, sameFilesize, sameFileduration, RoomPasswordProvider, formatSize
from functools import wraps
lastCheckedForUpdates = None lastCheckedForUpdates = None
class UserlistItemDelegate(QtGui.QStyledItemDelegate): class UserlistItemDelegate(QtGui.QStyledItemDelegate):
@ -71,14 +72,35 @@ class MainWindow(QtGui.QMainWindow):
QtGui.QSplitterHandle.mouseMoveEvent(self, event) QtGui.QSplitterHandle.mouseMoveEvent(self, event)
self.parent().parent().parent().updateListGeometry() self.parent().parent().parent().updateListGeometry()
def needsClient(f): # @NoSelf
@wraps(f)
def wrapper(self, *args, **kwds):
if not self._syncplayClient:
self.showDebugMessage("Tried to use client before it was ready!")
return
return f(self, *args, **kwds)
return wrapper
def addClient(self, client): def addClient(self, client):
self._syncplayClient = client self._syncplayClient = client
self.roomInput.setText(self._syncplayClient.getRoom()) self.roomInput.setText(self._syncplayClient.getRoom())
self.config = self._syncplayClient.getConfig() self.config = self._syncplayClient.getConfig()
try: try:
self.updateReadyState(self.config['readyAtStart']) self.updateReadyState(self.config['readyAtStart'])
autoplayInitialState = self.config['autoplayInitialState']
if autoplayInitialState is not None:
self.autoplayPushButton.blockSignals(True)
self.autoplayPushButton.setChecked(autoplayInitialState)
self.autoplayPushButton.blockSignals(False)
if self.config['autoplayInitialThreshold'] > 1:
self.autoplayThresholdSpinbox.blockSignals(True)
self.autoplayThresholdSpinbox.setValue(self.config['autoplayInitialThreshold'])
self.autoplayThresholdSpinbox.blockSignals(False)
self.changeAutoplayState()
self.changeAutoplayThreshold()
self.updateAutoPlayIcon()
except: except:
pass self.showErrorMessage("Failed to load some settings.")
self.automaticUpdateCheck() self.automaticUpdateCheck()
def promptFor(self, prompt=">", message=""): def promptFor(self, prompt=">", message=""):
@ -212,6 +234,7 @@ class MainWindow(QtGui.QMainWindow):
item = item.parent() item = item.parent()
self.joinRoom(item.sibling(item.row(), 0).data()) self.joinRoom(item.sibling(item.row(), 0).data())
@needsClient
def userListChange(self): def userListChange(self):
self._syncplayClient.showUserList() self._syncplayClient.showUserList()
@ -230,6 +253,7 @@ class MainWindow(QtGui.QMainWindow):
message = "<span style=\"{}\">".format(constants.STYLE_ERRORNOTIFICATION) + message + "</span>" message = "<span style=\"{}\">".format(constants.STYLE_ERRORNOTIFICATION) + message + "</span>"
self.newMessage(time.strftime(constants.UI_TIME_FORMAT, time.localtime()) + message + "<br />") self.newMessage(time.strftime(constants.UI_TIME_FORMAT, time.localtime()) + message + "<br />")
@needsClient
def joinRoom(self, room=None): def joinRoom(self, room=None):
if room == None: if room == None:
room = self.roomInput.text() room = self.roomInput.text()
@ -240,7 +264,7 @@ class MainWindow(QtGui.QMainWindow):
room = self._syncplayClient.defaultRoom room = self._syncplayClient.defaultRoom
self.roomInput.setText(room) self.roomInput.setText(room)
if room != self._syncplayClient.getRoom(): if room != self._syncplayClient.getRoom():
self._syncplayClient.setRoom(room) self._syncplayClient.setRoom(room, resetAutoplay=True)
self._syncplayClient.sendRoom() self._syncplayClient.sendRoom()
def seekPositionDialog(self): def seekPositionDialog(self):
@ -253,6 +277,7 @@ class MainWindow(QtGui.QMainWindow):
def seekFromButton(self): def seekFromButton(self):
self.seekPosition(self.seekInput.text()) self.seekPosition(self.seekInput.text())
@needsClient
def seekPosition(self, seekTime): def seekPosition(self, seekTime):
s = re.match(constants.UI_SEEK_REGEX, seekTime) s = re.match(constants.UI_SEEK_REGEX, seekTime)
if s: if s:
@ -266,20 +291,25 @@ class MainWindow(QtGui.QMainWindow):
else: else:
self.showErrorMessage(getMessage("invalid-seek-value")) self.showErrorMessage(getMessage("invalid-seek-value"))
@needsClient
def undoSeek(self): def undoSeek(self):
tmp_pos = self._syncplayClient.getPlayerPosition() tmp_pos = self._syncplayClient.getPlayerPosition()
self._syncplayClient.setPosition(self._syncplayClient.playerPositionBeforeLastSeek) self._syncplayClient.setPosition(self._syncplayClient.playerPositionBeforeLastSeek)
self._syncplayClient.playerPositionBeforeLastSeek = tmp_pos self._syncplayClient.playerPositionBeforeLastSeek = tmp_pos
@needsClient
def togglePause(self): def togglePause(self):
self._syncplayClient.setPaused(not self._syncplayClient.getPlayerPaused()) self._syncplayClient.setPaused(not self._syncplayClient.getPlayerPaused())
@needsClient
def play(self): def play(self):
self._syncplayClient.setPaused(False) self._syncplayClient.setPaused(False)
@needsClient
def pause(self): def pause(self):
self._syncplayClient.setPaused(True) self._syncplayClient.setPaused(True)
@needsClient
def exitSyncplay(self): def exitSyncplay(self):
self._syncplayClient.stop() self._syncplayClient.stop()
@ -299,6 +329,7 @@ class MainWindow(QtGui.QMainWindow):
settings.setValue("mediadir", self.mediadirectory) settings.setValue("mediadir", self.mediadirectory)
settings.endGroup() settings.endGroup()
@needsClient
def browseMediapath(self): def browseMediapath(self):
if self._syncplayClient._player.customOpenDialog == True: if self._syncplayClient._player.customOpenDialog == True:
self._syncplayClient._player.openCustomOpenDialog() self._syncplayClient._player.openCustomOpenDialog()
@ -324,6 +355,7 @@ class MainWindow(QtGui.QMainWindow):
self.saveMediaBrowseSettings() self.saveMediaBrowseSettings()
self._syncplayClient._player.openFile(fileName) self._syncplayClient._player.openFile(fileName)
@needsClient
def promptForStreamURL(self): def promptForStreamURL(self):
streamURL, ok = QtGui.QInputDialog.getText(self, getMessage("promptforstreamurl-msgbox-label"), streamURL, ok = QtGui.QInputDialog.getText(self, getMessage("promptforstreamurl-msgbox-label"),
getMessage("promptforstreamurlinfo-msgbox-label"), QtGui.QLineEdit.Normal, getMessage("promptforstreamurlinfo-msgbox-label"), QtGui.QLineEdit.Normal,
@ -331,6 +363,7 @@ class MainWindow(QtGui.QMainWindow):
if ok and streamURL != '': if ok and streamURL != '':
self._syncplayClient._player.openFile(streamURL) self._syncplayClient._player.openFile(streamURL)
@needsClient
def createControlledRoom(self): def createControlledRoom(self):
controlroom, ok = QtGui.QInputDialog.getText(self, getMessage("createcontrolledroom-msgbox-label"), controlroom, ok = QtGui.QInputDialog.getText(self, getMessage("createcontrolledroom-msgbox-label"),
getMessage("controlledroominfo-msgbox-label"), QtGui.QLineEdit.Normal, getMessage("controlledroominfo-msgbox-label"), QtGui.QLineEdit.Normal,
@ -338,6 +371,7 @@ class MainWindow(QtGui.QMainWindow):
if ok and controlroom != '': if ok and controlroom != '':
self._syncplayClient.createControlledRoom(controlroom) self._syncplayClient.createControlledRoom(controlroom)
@needsClient
def identifyAsController(self): def identifyAsController(self):
msgboxtitle = getMessage("identifyascontroller-msgbox-label") msgboxtitle = getMessage("identifyascontroller-msgbox-label")
msgboxtext = getMessage("identifyinfo-msgbox-label") msgboxtext = getMessage("identifyinfo-msgbox-label")
@ -354,6 +388,7 @@ class MainWindow(QtGui.QMainWindow):
else: else:
return None return None
@needsClient
def setOffset(self): def setOffset(self):
newoffset, ok = QtGui.QInputDialog.getText(self, getMessage("setoffset-msgbox-label"), newoffset, ok = QtGui.QInputDialog.getText(self, getMessage("setoffset-msgbox-label"),
getMessage("offsetinfo-msgbox-label"), QtGui.QLineEdit.Normal, getMessage("offsetinfo-msgbox-label"), QtGui.QLineEdit.Normal,
@ -465,19 +500,41 @@ class MainWindow(QtGui.QMainWindow):
window.readyPushButton.toggled.connect(self.changeReadyState) window.readyPushButton.toggled.connect(self.changeReadyState)
window.readyPushButton.setFont(readyFont) window.readyPushButton.setFont(readyFont)
window.readyPushButton.setStyleSheet(constants.STYLE_READY_PUSHBUTTON) window.readyPushButton.setStyleSheet(constants.STYLE_READY_PUSHBUTTON)
window.readyPushButton.setToolTip(getMessage("ready-tooltip"))
window.listLayout.addWidget(window.readyPushButton, Qt.AlignRight) window.listLayout.addWidget(window.readyPushButton, Qt.AlignRight)
window.autoPlayPushButton = QtGui.QPushButton()
window.autoPlayPushButton.setVisible(False) window.autoplayLayout = QtGui.QHBoxLayout()
window.autoplayFrame = QtGui.QFrame()
window.autoplayFrame.setVisible(False)
window.autoplayLayout.setContentsMargins(0,0,0,0)
window.autoplayFrame.setLayout(window.autoplayLayout)
window.autoplayPushButton = QtGui.QPushButton()
autoPlayFont = QtGui.QFont() autoPlayFont = QtGui.QFont()
autoPlayFont.setWeight(QtGui.QFont.Bold) autoPlayFont.setWeight(QtGui.QFont.Bold)
window.autoPlayPushButton.setText(getMessage("autoplay-guipushbuttonlabel")) window.autoplayPushButton.setText(getMessage("autoplay-guipushbuttonlabel"))
window.autoPlayPushButton.setCheckable(True) window.autoplayPushButton.setCheckable(True)
window.autoPlayPushButton.setAutoExclusive(False) window.autoplayPushButton.setAutoExclusive(False)
window.autoPlayPushButton.toggled.connect(self.changeAutoPlayState) window.autoplayPushButton.toggled.connect(self.changeAutoplayState)
window.autoPlayPushButton.setFont(autoPlayFont) window.autoplayPushButton.setFont(autoPlayFont)
window.autoPlayPushButton.setStyleSheet(constants.STYLE_AUTO_PLAY_PUSHBUTTON) window.autoplayPushButton.setStyleSheet(constants.STYLE_AUTO_PLAY_PUSHBUTTON)
window.listLayout.addWidget(window.autoPlayPushButton, Qt.AlignRight) window.autoplayPushButton.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
self.updateAutoPlayIcon() window.autoplayPushButton.setToolTip(getMessage("autoplay-tooltip"))
window.autoplayLabel = QtGui.QLabel(getMessage("autoplay-minimum-label"))
window.autoplayLabel.setSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Minimum)
window.autoplayLabel.setMaximumWidth(window.autoplayLabel.minimumSizeHint().width())
window.autoplayLabel.setToolTip(getMessage("autoplay-tooltip"))
window.autoplayThresholdSpinbox = QtGui.QSpinBox()
window.autoplayThresholdSpinbox.setMaximumWidth(window.autoplayThresholdSpinbox.minimumSizeHint().width())
window.autoplayThresholdSpinbox.setMinimum(2)
window.autoplayThresholdSpinbox.setMaximum(99)
window.autoplayThresholdSpinbox.setToolTip(getMessage("autoplay-tooltip"))
window.autoplayThresholdSpinbox.valueChanged.connect(self.changeAutoplayThreshold)
window.autoplayLayout.addWidget(window.autoplayPushButton, Qt.AlignRight)
window.autoplayLayout.addWidget(window.autoplayLabel, Qt.AlignRight)
window.autoplayLayout.addWidget(window.autoplayThresholdSpinbox, Qt.AlignRight)
window.listLayout.addWidget(window.autoplayFrame, Qt.AlignLeft)
window.autoplayFrame.setMaximumHeight(window.autoplayFrame.sizeHint().height())
window.mainLayout.addWidget(window.bottomFrame, Qt.AlignLeft) window.mainLayout.addWidget(window.bottomFrame, Qt.AlignLeft)
window.bottomFrame.setMaximumHeight(window.bottomFrame.minimumSizeHint().height()) window.bottomFrame.setMaximumHeight(window.bottomFrame.minimumSizeHint().height())
@ -617,21 +674,34 @@ class MainWindow(QtGui.QMainWindow):
self.playbackFrame.setVisible(self.playbackAction.isChecked()) self.playbackFrame.setVisible(self.playbackAction.isChecked())
def updateAutoplayVisibility(self): def updateAutoplayVisibility(self):
self.autoPlayPushButton.setVisible(self.autoplayAction.isChecked()) self.autoplayFrame.setVisible(self.autoplayAction.isChecked())
def changeReadyState(self): def changeReadyState(self):
self.updateReadyIcon() self.updateReadyIcon()
self._syncplayClient.changeReadyState(self.readyPushButton.isChecked()) if self._syncplayClient:
self._syncplayClient.changeReadyState(self.readyPushButton.isChecked())
else:
self.showDebugMessage("Tried to change ready state too soon.")
@needsClient
def changeAutoplayThreshold(self, source=None):
self._syncplayClient.changeAutoPlayThrehsold(self.autoplayThresholdSpinbox.value())
def updateAutoPlayState(self, newState): def updateAutoPlayState(self, newState):
oldState = self.autoPlayPushButton.isChecked() oldState = self.autoplayPushButton.isChecked()
if newState != oldState and newState != None: if newState != oldState and newState != None:
self.autoPlayPushButton.setChecked(newState) self.autoplayPushButton.blockSignals(True)
self.autoplayPushButton.setChecked(newState)
self.autoplayPushButton.blockSignals(False)
self.updateAutoPlayIcon() self.updateAutoPlayIcon()
def changeAutoPlayState(self): @needsClient
def changeAutoplayState(self, source=None):
self.updateAutoPlayIcon() self.updateAutoPlayIcon()
self._syncplayClient.changeAutoPlayState(self.autoPlayPushButton.isChecked()) if self._syncplayClient:
self._syncplayClient.changeAutoplayState(self.autoplayPushButton.isChecked())
else:
self.showDebugMessage("Tried to set AutoplayState too soon")
def updateReadyIcon(self): def updateReadyIcon(self):
ready = self.readyPushButton.isChecked() ready = self.readyPushButton.isChecked()
@ -641,11 +711,11 @@ class MainWindow(QtGui.QMainWindow):
self.readyPushButton.setIcon(QtGui.QIcon(self.resourcespath + 'empty_checkbox.png')) self.readyPushButton.setIcon(QtGui.QIcon(self.resourcespath + 'empty_checkbox.png'))
def updateAutoPlayIcon(self): def updateAutoPlayIcon(self):
ready = self.autoPlayPushButton.isChecked() ready = self.autoplayPushButton.isChecked()
if ready: if ready:
self.autoPlayPushButton.setIcon(QtGui.QIcon(self.resourcespath + 'tick_checkbox.png')) self.autoplayPushButton.setIcon(QtGui.QIcon(self.resourcespath + 'tick_checkbox.png'))
else: else:
self.autoPlayPushButton.setIcon(QtGui.QIcon(self.resourcespath + 'empty_checkbox.png')) self.autoplayPushButton.setIcon(QtGui.QIcon(self.resourcespath + 'empty_checkbox.png'))
def automaticUpdateCheck(self): def automaticUpdateCheck(self):
currentDateTime = datetime.utcnow() currentDateTime = datetime.utcnow()
@ -665,6 +735,7 @@ class MainWindow(QtGui.QMainWindow):
def userCheckForUpdates(self): def userCheckForUpdates(self):
self.checkForUpdates(userInitiated=True) self.checkForUpdates(userInitiated=True)
@needsClient
def checkForUpdates(self, userInitiated=False): def checkForUpdates(self, userInitiated=False):
self.lastCheckedForUpdates = datetime.utcnow() self.lastCheckedForUpdates = datetime.utcnow()
updateStatus, updateMessage, updateURL = self._syncplayClient.checkForUpdate(userInitiated) updateStatus, updateMessage, updateURL = self._syncplayClient.checkForUpdate(userInitiated)
@ -717,6 +788,8 @@ class MainWindow(QtGui.QMainWindow):
settings.setValue("pos", self.pos()) settings.setValue("pos", self.pos())
settings.setValue("showPlaybackButtons", self.playbackAction.isChecked()) settings.setValue("showPlaybackButtons", self.playbackAction.isChecked())
settings.setValue("showAutoPlayButton", self.autoplayAction.isChecked()) settings.setValue("showAutoPlayButton", self.autoplayAction.isChecked())
settings.setValue("autoplayChecked", self.autoplayPushButton.isChecked())
settings.setValue("autoplayMinUsers", self.autoplayThresholdSpinbox.value())
settings.endGroup() settings.endGroup()
settings = QSettings("Syncplay", "Interface") settings = QSettings("Syncplay", "Interface")
settings.beginGroup("Update") settings.beginGroup("Update")
@ -734,6 +807,12 @@ class MainWindow(QtGui.QMainWindow):
if settings.value("showAutoPlayButton", "false") == "true": if settings.value("showAutoPlayButton", "false") == "true":
self.autoplayAction.setChecked(True) self.autoplayAction.setChecked(True)
self.updateAutoplayVisibility() self.updateAutoplayVisibility()
if settings.value("autoplayChecked", "false") == "true":
self.updateAutoPlayState(True)
self.autoplayPushButton.setChecked(True)
self.autoplayThresholdSpinbox.blockSignals(True)
self.autoplayThresholdSpinbox.setValue(settings.value("autoplayMinUsers", 2))
self.autoplayThresholdSpinbox.blockSignals(False)
settings.endGroup() settings.endGroup()
settings = QSettings("Syncplay", "Interface") settings = QSettings("Syncplay", "Interface")
settings.beginGroup("Update") settings.beginGroup("Update")
@ -741,6 +820,7 @@ class MainWindow(QtGui.QMainWindow):
def __init__(self): def __init__(self):
super(MainWindow, self).__init__() super(MainWindow, self).__init__()
self._syncplayClient = None
self.QtGui = QtGui self.QtGui = QtGui
if sys.platform.startswith('win'): if sys.platform.startswith('win'):
self.resourcespath = utils.findWorkingDir() + "\\resources\\" self.resourcespath = utils.findWorkingDir() + "\\resources\\"