diff --git a/dreampielib/data/dreampie.glade b/dreampielib/data/dreampie.glade index b063bc8..30cfd92 100644 --- a/dreampielib/data/dreampie.glade +++ b/dreampielib/data/dreampie.glade @@ -1195,6 +1195,21 @@ You can also set the __expects_str__ attribute of a function to True to achieve 5 + + + Swap panes + True + True + False + False + True + + + False + True + 5.5 + + Leave code in the code box after execution @@ -1967,6 +1982,17 @@ You can also set the __expects_str__ attribute of a function to True to achieve + + + True + False + Try to unclog a stuck subprocess. Use with care! + False + Unclog subprocess + True + + + True diff --git a/dreampielib/gui/__init__.py b/dreampielib/gui/__init__.py index f93d75b..c71fefc 100644 --- a/dreampielib/gui/__init__.py +++ b/dreampielib/gui/__init__.py @@ -169,11 +169,6 @@ def __init__(self, pyexec, runfile): # A tuple (page_num, text) of the recently closed tab self.reopen_tab_data = None - # last (font, vertical_layout) configured. If they are changed, - # configure() will resize the window and place the paned. - self.last_configured_layout = (None, None) - self.configure() - self.output = Output(self.textview) self.folding = Folding(self.textbuffer, LINE_LEN) @@ -213,6 +208,14 @@ def __init__(self, pyexec, runfile): self.complete_dict_keys, INDENT_WIDTH) + # had to move this down below autocomplete in order to allow configuration of autocomplete popup direction + + # last (font, vertical_layout) configured. If they are changed, + # configure() will resize the window and place the paned. + self.last_configured_layout = (None, None) + self.configure() + + # Hack: we connect this signal here, so that it will have lower # priority than the key-press event of autocomplete, when active. self.sourceview_keypress_handler = self.sourceview.connect( @@ -961,6 +964,16 @@ def on_interrupt(self, _widget): _("A command isn't being executed currently")) beep() + def on_unclog_subprocess(self, _widget): + # It seems that sometimes DreamPie thinks there is an unclaimed + # result when there really isn't. Here we try to clear the clog by + # decrementing the unclaimed result counter. This could blow up + # badly if used at the wrong time, so should only be used when it + # really seems like DreamPie thinks the subprocess is busy but it + # really isn't. + self._n_unclaimed_results -= 1 + + # History persistence def on_save_history(self, _widget): @@ -1266,9 +1279,13 @@ def configure(self): tags.apply_theme_source(sv.get_buffer(), theme) vertical_layout = self.config.get_bool('vertical-layout') + swap_panes = self.config.get_bool('swap-panes') if vertical_layout: pane = self.vpaned_main; other_pane = self.hpaned_main - self.notebook.props.tab_pos = gtk.POS_BOTTOM + if swap_panes: + self.notebook.props.tab_pos = gtk.POS_TOP + else: + self.notebook.props.tab_pos = gtk.POS_BOTTOM else: pane = self.hpaned_main; other_pane = self.vpaned_main self.notebook.props.tab_pos = gtk.POS_TOP @@ -1277,9 +1294,26 @@ def configure(self): if pane.get_child1() is None: child1 = other_pane.get_child1(); other_pane.remove(child1) child2 = other_pane.get_child2(); other_pane.remove(child2) - pane.pack1(child1, resize=True, shrink=False) - pane.pack2(child2, resize=not vertical_layout, shrink=False) + else: + child1 = pane.get_child1(); pane.remove(child1) + child2 = pane.get_child2(); pane.remove(child2) + if child1.get_name() == 'scrolledwindow_textview': + editPane, outputPane = child1, child2 + else: + editPane, outputPane = child2, child1 + + if swap_panes: + pane.pack1(outputPane, resize=not vertical_layout, shrink=False) + pane.pack2(editPane, resize=True, shrink=False) + else: + pane.pack1(editPane, resize=True, shrink=False) + pane.pack2(outputPane, resize=not vertical_layout, shrink=False) + + # if panes are swapped, the autocomplete window should pop up BELOW cursor + # (otherwise it will extend up off the screen) + self.autocomplete.window.align = "top" if swap_panes else "bottom" + # If the fonts were changed, we might need to enlarge the window last_font, last_vertical = self.last_configured_layout if last_font != font or last_vertical != vertical_layout: diff --git a/dreampielib/gui/autocomplete_window.py b/dreampielib/gui/autocomplete_window.py index 0be49e8..34df1c3 100644 --- a/dreampielib/gui/autocomplete_window.py +++ b/dreampielib/gui/autocomplete_window.py @@ -240,7 +240,14 @@ def place_window(self): self.window.show_all() self.window_height = self.window.get_size()[1] self.window.hide() - self.window.move(x, y-self.window_height) + #self.window.move(x, y-self.window_height) + # If panes are swapped, the TOP of the autocomplete will align with cursor; if not, the BOTTOM will align + # This prevents the window from extending off the screen. + if self.align == "bottom": + offset = -self.window_height + else: + offset = sv.get_line_yrange(it)[1] + self.window.move(x, y+offset) def on_mark_set(self, sb, it, mark): if mark is sb.get_insert(): diff --git a/dreampielib/gui/call_tip_window.py b/dreampielib/gui/call_tip_window.py index 8748f44..9f60d7c 100644 --- a/dreampielib/gui/call_tip_window.py +++ b/dreampielib/gui/call_tip_window.py @@ -54,6 +54,7 @@ def __init__(self, sourceview, sv_changed): # Widgets self.textview = tv = gtk.TextView() + tv.set_wrap_mode(gtk.WRAP_WORD) self.hscrollbar = hs = gtk.HScrollbar() self.vscrollbar = vs = gtk.VScrollbar() self.resizegrip = rg = gtk.EventBox() diff --git a/dreampielib/gui/config.py b/dreampielib/gui/config.py index 23606f0..ebde1a5 100644 --- a/dreampielib/gui/config.py +++ b/dreampielib/gui/config.py @@ -49,6 +49,7 @@ recall-1-char-commands = False hide-defs = False leave-code = False +swap-panes = False [Dark theme] is-active = True diff --git a/dreampielib/gui/config_dialog.py b/dreampielib/gui/config_dialog.py index bf34cdc..f33b683 100644 --- a/dreampielib/gui/config_dialog.py +++ b/dreampielib/gui/config_dialog.py @@ -65,6 +65,8 @@ def __init__(self, config, gladefile, parent): self.horizontal_layout_rad.props.active = not config.get_bool('vertical-layout') self.leave_code_chk.props.active = config.get_bool('leave-code') + + self.swap_panes_chk.props.active = config.get_bool('swap-panes') self.hide_defs_chk.props.active = config.get_bool('hide-defs') @@ -156,6 +158,8 @@ def run(self): config.set_bool('leave-code', self.leave_code_chk.props.active) + config.set_bool('swap-panes', self.swap_panes_chk.props.active) + config.set_bool('hide-defs', self.hide_defs_chk.props.active) if self.matplotlib_ia_switch_rad.props.active: