From 2a76382e47430780f0b025ba4cfd4ef49262ada8 Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Wed, 25 Nov 2009 00:37:29 +0000 Subject: [PATCH] migrate to using the factory and extend it to have an isinstance() --- terminatorlib/factory.py | 21 ++++++++++++++++ terminatorlib/notebook.py | 51 ++++++++++++++++++++++++++++++++++++--- terminatorlib/paned.py | 28 ++++++++++++++------- terminatorlib/test.py | 5 ++-- terminatorlib/window.py | 22 +++++++++-------- 5 files changed, 102 insertions(+), 25 deletions(-) diff --git a/terminatorlib/factory.py b/terminatorlib/factory.py index b4968235..3f22964a 100755 --- a/terminatorlib/factory.py +++ b/terminatorlib/factory.py @@ -19,6 +19,27 @@ class Factory(Borg): """Required by the borg, but a no-op here""" pass + def isinstance(self, product, classtype): + """Check if a given product is a particular type of object""" + if classtype == 'Terminal': + import terminal + return(isinstance(product, terminal.Terminal)) + elif classtype == 'VPaned': + import paned + return(isinstance(product, paned.VPaned)) + elif classtype == 'HPaned': + import paned + return(isinstance(product, paned.HPaned)) + elif classtype == 'Paned': + import paned + return(isinstance(product, paned.Paned)) + elif classtype == 'Notebook': + import notebook + return(isinstance(product, notebook.Notebook)) + else: + err('Factory::isinstance: unknown class type: %s' % classtype) + return(False) + def make(self, product, *args): """Make the requested product""" try: diff --git a/terminatorlib/notebook.py b/terminatorlib/notebook.py index 3f5e7fcc..e363ee5c 100755 --- a/terminatorlib/notebook.py +++ b/terminatorlib/notebook.py @@ -8,8 +8,8 @@ import gtk from newterminator import Terminator from config import Config +from factory import Factory from container import Container -from terminal import Terminal from editablelabel import EditableLabel from translation import _ from util import err @@ -57,7 +57,32 @@ class Notebook(Container, gtk.Notebook): def split_axis(self, widget, vertical=True, sibling=None): """Default axis splitter. This should be implemented by subclasses""" - raise NotImplementedError('split_axis') + page_num = self.page_num(widget) + if page_num == -1: + err('Notebook::split_axis: %s not found in Notebook' % widget) + return + + self.remove_page(page_num) + + maker = Factory() + if vertical: + container = maker.make('vpaned') + else: + container = maker.make('hpaned') + + if not sibling: + sibling = maker.make('terminal') + self.terminator.register_terminal(sibling) + sibling.spawn_child() + + self.insert_page(container, None, page_num) + self.show_all() + + container.add(widget) + container.add(sibling) + self.set_current_page(page_num) + + self.show_all() def add(self, widget): """Add a widget to the container""" @@ -65,15 +90,32 @@ class Notebook(Container, gtk.Notebook): def remove(self, widget): """Remove a widget from the container""" - raise NotImplementedError('remove') + page_num = self.page_num(widget) + if page_num == -1: + err('Notebook::remove: %s not found in Notebook' % widget) + return(False) + self.remove_page(page_num) def newtab(self, widget=None): """Add a new tab, optionally supplying a child widget""" if not widget: - widget = Terminal() + maker = Factory() + widget = maker.make('terminal') self.terminator.register_terminal(widget) widget.spawn_child() + # FIXME: We likely need a wrapcloseterm() to handle + # things like removing Notebook when there is only + # one tab left. + signals = {'close-term': self.closeterm, + #'title-change': self.title.set_title, + 'split-horiz': self.split_horiz, + 'split-vert': self.split_vert, + 'unzoom': self.unzoom} + + for signal in signals: + self.connect_child(widget, signal, signals[signal]) + self.set_tab_reorderable(widget, True) label = TabLabel(self.window.get_title(), self) @@ -87,6 +129,7 @@ class Notebook(Container, gtk.Notebook): self.append_page(widget, None) + self.set_current_page(-1) widget.grab_focus() def resizeterm(self, widget, keyname): diff --git a/terminatorlib/paned.py b/terminatorlib/paned.py index 3358e4d1..6a8e1886 100755 --- a/terminatorlib/paned.py +++ b/terminatorlib/paned.py @@ -9,7 +9,7 @@ import gtk from util import dbg, err, get_top_window from newterminator import Terminator -from terminal import Terminal +from factory import Factory from container import Container # pylint: disable-msg=R0921 @@ -43,6 +43,8 @@ class Paned(Container): # pylint: disable-msg=W0613 def split_axis(self, widget, vertical=True, sibling=None): """Default axis splitter. This should be implemented by subclasses""" + maker = Factory() + self.remove(widget) if vertical: container = VPaned() @@ -50,7 +52,7 @@ class Paned(Container): container = HPaned() if not sibling: - sibling = Terminal() + sibling = maker.make('terminal') self.terminator.register_terminal(sibling) sibling.spawn_child() @@ -64,6 +66,7 @@ class Paned(Container): def add(self, widget): """Add a widget to the container""" + maker = Factory() if len(self.children) == 0: self.pack1(widget, True, True) self.children.append(widget) @@ -77,7 +80,7 @@ class Paned(Container): raise ValueError('Paned widgets can only have two children') self.cnxids[widget] = [] - if isinstance(widget, Terminal): + if maker.isinstance(widget, 'Terminal'): top_window = get_top_window(self) # FIXME: somehow propagate the title-change signal to the Window @@ -111,13 +114,19 @@ class Paned(Container): def wrapcloseterm(self, widget): """A child terminal has closed, so this container must die""" if self.closeterm(widget): - parent = self.get_parent() - parent.remove(self) - # At this point we only have one child, which is the surviving term sibling = self.children[0] self.remove(sibling) - parent.add(sibling) + + parent = self.get_parent() + maker = Factory() + if maker.isinstance(parent, 'Notebook'): + page_num = parent.page_num(self) + parent.remove_page(page_num) + parent.insert_page(sibling, None, page_num) + else: + parent.remove(self) + parent.add(sibling) del(self) else: dbg("Paned::wrapcloseterm: self.closeterm failed") @@ -135,11 +144,12 @@ class Paned(Container): def resizeterm(self, widget, keyname): """Handle a keyboard event requesting a terminal resize""" + maker = Factory() if keyname in ['up', 'down'] and isinstance(self, gtk.VPaned): # This is a key we can handle position = self.get_position() - if isinstance(widget, Terminal): + if maker.isinstance(widget, 'Terminal'): fontheight = widget.vte.get_char_height() else: fontheight = 10 @@ -152,7 +162,7 @@ class Paned(Container): # This is a key we can handle position = self.get_position() - if isinstance(widget, Terminal): + if maker.isinstance(widget, 'Terminal'): fontwidth = widget.vte.get_char_width() else: fontwidth = 10 diff --git a/terminatorlib/test.py b/terminatorlib/test.py index 9438b9b7..a16e6291 100755 --- a/terminatorlib/test.py +++ b/terminatorlib/test.py @@ -4,15 +4,16 @@ import gtk from newterminator import Terminator from window import Window -from terminal import Terminal +from factory import Factory def on_window_destroyed(widget): """Window destroyed, so exit""" gtk.main_quit() +maker = Factory() window = Window() foo = Terminator() -term = Terminal() +term = maker.make('Terminal') foo.register_terminal(term) window.add(term) diff --git a/terminatorlib/window.py b/terminatorlib/window.py index 53731a37..8ac54936 100755 --- a/terminatorlib/window.py +++ b/terminatorlib/window.py @@ -12,10 +12,8 @@ from util import dbg, err from translation import _ from version import APP_NAME from container import Container -from notebook import Notebook +from factory import Factory from newterminator import Terminator -from terminal import Terminal -from paned import HPaned, VPaned try: import deskbar.core.keybinder as bindkey @@ -103,6 +101,7 @@ class Window(Container, gtk.Window): def on_key_press(self, window, event): """Handle a keyboard event""" + maker = Factory() # FIXME: We probably want to cancel window urgency here mapping = self.terminator.keybindings.lookup(event) @@ -117,8 +116,8 @@ class Window(Container, gtk.Window): self.on_destroy_event(window, gtk.gdk.Event(gtk.gdk.DESTROY)) elif mapping == 'new_tab': - if not isinstance(self.get_child(), Notebook): - notebook = Notebook(self) + if not maker.isinstance(self.get_child(), 'Notebook'): + notebook = maker.make('Notebook', self) self.get_child().newtab() else: return(False) @@ -126,7 +125,8 @@ class Window(Container, gtk.Window): def on_delete_event(self, window, event, data=None): """Handle a window close request""" - if isinstance(self.get_child(), Terminal): + maker = Factory() + if maker.isinstance(self.get_child(), 'Terminal'): dbg('Window::on_delete_event: Only one child, closing is fine') return(False) return(self.confirm_close(window, _('window'))) @@ -200,8 +200,9 @@ class Window(Container, gtk.Window): def add(self, widget): """Add a widget to the window by way of gtk.Window.add()""" + maker = Factory() gtk.Window.add(self, widget) - if isinstance(widget, Terminal): + if maker.isinstance(widget, 'Terminal'): signals = {'close-term': self.closeterm, 'title-change': self.title.set_title, 'split-horiz': self.split_horiz, @@ -221,16 +222,17 @@ class Window(Container, gtk.Window): def split_axis(self, widget, vertical=True, sibling=None): """Split the window""" + maker = Factory() self.remove(widget) # FIXME: we should be creating proper containers, not these gtk widgets if vertical: - container = VPaned() + container = maker.make('VPaned') else: - container = HPaned() + container = maker.make('HPaned') if not sibling: - sibling = Terminal() + sibling = maker.make('Terminal') self.terminator.register_terminal(sibling) self.add(container) container.show_all()