388 lines
18 KiB
Python
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"):
|
|
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" |