pesterchum/menus.py
2022-04-11 05:57:13 +02:00

1853 lines
77 KiB
Python

import re
from os import remove
from PyQt5 import QtCore, QtGui, QtWidgets
import ostools
import parsetools
from generic import RightClickList, RightClickTree, MultiTextDialog
from dataobjs import pesterQuirk, PesterProfile, PesterHistory
from memos import TimeSlider, TimeInput
from version import _pcVersion
from convo import PesterInput, PesterText
from parsetools import lexMessage
QString = str
_datadir = ostools.getDataDir()
class PesterQuirkItem(QtWidgets.QTreeWidgetItem):
def __init__(self, quirk):
parent = None
QtWidgets.QTreeWidgetItem.__init__(self, parent)
self.quirk = quirk
self.setText(0, str(quirk))
def update(self, quirk):
self.quirk = quirk
self.setText(0, str(quirk))
def __lt__(self, quirkitem):
"""Sets the order of quirks if auto-sorted by Qt. Obsolete now."""
if self.quirk.type == "prefix":
return True
elif (self.quirk.type == "replace" or self.quirk.type == "regexp") and \
quirkitem.type == "suffix":
return True
else:
return False
class PesterQuirkList(QtWidgets.QTreeWidget):
def __init__(self, mainwindow, parent):
QtWidgets.QTreeWidget.__init__(self, parent)
self.resize(400, 200)
# make sure we have access to mainwindow info like profiles
self.mainwindow = mainwindow
self.setStyleSheet("background:black; color:white;")
self.itemChanged[QtWidgets.QTreeWidgetItem, int].connect(self.changeCheckState)
for q in mainwindow.userprofile.quirks:
item = PesterQuirkItem(q)
self.addItem(item, False)
self.changeCheckState()
#self.setDragEnabled(True)
#self.setDragDropMode(QtGui.QAbstractItemView.InternalMove)
self.setDropIndicatorShown(True)
self.setSortingEnabled(False)
self.setIndentation(15)
self.header().hide()
def addItem(self, item, new=True):
item.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsDragEnabled | QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled)
if item.quirk.on:
item.setCheckState(0, 2)
else:
item.setCheckState(0, 0)
if new:
curgroup = self.currentItem()
if curgroup:
if curgroup.parent(): curgroup = curgroup.parent()
item.quirk.quirk["group"] = item.quirk.group = curgroup.text(0)
found = self.findItems(item.quirk.group, QtCore.Qt.MatchExactly)
if len(found) > 0:
found[0].addChild(item)
else:
child_1 = QtWidgets.QTreeWidgetItem([item.quirk.group])
self.addTopLevelItem(child_1)
child_1.setFlags(child_1.flags() | QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled)
child_1.setChildIndicatorPolicy(QtWidgets.QTreeWidgetItem.DontShowIndicatorWhenChildless)
child_1.setCheckState(0,0)
child_1.setExpanded(True)
child_1.addChild(item)
self.changeCheckState()
def currentQuirk(self):
if type(self.currentItem()) is PesterQuirkItem:
return self.currentItem()
else: return None
@QtCore.pyqtSlot()
def upShiftQuirk(self):
found = self.findItems(self.currentItem().text(0), QtCore.Qt.MatchExactly)
if len(found): # group
i = self.indexOfTopLevelItem(found[0])
if i > 0:
expand = found[0].isExpanded()
shifted_item = self.takeTopLevelItem(i)
self.insertTopLevelItem(i-1, shifted_item)
shifted_item.setExpanded(expand)
self.setCurrentItem(shifted_item)
else: # quirk
found = self.findItems(self.currentItem().text(0), QtCore.Qt.MatchExactly | QtCore.Qt.MatchRecursive)
for f in found:
if not f.isSelected(): continue
if not f.parent(): continue
i = f.parent().indexOfChild(f)
if i > 0: # keep in same group
p = f.parent()
shifted_item = f.parent().takeChild(i)
p.insertChild(i-1, shifted_item)
self.setCurrentItem(shifted_item)
else: # move to another group
j = self.indexOfTopLevelItem(f.parent())
if j <= 0: continue
shifted_item = f.parent().takeChild(i)
self.topLevelItem(j-1).addChild(shifted_item)
self.setCurrentItem(shifted_item)
self.changeCheckState()
@QtCore.pyqtSlot()
def downShiftQuirk(self):
found = self.findItems(self.currentItem().text(0), QtCore.Qt.MatchExactly)
if len(found): # group
i = self.indexOfTopLevelItem(found[0])
if i < self.topLevelItemCount()-1 and i >= 0:
expand = found[0].isExpanded()
shifted_item = self.takeTopLevelItem(i)
self.insertTopLevelItem(i+1, shifted_item)
shifted_item.setExpanded(expand)
self.setCurrentItem(shifted_item)
else: # quirk
found = self.findItems(self.currentItem().text(0), QtCore.Qt.MatchExactly | QtCore.Qt.MatchRecursive)
for f in found:
if not f.isSelected(): continue
if not f.parent(): continue
i = f.parent().indexOfChild(f)
if i < f.parent().childCount()-1 and i >= 0:
p = f.parent()
shifted_item = f.parent().takeChild(i)
p.insertChild(i+1, shifted_item)
self.setCurrentItem(shifted_item)
else:
j = self.indexOfTopLevelItem(f.parent())
if j >= self.topLevelItemCount()-1 or j < 0: continue
shifted_item = f.parent().takeChild(i)
self.topLevelItem(j+1).insertChild(0, shifted_item)
self.setCurrentItem(shifted_item)
self.changeCheckState()
@QtCore.pyqtSlot()
def removeCurrent(self):
i = self.currentItem()
found = self.findItems(i.text(0), QtCore.Qt.MatchExactly | QtCore.Qt.MatchRecursive)
for f in found:
if not f.isSelected(): continue
if not f.parent(): # group
msgbox = QtWidgets.QMessageBox()
msgbox.setStyleSheet(self.mainwindow.theme["main/defaultwindow/style"])
msgbox.setObjectName("delquirkwarning")
msgbox.setWindowTitle("WARNING!")
msgbox.setInformativeText("Are you sure you want to delete the quirk group: %s" % (f.text(0)))
msgbox.setStandardButtons(QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Cancel)
# Find the Cancel button and make it default
for b in msgbox.buttons():
if msgbox.buttonRole(b) == QtWidgets.QMessageBox.RejectRole:
# We found the 'OK' button, set it as the default
b.setDefault(True)
b.setAutoDefault(True)
# Actually set it as the selected option, since we're
# already stealing focus
b.setFocus()
break
ret = msgbox.exec_()
if ret == QtWidgets.QMessageBox.Ok:
self.takeTopLevelItem(self.indexOfTopLevelItem(f))
else:
f.parent().takeChild(f.parent().indexOfChild(f))
self.changeCheckState()
@QtCore.pyqtSlot()
def addQuirkGroup(self):
if not hasattr(self, 'addgroupdialog'):
self.addgroupdialog = None
if not self.addgroupdialog:
(gname, ok) = QtWidgets.QInputDialog.getText(self, "Add Group", "Enter a name for the new quirk group:")
if ok:
gname = str(gname)
if re.search("[^A-Za-z0-9_\s]", gname) is not None:
msgbox = QtWidgets.QMessageBox()
msgbox.setInformativeText("THIS IS NOT A VALID GROUP NAME")
msgbox.setStandardButtons(QtWidgets.QMessageBox.Ok)
msgbox.exec_()
self.addgroupdialog = None
return
found = self.findItems(gname, QtCore.Qt.MatchExactly)
if found:
msgbox = QtWidgets.QMessageBox()
msgbox.setInformativeText("THIS QUIRK GROUP ALREADY EXISTS")
msgbox.setStandardButtons(QtWidgets.QMessageBox.Ok)
msgbox.exec_()
return
child_1 = QtWidgets.QTreeWidgetItem([gname])
self.addTopLevelItem(child_1)
child_1.setFlags(child_1.flags() | QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled)
child_1.setChildIndicatorPolicy(QtWidgets.QTreeWidgetItem.DontShowIndicatorWhenChildless)
child_1.setCheckState(0,0)
child_1.setExpanded(True)
self.addgroupdialog = None
@QtCore.pyqtSlot()
def changeCheckState(self):
index = self.indexOfTopLevelItem(self.currentItem())
if index == -1:
for i in range(self.topLevelItemCount()):
allChecked = True
noneChecked = True
for j in range(self.topLevelItem(i).childCount()):
if self.topLevelItem(i).child(j).checkState(0):
noneChecked = False
else:
allChecked = False
if allChecked: self.topLevelItem(i).setCheckState(0, 2)
elif noneChecked: self.topLevelItem(i).setCheckState(0, 0)
else: self.topLevelItem(i).setCheckState(0, 1)
else:
state = self.topLevelItem(index).checkState(0)
for j in range(self.topLevelItem(index).childCount()):
self.topLevelItem(index).child(j).setCheckState(0, state)
class QuirkTesterWindow(QtWidgets.QDialog):
def __init__(self, parent):
QtWidgets.QDialog.__init__(self, parent)
self.prnt = parent
self.mainwindow = parent.mainwindow
self.setStyleSheet(self.mainwindow.theme["main/defaultwindow/style"])
self.setWindowTitle("Quirk Tester")
self.resize(350,300)
self.textArea = PesterText(self.mainwindow.theme, self)
self.textInput = PesterInput(self.mainwindow.theme, self)
self.textInput.setFocus()
self.textInput.returnPressed.connect(self.sentMessage)
self.chumopen = True
self.chum = self.mainwindow.profile()
self.history = PesterHistory()
layout_0 = QtWidgets.QVBoxLayout()
layout_0.addWidget(self.textArea)
layout_0.addWidget(self.textInput)
self.setLayout(layout_0)
def parent(self):
return self.prnt
def clearNewMessage(self):
pass
@QtCore.pyqtSlot()
def sentMessage(self):
text = str(self.textInput.text())
return parsetools.kxhandleInput(self, text, "menus")
def addMessage(self, msg, me=True):
if type(msg) in [str, str]:
lexmsg = lexMessage(msg)
else:
lexmsg = msg
if me:
chum = self.mainwindow.profile()
else:
chum = self.chum
self.textArea.addMessage(lexmsg, chum)
def closeEvent(self, event):
self.parent().quirktester = None
class PesterQuirkTypes(QtWidgets.QDialog):
def __init__(self, parent, quirk=None):
QtWidgets.QDialog.__init__(self, parent)
self.mainwindow = parent.mainwindow
self.setStyleSheet(self.mainwindow.theme["main/defaultwindow/style"])
self.setWindowTitle("Quirk Wizard")
self.resize(500,310)
self.quirk = quirk
self.pages = QtWidgets.QStackedWidget(self)
self.next = QtWidgets.QPushButton("Next", self)
self.next.setDefault(True)
self.next.clicked.connect(self.nextPage)
self.back = QtWidgets.QPushButton("Back", self)
self.back.setEnabled(False)
self.back.clicked.connect(self.backPage)
self.cancel = QtWidgets.QPushButton("Cancel", self)
self.cancel.clicked.connect(self.reject)
layout_2 = QtWidgets.QHBoxLayout()
layout_2.setAlignment(QtCore.Qt.AlignRight)
layout_2.addWidget(self.back)
layout_2.addWidget(self.next)
layout_2.addSpacing(5)
layout_2.addWidget(self.cancel)
vr = QtWidgets.QFrame()
vr.setFrameShape(QtWidgets.QFrame.VLine)
vr.setFrameShadow(QtWidgets.QFrame.Sunken)
vr2 = QtWidgets.QFrame()
vr2.setFrameShape(QtWidgets.QFrame.VLine)
vr2.setFrameShadow(QtWidgets.QFrame.Sunken)
self.funclist = QtWidgets.QListWidget(self)
self.funclist.setStyleSheet("color: #000000; background-color: #FFFFFF;")
self.funclist2 = QtWidgets.QListWidget(self)
self.funclist2.setStyleSheet("color: #000000; background-color: #FFFFFF;")
from parsetools import quirkloader
funcs = [q+"()" for q in list(quirkloader.quirks.keys())]
funcs.sort()
self.funclist.addItems(funcs)
self.funclist2.addItems(funcs)
self.reloadQuirkFuncButton = QtWidgets.QPushButton("RELOAD FUNCTIONS", self)
self.reloadQuirkFuncButton.clicked.connect(self.reloadQuirkFuncSlot)
self.reloadQuirkFuncButton2 = QtWidgets.QPushButton("RELOAD FUNCTIONS", self)
self.reloadQuirkFuncButton2.clicked.connect(self.reloadQuirkFuncSlot)
self.funclist.setMaximumWidth(160)
self.funclist.resize(160,50)
self.funclist2.setMaximumWidth(160)
self.funclist2.resize(160,50)
layout_f = QtWidgets.QVBoxLayout()
layout_f.addWidget(QtWidgets.QLabel("Available Regexp\nFunctions"))
layout_f.addWidget(self.funclist)
layout_f.addWidget(self.reloadQuirkFuncButton)
layout_g = QtWidgets.QVBoxLayout()
layout_g.addWidget(QtWidgets.QLabel("Available Regexp\nFunctions"))
layout_g.addWidget(self.funclist2)
layout_g.addWidget(self.reloadQuirkFuncButton2)
# Pages
# Type select
widget = QtWidgets.QWidget()
self.pages.addWidget(widget)
layout_select = QtWidgets.QVBoxLayout(widget)
layout_select.setAlignment(QtCore.Qt.AlignTop)
self.radios = []
self.radios.append(QtWidgets.QRadioButton("Prefix", self))
self.radios.append(QtWidgets.QRadioButton("Suffix", self))
self.radios.append(QtWidgets.QRadioButton("Simple Replace", self))
self.radios.append(QtWidgets.QRadioButton("Regexp Replace", self))
self.radios.append(QtWidgets.QRadioButton("Random Replace", self))
self.radios.append(QtWidgets.QRadioButton("Mispeller", self))
layout_select.addWidget(QtWidgets.QLabel("Select Quirk Type:"))
for r in self.radios:
layout_select.addWidget(r)
# Prefix
widget = QtWidgets.QWidget()
self.pages.addWidget(widget)
layout_prefix = QtWidgets.QVBoxLayout(widget)
layout_prefix.setAlignment(QtCore.Qt.AlignTop)
layout_prefix.addWidget(QtWidgets.QLabel("Prefix"))
layout_3 = QtWidgets.QHBoxLayout()
layout_3.addWidget(QtWidgets.QLabel("Value:"))
layout_3.addWidget(QtWidgets.QLineEdit())
layout_prefix.addLayout(layout_3)
# Suffix
widget = QtWidgets.QWidget()
self.pages.addWidget(widget)
layout_suffix = QtWidgets.QVBoxLayout(widget)
layout_suffix.setAlignment(QtCore.Qt.AlignTop)
layout_suffix.addWidget(QtWidgets.QLabel("Suffix"))
layout_3 = QtWidgets.QHBoxLayout()
layout_3.addWidget(QtWidgets.QLabel("Value:"))
layout_3.addWidget(QtWidgets.QLineEdit())
layout_suffix.addLayout(layout_3)
# Simple Replace
widget = QtWidgets.QWidget()
self.pages.addWidget(widget)
layout_replace = QtWidgets.QVBoxLayout(widget)
layout_replace.setAlignment(QtCore.Qt.AlignTop)
layout_replace.addWidget(QtWidgets.QLabel("Simple Replace"))
layout_3 = QtWidgets.QHBoxLayout()
layout_3.addWidget(QtWidgets.QLabel("Replace:"))
layout_3.addWidget(QtWidgets.QLineEdit())
layout_replace.addLayout(layout_3)
layout_3 = QtWidgets.QHBoxLayout()
layout_3.addWidget(QtWidgets.QLabel("With:"))
layout_3.addWidget(QtWidgets.QLineEdit())
layout_replace.addLayout(layout_3)
# Regexp Replace
widget = QtWidgets.QWidget()
self.pages.addWidget(widget)
layout_all = QtWidgets.QHBoxLayout(widget)
layout_regexp = QtWidgets.QVBoxLayout()
layout_regexp.setAlignment(QtCore.Qt.AlignTop)
layout_regexp.addWidget(QtWidgets.QLabel("Regexp Replace"))
layout_3 = QtWidgets.QHBoxLayout()
layout_3.addWidget(QtWidgets.QLabel("Regexp:"))
layout_3.addWidget(QtWidgets.QLineEdit())
layout_regexp.addLayout(layout_3)
layout_3 = QtWidgets.QHBoxLayout()
layout_3.addWidget(QtWidgets.QLabel("Replace With:"))
layout_3.addWidget(QtWidgets.QLineEdit())
layout_regexp.addLayout(layout_3)
layout_all.addLayout(layout_f)
layout_all.addWidget(vr)
layout_all.addLayout(layout_regexp)
# Random Replace
widget = QtWidgets.QWidget()
self.pages.addWidget(widget)
layout_all = QtWidgets.QHBoxLayout(widget)
layout_random = QtWidgets.QVBoxLayout()
layout_random.setAlignment(QtCore.Qt.AlignTop)
layout_random.addWidget(QtWidgets.QLabel("Random Replace"))
layout_5 = QtWidgets.QHBoxLayout()
regexpl = QtWidgets.QLabel("Regexp:", self)
self.regexp = QtWidgets.QLineEdit("", self)
layout_5.addWidget(regexpl)
layout_5.addWidget(self.regexp)
replacewithl = QtWidgets.QLabel("Replace With:", self)
layout_all.addLayout(layout_g)
layout_all.addWidget(vr2)
layout_all.addLayout(layout_random)
layout_6 = QtWidgets.QVBoxLayout()
layout_7 = QtWidgets.QHBoxLayout()
self.replacelist = QtWidgets.QListWidget(self)
self.replaceinput = QtWidgets.QLineEdit(self)
addbutton = QtWidgets.QPushButton("ADD", self)
addbutton.clicked.connect(self.addRandomString)
removebutton = QtWidgets.QPushButton("REMOVE", self)
removebutton.clicked.connect(self.removeRandomString)
layout_7.addWidget(addbutton)
layout_7.addWidget(removebutton)
layout_6.addLayout(layout_5)
layout_6.addWidget(replacewithl)
layout_6.addWidget(self.replacelist)
layout_6.addWidget(self.replaceinput)
layout_6.addLayout(layout_7)
layout_random.addLayout(layout_6)
# Misspeller
widget = QtWidgets.QWidget()
self.pages.addWidget(widget)
layout_mispeller = QtWidgets.QVBoxLayout(widget)
layout_mispeller.setAlignment(QtCore.Qt.AlignTop)
layout_mispeller.addWidget(QtWidgets.QLabel("Mispeller"))
layout_1 = QtWidgets.QHBoxLayout()
zero = QtWidgets.QLabel("1%", self)
hund = QtWidgets.QLabel("100%", self)
self.current = QtWidgets.QLabel("50%", self)
self.current.setAlignment(QtCore.Qt.AlignHCenter)
self.slider = QtWidgets.QSlider(QtCore.Qt.Horizontal, self)
self.slider.setMinimum(1)
self.slider.setMaximum(100)
self.slider.setValue(50)
self.slider.valueChanged[int].connect(self.printValue)
layout_1.addWidget(zero)
layout_1.addWidget(self.slider)
layout_1.addWidget(hund)
layout_mispeller.addLayout(layout_1)
layout_mispeller.addWidget(self.current)
layout_0 = QtWidgets.QVBoxLayout()
layout_0.addWidget(self.pages)
layout_0.addLayout(layout_2)
if quirk:
types = ["prefix","suffix","replace","regexp","random","spelling"]
for (i,r) in enumerate(self.radios):
if i == types.index(quirk.quirk.type):
r.setChecked(True)
self.changePage(types.index(quirk.quirk.type)+1)
page = self.pages.currentWidget().layout()
q = quirk.quirk.quirk
if q["type"] in ("prefix","suffix"):
page.itemAt(1).layout().itemAt(1).widget().setText(q["value"])
elif q["type"] == "replace":
page.itemAt(1).layout().itemAt(1).widget().setText(q["from"])
page.itemAt(2).layout().itemAt(1).widget().setText(q["to"])
elif q["type"] == "regexp":
page.itemAt(2).layout().itemAt(1).layout().itemAt(1).widget().setText(q["from"])
page.itemAt(2).layout().itemAt(2).layout().itemAt(1).widget().setText(q["to"])
elif q["type"] == "random":
self.regexp.setText(q["from"])
for v in q["randomlist"]:
item = QtWidgets.QListWidgetItem(v, self.replacelist)
elif q["type"] == "spelling":
self.slider.setValue(q["percentage"])
self.setLayout(layout_0)
def closeEvent(self, event):
self.parent().quirkadd = None
def changePage(self, page):
c = self.pages.count()
if page >= c or page < 0: return
self.back.setEnabled(page > 0)
if page >= 1 and page <= 6:
self.next.setText("Finish")
else:
self.next.setText("Next")
self.pages.setCurrentIndex(page)
@QtCore.pyqtSlot()
def nextPage(self):
if self.next.text() == "Finish":
self.accept()
return
cur = self.pages.currentIndex()
if cur == 0:
for (i,r) in enumerate(self.radios):
if r.isChecked():
self.changePage(i+1)
else:
self.changePage(cur+1)
@QtCore.pyqtSlot()
def backPage(self):
cur = self.pages.currentIndex()
if cur >= 1 and cur <= 6:
self.changePage(0)
@QtCore.pyqtSlot(int)
def printValue(self, value):
self.current.setText(str(value)+"%")
@QtCore.pyqtSlot()
def addRandomString(self):
text = str(self.replaceinput.text())
item = QtWidgets.QListWidgetItem(text, self.replacelist)
self.replaceinput.setText("")
self.replaceinput.setFocus()
@QtCore.pyqtSlot()
def removeRandomString(self):
if not self.replacelist.currentItem():
return
else:
self.replacelist.takeItem(self.replacelist.currentRow())
self.replaceinput.setFocus()
@QtCore.pyqtSlot()
def reloadQuirkFuncSlot(self):
from parsetools import reloadQuirkFunctions, quirkloader
reloadQuirkFunctions()
funcs = [q+"()" for q in list(quirkloader.quirks.keys())]
funcs.sort()
self.funclist.clear()
self.funclist.addItems(funcs)
self.funclist2.clear()
self.funclist2.addItems(funcs)
class PesterChooseQuirks(QtWidgets.QDialog):
def __init__(self, config, theme, parent):
QtWidgets.QDialog.__init__(self, parent)
self.setModal(False)
self.config = config
self.theme = theme
self.mainwindow = parent
self.setStyleSheet(self.theme["main/defaultwindow/style"])
self.setWindowTitle("Set Quirks")
self.quirkList = PesterQuirkList(self.mainwindow, self)
self.addQuirkButton = QtWidgets.QPushButton("ADD QUIRK", self)
self.addQuirkButton.clicked.connect(self.addQuirkDialog)
self.upShiftButton = QtWidgets.QPushButton("^", self)
self.downShiftButton = QtWidgets.QPushButton("v", self)
self.upShiftButton.setToolTip("Move quirk up one")
self.downShiftButton.setToolTip("Move quirk down one")
self.upShiftButton.clicked.connect(self.quirkList.upShiftQuirk)
self.downShiftButton.clicked.connect(self.quirkList.downShiftQuirk)
self.newGroupButton = QtWidgets.QPushButton("*", self)
self.newGroupButton.setToolTip("New Quirk Group")
self.newGroupButton.clicked.connect(self.quirkList.addQuirkGroup)
layout_quirklist = QtWidgets.QHBoxLayout() #the nude layout quirklist
layout_shiftbuttons = QtWidgets.QVBoxLayout() #the shift button layout
layout_shiftbuttons.addWidget(self.upShiftButton)
layout_shiftbuttons.addWidget(self.newGroupButton)
layout_shiftbuttons.addWidget(self.downShiftButton)
layout_quirklist.addWidget(self.quirkList)
layout_quirklist.addLayout(layout_shiftbuttons)
layout_1 = QtWidgets.QHBoxLayout()
layout_1.addWidget(self.addQuirkButton)
self.editSelectedButton = QtWidgets.QPushButton("EDIT", self)
self.editSelectedButton.clicked.connect(self.editSelected)
self.removeSelectedButton = QtWidgets.QPushButton("REMOVE", self)
self.removeSelectedButton.clicked.connect(self.quirkList.removeCurrent)
layout_3 = QtWidgets.QHBoxLayout()
layout_3.addWidget(self.editSelectedButton)
layout_3.addWidget(self.removeSelectedButton)
self.ok = QtWidgets.QPushButton("OK", self)
self.ok.setDefault(True)
self.ok.clicked.connect(self.accept)
self.test = QtWidgets.QPushButton("TEST QUIRKS", self)
self.test.clicked.connect(self.testQuirks)
self.cancel = QtWidgets.QPushButton("CANCEL", self)
self.cancel.clicked.connect(self.reject)
layout_ok = QtWidgets.QHBoxLayout()
layout_ok.addWidget(self.cancel)
layout_ok.addWidget(self.test)
layout_ok.addWidget(self.ok)
layout_0 = QtWidgets.QVBoxLayout()
layout_0.addLayout(layout_quirklist)
layout_0.addLayout(layout_1)
#layout_0.addLayout(layout_2)
layout_0.addLayout(layout_3)
layout_0.addLayout(layout_ok)
self.setLayout(layout_0)
def quirks(self):
u = []
for i in range(self.quirkList.topLevelItemCount()):
for j in range(self.quirkList.topLevelItem(i).childCount()):
u.append(self.quirkList.topLevelItem(i).child(j).quirk)
return u
#return [self.quirkList.item(i).quirk for i in range(self.quirkList.count())]
def testquirks(self):
u = []
for i in range(self.quirkList.topLevelItemCount()):
for j in range(self.quirkList.topLevelItem(i).childCount()):
item = self.quirkList.topLevelItem(i).child(j)
if (item.checkState(0) == QtCore.Qt.Checked):
u.append(item.quirk)
return u
@QtCore.pyqtSlot()
def testQuirks(self):
if not hasattr(self, 'quirktester'):
self.quirktester = None
if self.quirktester:
return
self.quirktester = QuirkTesterWindow(self)
self.quirktester.show()
@QtCore.pyqtSlot()
def editSelected(self):
q = self.quirkList.currentQuirk()
if not q: return
#quirk = q.quirk
self.addQuirkDialog(q)
@QtCore.pyqtSlot()
def addQuirkDialog(self, quirk=None):
if not hasattr(self, 'quirkadd'):
self.quirkadd = None
if self.quirkadd:
return
self.quirkadd = PesterQuirkTypes(self, quirk)
self.quirkadd.accepted.connect(self.addQuirk)
self.quirkadd.rejected.connect(self.closeQuirk)
self.quirkadd.show()
@QtCore.pyqtSlot()
def addQuirk(self):
types = ["prefix","suffix","replace","regexp","random","spelling"]
vdict = {}
vdict["type"] = types[self.quirkadd.pages.currentIndex()-1]
page = self.quirkadd.pages.currentWidget().layout()
if vdict["type"] in ("prefix","suffix"):
vdict["value"] = str(page.itemAt(1).layout().itemAt(1).widget().text())
elif vdict["type"] == "replace":
vdict["from"] = str(page.itemAt(1).layout().itemAt(1).widget().text())
vdict["to"] = str(page.itemAt(2).layout().itemAt(1).widget().text())
elif vdict["type"] == "regexp":
vdict["from"] = str(page.itemAt(2).layout().itemAt(1).layout().itemAt(1).widget().text())
vdict["to"] = str(page.itemAt(2).layout().itemAt(2).layout().itemAt(1).widget().text())
elif vdict["type"] == "random":
vdict["from"] = str(self.quirkadd.regexp.text())
randomlist = [str(self.quirkadd.replacelist.item(i).text())
for i in range(0,self.quirkadd.replacelist.count())]
vdict["randomlist"] = randomlist
elif vdict["type"] == "spelling":
vdict["percentage"] = self.quirkadd.slider.value()
if vdict["type"] in ("regexp", "random"):
try:
re.compile(vdict["from"])
except re.error as e:
quirkWarning = QtWidgets.QMessageBox(self)
quirkWarning.setText("Not a valid regular expression!")
quirkWarning.setInformativeText("H3R3S WHY DUMP4SS: %s" % (e))
quirkWarning.exec_()
self.quirkadd = None
return
quirk = pesterQuirk(vdict)
if self.quirkadd.quirk is None:
item = PesterQuirkItem(quirk)
self.quirkList.addItem(item)
else:
self.quirkadd.quirk.update(quirk)
self.quirkadd = None
@QtCore.pyqtSlot()
def closeQuirk(self):
self.quirkadd = None
class PesterChooseTheme(QtWidgets.QDialog):
def __init__(self, config, theme, parent):
QtWidgets.QDialog.__init__(self, parent)
self.config = config
self.theme = theme
self.parent = parent
self.setStyleSheet(self.theme["main/defaultwindow/style"])
self.setWindowTitle("Pick a theme")
instructions = QtWidgets.QLabel("Pick a theme:")
avail_themes = config.availableThemes()
self.themeBox = QtWidgets.QComboBox(self)
for (i, t) in enumerate(avail_themes):
self.themeBox.addItem(t)
if t == theme.name:
self.themeBox.setCurrentIndex(i)
self.ok = QtWidgets.QPushButton("OK", self)
self.ok.setDefault(True)
self.ok.clicked.connect(self.accept)
self.cancel = QtWidgets.QPushButton("CANCEL", self)
self.cancel.clicked.connect(self.reject)
layout_ok = QtWidgets.QHBoxLayout()
layout_ok.addWidget(self.cancel)
layout_ok.addWidget(self.ok)
layout_0 = QtWidgets.QVBoxLayout()
layout_0.addWidget(instructions)
layout_0.addWidget(self.themeBox)
layout_0.addLayout(layout_ok)
self.setLayout(layout_0)
self.accepted.connect(parent.themeSelected)
self.rejected.connect(parent.closeTheme)
class PesterChooseProfile(QtWidgets.QDialog):
def __init__(self, userprofile, config, theme, parent, collision=None):
QtWidgets.QDialog.__init__(self, parent)
self.userprofile = userprofile
self.theme = theme
self.config = config
self.parent = parent
self.setStyleSheet(self.theme["main/defaultwindow/style"])
self.currentHandle = QtWidgets.QLabel("CHANGING FROM %s" % userprofile.chat.handle)
self.chumHandle = QtWidgets.QLineEdit(self)
self.chumHandle.setMinimumWidth(200)
self.chumHandle.setObjectName("setprofilehandle")
self.chumHandleLabel = QtWidgets.QLabel(self.theme["main/mychumhandle/label/text"], self)
self.chumColorButton = QtWidgets.QPushButton(self)
self.chumColorButton.setObjectName("setprofilecolor")
self.chumColorButton.resize(50, 20)
self.chumColorButton.setStyleSheet("background: %s" % (userprofile.chat.colorhtml()))
self.chumcolor = userprofile.chat.color
self.chumColorButton.clicked.connect(self.openColorDialog)
layout_1 = QtWidgets.QHBoxLayout()
layout_1.addWidget(self.chumHandleLabel)
layout_1.addWidget(self.chumHandle)
layout_1.addWidget(self.chumColorButton)
# available profiles?
avail_profiles = self.config.availableProfiles()
if avail_profiles:
self.profileBox = QtWidgets.QComboBox(self)
self.profileBox.addItem("Choose a profile...")
for p in avail_profiles:
#PchumLog.debug("Adding profile: %s" % p.chat.handle)
self.profileBox.addItem(p.chat.handle)
else:
self.profileBox = None
self.defaultcheck = QtWidgets.QCheckBox(self)
self.defaultlabel = QtWidgets.QLabel("Set This Profile As Default", self)
layout_2 = QtWidgets.QHBoxLayout()
layout_2.addWidget(self.defaultlabel)
layout_2.addWidget(self.defaultcheck)
self.ok = QtWidgets.QPushButton("OK", self)
self.ok.setDefault(True)
self.ok.clicked.connect(self.validateProfile)
self.cancel = QtWidgets.QPushButton("CANCEL", self)
self.cancel.clicked.connect(self.reject)
if not collision and avail_profiles:
self.delete = QtWidgets.QPushButton("DELETE", self)
self.delete.clicked.connect(self.deleteProfile)
layout_ok = QtWidgets.QHBoxLayout()
layout_ok.addWidget(self.cancel)
layout_ok.addWidget(self.ok)
layout_0 = QtWidgets.QVBoxLayout()
if collision:
collision_warning = QtWidgets.QLabel("%s is taken already! Pick a new profile." % (collision))
layout_0.addWidget(collision_warning)
else:
layout_0.addWidget(self.currentHandle, alignment=QtCore.Qt.AlignHCenter)
layout_0.addLayout(layout_1)
if avail_profiles:
profileLabel = QtWidgets.QLabel("Or choose an existing profile:", self)
layout_0.addWidget(profileLabel)
layout_0.addWidget(self.profileBox)
layout_0.addLayout(layout_ok)
if not collision and avail_profiles:
layout_0.addWidget(self.delete)
layout_0.addLayout(layout_2)
self.errorMsg = QtWidgets.QLabel(self)
self.errorMsg.setObjectName("errormsg")
self.errorMsg.setStyleSheet("color:red;")
layout_0.addWidget(self.errorMsg)
self.setLayout(layout_0)
self.accepted.connect(parent.profileSelected)
self.rejected.connect(parent.closeProfile)
@QtCore.pyqtSlot()
def openColorDialog(self):
self.colorDialog = QtWidgets.QColorDialog(self)
color = self.colorDialog.getColor(initial=self.userprofile.chat.color)
self.chumColorButton.setStyleSheet("background: %s" % color.name())
self.chumcolor = color
self.colorDialog = None
@QtCore.pyqtSlot()
def validateProfile(self):
if not self.profileBox or self.profileBox.currentIndex() == 0:
handle = str(self.chumHandle.text())
if not PesterProfile.checkLength(handle):
self.errorMsg.setText("PROFILE HANDLE IS TOO LONG")
return
if not PesterProfile.checkValid(handle)[0]:
self.errorMsg.setText("NOT A VALID CHUMTAG. REASON:\n%s" % (PesterProfile.checkValid(handle)[1]))
return
self.accept()
@QtCore.pyqtSlot()
def deleteProfile(self):
if self.profileBox and self.profileBox.currentIndex() > 0:
handle = str(self.profileBox.currentText())
if handle == self.parent.profile().handle:
problem = QtWidgets.QMessageBox()
# karxi Will probably change this to its own name later.
problem.setObjectName("errmsg")
problem.setStyleSheet(self.theme["main/defaultwindow/style"])
problem.setWindowTitle("Problem!")
problem.setInformativeText("You can't delete the profile you're currently using!")
problem.setStandardButtons(QtWidgets.QMessageBox.Ok)
problem.exec_()
return
# TODO: Make this select 'no' as the default, as usual.
msgbox = QtWidgets.QMessageBox()
msgbox.setStyleSheet(self.theme["main/defaultwindow/style"])
msgbox.setWindowTitle("WARNING!")
msgbox.setInformativeText("Are you sure you want to delete the profile: %s" % (handle))
msgbox.setStandardButtons(QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Cancel)
ret = msgbox.exec_()
if ret == QtWidgets.QMessageBox.Ok:
try:
remove(_datadir+"profiles/%s.js" % (handle))
except OSError:
problem = QtWidgets.QMessageBox()
problem.setObjectName("errmsg")
problem.setStyleSheet(self.theme["main/defaultwindow/style"])
problem.setWindowTitle("Problem!")
problem.setInformativeText("There was a problem deleting the profile: %s" % (handle))
problem.setStandardButtons(QtWidgets.QMessageBox.Ok)
problem.exec_()
class PesterMentions(QtWidgets.QDialog):
def __init__(self, window, theme, parent):
QtWidgets.QDialog.__init__(self, parent)
self.setWindowTitle("Mentions")
self.setModal(True)
self.mainwindow = window
self.theme = theme
self.setStyleSheet(self.theme["main/defaultwindow/style"])
self.mentionlist = QtWidgets.QListWidget(self)
self.mentionlist.addItems(self.mainwindow.userprofile.getMentions())
self.addBtn = QtWidgets.QPushButton("ADD MENTION", self)
self.addBtn.clicked.connect(self.addMention)
self.editBtn = QtWidgets.QPushButton("EDIT", self)
self.editBtn.clicked.connect(self.editSelected)
self.rmBtn = QtWidgets.QPushButton("REMOVE", self)
self.rmBtn.clicked.connect(self.removeCurrent)
layout_1 = QtWidgets.QHBoxLayout()
layout_1.addWidget(self.editBtn)
layout_1.addWidget(self.rmBtn)
self.ok = QtWidgets.QPushButton("OK", self)
self.ok.setDefault(True)
self.ok.clicked.connect(self.accept)
self.cancel = QtWidgets.QPushButton("CANCEL", self)
self.cancel.clicked.connect(self.reject)
layout_2 = QtWidgets.QHBoxLayout()
layout_2.addWidget(self.cancel)
layout_2.addWidget(self.ok)
layout_0 = QtWidgets.QVBoxLayout()
layout_0.addWidget(self.mentionlist)
layout_0.addWidget(self.addBtn)
layout_0.addLayout(layout_1)
layout_0.addLayout(layout_2)
self.setLayout(layout_0)
@QtCore.pyqtSlot()
def editSelected(self):
m = self.mentionlist.currentItem()
if not m:
return
self.addMention(m)
@QtCore.pyqtSlot()
def addMention(self, mitem=None):
d = {"label": "Mention:", "inputname": "value" }
if mitem is not None:
d["value"] = str(mitem.text())
pdict = MultiTextDialog("ENTER MENTION", self, d).getText()
if pdict is None:
return
try:
re.compile(pdict["value"])
except re.error as e:
quirkWarning = QtWidgets.QMessageBox(self)
quirkWarning.setText("Not a valid regular expression!")
quirkWarning.setInformativeText("H3R3S WHY DUMP4SS: %s" % (e))
quirkWarning.exec_()
else:
if mitem is None:
self.mentionlist.addItem(pdict["value"])
else:
mitem.setText(pdict["value"])
@QtCore.pyqtSlot()
def removeCurrent(self):
i = self.mentionlist.currentRow()
if i >= 0:
self.mentionlist.takeItem(i)
class PesterOptions(QtWidgets.QDialog):
def __init__(self, config, theme, parent):
QtWidgets.QDialog.__init__(self, parent)
self.setWindowTitle("Options")
self.setModal(False)
self.config = config
self.theme = theme
self.setStyleSheet(self.theme["main/defaultwindow/style"])
layout_4 = QtWidgets.QVBoxLayout()
hr = QtWidgets.QFrame()
hr.setFrameShape(QtWidgets.QFrame.HLine)
hr.setFrameShadow(QtWidgets.QFrame.Sunken)
vr = QtWidgets.QFrame()
vr.setFrameShape(QtWidgets.QFrame.VLine)
vr.setFrameShadow(QtWidgets.QFrame.Sunken)
self.tabs = QtWidgets.QButtonGroup(self)
self.tabs.buttonClicked[int].connect(self.changePage)
tabNames = ["Chum List", "Conversations", "Interface", "Sound", "Notifications", "Logging", "Idle/Updates", "Theme", "Connection"]
if parent.advanced: tabNames.append("Advanced")
for t in tabNames:
button = QtWidgets.QPushButton(t)
self.tabs.addButton(button)
layout_4.addWidget(button)
button.setCheckable(True)
self.tabs.button(-2).setChecked(True)
self.pages = QtWidgets.QStackedWidget(self)
self.bandwidthcheck = QtWidgets.QCheckBox("Low Bandwidth", self)
if self.config.lowBandwidth():
self.bandwidthcheck.setChecked(True)
bandwidthLabel = QtWidgets.QLabel("(Stops you for receiving the flood of MOODS,\n"
" though stops chumlist from working properly)")
font = bandwidthLabel.font()
font.setPointSize(8)
bandwidthLabel.setFont(font)
self.autonickserv = QtWidgets.QCheckBox("Auto-Identify with NickServ", self)
self.autonickserv.setChecked(parent.userprofile.getAutoIdentify())
self.autonickserv.stateChanged[int].connect(self.autoNickServChange)
self.nickservpass = QtWidgets.QLineEdit(self)
self.nickservpass.setPlaceholderText("NickServ Password")
self.nickservpass.setEchoMode(QtWidgets.QLineEdit.PasswordEchoOnEdit)
self.nickservpass.setText(parent.userprofile.getNickServPass())
self.autojoinlist = QtWidgets.QListWidget(self)
self.autojoinlist.addItems(parent.userprofile.getAutoJoins())
self.addAutoJoinBtn = QtWidgets.QPushButton("Add", self)
self.addAutoJoinBtn.clicked.connect(self.addAutoJoin)
self.delAutoJoinBtn = QtWidgets.QPushButton("Remove", self)
self.delAutoJoinBtn.clicked.connect(self.delAutoJoin)
self.tabcheck = QtWidgets.QCheckBox("Tabbed Conversations", self)
if self.config.tabs():
self.tabcheck.setChecked(True)
self.tabmemocheck = QtWidgets.QCheckBox("Tabbed Memos", self)
if self.config.tabMemos():
self.tabmemocheck.setChecked(True)
self.hideOffline = QtWidgets.QCheckBox("Hide Offline Chums", self)
if self.config.hideOfflineChums():
self.hideOffline.setChecked(True)
self.soundcheck = QtWidgets.QCheckBox("Sounds On", self)
self.soundcheck.stateChanged[int].connect(self.soundChange)
self.chatsoundcheck = QtWidgets.QCheckBox("Pester Sounds", self)
self.chatsoundcheck.setChecked(self.config.chatSound())
self.memosoundcheck = QtWidgets.QCheckBox("Memo Sounds", self)
self.memosoundcheck.setChecked(self.config.memoSound())
self.memosoundcheck.stateChanged[int].connect(self.memoSoundChange)
self.memopingcheck = QtWidgets.QCheckBox("Memo Ping", self)
self.memopingcheck.setChecked(self.config.memoPing())
self.namesoundcheck = QtWidgets.QCheckBox("Memo Mention (initials)", self)
self.namesoundcheck.setChecked(self.config.nameSound())
if self.config.soundOn():
self.soundcheck.setChecked(True)
if not self.memosoundcheck.isChecked():
self.memoSoundChange(0)
else:
self.chatsoundcheck.setEnabled(False)
self.memosoundcheck.setEnabled(False)
self.memoSoundChange(0)
self.editMentions = QtWidgets.QPushButton("Edit Mentions", self)
self.editMentions.clicked.connect(self.openMentions)
self.editMentions2 = QtWidgets.QPushButton("Edit Mentions", self)
self.editMentions2.clicked.connect(self.openMentions)
self.volume = QtWidgets.QSlider(QtCore.Qt.Horizontal, self)
self.volume.setMinimum(0)
self.volume.setMaximum(100)
self.volume.setValue(self.config.volume())
self.volume.valueChanged[int].connect(self.printValue)
# Disable the volume slider if we can't actually use it.
if parent.canSetVolume():
self.currentVol = QtWidgets.QLabel(
"{0!s}%".format(self.config.volume()), self)
# We don't need to explicitly set this, but it helps drive the
# point home
self.volume.setEnabled(True)
else:
# We can't set the volume....
self.currentVol = QtWidgets.QLabel(
"(Disabled: Sound Mixer Error)", self)
self.volume.setEnabled(False)
self.currentVol.setAlignment(QtCore.Qt.AlignHCenter)
self.timestampcheck = QtWidgets.QCheckBox("Time Stamps", self)
if self.config.showTimeStamps():
self.timestampcheck.setChecked(True)
self.timestampBox = QtWidgets.QComboBox(self)
self.timestampBox.addItem("12 hour")
self.timestampBox.addItem("24 hour")
if self.config.time12Format():
self.timestampBox.setCurrentIndex(0)
else:
self.timestampBox.setCurrentIndex(1)
self.secondscheck = QtWidgets.QCheckBox("Show Seconds", self)
if self.config.showSeconds():
self.secondscheck.setChecked(True)
self.memomessagecheck = QtWidgets.QCheckBox("Show OP and Voice Messages in Memos", self)
if self.config.opvoiceMessages():
self.memomessagecheck.setChecked(True)
if not ostools.isOSXBundle():
self.animationscheck = QtWidgets.QCheckBox("Use animated smilies", self)
if self.config.animations():
self.animationscheck.setChecked(True)
animateLabel = QtWidgets.QLabel("(Disable if you leave chats open for LOOOONG periods of time)")
font = animateLabel.font()
font.setPointSize(8)
animateLabel.setFont(font)
self.userlinkscheck = QtWidgets.QCheckBox("Disable #Memo and @User Links", self)
self.userlinkscheck.setChecked(self.config.disableUserLinks())
self.userlinkscheck.setVisible(False)
# Will add ability to turn off groups later
#self.groupscheck = QtGui.QCheckBox("Use Groups", self)
#self.groupscheck.setChecked(self.config.useGroups())
self.showemptycheck = QtWidgets.QCheckBox("Show Empty Groups", self)
self.showemptycheck.setChecked(self.config.showEmptyGroups())
self.showonlinenumbers = QtWidgets.QCheckBox("Show Number of Online Chums", self)
self.showonlinenumbers.setChecked(self.config.showOnlineNumbers())
sortLabel = QtWidgets.QLabel("Sort Chums")
self.sortBox = QtWidgets.QComboBox(self)
self.sortBox.addItem("Alphabetically")
self.sortBox.addItem("By Mood")
self.sortBox.addItem("Manually")
method = self.config.sortMethod()
if method >= 0 and method < self.sortBox.count():
self.sortBox.setCurrentIndex(method)
layout_3 = QtWidgets.QHBoxLayout()
layout_3.addWidget(sortLabel)
layout_3.addWidget(self.sortBox, 10)
self.logpesterscheck = QtWidgets.QCheckBox("Log all Pesters", self)
if self.config.logPesters() & self.config.LOG:
self.logpesterscheck.setChecked(True)
self.logmemoscheck = QtWidgets.QCheckBox("Log all Memos", self)
if self.config.logMemos() & self.config.LOG:
self.logmemoscheck.setChecked(True)
self.stamppestercheck = QtWidgets.QCheckBox("Log Time Stamps for Pesters", self)
if self.config.logPesters() & self.config.STAMP:
self.stamppestercheck.setChecked(True)
self.stampmemocheck = QtWidgets.QCheckBox("Log Time Stamps for Memos", self)
if self.config.logMemos() & self.config.STAMP:
self.stampmemocheck.setChecked(True)
self.idleBox = QtWidgets.QSpinBox(self)
self.idleBox.setStyleSheet("background:#FFFFFF")
self.idleBox.setRange(1, 1440)
self.idleBox.setValue(self.config.idleTime())
layout_5 = QtWidgets.QHBoxLayout()
layout_5.addWidget(QtWidgets.QLabel("Minutes before Idle:"))
layout_5.addWidget(self.idleBox)
#self.updateBox = QtWidgets.QComboBox(self)
#self.updateBox.addItem("Once a Day")
#self.updateBox.addItem("Once a Week")
#self.updateBox.addItem("Only on Start")
#self.updateBox.addItem("Never")
#check = self.config.checkForUpdates()
#if check >= 0 and check < self.updateBox.count():
# self.updateBox.setCurrentIndex(check)
layout_6 = QtWidgets.QHBoxLayout()
#layout_6.addWidget(QtWidgets.QLabel("Check for\nPesterchum Updates:"))
#layout_6.addWidget(self.updateBox)
#if not ostools.isOSXLeopard():
# self.mspaCheck = QtWidgets.QCheckBox("Check for MSPA Updates", self)
# self.mspaCheck.setChecked(self.config.checkMSPA())
self.randomscheck = QtWidgets.QCheckBox("Receive Random Encounters")
self.randomscheck.setChecked(parent.userprofile.randoms)
if not parent.randhandler.running:
self.randomscheck.setEnabled(False)
avail_themes = self.config.availableThemes()
self.themeBox = QtWidgets.QComboBox(self)
notheme = (theme.name not in avail_themes)
for (i, t) in enumerate(avail_themes):
self.themeBox.addItem(t)
if (not notheme and t == theme.name) or (notheme and t == "pesterchum"):
self.themeBox.setCurrentIndex(i)
self.refreshtheme = QtWidgets.QPushButton("Refresh current theme", self)
self.refreshtheme.clicked.connect(parent.themeSelectOverride)
self.ghostchum = QtWidgets.QCheckBox("Pesterdunk Ghostchum!!", self)
self.ghostchum.setChecked(self.config.ghostchum())
self.buttonOptions = ["Minimize to Taskbar", "Minimize to Tray", "Quit"]
self.miniBox = QtWidgets.QComboBox(self)
self.miniBox.addItems(self.buttonOptions)
self.miniBox.setCurrentIndex(self.config.minimizeAction())
self.closeBox = QtWidgets.QComboBox(self)
self.closeBox.addItems(self.buttonOptions)
self.closeBox.setCurrentIndex(self.config.closeAction())
layout_mini = QtWidgets.QHBoxLayout()
layout_mini.addWidget(QtWidgets.QLabel("Minimize"))
layout_mini.addWidget(self.miniBox)
layout_close = QtWidgets.QHBoxLayout()
layout_close.addWidget(QtWidgets.QLabel("Close"))
layout_close.addWidget(self.closeBox)
self.pesterBlink = QtWidgets.QCheckBox("Blink Taskbar on Pesters", self)
if self.config.blink() & self.config.PBLINK:
self.pesterBlink.setChecked(True)
self.memoBlink = QtWidgets.QCheckBox("Blink Taskbar on Memos", self)
if self.config.blink() & self.config.MBLINK:
self.memoBlink.setChecked(True)
self.notifycheck = QtWidgets.QCheckBox("Toast Notifications", self)
if self.config.notify():
self.notifycheck.setChecked(True)
self.notifycheck.stateChanged[int].connect(self.notifyChange)
self.notifyOptions = QtWidgets.QComboBox(self)
types = self.parent().tm.availableTypes()
cur = self.parent().tm.currentType()
self.notifyOptions.addItems(types)
for (i,t) in enumerate(types):
if t == cur:
self.notifyOptions.setCurrentIndex(i)
break
self.notifyTypeLabel = QtWidgets.QLabel("Type", self)
layout_type = QtWidgets.QHBoxLayout()
layout_type.addWidget(self.notifyTypeLabel)
layout_type.addWidget(self.notifyOptions)
self.notifySigninCheck = QtWidgets.QCheckBox("Chum signs in", self)
if self.config.notifyOptions() & self.config.SIGNIN:
self.notifySigninCheck.setChecked(True)
self.notifySignoutCheck = QtWidgets.QCheckBox("Chum signs out", self)
if self.config.notifyOptions() & self.config.SIGNOUT:
self.notifySignoutCheck.setChecked(True)
self.notifyNewMsgCheck = QtWidgets.QCheckBox("New messages", self)
if self.config.notifyOptions() & self.config.NEWMSG:
self.notifyNewMsgCheck.setChecked(True)
self.notifyNewConvoCheck = QtWidgets.QCheckBox("Only new conversations", self)
if self.config.notifyOptions() & self.config.NEWCONVO:
self.notifyNewConvoCheck.setChecked(True)
self.notifyMentionsCheck = QtWidgets.QCheckBox("Memo Mentions (initials)", self)
if self.config.notifyOptions() & self.config.INITIALS:
self.notifyMentionsCheck.setChecked(True)
self.notifyChange(self.notifycheck.checkState())
if parent.advanced:
# NOTE: This doesn't do anything right now - so change it!
self.modechange = QtWidgets.QLineEdit(self)
layout_change = QtWidgets.QHBoxLayout()
layout_change.addWidget(QtWidgets.QLabel("Change:"))
layout_change.addWidget(self.modechange)
self.ok = QtWidgets.QPushButton("OK", self)
self.ok.setDefault(True)
self.ok.clicked.connect(self.accept)
self.cancel = QtWidgets.QPushButton("CANCEL", self)
self.cancel.clicked.connect(self.reject)
layout_2 = QtWidgets.QHBoxLayout()
layout_2.addWidget(self.cancel)
layout_2.addWidget(self.ok)
# Tab layouts
# Chum List
widget = QtWidgets.QWidget()
layout_chumlist = QtWidgets.QVBoxLayout(widget)
layout_chumlist.setAlignment(QtCore.Qt.AlignTop)
layout_chumlist.addWidget(self.hideOffline)
#layout_chumlist.addWidget(self.groupscheck)
layout_chumlist.addWidget(self.showemptycheck)
layout_chumlist.addWidget(self.showonlinenumbers)
layout_chumlist.addLayout(layout_3)
self.pages.addWidget(widget)
# Conversations
widget = QtWidgets.QWidget()
layout_chat = QtWidgets.QVBoxLayout(widget)
layout_chat.setAlignment(QtCore.Qt.AlignTop)
layout_chat.addWidget(self.timestampcheck)
layout_chat.addWidget(self.timestampBox)
layout_chat.addWidget(self.secondscheck)
layout_chat.addWidget(self.memomessagecheck)
if not ostools.isOSXBundle():
layout_chat.addWidget(self.animationscheck)
layout_chat.addWidget(animateLabel)
layout_chat.addWidget(self.randomscheck)
# Re-enable these when it's possible to disable User and Memo links
#layout_chat.addWidget(hr)
#layout_chat.addWidget(QtGui.QLabel("User and Memo Links"))
#layout_chat.addWidget(self.userlinkscheck)
self.pages.addWidget(widget)
# Interface
widget = QtWidgets.QWidget()
layout_interface = QtWidgets.QVBoxLayout(widget)
layout_interface.setAlignment(QtCore.Qt.AlignTop)
layout_interface.addWidget(self.tabcheck)
layout_interface.addWidget(self.tabmemocheck)
layout_interface.addLayout(layout_mini)
layout_interface.addLayout(layout_close)
layout_interface.addWidget(self.pesterBlink)
layout_interface.addWidget(self.memoBlink)
self.pages.addWidget(widget)
# Sound
widget = QtWidgets.QWidget()
layout_sound = QtWidgets.QVBoxLayout(widget)
layout_sound.setAlignment(QtCore.Qt.AlignTop)
layout_sound.addWidget(self.soundcheck)
layout_indent = QtWidgets.QVBoxLayout()
layout_indent.addWidget(self.chatsoundcheck)
layout_indent.addWidget(self.memosoundcheck)
layout_doubleindent = QtWidgets.QVBoxLayout()
layout_doubleindent.addWidget(self.memopingcheck)
layout_doubleindent.addWidget(self.namesoundcheck)
layout_doubleindent.addWidget(self.editMentions)
layout_doubleindent.setContentsMargins(22,0,0,0)
layout_indent.addLayout(layout_doubleindent)
layout_indent.setContentsMargins(22,0,0,0)
layout_sound.addLayout(layout_indent)
layout_sound.addSpacing(15)
mvol = QtWidgets.QLabel("Master Volume:", self)
# If we can't set the volume, grey this out as well
#~mvol.setEnabled(parent.canSetVolume())
# Normally we'd grey this out, but that presently makes things
# rather unreadable
# Later we can look into changing the color to a theme[] entry
layout_sound.addWidget(mvol)
layout_sound.addWidget(self.volume)
layout_sound.addWidget(self.currentVol)
self.pages.addWidget(widget)
# Notifications
widget = QtWidgets.QWidget()
layout_notify = QtWidgets.QVBoxLayout(widget)
layout_notify.setAlignment(QtCore.Qt.AlignTop)
layout_notify.addWidget(self.notifycheck)
layout_indent = QtWidgets.QVBoxLayout()
layout_indent.addLayout(layout_type)
layout_indent.setContentsMargins(22,0,0,0)
layout_indent.addWidget(self.notifySigninCheck)
layout_indent.addWidget(self.notifySignoutCheck)
layout_indent.addWidget(self.notifyNewMsgCheck)
layout_doubleindent = QtWidgets.QVBoxLayout()
layout_doubleindent.addWidget(self.notifyNewConvoCheck)
layout_doubleindent.setContentsMargins(22,0,0,0)
layout_indent.addLayout(layout_doubleindent)
layout_indent.addWidget(self.notifyMentionsCheck)
layout_indent.addWidget(self.editMentions2)
layout_notify.addLayout(layout_indent)
self.pages.addWidget(widget)
# Logging
widget = QtWidgets.QWidget()
layout_logs = QtWidgets.QVBoxLayout(widget)
layout_logs.setAlignment(QtCore.Qt.AlignTop)
layout_logs.addWidget(self.logpesterscheck)
layout_logs.addWidget(self.logmemoscheck)
layout_logs.addWidget(self.stamppestercheck)
layout_logs.addWidget(self.stampmemocheck)
self.pages.addWidget(widget)
# Idle/Updates
widget = QtWidgets.QWidget()
layout_idle = QtWidgets.QVBoxLayout(widget)
layout_idle.setAlignment(QtCore.Qt.AlignTop)
layout_idle.addLayout(layout_5)
layout_idle.addLayout(layout_6)
#if not ostools.isOSXLeopard():
# layout_idle.addWidget(self.mspaCheck)
self.pages.addWidget(widget)
# Theme
widget = QtWidgets.QWidget()
layout_theme = QtWidgets.QVBoxLayout(widget)
layout_theme.setAlignment(QtCore.Qt.AlignTop)
layout_theme.addWidget(QtWidgets.QLabel("Pick a Theme:"))
layout_theme.addWidget(self.themeBox)
layout_theme.addWidget(self.refreshtheme)
layout_theme.addWidget(self.ghostchum)
self.pages.addWidget(widget)
# Connection
widget = QtWidgets.QWidget()
layout_connect = QtWidgets.QVBoxLayout(widget)
layout_connect.setAlignment(QtCore.Qt.AlignTop)
layout_connect.addWidget(self.bandwidthcheck)
layout_connect.addWidget(bandwidthLabel)
layout_connect.addWidget(self.autonickserv)
layout_indent = QtWidgets.QVBoxLayout()
layout_indent.addWidget(self.nickservpass)
layout_indent.setContentsMargins(22,0,0,0)
layout_connect.addLayout(layout_indent)
layout_connect.addWidget(QtWidgets.QLabel("Auto-Join Memos:"))
layout_connect.addWidget(self.autojoinlist)
layout_8 = QtWidgets.QHBoxLayout()
layout_8.addWidget(self.addAutoJoinBtn)
layout_8.addWidget(self.delAutoJoinBtn)
layout_connect.addLayout(layout_8)
self.pages.addWidget(widget)
# Advanced
if parent.advanced:
widget = QtWidgets.QWidget()
layout_advanced = QtWidgets.QVBoxLayout(widget)
layout_advanced.setAlignment(QtCore.Qt.AlignTop)
layout_advanced.addWidget(QtWidgets.QLabel("Current User Mode: %s" % parent.modes))
layout_advanced.addLayout(layout_change)
self.pages.addWidget(widget)
layout_0 = QtWidgets.QVBoxLayout()
layout_1 = QtWidgets.QHBoxLayout()
layout_1.addLayout(layout_4)
layout_1.addWidget(vr)
layout_1.addWidget(self.pages)
layout_0.addLayout(layout_1)
layout_0.addSpacing(30)
layout_0.addLayout(layout_2)
self.setLayout(layout_0)
@QtCore.pyqtSlot(int)
def changePage(self, page):
self.tabs.button(page).setChecked(True)
# What is this, I don't even. qt, fuck
page = -page - 2
self.pages.setCurrentIndex(page)
@QtCore.pyqtSlot(int)
def notifyChange(self, state):
if state == 0:
self.notifyTypeLabel.setEnabled(False)
self.notifyOptions.setEnabled(False)
self.notifySigninCheck.setEnabled(False)
self.notifySignoutCheck.setEnabled(False)
self.notifyNewMsgCheck.setEnabled(False)
self.notifyNewConvoCheck.setEnabled(False)
self.notifyMentionsCheck.setEnabled(False)
else:
self.notifyTypeLabel.setEnabled(True)
self.notifyOptions.setEnabled(True)
self.notifySigninCheck.setEnabled(True)
self.notifySignoutCheck.setEnabled(True)
self.notifyNewMsgCheck.setEnabled(True)
self.notifyNewConvoCheck.setEnabled(True)
self.notifyMentionsCheck.setEnabled(True)
@QtCore.pyqtSlot(int)
def autoNickServChange(self, state):
self.nickservpass.setEnabled(state != 0)
@QtCore.pyqtSlot()
def addAutoJoin(self, mitem=None):
d = {"label": "Memo:", "inputname": "value" }
if mitem is not None:
d["value"] = str(mitem.text())
pdict = MultiTextDialog("ENTER MEMO", self, d).getText()
if pdict is None:
return
pdict["value"] = "#" + pdict["value"]
if mitem is None:
items = self.autojoinlist.findItems(pdict["value"], QtCore.Qt.MatchFixedString)
if len(items) == 0:
self.autojoinlist.addItem(pdict["value"])
else:
mitem.setText(pdict["value"])
@QtCore.pyqtSlot()
def delAutoJoin(self):
i = self.autojoinlist.currentRow()
if i >= 0:
self.autojoinlist.takeItem(i)
@QtCore.pyqtSlot(int)
def soundChange(self, state):
if state == 0:
self.chatsoundcheck.setEnabled(False)
self.memosoundcheck.setEnabled(False)
self.memoSoundChange(0)
else:
self.chatsoundcheck.setEnabled(True)
self.memosoundcheck.setEnabled(True)
if self.memosoundcheck.isChecked():
self.memoSoundChange(1)
@QtCore.pyqtSlot(int)
def memoSoundChange(self, state):
if state == 0:
self.memopingcheck.setEnabled(False)
self.namesoundcheck.setEnabled(False)
else:
self.memopingcheck.setEnabled(True)
self.namesoundcheck.setEnabled(True)
@QtCore.pyqtSlot(int)
def printValue(self, v):
self.currentVol.setText(str(v)+"%")
@QtCore.pyqtSlot()
def openMentions(self):
if not hasattr(self, 'mentionmenu'):
self.mentionmenu = None
if not self.mentionmenu:
self.mentionmenu = PesterMentions(self.parent(), self.theme, self)
self.mentionmenu.accepted.connect(self.updateMentions)
self.mentionmenu.rejected.connect(self.closeMentions)
self.mentionmenu.show()
self.mentionmenu.raise_()
self.mentionmenu.activateWindow()
@QtCore.pyqtSlot()
def closeMentions(self):
self.mentionmenu.close()
self.mentionmenu = None
@QtCore.pyqtSlot()
def updateMentions(self):
m = []
for i in range(self.mentionmenu.mentionlist.count()):
m.append(str(self.mentionmenu.mentionlist.item(i).text()))
self.parent().userprofile.setMentions(m)
self.mentionmenu = None
class PesterUserlist(QtWidgets.QDialog):
def __init__(self, config, theme, parent):
QtWidgets.QDialog.__init__(self, parent)
self.setModal(False)
self.config = config
self.theme = theme
self.mainwindow = parent
self.setStyleSheet(self.theme["main/defaultwindow/style"])
self.resize(200, 600)
self.searchbox = QtWidgets.QLineEdit(self)
#self.searchbox.setStyleSheet(theme["convo/input/style"]) # which style is better?
self.searchbox.setPlaceholderText("Search")
self.searchbox.textChanged['QString'].connect(self.updateUsers)
self.label = QtWidgets.QLabel("USERLIST")
self.userarea = RightClickList(self)
self.userarea.setStyleSheet(self.theme["main/chums/style"])
self.userarea.optionsMenu = QtWidgets.QMenu(self)
self.addChumAction = QtWidgets.QAction(self.mainwindow.theme["main/menus/rclickchumlist/addchum"], self)
self.addChumAction.triggered.connect(self.addChumSlot)
self.pesterChumAction = QtWidgets.QAction(self.mainwindow.theme["main/menus/rclickchumlist/pester"], self)
self.pesterChumAction.triggered.connect(self.pesterChumSlot)
self.userarea.optionsMenu.addAction(self.addChumAction)
self.userarea.optionsMenu.addAction(self.pesterChumAction)
self.ok = QtWidgets.QPushButton("OK", self)
self.ok.setDefault(True)
self.ok.clicked.connect(self.accept)
layout_0 = QtWidgets.QVBoxLayout()
layout_0.addWidget(self.label)
layout_0.addWidget(self.userarea)
layout_0.addWidget(self.searchbox)
layout_0.addWidget(self.ok)
self.setLayout(layout_0)
self.mainwindow.namesUpdated.connect(self.updateUsers)
self.mainwindow.userPresentSignal['QString', 'QString', 'QString'].connect(self.updateUserPresent)
self.updateUsers()
self.searchbox.setFocus()
@QtCore.pyqtSlot()
def updateUsers(self):
names = self.mainwindow.namesdb["#pesterchum"]
self.userarea.clear()
for n in names:
if str(self.searchbox.text()) == "" or n.lower().find(str(self.searchbox.text()).lower()) != -1:
item = QtWidgets.QListWidgetItem(n)
item.setForeground(QtGui.QBrush(QtGui.QColor(self.theme["main/chums/userlistcolor"])))
self.userarea.addItem(item)
self.userarea.sortItems()
@QtCore.pyqtSlot(QString, QString, QString)
def updateUserPresent(self, handle, channel, update):
h = str(handle)
c = str(channel)
if update == "quit":
self.delUser(h)
elif update == "left" and c == "#pesterchum":
self.delUser(h)
elif update == "join" and c == "#pesterchum":
if str(self.searchbox.text()) == "" or h.lower().find(str(self.searchbox.text()).lower()) != -1:
self.addUser(h)
def addUser(self, name):
item = QtWidgets.QListWidgetItem(name)
item.setForeground(QtGui.QBrush(QtGui.QColor(self.theme["main/chums/userlistcolor"])))
self.userarea.addItem(item)
self.userarea.sortItems()
def delUser(self, name):
matches = self.userarea.findItems(name, QtCore.Qt.MatchFlags(0))
for m in matches:
self.userarea.takeItem(self.userarea.row(m))
def changeTheme(self, theme):
self.theme = theme
self.setStyleSheet(theme["main/defaultwindow/style"])
self.userarea.setStyleSheet(theme["main/chums/style"])
self.addChumAction.setText(theme["main/menus/rclickchumlist/addchum"])
for item in [self.userarea.item(i) for i in range(0, self.userarea.count())]:
item.setForeground(0, QtGui.QBrush(QtGui.QColor(theme["main/chums/userlistcolor"])))
@QtCore.pyqtSlot()
def addChumSlot(self):
cur = self.userarea.currentItem()
if not cur:
return
self.addChum.emit(cur.text())
@QtCore.pyqtSlot()
def pesterChumSlot(self):
cur = self.userarea.currentItem()
if not cur:
return
self.pesterChum.emit(cur.text())
addChum = QtCore.pyqtSignal('QString')
pesterChum = QtCore.pyqtSignal('QString')
class MemoListItem(QtWidgets.QTreeWidgetItem):
def __init__(self, channel, usercount):
QtWidgets.QTreeWidgetItem.__init__(self, [channel, str(usercount)])
self.target = channel
def __lt__(self, other):
column = self.treeWidget().sortColumn()
if str(self.text(column)).isdigit() and str(other.text(column)).isdigit():
return int(self.text(column)) < int(other.text(column))
return self.text(column) < other.text(column)
class PesterMemoList(QtWidgets.QDialog):
def __init__(self, parent, channel=""):
QtWidgets.QDialog.__init__(self, parent)
self.setModal(False)
self.theme = parent.theme
self.mainwindow = parent
self.setStyleSheet(self.theme["main/defaultwindow/style"])
self.resize(460, 300)
self.label = QtWidgets.QLabel("MEMOS")
self.channelarea = RightClickTree(self)
self.channelarea.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
self.channelarea.setStyleSheet(self.theme["main/chums/style"])
self.channelarea.optionsMenu = QtWidgets.QMenu(self)
self.channelarea.setColumnCount(2)
self.channelarea.setHeaderLabels(["Memo", "Users"])
self.channelarea.setIndentation(0)
self.channelarea.setColumnWidth(0,200)
self.channelarea.setColumnWidth(1,10)
self.channelarea.setSortingEnabled(True)
self.channelarea.sortByColumn(0, QtCore.Qt.AscendingOrder)
self.channelarea.itemDoubleClicked[QtWidgets.QTreeWidgetItem, int].connect(self.AcceptSelection)
self.orjoinlabel = QtWidgets.QLabel("OR MAKE A NEW MEMO:")
self.newmemo = QtWidgets.QLineEdit(channel, self)
self.secretChannel = QtWidgets.QCheckBox("HIDDEN CHANNEL?", self)
self.inviteChannel = QtWidgets.QCheckBox("INVITATION ONLY?", self)
self.timelabel = QtWidgets.QLabel("TIMEFRAME:")
self.timeslider = TimeSlider(QtCore.Qt.Horizontal, self)
self.timeinput = TimeInput(self.timeslider, self)
self.cancel = QtWidgets.QPushButton("CANCEL", self)
self.cancel.clicked.connect(self.reject)
self.join = QtWidgets.QPushButton("JOIN", self)
self.join.setDefault(True)
self.join.clicked.connect(self.AcceptIfSelectionMade)
layout_ok = QtWidgets.QHBoxLayout()
layout_ok.addWidget(self.cancel)
layout_ok.addWidget(self.join)
layout_left = QtWidgets.QVBoxLayout()
layout_right = QtWidgets.QVBoxLayout()
layout_right.setAlignment(QtCore.Qt.AlignTop)
layout_0 = QtWidgets.QVBoxLayout()
layout_1 = QtWidgets.QHBoxLayout()
layout_left.addWidget(self.label)
layout_left.addWidget(self.channelarea)
layout_right.addWidget(self.orjoinlabel)
layout_right.addWidget(self.newmemo)
layout_right.addWidget(self.secretChannel)
layout_right.addWidget(self.inviteChannel)
layout_right.addWidget(self.timelabel)
layout_right.addWidget(self.timeslider)
layout_right.addWidget(self.timeinput)
layout_1.addLayout(layout_left)
layout_1.addLayout(layout_right)
layout_0.addLayout(layout_1)
layout_0.addLayout(layout_ok)
self.setLayout(layout_0)
def newmemoname(self):
return self.newmemo.text()
def SelectedMemos(self):
return self.channelarea.selectedItems()
def HasSelection(self):
return len(self.SelectedMemos()) > 0 or self.newmemoname()
def updateChannels(self, channels):
for c in channels:
item = MemoListItem(c[0][1:],c[1])
item.setForeground(0, QtGui.QBrush(QtGui.QColor(self.theme["main/chums/userlistcolor"])))
item.setForeground(1, QtGui.QBrush(QtGui.QColor(self.theme["main/chums/userlistcolor"])))
item.setIcon(0, QtGui.QIcon(self.theme["memos/memoicon"]))
self.channelarea.addTopLevelItem(item)
def updateTheme(self, theme):
self.theme = theme
self.setStyleSheet(theme["main/defaultwindow/style"])
for item in [self.userarea.item(i) for i in range(0, self.channelarea.count())]:
item.setForeground(0, QtGui.QBrush(QtGui.QColor(theme["main/chums/userlistcolor"])))
item.setIcon(QtGui.QIcon(theme["memos/memoicon"]))
@QtCore.pyqtSlot()
def AcceptIfSelectionMade(self):
if self.HasSelection():
self.AcceptSelection()
@QtCore.pyqtSlot()
def AcceptSelection(self):
self.accept()
class LoadingScreen(QtWidgets.QDialog):
tryAgain = QtCore.pyqtSignal()
def __init__(self, parent=None):
QtWidgets.QDialog.__init__(self, parent, (QtCore.Qt.CustomizeWindowHint |
QtCore.Qt.FramelessWindowHint))
self.mainwindow = parent
self.setStyleSheet(self.mainwindow.theme["main/defaultwindow/style"])
self.loadinglabel = QtWidgets.QLabel("CONN3CT1NG", self)
self.cancel = QtWidgets.QPushButton("QU1T >:?", self)
self.ok = QtWidgets.QPushButton("R3CONN3CT >:]", self)
# Help reduce the number of accidental Pesterchum closures... :|
self.cancel.setAutoDefault(False)
self.ok.setAutoDefault(True)
self.cancel.clicked.connect(self.reject)
self.ok.clicked.connect(self.tryAgain)
self.layout = QtWidgets.QVBoxLayout()
self.layout.addWidget(self.loadinglabel)
layout_1 = QtWidgets.QHBoxLayout()
layout_1.addWidget(self.cancel)
layout_1.addWidget(self.ok)
self.layout.addLayout(layout_1)
self.setLayout(self.layout)
# Help reduce the number of accidental Pesterchum closures... :|
self.cancel.setDefault(False)
self.ok.setDefault(True)
self.ok.setFocus()
self.timer = None
def hideReconnect(self, safe=True):
self.ok.hide()
if safe:
# Set a timer so that we don't immediately disconnect anyway.
self.cancel.setEnabled(False)
# A few seconds should be enough.
self.timer = QtCore.QTimer.singleShot(2000, self.enableQuit)
def showReconnect(self):
self.ok.show()
# Again...stop accidental closes.
self.ok.setFocus()
@QtCore.pyqtSlot()
def enableQuit(self):
self.cancel.setEnabled(True)
tryAgain = QtCore.pyqtSignal()
class AboutPesterchum(QtWidgets.QDialog):
def __init__(self, parent=None):
QtWidgets.QDialog.__init__(self, parent)
self.mainwindow = parent
self.setStyleSheet(self.mainwindow.theme["main/defaultwindow/style"])
self.title = QtWidgets.QLabel("P3ST3RCHUM %s" % (_pcVersion))
self.credits = QtWidgets.QLabel("Programming by:\n\
illuminatedwax (ghostDunk)\n\
Kiooeht (evacipatedBox)\n\
Lexi (lexicalNuance)\n\
oakwhiz\n\
alGore\n\
Cerxi (binaryCabalist)\n\
Arcane (arcaneAgilmente)\n\
karxi (Midna)\n\
Shou :)\n\
\n\
Art by:\n\
Grimlive (aquaMarinist)\n\
Cerxi (binaryCabalist)\n\
\n\
Special Thanks:\n\
ABT\n\
gamblingGenocider\n\
Eco-Mono")
self.ok = QtWidgets.QPushButton("OK", self)
self.ok.clicked.connect(self.reject)
layout_0 = QtWidgets.QVBoxLayout()
layout_0.addWidget(self.title)
layout_0.addWidget(self.credits)
layout_0.addWidget(self.ok)
self.setLayout(layout_0)
class UpdatePesterchum(QtWidgets.QDialog):
def __init__(self, ver, url, parent=None):
QtWidgets.QDialog.__init__(self, parent)
self.url = url
self.mainwindow = parent
self.setStyleSheet(self.mainwindow.theme["main/defaultwindow/style"])
self.setWindowTitle("Pesterchum v%s Update" % (ver))
self.setModal(False)
self.title = QtWidgets.QLabel("An update to Pesterchum is available!")
layout_0 = QtWidgets.QVBoxLayout()
layout_0.addWidget(self.title)
self.ok = QtWidgets.QPushButton("D0WNL04D 4ND 1NST4LL N0W", self)
self.ok.setDefault(True)
self.ok.clicked.connect(self.accept)
self.cancel = QtWidgets.QPushButton("CANCEL", self)
self.cancel.clicked.connect(self.reject)
layout_2 = QtWidgets.QHBoxLayout()
layout_2.addWidget(self.cancel)
layout_2.addWidget(self.ok)
layout_0.addLayout(layout_2)
self.setLayout(layout_0)
class AddChumDialog(QtWidgets.QDialog):
def __init__(self, avail_groups, parent=None):
QtWidgets.QDialog.__init__(self, parent)
self.mainwindow = parent
self.setStyleSheet(self.mainwindow.theme["main/defaultwindow/style"])
self.setWindowTitle("Enter Chum Handle")
self.setModal(True)
self.title = QtWidgets.QLabel("Enter Chum Handle")
self.chumBox = QtWidgets.QLineEdit(self)
self.groupBox = QtWidgets.QComboBox(self)
avail_groups.sort()
avail_groups.pop(avail_groups.index("Chums"))
avail_groups.insert(0, "Chums")
for g in avail_groups:
self.groupBox.addItem(g)
self.newgrouplabel = QtWidgets.QLabel("Or make a new group:")
self.newgroup = QtWidgets.QLineEdit(self)
layout_0 = QtWidgets.QVBoxLayout()
layout_0.addWidget(self.title)
layout_0.addWidget(self.chumBox)
layout_0.addWidget(self.groupBox)
layout_0.addWidget(self.newgrouplabel)
layout_0.addWidget(self.newgroup)
self.ok = QtWidgets.QPushButton("OK", self)
self.ok.setDefault(True)
self.ok.clicked.connect(self.accept)
self.cancel = QtWidgets.QPushButton("CANCEL", self)
self.cancel.clicked.connect(self.reject)
layout_2 = QtWidgets.QHBoxLayout()
layout_2.addWidget(self.cancel)
layout_2.addWidget(self.ok)
layout_0.addLayout(layout_2)
self.setLayout(layout_0)