diff --git a/terminatorlib/notebook.py b/terminatorlib/notebook.py new file mode 100755 index 00000000..17572927 --- /dev/null +++ b/terminatorlib/notebook.py @@ -0,0 +1,172 @@ +#!/usr/bin/python +# Terminator by Chris Jones +# GPL v2 only +"""container.py - classes necessary to contain Terminal widgets""" + +import gobject +import gtk + +from config import Config +from util import dbg, err +from translation import _ + +# pylint: disable-msg=R0921 +class Container(object): + """Base class for Terminator Containers""" + + terminator = None + immutable = None + children = None + config = None + signals = None + cnxids = None + + def __init__(self): + """Class initialiser""" + self.children = [] + self.signals = [] + self.cnxids = {} + self.config = Config() + + def register_signals(self, widget): + """Register gobject signals in a way that avoids multiple inheritance""" + existing = gobject.signal_list_names(widget) + for signal in self.signals: + if signal['name'] in existing: + dbg('Container:: skipping signal %s for %s, already exists' % ( + signal['name'], widget)) + else: + dbg('Container:: registering signal for %s on %s' % + (signal['name'], widget)) + try: + gobject.signal_new(signal['name'], + widget, + signal['flags'], + signal['return_type'], + signal['param_types']) + except RuntimeError: + err('Container:: registering signal for %s on %s failed' % + (signal['name'], widget)) + + def connect_child(self, widget, signal, handler, data=None): + """Register the requested signal and record its connection ID""" + if not self.cnxids.has_key(widget): + self.cnxids[widget] = [] + + if data is not None: + self.cnxids[widget].append(widget.connect(signal, handler, data)) + dbg('Container::connect_child: connecting %s(%s) for %s::%s' % + (handler.__name__, data, widget.__class__.__name__, signal)) + else: + self.cnxids[widget].append(widget.connect(signal, handler)) + dbg('Container::connect_child: registering %s to handle %s::%s' % + (handler.__name__, widget.__class__.__name__, signal)) + + def disconnect_child(self, widget): + """De-register the signals for a child""" + if self.cnxids.has_key(widget): + for cnxid in self.cnxids[widget]: + # FIXME: Look up the IDs to print a useful debugging message + widget.disconnect(cnxid) + del(self.cnxids[widget]) + + def get_offspring(self): + """Return a list of child widgets, if any""" + return(self.children) + + def split_horiz(self, widget): + """Split this container horizontally""" + return(self.split_axis(widget, True)) + + def split_vert(self, widget): + """Split this container vertically""" + return(self.split_axis(widget, False)) + + def split_axis(self, widget, vertical=True, sibling=None): + """Default axis splitter. This should be implemented by subclasses""" + raise NotImplementedError('split_axis') + + def add(self, widget): + """Add a widget to the container""" + raise NotImplementedError('add') + + def remove(self, widget): + """Remove a widget from the container""" + raise NotImplementedError('remove') + + def closeterm(self, widget): + """Handle the closure of a terminal""" + try: + if self.get_property('term_zoomed'): + # We're zoomed, so unzoom and then start closing again + dbg('Container::closeterm: terminal zoomed, unzooming') + self.unzoom(widget) + widget.close() + return(True) + except TypeError: + pass + + if not self.remove(widget): + return(False) + + self.terminator.deregister_terminal(widget) + self.terminator.group_hoover() + return(True) + + def resizeterm(self, widget, keyname): + """Handle a keyboard event requesting a terminal resize""" + raise NotImplementedError('resizeterm') + + def toggle_zoom(self, widget, fontscale = False): + """Toggle the existing zoom state""" + try: + if self.get_property('term_zoomed'): + self.unzoom(widget) + else: + self.zoom(widget, fontscale) + except TypeError: + err('Container::toggle_zoom: %s is unable to handle zooming, for \ + %s' % (self, widget)) + + def zoom(self, widget, fontscale = False): + """Zoom a terminal""" + raise NotImplementedError('zoom') + + def unzoom(self, widget): + """Unzoom a terminal""" + raise NotImplementedError('unzoom') + + def construct_confirm_close(self, window, type): + """Create a confirmation dialog for closing things""" + dialog = gtk.Dialog(_('Close?'), window, gtk.DIALOG_MODAL) + dialog.set_has_separator(False) + dialog.set_resizable(False) + + cancel = dialog.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT) + close_all = dialog.add_button(gtk.STOCK_CLOSE, gtk.RESPONSE_ACCEPT) + label = close_all.get_children()[0].get_children()[0].get_children()[1].set_label(_('Close _Terminals')) + + primary = gtk.Label(_('Close multiple temrinals?')) + primary.set_use_markup(True) + primary.set_alignment(0, 0.5) + secondary = gtk.Label(_('This %s has several terminals open. Closing the \ +%s will also close all terminals within it.') % (type, type)) + secondary.set_line_wrap(True) + + labels = gtk.VBox() + labels.pack_start(primary, False, False, 6) + labels.pack_start(secondary, False, False, 6) + + image = gtk.image_new_from_stock(gtk.STOCK_DIALOG_WARNING, + gtk.ICON_SIZE_DIALOG) + image.set_alignment(0.5, 0) + + box = gtk.HBox() + box.pack_start(image, False, False, 6) + box.pack_start(labels, False, False, 6) + dialog.vbox.pack_start(box, False, False, 12) + + dialog.show_all() + return(dialog) + +# vim: set expandtab ts=4 sw=4: