This commit is contained in:
Stephen Dranger 2011-01-31 17:43:49 -06:00
parent 0337a77bb5
commit 7cc312a4bd
13 changed files with 133 additions and 44 deletions

17
TODO
View file

@ -1,11 +1,15 @@
Features:
-- package
* CEASE shouldn't be sent if chum window is closed
* icon not restored after client logs back on -- User signon
* color is lost if you close window!
* chumdb still trying to serialize QString?
* Windows: courier doesn't bold??
* Transparent background
* switch focus to lineedit
* colors from ppl msging you not on your buddy list dont work
* colors from ppl msging you not on your buddy list dont work - check chumdb
* scaling icons
* menubar should pass on mouse move
* chat scrolls when switch theme
* softcode menu names and protocol messages, menu location
* eliminate "SWITCH" in profile menu
* windows text goes gray when out of focus
* Logging
* Block list
* User list/add from list
@ -13,10 +17,9 @@ Features:
* User commands/stop user from sending commands accidentally
* Hyperlinks
* color tags
* Transparent background
* /me
-- release alpha
* shared buddy lists - changes to the buddy list should refresh it?
* shared buddy lists - changes to the buddy list should refresh it?
multiple clients share buddy list???
* User profile menu options (color...?)
* System tray menu

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -1 +1 @@
{"tabs": true, "chums": ["aquaMarinist", "gardenGnostic", "gamblingGenocider", "schlagzeugGator", "mechanicalSpectacle"]}
{"tabs": true, "chums": ["aquaMarinist", "gardenGnostic", "gamblingGenocider", "schlagzeugGator", "mechanicalSpectacle", "marineAquist"], "defaultprofile": "testProfile"}

View file

@ -64,10 +64,47 @@ class waitingMessageHolder(object):
class NoneSound(object):
def play(self): pass
class PesterProfileDB(dict):
def __init__(self):
try:
fp = open("logs/chums.js", 'r')
chumdict = json.load(fp)
fp.close()
except IOError:
chumdict = {}
fp = open("logs/chums.js", 'w')
json.dump(chumdict, fp)
fp.close()
converted = dict([(handle, PesterProfile(handle, color=QtGui.Color(c['color']), mood=Mood(c['mood']))) for (handle, c) in chumdict.iteritems()])
self.update(converted)
def save(self):
fp = open("logs/chums.js", 'w')
chumdict = dict([p.plaindict() for p in self.itervalues()])
json.dump(chumdict, fp)
fp.close()
def getColor(self, handle, default=None):
if not self.has_key(handle):
return default
else:
return self[handle]["color"]
def setColor(self, handle, color):
if self.has_key(handle):
self[handle].color = color
else:
self[handle] = PesterProfile(handle, color)
def __setitem__(self, key, val):
dict.__setitem__(self, key, val)
self.save()
class PesterProfile(object):
def __init__(self, handle, color=QtGui.QColor("black"),
mood=Mood("offline")):
def __init__(self, handle, color=None, mood=Mood("offline"), chumdb=None):
self.handle = handle
if color is None:
if chumdb:
color = chumdb.getColor(handle, QtGui.QColor("black"))
else:
color = QtGui.QColor("black")
self.color = color
self.mood = mood
def initials(self):
@ -81,6 +118,11 @@ class PesterProfile(object):
def colorcmd(self):
(r, g, b, a) = self.color.getRgb()
return "%d,%d,%d" % (r,g,b)
def plaindict(self):
return (self.handle, {"handle": self.handle,
"mood": self.mood.name(),
"color": unicode(self.color.name())})
def beganpestermsg(self, otherchum):
return "<span style='color:black;'>-- %s <span style='color:%s'>[%s]</span> began pestering %s <span style='color:%s'>[%s]</span> at %s --</span>" % (self.handle, self.colorhtml(), self.initials(), otherchum.handle, otherchum.colorhtml(), otherchum.initials(), datetime.now().strftime("%H:%M"))
def ceasedpestermsg(self, otherchum):
@ -230,7 +272,11 @@ class userProfile(object):
fp = open("profiles/%s.js" % (user))
self.userprofile = json.load(fp)
fp.close()
self.theme = pesterTheme(self.userprofile["theme"])
try:
self.theme = pesterTheme(self.userprofile["theme"])
except ValueError, e:
self.theme = pesterTheme("pesterchum")
self.chat = PesterProfile(self.userprofile["handle"],
QtGui.QColor(self.userprofile["color"]),
Mood(self.theme["main/defaultmood"]))
@ -310,7 +356,7 @@ class PesterQuirkItem(QtGui.QListWidgetItem):
def __init__(self, quirk, parent):
QtGui.QListWidgetItem.__init__(self, parent)
self.quirk = quirk
self.setText(str(quirk))
self.setText(unicode(quirk))
def __lt__(self, quirkitem):
if self.quirk.type == "prefix":
@ -1018,7 +1064,7 @@ class PesterConvo(QtGui.QFrame):
def updateMood(self, mood):
if mood.name() == "offline":
msg = self.mainwindow.profile().ceasepestermsg(self.chum)
msg = self.mainwindow.profile().ceasedpestermsg(self.chum)
self.textArea.append(msg)
self.chumopen = False
if self.parent():
@ -1156,6 +1202,8 @@ class PesterWindow(MovingWindow):
self.connect(self.miniButton, QtCore.SIGNAL('clicked()'),
self, QtCore.SLOT('showMinimized()'))
self.chumdb = PesterProfileDB()
chums = [PesterProfile(c) for c in set(self.config.chums())]
self.chumList = chumArea(chums, self)
self.connect(self.chumList,
@ -1174,6 +1222,8 @@ class PesterWindow(MovingWindow):
self.connect(self.pesterButton, QtCore.SIGNAL('clicked()'),
self, QtCore.SLOT('pesterSelectedChum()'))
self.moodsLabel = QtGui.QLabel(self.theme["main/moodlabel/text"], self)
self.mychumhandleLabel = QtGui.QLabel(self.theme["main/mychumhandle/label/text"], self)
self.mychumhandle = QtGui.QPushButton(self.profile().handle, self)
self.mychumhandle.setFlat(True)
@ -1227,6 +1277,7 @@ class PesterWindow(MovingWindow):
self.chumList.updateColor(handle, color)
if self.convos.has_key(handle):
self.convos[handle].updateColor(color)
self.chumdb.setColor(handle, color)
def updateMood(self, handle, mood):
self.chumList.updateMood(handle, mood)
@ -1280,6 +1331,10 @@ class PesterWindow(MovingWindow):
self.miniButton.setIcon(QtGui.QIcon(theme["main/minimize/image"]))
self.miniButton.move(*theme["main/minimize/loc"])
# moods
self.moodsLabel.setText(theme["main/moodlabel/text"])
self.moodsLabel.move(*theme["main/moodlabel/loc"])
self.moodsLabel.setStyleSheet(theme["main/moodlabel/style"])
if hasattr(self, 'moods'):
self.moods.removeButtons()
self.moods = PesterMoodHandler(self, *[PesterMoodButton(self, **d) for d in theme["main/moods"]])
@ -1358,9 +1413,11 @@ class PesterWindow(MovingWindow):
self.newConversation(chum)
@QtCore.pyqtSlot(QtCore.QString)
def closeConvo(self, handle):
h = str(handle)
h = unicode(handle)
chumopen = self.convos[h].chumopen
del self.convos[h]
self.convoClosed.emit(handle)
if chumopen:
self.convoClosed.emit(handle)
@QtCore.pyqtSlot()
def tabsClosed(self):
del self.tabconvo
@ -1368,18 +1425,18 @@ class PesterWindow(MovingWindow):
@QtCore.pyqtSlot(QtCore.QString, Mood)
def updateMoodSlot(self, handle, mood):
h = str(handle)
h = unicode(handle)
self.updateMood(h, mood)
@QtCore.pyqtSlot(QtCore.QString, QtGui.QColor)
def updateColorSlot(self, handle, color):
h = str(handle)
h = unicode(handle)
self.changeColor(h, color)
@QtCore.pyqtSlot(QtCore.QString, QtCore.QString)
def deliverMessage(self, handle, msg):
h = str(handle)
m = str(msg)
h = unicode(handle)
m = unicode(msg)
self.newMessage(h, m)
@QtCore.pyqtSlot()
@ -1477,7 +1534,12 @@ class PesterWindow(MovingWindow):
def themeSelected(self):
themename = unicode(self.choosetheme.themeBox.currentText())
if themename != self.theme.name:
self.changeTheme(pesterTheme(themename))
try:
self.changeTheme(pesterTheme(themename))
except ValueError, e:
themeWarning = QtGui.QMessageBox()
closeWarning.setText("Theme Error: %s", e)
return
# update profile
self.userprofile.setTheme(self.theme)
self.choosetheme = None
@ -1520,6 +1582,7 @@ class PesterWindow(MovingWindow):
color = self.colorDialog.getColor(initial=self.profile().color)
self.mychumcolor.setStyleSheet("background: %s" % color.name())
self.userprofile.setColor(color)
self.mycolorUpdated.emit()
self.colorDialog = None
@QtCore.pyqtSlot()
def closeProfile(self):
@ -1561,6 +1624,7 @@ class PesterWindow(MovingWindow):
profileChanged = QtCore.pyqtSignal()
moodRequest = QtCore.pyqtSignal(PesterProfile)
moodUpdated = QtCore.pyqtSignal()
mycolorUpdated = QtCore.pyqtSignal()
trayIconSignal = QtCore.pyqtSignal(int)
class PesterIRC(QtCore.QObject):
@ -1584,13 +1648,13 @@ class PesterIRC(QtCore.QObject):
@QtCore.pyqtSlot(QtCore.QString, bool)
def startConvo(self, handle, initiated):
h = str(handle)
h = unicode(handle)
if initiated:
helpers.msg(self.cli, h, "PESTERCHUM:BEGIN")
helpers.msg(self.cli, h, "COLOR >%s" % (self.mainwindow.profile().colorcmd()))
@QtCore.pyqtSlot(QtCore.QString)
def endConvo(self, handle):
h = str(handle)
h = unicode(handle)
helpers.msg(self.cli, h, "PESTERCHUM:CEASE")
@QtCore.pyqtSlot()
def updateProfile(self):
@ -1602,6 +1666,11 @@ class PesterIRC(QtCore.QObject):
def updateMood(self):
me = self.mainwindow.profile()
helpers.msg(self.cli, "#pesterchum", "MOOD >%d" % (me.mood.value()))
@QtCore.pyqtSlot()
def updateColor(self):
me = self.mainwindow.profile()
for h in self.mainwindow.convos.keys():
helpers.msg(self.cli, h, "COLOR >%s" % (self.mainwindow.profile().colorcmd()))
def updateIRC(self):
self.conn.next()
@ -1664,10 +1733,14 @@ class PesterHandler(DefaultCommandHandler):
def quit(self, nick, reason):
handle = nick[0:nick.find("!")]
self.parent.moodUpdated.emit(handle, Mood("offline"))
def part(self, nick, channel):
def part(self, nick, channel, reason="nanchos"):
handle = nick[0:nick.find("!")]
if channel == "#pesterchum":
self.parent.moodUpdated.emit(handle, Mood("offline"))
self.parent.moodUpdated.emit(handle, Mood("offline"))
def join(self, nick, channel):
handle = nick[0:nick.find("!")]
if channel == "#pesterchum":
self.parent.moodUpdated.emit(handle, Mood("chummy"))
def nick(self, oldnick, newnick):
oldhandle = oldnick[0:oldnick.find("!")]
newchum = PesterProfile(newnick)
@ -1756,6 +1829,10 @@ def main():
QtCore.SIGNAL('moodUpdated()'),
irc,
QtCore.SLOT('updateMood()'))
irc.connect(widget,
QtCore.SIGNAL('mycolorUpdated()'),
irc,
QtCore.SLOT('updateColor()'))
irc.connect(irc,
QtCore.SIGNAL('moodUpdated(QString, PyQt_PyObject)'),
widget,

View file

@ -1 +1 @@
{"color": "#ff00ff", "theme": "pesterchum", "quirks": [], "handle": "ghostDunk"}
{"color": "#ff00ff", "theme": "trollian", "quirks": [], "handle": "ghostDunk"}

1
profiles/testProfile.js Normal file
View file

@ -0,0 +1 @@
{"color": "#aa00ff", "theme": "pesterchum", "quirks": [], "handle": "testProfile"}

View file

@ -45,12 +45,12 @@
}
},
"mychumhandle": { "label": { "text": "MYCHUMHANDLE",
"loc": [70,410],
"loc": [70,380],
"style": "color:black;font:bold;" },
"handle": { "style": "border:3px solid yellow; background: black; color:white;",
"loc": [20,430],
"loc": [20,400],
"size": [220,30] },
"colorswatch": { "loc": [243,430],
"colorswatch": { "loc": [243,400],
"size": [40,30],
"text": "" }
},
@ -66,7 +66,11 @@
"size": [100, 40],
"text": "PESTER!"
},
"defaultmood": 0,
"defaultmood": "chummy",
"moodlabel": { "style": "",
"loc": [20, 430],
"text": "MOODS"
},
"moods": [
{ "style": "text-align:left; background: white; border:3px solid black; padding: 5px;color:#919191;",
"selected": "text-align:left; background: white; border:3px solid black; padding: 5px;font: bold;",
@ -74,7 +78,7 @@
"size": [133, 30],
"text": "CHUMMY",
"icon": "$path/chummy.gif",
"mood": 0
"mood": "chummy"
},
{ "style": "text-align:left; background: white; border:3px solid black; padding: 5px;color: #919191",
"selected": "text-align:left; background: white; border:3px solid black; padding: 5px;font: bold;",
@ -82,7 +86,7 @@
"size": [133, 30],
"text": "PLEASANT",
"icon": "$path/pleasant.gif",
"mood": 3
"mood": "pleasant"
},
{ "style": "text-align:left; background: white; border:3px solid black; padding: 5px;color:#919191;",
"selected": "text-align:left; background: white; border:3px solid black; padding: 5px;font: bold;",
@ -90,7 +94,7 @@
"size": [133, 30],
"text": "DISTRAUGHT",
"icon": "$path/distraught.gif",
"mood": 4
"mood": "distraught"
},
{ "style": "text-align:left; background: white; border:3px solid black; padding: 5px;color:#919191;",
"selected": "text-align:left; background: white; border:3px solid black; padding: 5px;font: bold;",
@ -98,7 +102,7 @@
"size": [133, 30],
"text": "UNRULY",
"icon": "$path/unruly.gif",
"mood": 5
"mood": "unruly"
},
{ "style": "text-align:left; background: white; border:3px solid black; padding: 5px;color:#919191;",
"selected": "text-align:left; background: white; border:3px solid black; padding: 5px;font: bold;",
@ -106,7 +110,7 @@
"size": [133, 30],
"text": "SMOOTH",
"icon": "$path/smooth.gif",
"mood": 6
"mood": "smooth"
},
{ "style": "text-align:left; background: red; border:3px solid black; padding: 5px;",
"selected": "text-align:left; background: red; border:3px solid black; padding: 5px;font: bold;",
@ -114,7 +118,7 @@
"size": [133, 30],
"text": "RANCOROUS",
"icon": "$path/rancorous.gif",
"mood": 1
"mood": "rancorous"
},
{ "style": "text-align:center; background: #919191; border:3px solid black; padding: 5px;",
"selected": "text-align:center; background: #919191; border:3px solid black; padding: 5px;font: bold;",
@ -122,7 +126,7 @@
"size": [263, 30],
"text": "ABSCOND",
"icon": "$path/offline.gif",
"mood": 2
"mood": "offline"
}
]
},

View file

@ -66,7 +66,11 @@
"size": [100, 40],
"text": "TROLL"
},
"defaultmood": 7,
"defaultmood": "ecstatic",
"moodlabel": { "style": "",
"loc": [20, 430],
"text": "MOODS"
},
"moods": [
{ "style": "text-align:left; background: black; border:3px solid black; padding: 5px;color:#dbdbdb;",
"selected": "text-align:left; background: white; border:3px solid black; padding: 5px;font: bold;",
@ -74,7 +78,7 @@
"size": [133, 30],
"text": "ECSTATIC",
"icon": "$path/estatic.gif",
"mood": 7
"mood": "ecstatic"
},
{ "style": "text-align:left; background: black; border:3px solid black; padding: 5px;color: #dbdbdb",
"selected": "text-align:left; background: white; border:3px solid black; padding: 5px;font: bold;",
@ -82,7 +86,7 @@
"size": [133, 30],
"text": "RELAXED",
"icon": "$path/relaxed.gif",
"mood": 8
"mood": "relaxed"
},
{ "style": "text-align:left; background: black; border:3px solid black; padding: 5px;color:#dbdbdb;",
"selected": "text-align:left; background: white; border:3px solid black; padding: 5px;font: bold;",
@ -90,7 +94,7 @@
"size": [133, 30],
"text": "DISCONTENT",
"icon": "$path/discontent.gif",
"mood": 9
"mood": "discontent"
},
{ "style": "text-align:left; background: black; border:3px solid black; padding: 5px;color:#dbdbdb;",
"selected": "text-align:left; background: white; border:3px solid black; padding: 5px;font: bold;",
@ -98,7 +102,7 @@
"size": [133, 30],
"text": "DEVIOUS",
"icon": "$path/devious.gif",
"mood": 10
"mood": "devious"
},
{ "style": "text-align:left; background: black; border:3px solid black; padding: 5px;color:#dbdbdb;",
"selected": "text-align:left; background: white; border:3px solid black; padding: 5px;font: bold;",
@ -106,7 +110,7 @@
"size": [133, 30],
"text": "SLEEK",
"icon": "$path/sleek.gif",
"mood": 11
"mood": "sleek"
},
{ "style": "text-align:left; background: red; border:3px solid black; padding: 5px;",
"selected": "text-align:left; background: red; border:3px solid black; padding: 5px;font: bold;",
@ -114,7 +118,7 @@
"size": [133, 30],
"text": "DETESTFUL",
"icon": "$path/detestful.gif",
"mood": 12
"mood": "detestful"
},
{ "style": "text-align:center; background: #919191; border:3px solid black; padding: 5px;",
"selected": "text-align:center; background: #919191; border:3px solid black; padding: 5px;font: bold;",
@ -122,7 +126,7 @@
"size": [263, 30],
"text": "ABSCOND",
"icon": "$path/offline.gif",
"mood": 2
"mood": "offline"
}
]
},