2
# Twisted, the Framework of Your Internet
3
# Copyright (C) 2001 Matthew W. Lefkowitz
5
# This library is free software; you can redistribute it and/or
6
# modify it under the terms of version 2.1 of the GNU Lesser General Public
7
# License as published by the Free Software Foundation.
9
# This library is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
# Lesser General Public License for more details.
14
# You should have received a copy of the GNU Lesser General Public
15
# License along with this library; if not, write to the Free Software
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22
from twisted.internet import ingtkernet
26
from twisted.spread import pb
27
from twisted.spread.ui import gtkutil
28
from twisted.words.ui import im
29
class Group(pb.RemoteCache):
30
"""A local cache of a group.
33
pb.setCopierForClass("twisted.words.service.Group", Group)
36
class AccountManager(gtk.GtkWindow, gtkutil.ButtonBar):
37
def __init__(self, *args, **kw):
38
apply(gtk.GtkWindow.__init__, (self,)+args, kw)
40
vbox = gtk.GtkVBox(gtk.FALSE, 5)
41
vbox.set_border_width(5)
43
titles = ['Username', 'Online', 'Auto-Login', 'Gateway']
44
clist = gtk.GtkCList(len(titles), titles)
45
clist.signal_connect("select_row", self.rowSelected)
46
clist.set_shadow_type(gtk.SHADOW_OUT)
47
scrolled = gtk.GtkScrolledWindow(None, None)
48
scrolled.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_ALWAYS)
49
vbox.pack_start(scrolled, gtk.TRUE, gtk.TRUE, 0)
51
hb = gtk.GtkHBox(gtk.FALSE, 0)
52
vbox.pack_start(hb, gtk.FALSE, gtk.TRUE, 0)
53
self.getButtonList(container=hb)
54
self.signal_connect('destroy', gtk.mainquit, None)
56
barButtons = ['Add', 'Modify', 'Logon', 'Delete']
57
def button_Add(self, btn):
58
AddAccount(gtk.WINDOW_TOPLEVEL)
60
def button_Modify(self, btn):
61
print 'modify clicked!'
63
def button_Logon(self, btn):
64
print 'logon clicked!'
66
def button_Delete(self, btn):
67
print 'delete clicked!'
69
def rowSelected(self, clist, row, column, event, data):
72
class _AccountInstantiator:
73
def __init__(self, this, vb, klas):
78
def activate(self, mitem):
81
old = self.this.currentAcct
84
self.this.currentAcct = k
85
self.vb.pack_start(k, padding=2)
88
class AddAccount(gtk.GtkWindow):
90
def __init__(self, *args, **kw):
91
apply(gtk.GtkWindow.__init__, (self,)+args, kw)
94
vb.pack_start(hb, expand=gtk.FALSE, fill=gtk.TRUE, padding=2)
95
hb.pack_start(gtk.GtkLabel("Account Type:"),
96
expand=gtk.FALSE, fill=gtk.FALSE, padding=2)
97
om = gtk.GtkOptionMenu()
100
for name, klas in registeredTypes:
101
i = gtk.GtkMenuItem(name)
103
i.connect("activate", _AccountInstantiator(self, vb, klas).activate)
105
hb.pack_start(om, expand=gtk.TRUE, fill=gtk.TRUE, padding=2)
107
self.set_usize(300, 300)
110
class DummyAOLPanel(gtk.GtkFrame):
112
gtk.GtkFrame.__init__(self, "AOL Account")
113
self.add(gtk.GtkButton("AOL!"))
114
class DummyIRCPanel(gtk.GtkFrame):
116
gtk.GtkFrame.__init__(self, "IRC Account")
117
self.add(gtk.GtkButton("IRC!"))
118
class DummyTRPanel(gtk.GtkFrame):
120
gtk.GtkFrame.__init__(self, "Twisted Reality Account")
121
self.add(gtk.GtkButton("Reality!"))
123
registeredTypes = [("Dummy AOL", DummyAOLPanel),
124
("Dummy IRC", DummyIRCPanel),
125
("Dummy Twisted Reality", DummyTRPanel)]
127
class AddContact(gtkutil.GetString):
128
def __init__(self, im):
129
gtkutil.GetString.__init__(self, im, "Add Contact")
131
def clicked(self, btn):
132
self.im.remote.addContact(self.entry.get_text())
137
class Conversation(gtk.GtkWindow):
138
def __init__(self, im, contact):
139
gtk.GtkWindow.__init__(self, gtk.WINDOW_TOPLEVEL)
141
self.contact = contact
142
self.set_title("%s - Instance Messenger" % contact)
143
self.text = gtk.GtkText()
145
gtkutil.defocusify(self.text)
146
self.text.set_word_wrap(gtk.TRUE)
147
vb.pack_start(gtkutil.scrollify(self.text), 1, 1, 0)
148
self.entry = gtk.GtkEntry()
149
self.entry.signal_connect('activate', self.sendMessage)
150
vb.pack_start(self.entry, 0, 0, 0)
152
self.signal_connect('destroy', self.removeFromList, None)
155
def messageReceived(self, message, sender=None, font=None):
157
t.set_point(t.get_length())
159
y,mon,d,h,min,sec, ig,no,re = time.localtime(time.time())
160
t.insert(font or gtkutil.boldFont, None, None, "%s:%s:%s %s: %s\n"
161
% (h,min,sec,sender or self.contact, message))
162
a = t.get_vadjustment()
164
a.set_value(a.upper - a.page_size)
165
self.entry.grab_focus()
167
def sendMessage(self, entry):
168
txt = self.entry.get_text()
169
self.entry.set_text("")
170
ms = MessageSent(self.im, self, txt)
171
self.im.remote.directMessage(self.contact, txt).addCallbacks(ms.success, ms.failure)
173
def removeFromList(self, win, evt):
174
del self.im.conversations[self.contact]
178
class GroupSession(gtk.GtkWindow):
179
def __init__(self, groupName, im):
180
self.groupName = groupName
186
gtk.GtkWindow.__init__(self, gtk.WINDOW_TOPLEVEL)
187
self.set_title("%s - Instance Messenger" % groupName)
188
self.connect('destroy', self.leaveGroup)
193
self.output = gtk.GtkText()
194
self.output.set_word_wrap(gtk.TRUE)
195
gtkutil.defocusify(self.output)
196
hb.pack_start(gtkutil.scrollify(self.output), 1,1,1)
198
userlist = gtk.GtkCList(1, ["Users"])
199
userlist.set_shadow_type(gtk.SHADOW_OUT)
200
gtkutil.defocusify(userlist)
201
hb.pack_start(gtkutil.scrollify(userlist), gtk.TRUE, gtk.TRUE, 0)
203
# print self.im.remote.groups
204
# for group in self.im.remote.groups:
205
# if group.name == groupName:
206
# for member in group.members:
207
# userlist.append_items([member.name])
209
self.userlist = userlist
211
vb.pack_start(hb, 1,1,1)
212
self.input = gtk.GtkEntry()
213
vb.pack_start(self.input,0,0,1)
214
#took this out so I can check in and not be broken
215
#self.input.connect('key_press_event', self.processKey)
216
self.input.connect('activate', self.sendMessage)
220
def processKey(self, entry, event):
221
if event.keyval == gtk.GDK.Up:
224
elif event.keyval == gtk.GDK.Down:
228
def focusInput(self):
229
self.input.grab_focus()
233
l = self.input.get_text()
234
if len(l) > 0 and l[0] == '\n': l = l[1:]
235
if len(l) > 0 and l[-1] == '\n': l = l[:-1]
236
self.history[self.histpos] = l
237
self.histpos = self.histpos - 1
238
self.input.set_text(self.history[self.histpos])
241
def historyDown(self):
242
if self.histpos < len(self.history) - 1:
243
l = self.input.get_text()
244
if len(l) > 0 and l[0] == '\n': l = l[1:]
245
if len(l) > 0 and l[-1] == '\n': l = l[:-1]
246
self.history[self.histpos] = l
247
self.histpos = self.histpos + 1
248
self.input.set_text(self.history[self.histpos])
250
def leaveGroup(self, blargh):
251
self.im.remote.leaveGroup(self.groupName)
254
def sendMessage(self, entry):
255
val = entry.get_text()
258
self.histpos = len(self.history) - 1
259
self.history[self.histpos] = val
260
self.histpos = self.histpos + 1
261
self.history.append('')
263
self.im.remote.groupMessage(self.groupName, val)
264
self.output.insert_defaults("<<%s>> %s\n" % (self.im.name, val))
267
def displayMessage(self, sender, message):
268
self.output.insert_defaults("<%s> %s\n" % (sender,message))
270
def memberJoined(self,member):
271
self.output.insert_defaults("%s joined!\n" % member)
272
#self.userlist.append_items(member)
274
def memberLeft(self,member):
275
self.output.insert_defaults("%s left!\n" % member)
276
#row = self.list.find_row_from_data(intern(contact))
278
# self.list.remove(row)
280
# print "uhh.. %s wasn't found." % member
283
def __init__(self, im, conv, mesg):
288
def success(self, result):
289
self.conv.messageReceived(self.mesg, self.im.name, gtkutil.normalFont)
291
def failure(self, tb):
292
self.conv.messageReceived("could not send message %s: %s"
293
% (repr(self.mesg), tb), "error", gtkutil.errorFont )
297
class JoinGroup(gtkutil.GetString):
298
def __init__(self, im):
299
gtkutil.GetString.__init__(self, im, "Join Group")
301
def clicked(self, btn):
302
val = self.entry.get_text()
303
self.im.remote.joinGroup(val)
304
self.im.groups[val] = GroupSession(val,self.im)
308
class ContactList(gtk.GtkWindow):
309
def __init__(self, im):
311
# Set up the Contact List window.
312
gtk.GtkWindow.__init__(self, gtk.WINDOW_TOPLEVEL)
313
# Cheat, we'll do this correctly later --
314
self.signal_connect('destroy', gtk.mainquit, None)
315
self.set_title("Instance Messenger")
316
# self.set_usize(200,400)
318
# Vertical Box packing
319
vb = gtk.GtkVBox(gtk.FALSE, 5)
322
self.list = gtk.GtkCList(2, ["Status", "Contact"])
323
self.list.set_shadow_type(gtk.SHADOW_OUT)
324
self.list.set_column_width(1, 150)
325
self.list.set_column_width(0, 50)
326
self.list.signal_connect("select_row", self.contactSelected)
328
vb.pack_start(gtkutil.scrollify(self.list), gtk.TRUE, gtk.TRUE, 0)
330
addContactButton = gtkutil.cbutton("Add Contact", self.addContactWindow)
331
removeContactButton = gtkutil.cbutton("Remove Contact", self.removeContact)
332
sendMessageButton = gtkutil.cbutton("Send Message", self.sendMessage)
333
joinGroupButton = gtkutil.cbutton("Join Group", self.joinGroupWindow)
335
hb.pack_start(addContactButton)
336
hb.pack_start(removeContactButton)
337
hb.pack_start(sendMessageButton)
338
hb.pack_start(joinGroupButton)
340
vb.pack_start(hb, gtk.FALSE, gtk.FALSE, 0)
344
def addContactWindow(self, blargh):
347
def joinGroupWindow(self, bleh):
350
def removeContact(self, blonk):
351
self.im.remote.removeContact(self.list.get_row_data(self.list.selection[0]))
352
self.list.remove(self.list.selection[0])
354
def contactSelected(self, clist, row, column, event):
355
#print 'event on',row
356
target = self.list.get_row_data(row)
357
if event.type == gtk.GDK._2BUTTON_PRESS:
358
#print 'Double Click on', target
359
self.im.conversationWith(target)
361
def sendMessage(self, blah):
362
self.im.conversationWith(self.list.get_row_data(self.list.selection[0]))
363
#print 'message send'
365
def changeContactStatus(self, contact, newStatus):
366
row = self.list.find_row_from_data(intern(contact))
367
r = [str(newStatus), contact]
369
#print 'pre-existing row',row,contact
370
self.list.remove(row)
371
self.list.insert(row, r)
373
#print 'new row',row,contact
374
row = self.list.append(r)
375
self.list.set_row_data(row, intern(contact))
377
im.Conversation=Conversation
378
im.ContactList=ContactList
382
am = AccountManager(gtk.WINDOW_TOPLEVEL)