Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/services/console/lib/purk/widgets.py
diff options
context:
space:
mode:
Diffstat (limited to 'services/console/lib/purk/widgets.py')
-rw-r--r--services/console/lib/purk/widgets.py811
1 files changed, 0 insertions, 811 deletions
diff --git a/services/console/lib/purk/widgets.py b/services/console/lib/purk/widgets.py
deleted file mode 100644
index 1ad3cb8..0000000
--- a/services/console/lib/purk/widgets.py
+++ /dev/null
@@ -1,811 +0,0 @@
-import codecs
-
-import gobject
-import gtk
-import gtk.gdk
-import pango
-
-from conf import conf
-import parse_mirc
-import windows
-
-import servers
-
-# Window activity Constants
-HILIT = 'h'
-TEXT ='t'
-EVENT = 'e'
-
-ACTIVITY_MARKUP = {
- HILIT: "<span style='italic' foreground='#00F'>%s</span>",
- TEXT: "<span foreground='#ca0000'>%s</span>",
- EVENT: "<span foreground='#363'>%s</span>",
- }
-
-# This holds all tags for all windows ever
-tag_table = gtk.TextTagTable()
-
-link_tag = gtk.TextTag('link')
-link_tag.set_property('underline', pango.UNDERLINE_SINGLE)
-
-indent_tag = gtk.TextTag('indent')
-indent_tag.set_property('indent', -20)
-
-tag_table.add(link_tag)
-tag_table.add(indent_tag)
-
-#FIXME: MEH hates dictionaries, they remind him of the bad words
-styles = {}
-
-def style_me(widget, style):
- widget.set_style(styles.get(style))
-
-def set_style(widget_name, style):
- if style:
- # FIXME: find a better way...
- dummy = gtk.Label()
- dummy.set_style(None)
-
- def apply_style_fg(value):
- dummy.modify_text(gtk.STATE_NORMAL, gtk.gdk.color_parse(value))
-
- def apply_style_bg(value):
- dummy.modify_base(gtk.STATE_NORMAL, gtk.gdk.color_parse(value))
-
- def apply_style_font(value):
- dummy.modify_font(pango.FontDescription(value))
-
- style_functions = (
- ('fg', apply_style_fg),
- ('bg', apply_style_bg),
- ('font', apply_style_font),
- )
-
- for name, f in style_functions:
- if name in style:
- f(style[name])
-
- style = dummy.rc_get_style()
- else:
- style = None
-
- styles[widget_name] = style
-
-def menu_from_list(alist):
- while alist and not alist[-1]:
- alist.pop(-1)
-
- last = None
- for item in alist:
- if item != last:
- if item:
- if len(item) == 2:
- name, function = item
-
- menuitem = gtk.ImageMenuItem(name)
-
- elif len(item) == 3:
- name, stock_id, function = item
-
- if isinstance(stock_id, bool):
- menuitem = gtk.CheckMenuItem(name)
- menuitem.set_active(stock_id)
- else:
- menuitem = gtk.ImageMenuItem(stock_id)
-
- if isinstance(function, list):
- submenu = gtk.Menu()
- for subitem in menu_from_list(function):
- submenu.append(subitem)
- menuitem.set_submenu(submenu)
-
- else:
- menuitem.connect("activate", lambda a, f: f(), function)
-
- yield menuitem
-
- else:
- yield gtk.SeparatorMenuItem()
-
- last = item
-
-class Nicklist(gtk.TreeView):
- def click(self, event):
- if event.button == 3:
- x, y = event.get_coords()
-
- (data,), path, x, y = self.get_path_at_pos(int(x), int(y))
-
- c_data = self.events.data(window=self.win, data=self[data], menu=[])
-
- self.events.trigger("ListRightClick", c_data)
-
- if c_data.menu:
- menu = gtk.Menu()
- for item in menu_from_list(c_data.menu):
- menu.append(item)
- menu.show_all()
- menu.popup(None, None, None, event.button, event.time)
-
- elif event.button == 1 and event.type == gtk.gdk._2BUTTON_PRESS:
- x, y = event.get_coords()
-
- (data,), path, x, y = self.get_path_at_pos(int(x), int(y))
-
- self.events.trigger("ListDoubleClick", window=self.win, target=self[data])
-
- def __getitem__(self, pos):
- return self.get_model()[pos][0]
-
- def __setitem__(self, pos, name_markup):
- realname, markedupname, sortkey = name_markup
-
- self.get_model()[pos] = realname, markedupname, sortkey
-
- def __len__(self):
- return len(self.get_model())
-
- def index(self, item):
- for i, x in enumerate(self):
- if x == item:
- return i
-
- return -1
-
- def append(self, realname, markedupname, sortkey):
- self.get_model().append((realname, markedupname, sortkey))
-
- def insert(self, pos, realname, markedupname, sortkey):
- self.get_model().insert(pos, (realname, markedupname, sortkey))
-
- def replace(self, names):
- self.set_model(gtk.ListStore(str, str, str))
-
- self.insert_column_with_attributes(
- 0, '', gtk.CellRendererText(), markup=1
- ).set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
-
- for name in names:
- self.append(*name)
-
- self.get_model().set_sort_column_id(2, gtk.SORT_ASCENDING)
-
- def remove(self, realname):
- index = self.index(realname)
-
- if index == -1:
- raise ValueError
-
- self.get_model().remove(self.get_model().iter_nth_child(None, index))
-
- def clear(self):
- self.get_model().clear()
-
- def __iter__(self):
- return (r[0] for r in self.get_model())
-
- def __init__(self, window, core):
- self.win = window
- self.core = core
- self.events = core.events
-
- gtk.TreeView.__init__(self)
-
- self.replace(())
-
- self.set_headers_visible(False)
- self.set_property("fixed-height-mode", True)
- self.connect("button-press-event", Nicklist.click)
- self.connect_after("button-release-event", lambda *a: True)
-
- style_me(self, "nicklist")
-
-# Label used to display/edit your current nick on a network
-class NickEditor(gtk.EventBox):
- def nick_change(self, entry):
- oldnick, newnick = self.label.get_text(), entry.get_text()
-
- if newnick and newnick != oldnick:
- self.events.run('nick %s' % newnick, self.win, self.win.network)
-
- self.win.input.grab_focus()
-
- def update(self, nick=None):
- self.label.set_text(nick or self.win.network.me)
-
- def to_edit_mode(self, widget, event):
- if self.label not in self.get_children():
- return
-
- if getattr(event, 'button', None) == 3:
- c_data = self.events.data(window=self.win, menu=[])
- self.events.trigger("NickEditMenu", c_data)
-
- if c_data.menu:
- menu = gtk.Menu()
- for item in menu_from_list(c_data.menu):
- menu.append(item)
- menu.show_all()
- menu.popup(None, None, None, event.button, event.time)
-
- else:
- entry = gtk.Entry()
- entry.set_text(self.label.get_text())
- entry.connect('activate', self.nick_change)
- entry.connect('focus-out-event', self.to_show_mode)
-
- self.remove(self.label)
- self.add(entry)
- self.window.set_cursor(None)
-
- entry.show()
- entry.grab_focus()
-
- def to_show_mode(self, widget, event):
- self.remove(widget)
- self.add(self.label)
- self.win.input.grab_focus()
- self.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.XTERM))
-
- def __init__(self, window, core):
- gtk.EventBox.__init__(self)
- self.events = core.events
- self.win = window
-
- self.label = gtk.Label()
- self.label.set_padding(5, 0)
- self.add(self.label)
-
- self.connect("button-press-event", self.to_edit_mode)
-
- self.update()
-
- self.connect(
- "realize",
- lambda *a: self.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.XTERM))
- )
-
-# The entry which you type in to send messages
-class TextInput(gtk.Entry):
- # Generates an input event
- def entered_text(self, ctrl):
- #for a in globals():
- # print a
- #print events.__file__
- #self.core.run_command(self.text)
- for line in self.text.splitlines():
- if line:
- e_data = self.events.data(
- window=self.win, network=self.win.network,
- text=line, ctrl=ctrl
- )
- self.events.trigger('Input', e_data)
- if not e_data.done:
- self.events.run(line, self.win, self.win.network)
-
- self.text = ''
-
- def _set_selection(self, s):
- if s:
- self.select_region(*s)
- else:
- self.select_region(self.cursor, self.cursor)
-
- #some nice toys for the scriptors
- text = property(gtk.Entry.get_text, gtk.Entry.set_text)
- cursor = property(gtk.Entry.get_position, gtk.Entry.set_position)
- selection = property(gtk.Entry.get_selection_bounds, _set_selection)
-
- def insert(self, text):
- self.do_insert_at_cursor(self, text)
-
- #hack to stop it selecting the text when we focus
- def do_grab_focus(self):
- temp = self.text, (self.selection or (self.cursor,)*2)
- self.text = ''
- gtk.Entry.do_grab_focus(self)
- self.text, self.selection = temp
-
- def keypress(self, event):
- keychar = (
- (gtk.gdk.CONTROL_MASK, '^'),
- (gtk.gdk.SHIFT_MASK, '+'),
- (gtk.gdk.MOD1_MASK, '!')
- )
-
- key = ''
- for keymod, char in keychar:
- # we make this an int, because otherwise it leaks
- if int(event.state) & keymod:
- key += char
- key += gtk.gdk.keyval_name(event.keyval)
-
- self.events.trigger('KeyPress', key=key, string=event.string, window=self.win)
-
- if key == "^Return":
- self.entered_text(True)
-
- up = gtk.gdk.keyval_from_name("Up")
- down = gtk.gdk.keyval_from_name("Down")
- tab = gtk.gdk.keyval_from_name("Tab")
-
- return event.keyval in (up, down, tab)
-
- def __init__(self, window, core):
- gtk.Entry.__init__(self)
- self.events = core.events
- self.core = core
- self.win = window
-
- # we don't want key events to propogate so we stop them in connect_after
- self.connect('key-press-event', TextInput.keypress)
- self.connect_after('key-press-event', lambda *a: True)
-
- self.connect('activate', TextInput.entered_text, False)
-
-gobject.type_register(TextInput)
-
-def prop_to_gtk(textview, (prop, val)):
- if val == parse_mirc.BOLD:
- val = pango.WEIGHT_BOLD
-
- elif val == parse_mirc.UNDERLINE:
- val = pango.UNDERLINE_SINGLE
-
- return {prop: val}
-
-def word_from_pos(text, pos):
- if text[pos] == ' ':
- return ' ', pos, pos+1
-
- else:
- fr = text[:pos].split(" ")[-1]
- to = text[pos:].split(" ")[0]
-
- return fr + to, pos - len(fr), pos + len(to)
-
-def get_iter_at_coords(view, x, y):
- return view.get_iter_at_location(
- *view.window_to_buffer_coords(gtk.TEXT_WINDOW_TEXT, int(x), int(y))
- )
-
-def get_event_at_iter(view, iter, core):
- buffer = view.get_buffer()
-
- line_strt = buffer.get_iter_at_line(iter.get_line())
- line_end = line_strt.copy()
- line_end.forward_lines(1)
-
- pos = iter.get_line_offset()
-
- #Caveat: text must be a unicode string, not utf-8 encoded; otherwise our
- # offsets will be off when we use anything outside 7-bit ascii
- #gtk.TextIter.get_text returns unicode but gtk.TextBuffer.get_text does not
- text = line_strt.get_text(line_end).rstrip("\n")
-
- word, fr, to = word_from_pos(text, pos)
-
- return core.events.data(
- window=view.win, pos=pos, text=text,
- target=word, target_fr=fr, target_to=to,
- )
-
-class TextOutput(gtk.TextView):
- def copy(self):
- startend = self.get_buffer().get_selection_bounds()
-
- tagsandtext = []
- if startend:
- start, end = startend
-
- while not start.equal(end):
- tags_at_iter = {}
- for tag in start.get_tags():
- try:
- tagname, tagval = eval(tag.get_property('name'))
- tags_at_iter[tagname] = tagval
- except NameError:
- continue
-
- tagsandtext.append((dict(tags_at_iter), start.get_char()))
- start.forward_char()
-
- text = parse_mirc.unparse_mirc(tagsandtext)
-
- gtk.clipboard_get(gtk.gdk.SELECTION_CLIPBOARD).set_text(text)
- gtk.clipboard_get(gtk.gdk.SELECTION_PRIMARY).set_text(text)
-
- return text
-
- def clear(self):
- self.get_buffer().set_text('')
-
- def get_y(self):
- rect = self.get_visible_rect()
- return rect.y
-
- def set_y(self,y):
- iter = self.get_iter_at_location(0, y)
- if self.get_iter_location(iter).y < y:
- self.forward_display_line(iter)
- yalign = float(self.get_iter_location(iter).y-y)/self.height
- self.scroll_to_iter(iter, 0, True, 0, yalign)
-
- self.check_autoscroll()
-
- def get_ymax(self):
- buffer = self.get_buffer()
- return sum(self.get_line_yrange(buffer.get_end_iter())) - self.height
-
- def get_height(self):
- return self.get_visible_rect().height
-
- y = property(get_y, set_y)
- ymax = property(get_ymax)
- height = property(get_height)
-
- # the unknowing print weird things to our text widget function
- def write(self, text, line_ending='\n', fg=None):
- if not isinstance(text, unicode):
- try:
- text = codecs.utf_8_decode(text)[0]
- except:
- text = codecs.latin_1_decode(text)[0]
- tags, text = parse_mirc.parse_mirc(text)
-
- if fg:
- tags.append({'data': ("foreground", isinstance(fg, basestring) and ('#%s'%fg) or parse_mirc.get_mirc_color(fg)), 'from': 0, 'to': len(text)})
-
- buffer = self.get_buffer()
-
- cc = buffer.get_char_count()
-
- buffer.insert_with_tags_by_name(
- buffer.get_end_iter(),
- text + line_ending,
- 'indent'
- )
-
- for tag in tags:
- tag_name = str(tag['data'])
-
- if not tag_table.lookup(tag_name):
- buffer.create_tag(tag_name, **prop_to_gtk(self, tag['data']))
-
- buffer.apply_tag_by_name(
- tag_name,
- buffer.get_iter_at_offset(tag['from'] + cc),
- buffer.get_iter_at_offset(tag['to'] + cc)
- )
-
- def popup(self, menu):
- hover_iter = get_iter_at_coords(self, *self.hover_coords)
-
- menuitems = []
- if not hover_iter.ends_line():
- c_data = get_event_at_iter(self, hover_iter)
- c_data.menu = []
-
- self.events.trigger("RightClick", c_data)
-
- menuitems = c_data.menu
-
- if not menuitems:
- c_data = self.events.data(menu=[])
- self.events.trigger("MainMenu", c_data)
-
- menuitems = c_data.menu
-
- for child in menu.get_children():
- menu.remove(child)
-
- for item in menu_from_list(menuitems):
- menu.append(item)
-
- menu.show_all()
-
- def mousedown(self, event):
- if event.button == 3:
- self.hover_coords = event.get_coords()
-
- def mouseup(self, event):
- if not self.get_buffer().get_selection_bounds():
- if event.button == 1:
- hover_iter = get_iter_at_coords(self, event.x, event.y)
-
- if not hover_iter.ends_line():
- c_data = get_event_at_iter(self, hover_iter, self.core)
-
- self.events.trigger("Click", c_data)
-
- if self.is_focus():
- self.win.focus()
-
- def clear_hover(self, _event=None):
- buffer = self.get_buffer()
-
- for fr, to in self.linking:
- buffer.remove_tag_by_name(
- "link",
- buffer.get_iter_at_mark(fr),
- buffer.get_iter_at_mark(to)
- )
-
- self.linking = set()
- self.get_window(gtk.TEXT_WINDOW_TEXT).set_cursor(None)
-
- def hover(self, event):
- if self.linking:
- self.clear_hover()
-
- hover_iter = get_iter_at_coords(self, event.x, event.y)
-
- if not hover_iter.ends_line():
- h_data = get_event_at_iter(self, hover_iter, self.core)
- h_data.tolink = set()
-
- self.events.trigger("Hover", h_data)
-
- if h_data.tolink:
- buffer = self.get_buffer()
-
- offset = buffer.get_iter_at_line(
- hover_iter.get_line()
- ).get_offset()
-
- for fr, to in h_data.tolink:
- fr = buffer.get_iter_at_offset(offset + fr)
- to = buffer.get_iter_at_offset(offset + to)
-
- buffer.apply_tag_by_name("link", fr, to)
-
- self.linking.add(
- (buffer.create_mark(None, fr),
- buffer.create_mark(None, to))
- )
-
- self.get_window(
- gtk.TEXT_WINDOW_TEXT
- ).set_cursor(gtk.gdk.Cursor(gtk.gdk.HAND2))
-
- self.get_pointer()
-
- def scroll(self, _allocation=None):
- if self.autoscroll:
- def do_scroll():
- self.scroller.value = self.scroller.upper - self.scroller.page_size
- self._scrolling = False
-
- if not self._scrolling:
- self._scrolling = gobject.idle_add(do_scroll)
-
- def check_autoscroll(self, *args):
- def set_to_scroll():
- self.autoscroll = self.scroller.value + self.scroller.page_size >= self.scroller.upper
-
- gobject.idle_add(set_to_scroll)
-
- def __init__(self, core, window, buffer=None):
- if not buffer:
- buffer = gtk.TextBuffer(tag_table)
-
- gtk.TextView.__init__(self, buffer)
- self.core = core
- self.events = core.events
- self.win = window
-
- self.set_size_request(0, -1)
-
- self.set_wrap_mode(gtk.WRAP_WORD_CHAR)
- self.set_editable(False)
- self.set_cursor_visible(False)
-
- self.set_property("left-margin", 3)
- self.set_property("right-margin", 3)
-
- self.linking = set()
-
- self.add_events(gtk.gdk.POINTER_MOTION_HINT_MASK)
- self.add_events(gtk.gdk.LEAVE_NOTIFY_MASK)
-
- self.connect('populate-popup', TextOutput.popup)
- self.connect('motion-notify-event', TextOutput.hover)
- self.connect('button-press-event', TextOutput.mousedown)
- self.connect('button-release-event', TextOutput.mouseup)
- self.connect_after('button-release-event', lambda *a: True)
- self.connect('leave-notify-event', TextOutput.clear_hover)
-
- self.hover_coords = 0, 0
-
- self.autoscroll = True
- self._scrolling = False
- self.scroller = gtk.Adjustment()
-
- def setup_scroll(self, _adj, vadj):
- self.scroller = vadj
-
- if vadj:
- def set_scroll(adj):
- self.autoscroll = adj.value + adj.page_size >= adj.upper
-
- vadj.connect("value-changed", set_scroll)
-
- self.connect("set-scroll-adjustments", setup_scroll)
- self.connect("size-allocate", TextOutput.scroll)
-
- def set_cursor(widget):
- self.get_window(gtk.TEXT_WINDOW_TEXT).set_cursor(None)
-
- self.connect("realize", set_cursor)
-
- style_me(self, "view")
-
-class WindowLabel(gtk.EventBox):
- def update(self):
- title = self.win.get_title()
-
- for escapes in (('&','&amp;'), ('<','&lt;'), ('>','&gt;')):
- title = title.replace(*escapes)
-
- for a_type in (HILIT, TEXT, EVENT):
- if a_type in self.win.activity:
- title = ACTIVITY_MARKUP[a_type] % title
- break
-
- self.label.set_markup(title)
-
- def tab_popup(self, event):
- if event.button == 3: # right click
- c_data = self.events.data(window=self.win, menu=[])
- self.events.trigger("WindowMenu", c_data)
-
- c_data.menu += [
- None,
- ("Close", gtk.STOCK_CLOSE, self.win.close),
- ]
-
- menu = gtk.Menu()
- for item in menu_from_list(c_data.menu):
- menu.append(item)
- menu.show_all()
- menu.popup(None, None, None, event.button, event.time)
-
- def __init__(self, window, core):
- gtk.EventBox.__init__(self)
- self.core = core
- self.events = core.events
-
- self.win = window
- self.connect("button-press-event", WindowLabel.tab_popup)
-
- self.label = gtk.Label()
- self.add(self.label)
-
- self.update()
- self.show_all()
-
-class FindBox(gtk.HBox):
- def remove(self, *args):
- self.parent.remove(self)
- self.win.focus()
-
- def clicked(self, button, search_down=False):
- text = self.textbox.get_text()
-
- if not text:
- return
-
- buffer = self.win.output.get_buffer()
-
- if buffer.get_selection_bounds():
- if button == self.down:
- _, cursor_iter = buffer.get_selection_bounds()
- else:
- cursor_iter, _ = buffer.get_selection_bounds()
- else:
- cursor_iter = buffer.get_end_iter()
-
- if search_down:
- cursor = cursor_iter.forward_search(
- text, gtk.TEXT_SEARCH_VISIBLE_ONLY
- )
- else:
- cursor = cursor_iter.backward_search(
- text, gtk.TEXT_SEARCH_VISIBLE_ONLY
- )
-
- if not cursor:
- return
-
- fr, to = cursor
-
- if button == self.up:
- buffer.place_cursor(fr)
- self.win.output.scroll_to_iter(fr, 0)
- elif button == self.down:
- buffer.place_cursor(to)
- self.win.output.scroll_to_iter(to, 0)
-
- buffer.select_range(*cursor)
-
- cursor_iter = buffer.get_iter_at_mark(buffer.get_insert())
-
- def __init__(self, window):
- gtk.HBox.__init__(self)
-
- self.win = window
-
- self.up = gtk.Button(stock='gtk-go-up')
- self.down = gtk.Button(stock='gtk-go-down')
-
- self.up.connect('clicked', self.clicked)
- self.down.connect('clicked', self.clicked, True)
-
- self.up.set_property('can_focus', False)
- self.down.set_property('can_focus', False)
-
- self.textbox = gtk.Entry()
-
- self.textbox.connect('focus-out-event', self.remove)
- self.textbox.connect('activate', self.clicked)
-
- self.pack_start(gtk.Label('Find:'), expand=False)
- self.pack_start(self.textbox)
-
- self.pack_start(self.up, expand=False)
- self.pack_start(self.down, expand=False)
-
- self.show_all()
-
-#class UrkUITabs(gtk.Window):
-class UrkUITabs(object):
- def __init__(self, core):
- # threading stuff
- gtk.gdk.threads_init()
- self.core = core
- self.events = core.events
- self.tabs = gtk.Notebook()
- self.tabs.set_property(
- "tab-pos",
- conf.get("ui-gtk/tab-pos", gtk.POS_BOTTOM)
- )
-
- self.tabs.set_scrollable(True)
- self.tabs.set_property("can-focus", False)
-
- self.box = gtk.VBox(False)
- self.box.pack_end(self.tabs)
-
- def __iter__(self):
- return iter(self.tabs.get_children())
-
- def __len__(self):
- return self.tabs.get_n_pages()
-
- def exit(self, *args):
- self.events.trigger("Exit")
- gtk.main_level() and gtk.main_quit()
-
- def get_active(self):
- return self.tabs.get_nth_page(self.tabs.get_current_page())
-
- def set_active(self, window):
- self.tabs.set_current_page(self.tabs.page_num(window))
-
- def add(self, window):
- for pos in reversed(range(self.tabs.get_n_pages())):
- if self.tabs.get_nth_page(pos).network == window.network:
- break
- else:
- pos = self.tabs.get_n_pages() - 1
-
- self.tabs.insert_page(window, WindowLabel(window, self.core), pos+1)
-
- def remove(self, window):
- self.tabs.remove_page(self.tabs.page_num(window))
-
- def update(self, window):
- self.tabs.get_tab_label(window).update()
-
- def show_all(self):
- self.box.show_all()