diff --git a/TODO b/TODO index 3893393..c3ed7fb 100644 --- a/TODO +++ b/TODO @@ -1,8 +1,9 @@ Features: * Theme Changing -* Handle user signoffs +* Handle user signoffs/signons * Handle nick changes -* Logging +* theme elements define, implement +* default user * Moods * Add chum * REMOVE chum @@ -11,10 +12,15 @@ Features: * User profile options * menubar should pass on mouse move * Quirks +-- package +* Logging * Block list * User list/add from list * User commands/stop user from sending commands accidentally * System tray stuff * Chat rooms +-- release beta +* Theme checking +* Spy mode -* Spy mode \ No newline at end of file +* put code into separate files \ No newline at end of file diff --git a/pesterchum.py b/pesterchum.py index 589287d..b7de5a1 100644 --- a/pesterchum.py +++ b/pesterchum.py @@ -57,6 +57,7 @@ class PesterProfile(object): class pesterTheme(dict): def __init__(self, name): self.path = "themes/%s" % (name) + self.name = name fp = open(self.path+"/style.js") theme = json.load(fp, object_hook=self.pathHook) self.update(theme) @@ -98,6 +99,13 @@ class userConfig(object): fp = open("pesterchum.js", 'w') json.dump(self.config, fp) fp.close() + def availableThemes(self): + themes = [] + for dirname, dirnames, filenames in os.walk('themes'): + for d in dirnames: + themes.append(d) + themes.sort() + return themes def availableProfiles(self): profs = [] for dirname, dirnames, filenames in os.walk('profiles'): @@ -146,6 +154,47 @@ class pesterQuirks(object): def __init__(self, quirklist): self.quirklist = quirklist +class PesterChooseTheme(QtGui.QDialog): + def __init__(self, config, theme, parent): + QtGui.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 = QtGui.QLabel("Pick a theme:") + + avail_themes = config.availableThemes() + self.themeBox = QtGui.QComboBox(self) + for (i, t) in enumerate(avail_themes): + self.themeBox.addItem(t) + if t == theme.name: + self.themeBox.setCurrentIndex(i) + + self.ok = QtGui.QPushButton("OK", self) + self.ok.setDefault(True) + self.connect(self.ok, QtCore.SIGNAL('clicked()'), + self, QtCore.SLOT('accept()')) + self.cancel = QtGui.QPushButton("CANCEL", self) + self.connect(self.cancel, QtCore.SIGNAL('clicked()'), + self, QtCore.SLOT('reject()')) + layout_ok = QtGui.QHBoxLayout() + layout_ok.addWidget(self.cancel) + layout_ok.addWidget(self.ok) + + layout_0 = QtGui.QVBoxLayout() + layout_0.addWidget(instructions) + layout_0.addWidget(self.themeBox) + layout_0.addLayout(layout_ok) + + self.setLayout(layout_0) + + self.connect(self, QtCore.SIGNAL('accepted()'), + parent, QtCore.SLOT('themeSelected()')) + self.connect(self, QtCore.SIGNAL('rejected()'), + parent, QtCore.SLOT('closeTheme()')) + class PesterChooseProfile(QtGui.QDialog): def __init__(self, userprofile, config, theme, parent, collision=None): QtGui.QDialog.__init__(self, parent) @@ -288,6 +337,9 @@ class chumListing(QtGui.QListWidgetItem): self.mood = mood self.setIcon(self.mood.icon(self.mainwindow.theme)) self.setTextColor(QtGui.QColor(self.mainwindow.theme["main/chums/moods"][self.mood.name()]["color"])) + def changeTheme(self, theme): + self.setIcon(self.mood.icon(theme)) + self.setTextColor(QtGui.QColor(theme["main/chums/moods"][self.mood.name()]["color"])) def __lt__(self, cl): h1 = self.handle.lower() h2 = cl.handle.lower() @@ -316,6 +368,12 @@ class chumArea(QtGui.QListWidget): chums = self.findItems(handle, QtCore.Qt.MatchFlags(0)) for c in chums: c.setColor(color) + def changeTheme(self, theme): + self.setGeometry(*(theme["main/chums/loc"]+theme["main/chums/size"])) + self.setStyleSheet(theme["main/chums/style"]) + chums = [self.item(i) for i in range(0, self.count())] + for c in chums: + c.changeTheme(theme) class MovingWindow(QtGui.QFrame): def __init__(self, *x, **y): @@ -393,6 +451,15 @@ class PesterTabWindow(QtGui.QFrame): while self.tabs.count() > 0: self.tabClose(0) self.windowClosed.emit() + def changeTheme(self, theme): + self.resize(*theme["convo/size"]) + self.setStyleSheet(theme["convo/style"]) + self.tabs.setShape(theme["convo/tabstyle"]) + for c in self.convos.values(): + tabi = self.tabIndices[c.chum.handle] + self.tabs.setTabIcon(tabi, c.chum.mood.icon(theme)) + currentHandle = unicode(self.tabs.tabText(self.tabs.currentIndex())) + self.setWindowIcon(self.convos[currentHandle].chum.mood.icon(theme)) @QtCore.pyqtSlot(int) def tabClose(self, i): @@ -469,11 +536,15 @@ class PesterText(QtGui.QTextEdit): msg = msg.replace("&", "&").replace("<", "<").replace(">", ">") self.append("%s: %s" % \ (color, initials, msg)) + def changeTheme(self, theme): + self.setStyleSheet(theme["convo/textarea/style"]) class PesterInput(QtGui.QLineEdit): def __init__(self, theme, parent=None): QtGui.QLineEdit.__init__(self, parent) self.setStyleSheet(theme["convo/input/style"]) + def changeTheme(self, theme): + self.setStyleSheet(theme["convo/input/style"]) class PesterConvo(QtGui.QFrame): def __init__(self, chum, initiated, mainwindow, parent=None): @@ -539,6 +610,13 @@ class PesterConvo(QtGui.QFrame): self.windowClosed.emit(self.chum.handle) def setChumOpen(self, o): self.chumopen = o + def changeTheme(self, theme): + self.resize(*theme["convo/size"]) + self.setStyleSheet(theme["convo/style"]) + self.setWindowIcon(self.chum.mood.icon(theme)) + self.chumLabel.setStyleSheet(theme["convo/chumlabel/style"]) + self.textArea.changeTheme(theme) + self.textInput.changeTheme(theme) @QtCore.pyqtSlot() def sentMessage(self): @@ -570,11 +648,10 @@ class PesterWindow(MovingWindow): self.theme = self.userprofile.getTheme() self.changeProfile() - main = self.theme["main"] - size = main['size'] + size = self.theme['main/size'] self.setGeometry(100, 100, size[0], size[1]) - self.setWindowIcon(QtGui.QIcon(main["icon"])) - self.setStyleSheet("QFrame#main { "+main["style"]+" }") + self.setWindowIcon(QtGui.QIcon(self.theme["main/icon"])) + self.mainSS() opts = QtGui.QAction("OPTIONS", self) self.connect(opts, QtCore.SIGNAL('triggered()'), @@ -588,18 +665,20 @@ class PesterWindow(MovingWindow): filemenu = self.menu.addMenu("FILE") filemenu.addAction(opts) filemenu.addAction(exitaction) - filemenu.setStyleSheet(qmenustyle) switch = QtGui.QAction("SWITCH", self) self.connect(switch, QtCore.SIGNAL('triggered()'), self, QtCore.SLOT('switchProfile()')) + changetheme = QtGui.QAction("THEME", self) + self.connect(changetheme, QtCore.SIGNAL('triggered()'), + self, QtCore.SLOT('pickTheme()')) profilemenu = self.menu.addMenu("PROFILE") profilemenu.addAction(switch) - profilemenu.setStyleSheet(qmenustyle) + profilemenu.addAction(changetheme) - self.menu.setStyleSheet("QMenuBar { background: transparent; %s } QMenuBar::item { background: transparent; } " % (self.theme["main/menubar/style"])) + self.menuBarSS() - closestyle = main["close"] + closestyle = self.theme["main/close"] self.closeButton = WMButton(QtGui.QIcon(closestyle["image"]), self) self.closeButton.move(*closestyle["loc"]) self.connect(self.closeButton, QtCore.SIGNAL('clicked()'), @@ -617,6 +696,10 @@ class PesterWindow(MovingWindow): self.convos = {} self.tabconvo = None self.optionmenu = None + def mainSS(self): + self.setStyleSheet("QFrame#main { "+self.theme["main/style"]+" }") + def menuBarSS(self): + self.menu.setStyleSheet("QMenuBar { background: transparent; %s } QMenuBar::item { background: transparent; } " % (self.theme["main/menubar/style"]) + "QMenu { background: transparent; %s } QMenu::item::selected { %s }" % (self.theme["main/menu/style"], self.theme["main/menu/selected"])) def closeConversations(self): if self.tabconvo: self.tabconvo.close() @@ -681,6 +764,28 @@ class PesterWindow(MovingWindow): self.chooseprofile = PesterChooseProfile(self.userprofile, self.config, self.theme, self, collision=collision) self.chooseprofile.exec_() + def themePicker(self): + self.choosetheme = PesterChooseTheme(self.config, self.theme, self) + self.choosetheme.exec_() + def changeTheme(self, theme): + self.theme = theme + # do self + self.resize(*self.theme["main/size"]) + self.setWindowIcon(QtGui.QIcon(self.theme["main/icon"])) + self.mainSS() + self.menuBarSS() + self.closeButton.setIcon(QtGui.QIcon(self.theme["main/close/image"])) + self.closeButton.move(*self.theme["main/close/loc"]) + self.miniButton.setIcon(QtGui.QIcon(self.theme["main/minimize/image"])) + self.miniButton.move(*self.theme["main/minimize/loc"]) + # chum area + self.chumList.changeTheme(theme) + # do open windows + if self.tabconvo: + self.tabconvo.changeTheme(theme) + for c in self.convos.values(): + c.changeTheme(theme) + @QtCore.pyqtSlot(QtGui.QListWidgetItem) def newConversationWindow(self, chumlisting): chum = chumlisting.chum @@ -757,6 +862,16 @@ class PesterWindow(MovingWindow): self.optionmenu = None @QtCore.pyqtSlot() + def themeSelected(self): + themename = self.choosetheme.themeBox.currentText() + if themename != self.theme.name: + # update profile + self.changeTheme(pesterTheme(themename)) + self.choosetheme = None + @QtCore.pyqtSlot() + def closeTheme(self): + self.choosetheme = None + @QtCore.pyqtSlot() def profileSelected(self): if self.chooseprofile.profileBox and \ self.chooseprofile.profileBox.currentIndex() > 0: @@ -798,6 +913,10 @@ class PesterWindow(MovingWindow): h = unicode(handle) self.changeProfile(collision=h) + @QtCore.pyqtSlot() + def pickTheme(self): + self.themePicker() + newConvoStarted = QtCore.pyqtSignal(QtCore.QString, bool, name="newConvoStarted") sendMessage = QtCore.pyqtSignal(QtCore.QString, PesterProfile) convoClosed = QtCore.pyqtSignal(QtCore.QString) diff --git a/themes/trollian/Thumbs.db b/themes/trollian/Thumbs.db new file mode 100644 index 0000000..f67753d Binary files /dev/null and b/themes/trollian/Thumbs.db differ diff --git a/themes/trollian/abouticon.png b/themes/trollian/abouticon.png new file mode 100644 index 0000000..e3feb2c Binary files /dev/null and b/themes/trollian/abouticon.png differ diff --git a/themes/trollian/alarm.wav b/themes/trollian/alarm.wav new file mode 100644 index 0000000..910abdc Binary files /dev/null and b/themes/trollian/alarm.wav differ diff --git a/themes/trollian/alarm2.wav b/themes/trollian/alarm2.wav new file mode 100644 index 0000000..5ae54fa Binary files /dev/null and b/themes/trollian/alarm2.wav differ diff --git a/themes/trollian/chummy.gif b/themes/trollian/chummy.gif new file mode 100644 index 0000000..bdacc01 Binary files /dev/null and b/themes/trollian/chummy.gif differ diff --git a/themes/trollian/detestful.gif b/themes/trollian/detestful.gif new file mode 100644 index 0000000..e8f3e08 Binary files /dev/null and b/themes/trollian/detestful.gif differ diff --git a/themes/trollian/devious.gif b/themes/trollian/devious.gif new file mode 100644 index 0000000..06ba8be Binary files /dev/null and b/themes/trollian/devious.gif differ diff --git a/themes/trollian/discontent.gif b/themes/trollian/discontent.gif new file mode 100644 index 0000000..addcf54 Binary files /dev/null and b/themes/trollian/discontent.gif differ diff --git a/themes/trollian/distraught.gif b/themes/trollian/distraught.gif new file mode 100644 index 0000000..222e9dd Binary files /dev/null and b/themes/trollian/distraught.gif differ diff --git a/themes/trollian/estatic.gif b/themes/trollian/estatic.gif new file mode 100644 index 0000000..dc3ee61 Binary files /dev/null and b/themes/trollian/estatic.gif differ diff --git a/themes/trollian/h.gif b/themes/trollian/h.gif new file mode 100644 index 0000000..0d0c9cc Binary files /dev/null and b/themes/trollian/h.gif differ diff --git a/themes/trollian/m.gif b/themes/trollian/m.gif new file mode 100644 index 0000000..946ed22 Binary files /dev/null and b/themes/trollian/m.gif differ diff --git a/themes/trollian/offline.gif b/themes/trollian/offline.gif new file mode 100644 index 0000000..1733bf0 Binary files /dev/null and b/themes/trollian/offline.gif differ diff --git a/themes/trollian/pleasant.gif b/themes/trollian/pleasant.gif new file mode 100644 index 0000000..ef1457c Binary files /dev/null and b/themes/trollian/pleasant.gif differ diff --git a/themes/trollian/rancorous.gif b/themes/trollian/rancorous.gif new file mode 100644 index 0000000..d4a3dc0 Binary files /dev/null and b/themes/trollian/rancorous.gif differ diff --git a/themes/trollian/relaxed.gif b/themes/trollian/relaxed.gif new file mode 100644 index 0000000..55a31a0 Binary files /dev/null and b/themes/trollian/relaxed.gif differ diff --git a/themes/trollian/sleek.gif b/themes/trollian/sleek.gif new file mode 100644 index 0000000..5573aa5 Binary files /dev/null and b/themes/trollian/sleek.gif differ diff --git a/themes/trollian/smooth.gif b/themes/trollian/smooth.gif new file mode 100644 index 0000000..e86ebd3 Binary files /dev/null and b/themes/trollian/smooth.gif differ diff --git a/themes/trollian/style.js b/themes/trollian/style.js new file mode 100644 index 0000000..671883c --- /dev/null +++ b/themes/trollian/style.js @@ -0,0 +1,44 @@ +{"main": + {"style": "background-image:url($path/tnbg2.png);", + "size": [300, 620], + "icon": "$path/trayicon3.gif", + "close": { "image": "$path/x.gif", + "loc": [255, 0]}, + "minimize": { "image": "$path/m.gif", + "loc": [225, 0]}, + "menubar": { "style": "font-family: 'Courier New'; font-weight: bold; font-size: 12px;" }, + "menu" : { "style": "font-family: 'Courier New'; font-weight: bold; font-size: 12px; background-color: #e5000f; border:2px solid #ff0000", + "selected": "background-color: #ff0000" + }, + "chums": { "style": "background-color: white;color: black;font: bold;font-family: 'Courier New';selection-background-color:#ffb6b6; ", + "loc": [20, 65], + "size": [265, 450], + "moods": { "chummy": { "icon": "$path/chummy.gif", + "color": "black" }, + "offline": { "icon": "$path/offline.gif", + "color": "#dbdbdb"}, + "rancorous": { "icon": "$path/rancorous.gif", + "color": "red" } + } + }, + "defaultwindow": { "style": "background: #e5000f; font-family:'Courier New';font:bold;selection-background-color:#ffb6b6; " + }, + "labels": { "mychumhandle": "MYTROLLTAG" }, + "elements": [ + { "style": "" } + ] + }, + "convo": + {"style": "background: #e5000f; font-family: 'Courier New'", + "size": [600, 500], + "chumlabel": { "style": "background: rgba(255, 255, 255, 25%);" }, + "textarea": { + "style": "background: white;" + }, + "input": { + "style": "background: white;" + }, + "tabstyle": 0 + } + +} diff --git a/themes/trollian/style.pcs b/themes/trollian/style.pcs new file mode 100644 index 0000000..90cc14d --- /dev/null +++ b/themes/trollian/style.pcs @@ -0,0 +1,167 @@ +#PESTERCHUM STYLE + +// The title will appear at the top of the window. +// Instead of a space in the name or title, use an '_'. It will come out as a space. +// The name and author will only be in the 'about' section. +// The name you will enter in the 'options' is the name of the folder this is in. +// The alarm only plays when a message is recieved. +// The mode can be set to 'regular' or 'trollian'. + +name Trollian +title Trollian +author Grimlive95 +alarm alarm.wav +mode trollian + +// Colors are in the format of 'red/green/blue/alpha', alpha being transparency. +// 255 is solid and 000 is invisible. + +// MAIN WINDOW + +// If you have a background image, set 'c 3' alpa to '000'. +// If your background image has a header on it, do the same with the title text color. + +c 1 000 000 000 000 // title text +c 2 000 000 000 255 // chumhandle/ mood label text +c 3 000 000 000 255 // outside menu text +c 4 000 000 000 255 // inside menu text +c 5 229 000 015 000 // main background +c 6 229 000 015 255 // menu background + +// BUTTONS + +// Main buttons are the moods that aren't 'rancorous', the 'pester' and 'add chum' buttons. +// They are also the buttons on the Options, Quirks Manager, and Trollslum. +// Block buttons are the 'rancorous' and 'block' buttons. + +c 7 120 000 000 255 // main button borders +c 8 120 000 000 255 // block button borders +c 9 120 000 000 255 // offline button border + +c 10 255 164 164 255 // main buttons +c 11 255 164 164 255 // block buttons +c 12 000 000 000 255 // offline button + +c 13 000 000 000 255 // main button text +c 14 000 000 000 255 // block button text +c 15 255 255 255 255 // offline button text + +// CHUMROLL & CHUMHANDLE + +c 16 255 095 132 255 // chumroll border +c 17 255 255 255 255 // chumroll background +c 18 200 200 200 255 // chumroll highlight + +c 19 050 050 050 255 // chumroll usertext +c 20 000 000 000 255 // chumroll highlighted usertext + +c 21 255 095 132 255 // my chumhandle border +c 22 255 255 255 255 // my chumhandle background +c 23 000 000 000 255 // my chumhandle usertext + +// PESTER WINDOW + +c 24 229 000 015 255 // pester window background +c 25 255 255 255 255 // pesterlog background +c 26 255 255 255 255 // text field background +c 27 000 000 000 255 // text field text color + +c 28 243 046 038 255 // pesterwindow topbar +c 29 255 255 255 255 // pesterwindow top bar text + +c 30 255 095 132 255 // text field border +c 31 255 095 132 255 // pesterlog border + +//PESTER WINDOW BUTTONS + +c 32 120 000 000 255 // main button borders +c 33 120 000 000 255 // block button border + +c 34 255 164 164 255 // main buttons +c 35 255 164 164 255 // block button + +c 36 000 000 000 255 // pesterwindow button text +c 37 000 000 000 255 // pesterwindow block text + +// OPTIONS WINDOW + +c 38 229 000 015 255 // background +c 39 000 000 000 255 // text color +c 40 120 000 000 255 // button borders +c 41 255 164 164 255 // buttons +c 42 000 000 000 255 // button text + +// QUIRKS MANAGER WINDOW + +c 43 229 000 015 255 // background +c 44 000 000 000 255 // text color +c 45 120 000 000 255 // button borders +c 46 255 164 164 255 // buttons +c 47 000 000 000 255 // button text + +// TROLLSLUM WINDOW + +c 48 229 000 015 255 // background +c 49 000 000 000 255 // text color +c 50 120 000 000 255 // button borders +c 51 255 164 164 255 // buttons +c 52 000 000 000 255 // button text + +// FONTS (In the format: Font_name MODE size) + +// gui is for the main window. +// menu is for the top menu. +// tray is for your tray popups. +// msg is for the pesterwindow. + +// menu is for the top menu. +// tagandmood is for the CHUMHANDLE and MOOD labels. +// message is for the text field in the pester window. +// topbar is for the ::nameName:: text on the top of the pester window. +// tray is for your tray popups. +// debug is for the debug console. + +f title Bitsream_Vera_Sans_mono BOLD 13 +f menu Bitsream_Vera_Sans_mono PLAIN 11 +f buttons Bitsream_Vera_Sans_mono BOLD 13 + +f tagandmood Bitsream_Vera_Sans_mono BOLD 13 +f chumroll Bitsream_Vera_Sans_mono BOLD 13 +f chumhandle Bitsream_Vera_Sans_mono BOLD 13 + +f message Courier BOLD 13 +f topbar Courier BOLD 13 + +f tray Bitsream_Vera_Sans_mono PLAIN 11 + +f debug Courier BOLD 13 + +// PESTERCHUM MOOD ICONS + +i ichummy chummy.gif +i ipleasant pleasant.gif +i idistraught distraught.gif +i iunruly unruly.gif +i ismooth smooth.gif +i irancorous rancorous.gif +i ioffline offline.gif + +// TROLLIAN MOOD ICONS + +i iestatic estatic.gif +i irelaxed relaxed.gif +i idiscontent discontent.gif +i idevious devious.gif +i isleek sleek.gif +i idetestful detestful.gif + +// ETC. + +// iicon only appears in the about section. +// ticon will appear in both your tray and your pesterwindow. + +i ticon trayicon3.png +i iicon abouticon.png +i iclose x.gif +i ihide m.gif +i ibg tnbg.png \ No newline at end of file diff --git a/themes/trollian/tnbg.png b/themes/trollian/tnbg.png new file mode 100644 index 0000000..ac1513b Binary files /dev/null and b/themes/trollian/tnbg.png differ diff --git a/themes/trollian/tnbg2.png b/themes/trollian/tnbg2.png new file mode 100644 index 0000000..87babae Binary files /dev/null and b/themes/trollian/tnbg2.png differ diff --git a/themes/trollian/trayicon.gif b/themes/trollian/trayicon.gif new file mode 100644 index 0000000..55a31a0 Binary files /dev/null and b/themes/trollian/trayicon.gif differ diff --git a/themes/trollian/trayicon2.png b/themes/trollian/trayicon2.png new file mode 100644 index 0000000..92b7081 Binary files /dev/null and b/themes/trollian/trayicon2.png differ diff --git a/themes/trollian/trayicon3.png b/themes/trollian/trayicon3.png new file mode 100644 index 0000000..31f7d29 Binary files /dev/null and b/themes/trollian/trayicon3.png differ diff --git a/themes/trollian/unruly.gif b/themes/trollian/unruly.gif new file mode 100644 index 0000000..3bbd8be Binary files /dev/null and b/themes/trollian/unruly.gif differ diff --git a/themes/trollian/x.gif b/themes/trollian/x.gif new file mode 100644 index 0000000..16a9d37 Binary files /dev/null and b/themes/trollian/x.gif differ