AO2XP/options.py

388 lines
18 KiB
Python

from ConfigParserEdit import ConfigParser
from os.path import exists
from os import listdir, _exit
import subprocess
try:
import Cocoa # mac
except: pass
from PyQt4 import QtGui, QtCore
from constants import *
import ini
class Settings(QtGui.QDialog):
def __init__(self, parent):
super(Settings, self).__init__()
self.setModal(True)
self.gamewindow = parent
self.parent = parent
self.inifile = ConfigParser()
self.setWindowTitle("AO2XP Settings")
self.setFixedSize(480, 512)
self.setWindowIcon(QtGui.QIcon("AO2XP.ico"))
self.setWindowFlags(QtCore.Qt.WindowCloseButtonHint)
self.hide()
layMain = QtGui.QVBoxLayout(self)
laySave = QtGui.QHBoxLayout()
self.tabs = QtGui.QTabWidget()
self.tabs.resize(320-16, 480-40)
self.tabs.move(8, 8)
tabGeneral = QtGui.QWidget()
tabAudio = QtGui.QWidget()
tabCallwords = QtGui.QWidget()
layGeneral = QtGui.QVBoxLayout(tabGeneral)
layGeneral.setAlignment(QtCore.Qt.AlignTop)
layAudio = QtGui.QFormLayout(tabAudio)
layAudio.setLabelAlignment(QtCore.Qt.AlignLeading | QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter)
layAudio.setFormAlignment(QtCore.Qt.AlignLeading | QtCore.Qt.AlignLeft | QtCore.Qt.AlignTop)
layCallwords = QtGui.QVBoxLayout(tabCallwords)
layCallwords.setAlignment(QtCore.Qt.AlignTop)
self.btnSave = QtGui.QPushButton()
self.btnSave.setText("Save")
self.btnSave.clicked.connect(self.onSaveClicked)
self.btnCancel = QtGui.QPushButton()
self.btnCancel.setText("Cancel")
self.btnCancel.clicked.connect(self.onCancelClicked)
self.btnAbout = QtGui.QPushButton()
self.btnAbout.setText("About...")
self.btnAbout.clicked.connect(self.onAboutClicked)
separators = []
for i in range(5):
separator = QtGui.QFrame()
separator.setFixedSize(separator.size().width(), 12)
separators.append(separator)
###### General tab ######
layDefaultOOCName = QtGui.QHBoxLayout()
lblDefaultOOCName = QtGui.QLabel("Default OOC name")
self.defaultOOCName = QtGui.QLineEdit()
layDefaultOOCName.addWidget(lblDefaultOOCName)
layDefaultOOCName.addWidget(self.defaultOOCName)
lblDefaultShowname = QtGui.QLabel("Default showname")
self.defaultShowname = QtGui.QLineEdit()
layDefaultOOCName.addWidget(lblDefaultShowname)
layDefaultOOCName.addWidget(self.defaultShowname)
laySaveToLog = QtGui.QHBoxLayout()
self.cbSaveToLog = QtGui.QCheckBox()
self.cbSaveToLog.setText("Save chat logs to a file")
self.cbSaveToLog.setChecked(False)
self.cbCombineLogs = QtGui.QCheckBox()
self.cbCombineLogs.setText("Combine OOC and IC chat logs in the same file")
self.cbCombineLogs.setChecked(False)
laySaveToLog.addWidget(self.cbSaveToLog)
laySaveToLog.addWidget(self.cbCombineLogs)
laySaveDemos = QtGui.QHBoxLayout()
self.cbSaveDemos = QtGui.QCheckBox()
self.cbSaveDemos.setText("Record demo files")
self.cbSaveDemos.setChecked(False)
laySaveDemos.addWidget(self.cbSaveDemos)
layTextStayTime = QtGui.QHBoxLayout()
lblTextStayTime = QtGui.QLabel("Text stay time (milliseconds)")
self.sbTextStayTime = QtGui.QSpinBox()
self.sbTextStayTime.setMinimum(0)
self.sbTextStayTime.setMaximum(10000)
layTextStayTime.addWidget(lblTextStayTime)
layTextStayTime.addWidget(self.sbTextStayTime)
laySlide = QtGui.QHBoxLayout()
self.cbEnableSlide = QtGui.QCheckBox()
self.cbEnableSlide.setText("(Experimental) Display courtroom slide (pan-tilt) animations")
self.cbEnableSlide.setChecked(True)
laySlide.addWidget(self.cbEnableSlide)
layTheme = QtGui.QHBoxLayout()
lblTheme = QtGui.QLabel("Current theme")
self.cbThemes = QtGui.QComboBox()
self.themes = listdir(AO2XPpath + "ao2xp_themes")
for theme in self.themes:
if exists(AO2XPpath + "ao2xp_themes/"+theme+"/theme.py") or exists(AO2XPpath + "ao2xp_themes/"+theme+"/courtroom_design.ini"):
self.cbThemes.addItem(theme)
layTheme.addWidget(lblTheme)
layTheme.addWidget(self.cbThemes)
layAutoConnect = QtGui.QHBoxLayout()
lblAutoConnect = QtGui.QLabel("Connect automatically to this server")
self.cbServers = QtGui.QComboBox()
layAutoConnect.addWidget(lblAutoConnect)
layAutoConnect.addWidget(self.cbServers)
self.cbServers.addItem("Always show server list")
if exists('serverlist.txt'):
with open('serverlist.txt') as file:
for server in [line.rstrip().split(':') for line in file]:
self.cbServers.addItem(server[-1])
layAutoPick = QtGui.QHBoxLayout()
lblAutoPick = QtGui.QLabel("Pick this character automatically on join")
self.cbCharacters = QtGui.QComboBox()
for folder in listdir(unicode(AOpath + 'characters')):
if exists(AOpath + 'characters/' + folder + '/char.ini'):
self.cbCharacters.addItem(folder)
self.cbCharacters.setEditable(1)
layAutoPick.addWidget(lblAutoPick)
layAutoPick.addWidget(self.cbCharacters)
layAutoJoinArea = QtGui.QHBoxLayout()
lblAutoJoinArea = QtGui.QLabel("Go to this area automatically on join")
self.autoJoinArea = QtGui.QLineEdit()
layAutoJoinArea.addWidget(lblAutoJoinArea)
layAutoJoinArea.addWidget(self.autoJoinArea)
lblDownloads = QtGui.QLabel()
lblDownloads.setText("Automatically download or stream online from WebAO:")
layDownloads = QtGui.QHBoxLayout()
self.cbDownloadChars = QtGui.QCheckBox("Characters")
self.cbDownloadSounds = QtGui.QCheckBox("Sounds")
self.cbDownloadMusic = QtGui.QCheckBox("Music")
self.cbDownloadEvidence = QtGui.QCheckBox("Evidence")
layDownloads.addWidget(self.cbDownloadChars)
layDownloads.addWidget(self.cbDownloadSounds)
layDownloads.addWidget(self.cbDownloadMusic)
layDownloads.addWidget(self.cbDownloadEvidence)
layUpdate = QtGui.QHBoxLayout()
self.cbCheckUpdates = QtGui.QCheckBox("Check for AO2XP updates on startup")
self.btnCheckUpdatesNow = QtGui.QPushButton()
self.btnCheckUpdatesNow.setText("Check now...")
self.btnCheckUpdatesNow.clicked.connect(self.onUpdateClicked)
layUpdate.addWidget(self.cbCheckUpdates)
layUpdate.addWidget(self.btnCheckUpdatesNow)
layGeneral.addLayout(layDefaultOOCName)
layGeneral.addLayout(laySaveToLog)
layGeneral.addLayout(laySaveDemos)
layGeneral.addWidget(separators[0])
layGeneral.addLayout(layTextStayTime)
layGeneral.addLayout(laySlide)
layGeneral.addWidget(separators[1])
layGeneral.addLayout(layTheme)
layGeneral.addLayout(layAutoConnect)
layGeneral.addLayout(layAutoPick)
layGeneral.addLayout(layAutoJoinArea)
layGeneral.addWidget(separators[2])
layGeneral.addWidget(lblDownloads)
layGeneral.addLayout(layDownloads)
layGeneral.addWidget(separators[3])
layGeneral.addLayout(layUpdate)
###### Audio tab ######
lblAudioDevice = QtGui.QLabel("Audio device")
self.cbDevices = QtGui.QComboBox()
layAudio.setWidget(0, QtGui.QFormLayout.LabelRole, lblAudioDevice)
layAudio.setWidget(0, QtGui.QFormLayout.FieldRole, self.cbDevices)
layAudio.setWidget(1, QtGui.QFormLayout.FieldRole, separators[4])
lblMusicVolume = QtGui.QLabel("Music")
lblSoundVolume = QtGui.QLabel("Sounds")
lblBlipsVolume = QtGui.QLabel("Blips")
self.sliMusicVolume = QtGui.QSlider(QtCore.Qt.Horizontal, self)
self.sliSoundVolume = QtGui.QSlider(QtCore.Qt.Horizontal, self)
self.sliBlipsVolume = QtGui.QSlider(QtCore.Qt.Horizontal, self)
self.sliMusicVolume.setRange(0, 100)
self.sliSoundVolume.setRange(0, 100)
self.sliBlipsVolume.setRange(0, 100)
layAudio.setWidget(2, QtGui.QFormLayout.LabelRole, lblMusicVolume)
layAudio.setWidget(2, QtGui.QFormLayout.FieldRole, self.sliMusicVolume)
layAudio.setWidget(3, QtGui.QFormLayout.LabelRole, lblSoundVolume)
layAudio.setWidget(3, QtGui.QFormLayout.FieldRole, self.sliSoundVolume)
layAudio.setWidget(4, QtGui.QFormLayout.LabelRole, lblBlipsVolume)
layAudio.setWidget(4, QtGui.QFormLayout.FieldRole, self.sliBlipsVolume)
self.btnReloadAudioSystem = QtGui.QPushButton(text="Reload audio system")
self.btnReloadAudioSystem.clicked.connect(self.onReloadAudioSystemClicked)
layAudio.setWidget(5, QtGui.QFormLayout.FieldRole, self.btnReloadAudioSystem)
for device in audio.getDevices():
self.cbDevices.addItem(device)
###### Callwords tab ######
self.callwords = QtGui.QTextEdit()
cbCallwordsWordWrap = QtGui.QCheckBox("Word Wrap")
cbCallwordsWordWrap.setChecked(True)
cbCallwordsWordWrap.stateChanged.connect(self.callwordsWordWrapCheckbox)
cbCallwordsInstructions = QtGui.QLabel()
cbCallwordsInstructions.setText("Separate callwords with newlines (ENTER key).")
layCallwords.addWidget(self.callwords)
layCallwords.addWidget(cbCallwordsWordWrap, 0, QtCore.Qt.AlignRight)
layCallwords.addWidget(cbCallwordsInstructions)
### Main settings window
self.tabs.addTab(tabGeneral, "General")
self.tabs.addTab(tabAudio, "Audio")
self.tabs.addTab(tabCallwords, "Callwords")
laySave.addWidget(self.btnSave, 100, QtCore.Qt.AlignRight)
laySave.addWidget(self.btnCancel, 0, QtCore.Qt.AlignRight)
laySave.addWidget(self.btnAbout, 0, QtCore.Qt.AlignLeft)
layMain.addWidget(self.tabs)
layMain.addLayout(laySave)
self.btnSave.setFocus()
# If they're different from the respective checkbox on save, tell the
# gui to start/stop logging
self.saveLogsState = False
self.combineLogsState = False
self.saveDemosState = False
self.themeState = ""
def showSettings(self):
if exists("AO2XP.ini"):
self.inifile.read("AO2XP.ini")
self.cbSaveToLog.setChecked(ini.read_ini_bool(self.inifile, "General", "save logs", False))
self.cbCombineLogs.setChecked(ini.read_ini_bool(self.inifile, "General", "combined logs", False))
self.cbSaveDemos.setChecked(ini.read_ini_bool(self.inifile, "General", "record demos", False))
try:
self.defaultOOCName.setText(ini.read_ini(self.inifile, "General", "OOC name").decode("utf-8"))
except:
self.defaultOOCName.setText(ini.read_ini(self.inifile, "General", "OOC name"))
try:
self.defaultShowname.setText(ini.read_ini(self.inifile, "General", "showname").decode("utf-8"))
except:
self.defaultShowname.setText(ini.read_ini(self.inifile, "General", "showname"))
self.cbEnableSlide.setChecked(ini.read_ini_bool(self.inifile, "General", "slide", False))
self.cbDownloadChars.setChecked(ini.read_ini_bool(self.inifile, "General", "download characters", False))
self.cbDownloadSounds.setChecked(ini.read_ini_bool(self.inifile, "General", "download sounds", False))
self.cbDownloadMusic.setChecked(ini.read_ini_bool(self.inifile, "General", "download music"))
self.cbDownloadEvidence.setChecked(ini.read_ini_bool(self.inifile, "General", "download evidence", False))
self.cbThemes.setCurrentIndex(self.themes.index(ini.read_ini(self.inifile, "General", "theme", "default")))
self.cbServers.setCurrentIndex(ini.read_ini_int(self.inifile, "General", "auto connect", -1) + 1)
self.cbCharacters.setEditText(ini.read_ini(self.inifile, "General", "auto pick").decode('utf-8'))
self.autoJoinArea.setText(ini.read_ini(self.inifile, "General", "auto join area").decode('utf-8'))
self.sbTextStayTime.setValue(ini.read_ini_int(self.inifile, "General", "text stay time", 200))
self.cbCheckUpdates.setChecked(ini.read_ini_bool(self.inifile, "General", "install updates", False)) # Automatic updates are opt-in!
self.cbDevices.setCurrentIndex(ini.read_ini_int(self.inifile, "Audio", "device", audio.getCurrDevice()))
self.sliMusicVolume.setValue(ini.read_ini_int(self.inifile, "Audio", "Music volume", 100))
self.sliSoundVolume.setValue(ini.read_ini_int(self.inifile, "Audio", "Sound volume", 100))
self.sliBlipsVolume.setValue(ini.read_ini_int(self.inifile, "Audio", "Blip volume", 100))
else:
self.cbSaveToLog.setChecked(False)
self.cbCombineLogs.setChecked(False)
self.cbSaveDemos.setChecked(False)
self.defaultOOCName.setText("")
self.defaultShowname.setText("")
self.cbEnableSlide.setChecked(False)
self.cbDownloadSounds.setChecked(True)
self.cbDownloadMusic.setChecked(True)
self.cbDownloadEvidence.setChecked(True)
self.cbThemes.setCurrentIndex(self.themes.index("default"))
self.cbCheckUpdates.setChecked(False)
self.sbTextStayTime.setValue(200)
self.cbCharacters.setEditText("")
self.autoJoinArea.setText("")
self.cbDevices.setCurrentIndex(audio.getCurrDevice())
self.sliMusicVolume.setValue(100)
self.sliSoundVolume.setValue(100)
self.sliBlipsVolume.setValue(100)
self.callwords.clear()
if exists(AO2XPpath + "callwords.ini"):
with open(AO2XPpath + "callwords.ini") as f:
for line in f:
self.callwords.append(line.rstrip().decode("utf-8"))
self.saveLogsState = self.cbSaveToLog.isChecked()
self.combineLogsState = self.cbCombineLogs.isChecked()
self.saveDemosState = self.cbSaveDemos.isChecked()
self.themeState = self.cbThemes.currentText()
self.tabs.setCurrentIndex(0)
self.show()
def callwordsWordWrapCheckbox(self, newstate):
if newstate:
self.callwords.setWordWrapMode(QtGui.QTextOption.WrapAtWordBoundaryOrAnywhere)
else:
self.callwords.setWordWrapMode(0)
def onSaveClicked(self):
if not self.inifile.has_section("General"): self.inifile.add_section("General")
if not self.inifile.has_section("Audio"): self.inifile.add_section("Audio")
self.inifile.set("General", "save logs", self.cbSaveToLog.isChecked())
self.inifile.set("General", "combined logs", self.cbCombineLogs.isChecked())
self.inifile.set("General", "record demos", self.cbSaveDemos.isChecked())
self.inifile.set("General", "OOC name", self.defaultOOCName.text().toUtf8())
self.inifile.set("General", "showname", self.defaultShowname.text().toUtf8())
self.inifile.set("General", "text stay time", self.sbTextStayTime.value())
self.inifile.set("General", "slide", self.cbEnableSlide.isChecked())
self.inifile.set("General", "download characters", self.cbDownloadChars.isChecked())
self.inifile.set("General", "download sounds", self.cbDownloadSounds.isChecked())
self.inifile.set("General", "download music", self.cbDownloadMusic.isChecked())
self.inifile.set("General", "download evidence", self.cbDownloadEvidence.isChecked())
self.inifile.set("General", "theme", self.cbThemes.currentText())
self.inifile.set("General", "auto connect", self.cbServers.currentIndex() - 1)
self.inifile.set("General", "auto pick", self.cbCharacters.currentText().toUtf8())
self.inifile.set("General", "auto join area", self.autoJoinArea.text().toUtf8())
self.inifile.set("General", "install updates", self.cbCheckUpdates.isChecked())
self.inifile.set("Audio", "device", self.cbDevices.currentIndex())
self.inifile.set("Audio", "Music volume", self.sliMusicVolume.value())
self.inifile.set("Audio", "Sound volume", self.sliSoundVolume.value())
self.inifile.set("Audio", "Blip volume", self.sliBlipsVolume.value())
with open("AO2XP.ini", "wb") as f:
self.inifile.write(f)
with open(AO2XPpath + "callwords.ini", "w") as f:
f.write(self.callwords.toPlainText().toUtf8())
self.gamewindow.gamewidget.textWaitTime = self.sbTextStayTime.value()
slideEnabled = self.cbEnableSlide.isChecked()
self.gamewindow.gamewidget.slideEnabled = slideEnabled
self.gamewindow.gamewidget.cbSlide.setEnabled(slideEnabled)
if not slideEnabled:
self.gamewindow.gamewidget.cbSlide.setChecked(False)
if not self.themeState == self.cbThemes.currentText():
self.gamewindow.gamewidget.loadTheme(True)
if not self.gamewindow.gamewidget.demoPlaying:
if not (self.saveLogsState == self.cbSaveToLog.isChecked() and self.combineLogsState == self.cbCombineLogs.isChecked()):
self.gamewindow.gamewidget.OOCLog.setLogFiles()
self.gamewindow.gamewidget.ICLog.setLogFiles(self.gamewindow.gamewidget.OOCLog.logfile)
if not self.saveDemosState == self.cbSaveDemos.isChecked():
if self.cbSaveDemos.isChecked():
self.gamewindow.gamewidget.startDemoRecorder()
else:
self.gamewindow.gamewidget.demoRecorder = None
self.hide()
def onCancelClicked(self):
self.hide()
def onAboutClicked(self):
self.gamewindow.aboutgui.exec_()
def onUpdateClicked(self):
import updater
code = updater.checkForUpdates()
if code == 0:
subprocess.Popen(["./AO2XPupdat"])
_exit(0)
def onReloadAudioSystemClicked(self):
audio.free()
audio.init()
print "[audio] Reloaded audio system"