Example #1
0
    def __init__(self, manager, window_conf):
        gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL)

        self.editors = []
        self.last_switch_time = None
        self.panels = weakref.WeakKeyDictionary()

        self.set_name('SnakedWindow')
        self.set_role('Editor')
        self.connect('delete-event', self.on_delete_event)

        # set border width handling, see self.on_state_event for more details
        self.connect('window-state-event', self.on_state_event)

        self.set_default_size(800, 500)

        manager.activator.attach(self)

        self.main_pane = gtk.VPaned()
        self.main_pane_position_set = False
        self.add(self.main_pane)

        conf = manager.conf
        self.window_conf = window_conf
        self.manager = manager

        self.floating_manager = FloatingManager()
        self.escape_manager = EscapeManager()

        self.note = gtk.Notebook()
        self.note.set_show_tabs(
            conf['SHOW_TABS'] if conf['SHOW_TABS'] is not None else window_conf.get('show-tabs', True))
        self.note.set_scrollable(True)
        self.note.set_property('tab-hborder', 10)
        self.note.set_property('homogeneous', False)
        self.note.set_show_border(False)
        self.note.connect_after('switch-page', self.on_switch_page)
        self.note.connect('page_removed', self.on_page_removed)
        self.note.connect('page_reordered', self.on_page_reordered)
        self.note.props.tab_pos = tab_bar_pos_mapping.get(conf['TAB_BAR_PLACEMENT'], gtk.POS_TOP)
        self.main_pane.add1(self.note)

        if conf['RESTORE_POSITION'] and 'last-position' in window_conf:
            try:
                pos, size = window_conf['last-position']
            except ValueError:
                if window_conf['last-position'] == 'fullscreen':
                    self.fullscreen()
                elif window_conf['last-position'] == 'maximized':
                    self.maximize()
            else:
                self.move(*pos)
                self.resize(*size)

        self.show_all()
Example #2
0
class Window(gtk.Window):
    def __init__(self, manager, window_conf):
        gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL)

        self.editors = []
        self.last_switch_time = None
        self.panels = weakref.WeakKeyDictionary()

        self.set_name('SnakedWindow')
        self.set_role('Editor')
        self.connect('delete-event', self.on_delete_event)

        # set border width handling, see self.on_state_event for more details
        self.connect('window-state-event', self.on_state_event)

        self.set_default_size(800, 500)

        manager.activator.attach(self)

        self.main_pane = gtk.VPaned()
        self.main_pane_position_set = False
        self.add(self.main_pane)

        conf = manager.conf
        self.window_conf = window_conf
        self.manager = manager

        self.floating_manager = FloatingManager()
        self.escape_manager = EscapeManager()

        self.note = gtk.Notebook()
        self.note.set_show_tabs(
            conf['SHOW_TABS'] if conf['SHOW_TABS'] is not None else window_conf.get('show-tabs', True))
        self.note.set_scrollable(True)
        self.note.set_property('tab-hborder', 10)
        self.note.set_property('homogeneous', False)
        self.note.set_show_border(False)
        self.note.connect_after('switch-page', self.on_switch_page)
        self.note.connect('page_removed', self.on_page_removed)
        self.note.connect('page_reordered', self.on_page_reordered)
        self.note.props.tab_pos = tab_bar_pos_mapping.get(conf['TAB_BAR_PLACEMENT'], gtk.POS_TOP)
        self.main_pane.add1(self.note)

        if conf['RESTORE_POSITION'] and 'last-position' in window_conf:
            try:
                pos, size = window_conf['last-position']
            except ValueError:
                if window_conf['last-position'] == 'fullscreen':
                    self.fullscreen()
                elif window_conf['last-position'] == 'maximized':
                    self.maximize()
            else:
                self.move(*pos)
                self.resize(*size)

        self.show_all()

    def get_editor_context(self):
        widget = self.note.get_nth_page(self.note.get_current_page())
        for e in self.editors:
            if e.widget is widget:
                return e

        return None

    active_editor = property(get_editor_context)

    def attach_editor(self, editor):
        self.editors.append(editor)
        label = gtk.Label('Unknown')
        self.note.append_page(editor.widget, label)
        self.note.set_tab_reorderable(editor.widget, True)
        self.focus_editor(editor)
        editor.view.grab_focus()

    def focus_editor(self, editor):
        idx = self.note.page_num(editor.widget)
        self.note.set_current_page(idx)

    def update_top_level_title(self):
        idx = self.note.get_current_page()
        if idx < 0:
            return

        editor = self.get_editor_context()
        if editor:
            title = editor.get_window_title.emit()

        if not title:
            title = self.note.get_tab_label_text(self.note.get_nth_page(idx))

        if title is not None:
            self.set_title(title)

    def set_editor_title(self, editor, title):
        self.note.set_tab_label_text(editor.widget, title)
        if self.note.get_current_page() == self.note.page_num(editor.widget):
            self.update_top_level_title()

    def on_delete_event(self, *args):
        self.close()

    def on_state_event(self, widget, event):
        """Sets the window border depending on state

        The window border eases the resizing of the window using the mouse.
        In maximized and fullscreen state the this use case is irrelevant.
        Removing the border in this cases makes it easier to hit the scrollbar.

        Unfortunately this currently only works with tabs hidden.
        """
        state = event.new_window_state
        if state & gtk.gdk.WINDOW_STATE_MAXIMIZED or state & gtk.gdk.WINDOW_STATE_FULLSCREEN:
            self.set_border_width(0)
        else:
            self.set_border_width(self.manager.conf['WINDOW_BORDER_WIDTH'])

    def detach_editor(self, editor):
        idx = self.note.page_num(editor.widget)
        self.note.remove_page(idx)
        self.editors.remove(editor)

    def close_editor(self, editor):
        self.manager.editor_closed(editor)
        self.detach_editor(editor)

        if not self.editors:
            self.close()

    def close(self, notify_manager=True):
        current_editor = self.get_editor_context()
        if current_editor:
            self.window_conf['active-uri'] = current_editor.uri

        files = self.window_conf.setdefault('files', [])
        files[:] = []
        for e in self.editors[:]:
            files.append(dict(uri=e.uri))
            self.manager.editor_closed(e)
            self.editors.remove(e)

        state = self.window.get_state()
        if state & gtk.gdk.WINDOW_STATE_FULLSCREEN:
            self.window_conf['last-position'] = 'fullscreen'
        elif state & gtk.gdk.WINDOW_STATE_MAXIMIZED:
            self.window_conf['last-position'] = 'maximized'
        else:
            self.window_conf['last-position'] = self.get_position(), self.get_size()

        if self.main_pane_position_set:
            _, _, _, wh, _ = self.window.get_geometry()
            self.window_conf['panel-height'] = wh - self.main_pane.get_position()

        if notify_manager:
            self.manager.window_closed(self)

    def save(self, editor):
        editor.save()

    def on_switch_page(self, *args):
        self.update_top_level_title()

    def on_page_removed(self, note, child, idx):
        switch_to = None
        for e in self.editors:
            if e.widget is child:
                spot = self.manager.spot_manager.get_last(None, e)
                if spot:
                    switch_to = note.page_num(spot.editor().widget)

                break

        if switch_to is None and idx > 0:
            switch_to = idx - 1

        if switch_to is not None:
            note.set_current_page(switch_to)
            refresh_gui()

        e = self.get_editor_context()
        if e:
            idle(e.view.grab_focus)

    def switch_to(self, editor, dir):
        if self.last_switch_time is None or time.time() - self.last_switch_time > 5:
            self.manager.spot_manager.add(editor)

        self.last_switch_time = time.time()

        idx = ( self.note.get_current_page() + dir ) % self.note.get_n_pages()
        self.note.set_current_page(idx)

        if not self.note.get_show_tabs() and \
                wait_mod_unpress_for_last_shortcut(self, self.hide_tab_menu):
            menu = self.get_tab_menu()

            for c in menu.get_children():
                c.deselect()

            menu.get_children()[idx].select()

    def get_tab_menu(self):
        try:
            return self.tab_menu
        except AttributeError:
            pass

        f = gtk.EventBox()

        vb = gtk.VBox()
        f.add(vb)

        for e in self.editors:
            it = gtk.MenuItem(e.get_title.emit(), False)
            vb.pack_start(it)

        add_float(self, f)
        self.tab_menu = vb
        return vb

    def hide_tab_menu(self):
        if getattr(self, 'tab_menu', None):
            remove_float(self.tab_menu.get_parent())
            del self.tab_menu

    def toggle_fullscreen(self, is_set):
        state = self.window.get_state() & gtk.gdk.WINDOW_STATE_FULLSCREEN
        if is_set:
            if state:
                self.unfullscreen()
            else:
                self.fullscreen()
        else:
            return state

    def show_tabs(self, is_set):
        if is_set:
            self.note.set_show_tabs(not self.note.get_show_tabs())
            self.window_conf['show-tabs'] = self.note.get_show_tabs()
        else:
            return self.note.get_show_tabs()

    def append_panel(self, widget):
        v = self.panels[widget] = PanelHandler(widget)
        return v

    def popup_panel(self, widget, activate=False, *args):
        if widget in self.panels:
            for w in self.panels:
                if w is not widget and w is self.main_pane.get_child2():
                    self.main_pane.remove(w)

            if not self.main_pane_position_set:
                self.main_pane_position_set = True
                _, _, _, wh, _ = self.window.get_geometry()
                self.main_pane.set_position(wh - self.window_conf.get('panel-height', 200))

            if self.main_pane.get_child2() is not widget:
                self.main_pane.add2(widget)

            if not widget.get_visible():
                widget.show()
                self.panels[widget].popup(*args)
            else:
                activate = True

            if activate:
                self.panels[widget].activate(*args)

    def on_page_reordered(self, note, child, num):
        for i, e in enumerate(self.editors):
            if e.widget is child:
                self.editors[i], self.editors[num] = self.editors[num], self.editors[i]
                break

    def move_tab(self, editor, is_right):
        pos = self.note.page_num(editor.widget)
        if is_right:
            pos += 1
        else:
            pos -= 1

        if pos < 0 or pos >= self.note.get_n_pages():
            editor.message('This is dead end')
            return

        self.note.reorder_child(editor.widget, pos)

    def activate_main_window(self):
        self.present()
        #self.present_with_time(gtk.get_current_event_time())

    def retach_editor(self, editor):
        self.detach_editor(editor)
        self.manager.get_free_window().attach_editor(editor)

    def duplicate_editor(self, editor):
        self.manager.get_free_window().attach_editor(self.manager.open(editor.uri))

    def save_editor(self, editor):
        editor.save()

    def open_or_activate(self, uri, line=None):
        return self.manager.open_or_activate(uri, self, line)

    def message(self, message, category=None, timeout=None, markup=False, parent=None):
        fb = TextFeedback(message, category, markup)
        if timeout is None:
            timeout = fb.timeout
        self.push_escape(fb)
        return self.floating_manager.add(parent or self, fb, timeout=timeout)

    def feedback(self, widget, priority=None, parent=None):
        fb = Feedback(widget)
        return self.floating_manager.add(parent or self, fb, priority)

    def emessage(self, message, category=None, timeout=None, markup=False):
        fb = TextFeedback(message, category, markup)
        if timeout is None:
            timeout = fb.timeout

        e = self.get_editor_context()
        parent = e.view if e else self
        self.push_escape(fb)
        return self.floating_manager.add(parent, fb, timeout=timeout)

    def push_escape(self, obj, priority=None):
        return self.escape_manager.push(obj, priority)

    def process_escape(self):
        if not self.escape_manager.process():
            widget = self.main_pane.get_child2()
            if widget:
                if widget.get_visible():
                    if widget.get_focus_child():
                        e = self.active_editor
                        if e:
                            e.view.grab_focus()
                    else:
                        widget.hide()

                    return True

        return False

    def get_panel_visible_context(self):
        w = self.main_pane.get_child2()
        if w and w.get_visible():
            return self
        else:
            return None

    def change_panel_size(self, delta):
        self.main_pane.set_position(self.main_pane.get_position() - delta)