def __init__(self, name, container, state): genericView.__init__(self, "channel_detach_container") nestable.__init__(self, self.window, container, state) nestingArrowSupport.__init__(self) # # Does this belong here? container.add(self.window) self.name = name self.entry = HistoryEntry(self.get_widget("entry")) self.list = UserList(self.get_widget("list")) self.topicentry = self.get_widget("topicentry") self.limitentry = self.get_widget("limitentry") self.keyentry = self.get_widget("keyentry") self.modelabel = self.get_widget("modelabel") font = self.limitentry.get_style().font width = font.width('555555') self.limitentry.set_usize(width, -1) font = self.keyentry.get_style().font width = font.width('MMMMMMMMMM') self.keyentry.set_usize(width, -1) self.setname(name) self.modestr = [] self.closeonleave = 0 self.active = 1 # by default self.tree = None self.treeitems = casedict() # XXX TODO: merge with self.list/self.users # # Perform bindings bindings = { 'input_activate':self.input_activate, 'window_close':self.window_close, 'detach_toggled':self.handle_detach_toggle, 'on_topicentry_activate':self.on_topicentry_activate, 'on_keyentry_activate':self.on_keyentry_activate, 'on_limitentry_activate':self.on_limitentry_activate } self.bindings(bindings) self.text = self.get_widget("text") self.text.set_word_wrap(1)
class channelView(genericView, msgSupport, nestingArrowSupport, nestable, detachSupport): def __init__(self, name, container, state): genericView.__init__(self, "channel_detach_container") nestable.__init__(self, self.window, container, state) nestingArrowSupport.__init__(self) # # Does this belong here? container.add(self.window) self.name = name self.entry = HistoryEntry(self.get_widget("entry")) self.list = UserList(self.get_widget("list")) self.topicentry = self.get_widget("topicentry") self.limitentry = self.get_widget("limitentry") self.keyentry = self.get_widget("keyentry") self.modelabel = self.get_widget("modelabel") font = self.limitentry.get_style().font width = font.width('555555') self.limitentry.set_usize(width, -1) font = self.keyentry.get_style().font width = font.width('MMMMMMMMMM') self.keyentry.set_usize(width, -1) self.setname(name) self.modestr = [] self.closeonleave = 0 self.active = 1 # by default self.tree = None self.treeitems = casedict() # XXX TODO: merge with self.list/self.users # # Perform bindings bindings = { 'input_activate':self.input_activate, 'window_close':self.window_close, 'detach_toggled':self.handle_detach_toggle, 'on_topicentry_activate':self.on_topicentry_activate, 'on_keyentry_activate':self.on_keyentry_activate, 'on_limitentry_activate':self.on_limitentry_activate } self.bindings(bindings) self.text = self.get_widget("text") self.text.set_word_wrap(1) def set_handler(self, handler): self.handler = handler def setname(self, name=None): if name: self.name = name self.set_title("Channel %s" % self.name) def adduser(self, nick, mode=None): # TODO: Take model + view of UserList apart so we can store treeitems # in it as well. i = self.list.adduser(nick, mode) # XXX No, no GtkItems here! i.connect("button-press-event", self.item_handler, nick) # # tmp treeitem = GtkTreeItem(nick) self.tree.append(treeitem) treeitem.show() self.treeitems[nick] = treeitem treeitem.connect("button-press-event", self.item_handler, nick) def deluser(self, nick): self.list.deluser(nick) if self.treeitems.has_key(nick): self.tree.remove_item(self.treeitems[nick]) del self.treeitems[nick] else: debug(ERROR, "Attempting to remove missing user %s from channel " \ "%s from tree" % (nick, self.name)) def userjoin(self, nick, userhost): self.announce("%s (%s) has joined channel %s" % \ (nick, userhost, self.name)) self.adduser(nick) def userquit(self, nick, userhost, reason): self.announce("%s has quit (%s)" % (nick, reason)) self.deluser(nick) # add: isself def userleave(self, nick, userhost, reason): self.announce("%s (%s) has left channel %s (%s)" % \ (nick, userhost, self.name, reason)) self.deluser(nick) def userkick(self, nick, userhost, target, reason, isself=0): if isself: self.announce("You have been kicked from channel %s by " \ "%s (%s) (%s)" % (self.name, nick, userhost, reason)) else: self.announce("%s has been kicked from channel %s by " \ "%s (%s) (%s)" % (target, self.name, nick, userhost, reason)) self.deluser(target) def modechange(self, nick, modechange, notice=1): """ handle channelmode changes """ modestr = "" plusmodes = modechange.plusmodes() minmodes = modechange.minmodes() plusparams = modechange.plusparams() minparams = modechange.minparams() if plusmodes != "": modestr = modestr + "+" + plusmodes if minmodes != "": modestr = modestr + "-" + minmodes if plusmodes != []: modestr = modestr + " " + join(plusparams, ' ') if minmodes != []: modestr = modestr + " " + join(minparams, ' ') if notice: self.announce("%s sets mode %s" % (nick, modestr)) if 'k' in minmodes: self.keyentry.set_text("") if 'l' in minmodes: self.limitentry.set_text("") if 'k' in plusmodes: i = find(plusmodes, 'k') self.keyentry.set_text(plusparams[i]) if 'l' in plusmodes: i = find(plusmodes, 'l') self.limitentry.set_text(plusparams[i]) ## ## XXX move to class, along with serverView for i in minmodes: if i not in "ovbeI" and i in self.modestr: self.modestr.remove(i) for i in plusmodes: if i not in "ovbeI" and i not in self.modestr: self.modestr.append(i) self.modelabel.set_text("+"+join(self.modestr, "")) def usermodechange(self, nick, mode): """ Handle a usermode change on a channel """ # do we want to work with GtkItems on this level? i = self.list.modechange(nick, mode) i.connect("button-press-event", self.item_handler, nick) def topic(self, topic, changed_by = None): print "Topic is nu", topic self.topicentry.set_text(topic) if changed_by: self.announce("%s sets the topic to %s" % (changed_by, topic)) def nickchange(self, oldnick, newnick): if self.list.hasuser(oldnick): self.announce("%s is now known as %s" % (oldnick, newnick)) # move connect to UserList i = self.list.nickchange(oldnick, newnick) i.connect("button-press-event", self.item_handler, newnick) # update tree item = self.treeitems[oldnick] del self.treeitems[oldnick] item.children()[0].set_text(newnick) self.treeitems[newnick] = item def window_close(self, item, extra): """ Invoked when someone closes the window. Todo: what does 'extra' do? Is it a gdk event? """ # If our state is "inactive" then PARTING won't have any use - # explicitly destroy the window. print "CLOSE" if not self.active: print "not active" # we need to inform handler anyway (so it can clean up references) # self.destroy() # ignore for now return 1 self.closeonleave = 1 # so window gets closed after PART if self.handler: self.handler.view_winclose(self.name, self.name) return 1 # don't close window for us def part(self): """ invoked when *I* leave this channel. I.e. after explicit /leave or after kick. Closing a window implicitly triggers a /leave, but also sets the self.closeonleave flag to true Todo (?): add type (type of parting: kick, part, ..) """ # # This gives us a (harmless?) # Gtk-WARNING **: gtk_signal_disconnect_by_data(): # could not find handler containing data (0x8271940) # Perhaps because we didn't install any handler, yet? #self.list.remove_items(self.users.values()) self.list.clear() self.topicentry.set_text("") if self.closeonleave: self.destroy() return 1 return 0 # create baseclass for generic (sub)tree support? def set_tree(self, tree): self.tree = tree # add dummy item - see serverView.set_tree why self.tree.append(GtkTreeItem()) # nickmenu handling/implementation should be in a separate class def item_handler(self, item, event, nick): """ handle events from tree and userlist items """ if event.type == BUTTON_PRESS and event.button == 3: foo = GladeXML("glade/most.glade", "nick_menu") bar = foo.get_widget("nick_menu") bar.popup(None, None, None, event.button, event.time) bar.connect("button-release-event", self.menu_handler, nick) foo.signal_autoconnect( {'whois_activate': (self.handle_whois, nick)} ) return 0 if event.type == GDK._2BUTTON_PRESS: if self.handler: self.handler.view_newquery(self.name, nick) return 1 def menu_handler(self, item, event, nick): pass def handle_whois(self, a, nick): if self.handler: self.handler.view_whois(self.name, nick) def reset(self, propagate=1, level=0): """ clear userlist, clear tree """ self.list.clear() for (name, item) in self.treeitems.items(): self.tree.remove_item(item) del self.treeitems[name] ## ## widget handlers def on_topicentry_activate(self, entry): text = entry.get_text() self.handler.view_topic(self.name, text) self.entry.grab_focus() ## ## Sending the modechanges as strings somewhat breaks the abstraction def on_keyentry_activate(self, entry): text = strip(entry.get_text()) if text == "": self.handler.view_mode(self.name, "-k") else: self.handler.view_mode(self.name, "-k+k %s" % text) self.entry.grab_focus() def on_limitentry_activate(self, entry): text = strip(entry.get_text()) # check if empty or number if text == "": self.handler.view_mode(self.name, "-l") else: self.handler.view_mode(self.name, "+l %s" % text) self.entry.grab_focus() def input_activate(self, item): text = item.get_text() item.set_text("") self.handler.handle_input(self.name, text)