def create_container(self): container = HSplit([ Box(body=VSplit([self.input_window, self.cancel_button], padding=1), padding=1, style="class:preview-input-field"), Window(height=1, char="-", style="class:preview-divider-line"), self.output_field, self.search_field, ]) frame = Shadow(body=Frame( title=lambda: "Preview: " + self.my_app.selected_object.name, body=container, style="class:dialog.body", width=D(preferred=180, min=30), modal=True)) return ConditionalContainer(content=frame, filter=ShowPreview(self.my_app) & ~is_done)
def __init__( # noqa: CCR001 self, title, handlers, intro=None, summary=False, next_text='Next', previous_text='Previous', cancel_text='Cancel', finish_text='Finish', ): self.title = title self.handlers = handlers self.answers = {} self.intro = intro self.summary = summary self.steps = [] self.current_step_idx = 0 self.title = title self.process_steps() self.current_step = self.steps[self.current_step_idx] self.label_next = next_text self.label_previous = previous_text self.label_cancel = cancel_text self.label_finish = finish_text self.error_messages = '' self.cancel_btn = Button( text=self.label_cancel, handler=self.cancel, ) self.previous_btn = Button( text=self.label_previous, handler=self.previous, ) self.next_btn = Button( text=self.label_next if len(self.steps) > 1 else self.label_finish, handler=self.next, ) self.buttons = [self.next_btn, self.cancel_btn] self.buttons_kb = KeyBindings() first_selected = has_focus(self.buttons[0]) last_selected = has_focus(self.buttons[-1]) self.buttons_kb.add('left', filter=~first_selected)(focus_previous) self.buttons_kb.add('right', filter=~last_selected)(focus_next) input_container = HSplit([ Box( body=DynamicContainer(self.get_current_step_container), padding=D(preferred=1, max=1), padding_bottom=0, ), ], ) left_container = Box( body=DynamicContainer(self.get_steps_labels), padding=D(preferred=1, max=1), padding_bottom=0, ) right_container = HSplit([ input_container, Box( body=DynamicContainer(self.get_status), padding=D(preferred=1, max=1), padding_bottom=1, ), ], ) top_container = VSplit( [left_container, right_container], padding_char='│', padding=1, padding_style='#000000', height=D(min=10, preferred=24), ) buttons_container = Box( body=DynamicContainer(self.get_buttons_container), height=D(min=1, max=3, preferred=3), ) kb = KeyBindings() kb.add(Keys.Tab)(focus_next) kb.add(Keys.BackTab)(focus_previous) frame = Shadow(body=Frame( title=self.get_title, body=HSplit( [ top_container, buttons_container, ], padding_char='─', padding=1, padding_style='#000000', ), style='class:dialog.body', key_bindings=kb, width=D(min=78, preferred=132), ), ) self.container = Box( body=frame, style='class:dialog', )
def __init__(self, body: AnyContainer, menu_items: List['MenuItem'], floats: Optional[List[Float]] = None, key_bindings: Optional[KeyBindingsBase] = None) -> None: self.body = body self.menu_items = menu_items self.selected_menu = [0] # Key bindings. kb = KeyBindings() @Condition def in_main_menu() -> bool: return len(self.selected_menu) == 1 @Condition def in_sub_menu() -> bool: return len(self.selected_menu) > 1 # Navigation through the main menu. @kb.add('left', filter=in_main_menu) def _(event: E) -> None: self.selected_menu[0] = max(0, self.selected_menu[0] - 1) @kb.add('right', filter=in_main_menu) def _(event: E) -> None: self.selected_menu[0] = min( len(self.menu_items) - 1, self.selected_menu[0] + 1) @kb.add('down', filter=in_main_menu) def _(event: E) -> None: self.selected_menu.append(0) @kb.add('c-c', filter=in_main_menu) @kb.add('c-g', filter=in_main_menu) def _(event: E) -> None: " Leave menu. " event.app.layout.focus_last() # Sub menu navigation. @kb.add('left', filter=in_sub_menu) @kb.add('c-g', filter=in_sub_menu) @kb.add('c-c', filter=in_sub_menu) def _(event: E) -> None: " Go back to parent menu. " if len(self.selected_menu) > 1: self.selected_menu.pop() @kb.add('right', filter=in_sub_menu) def _(event: E) -> None: " go into sub menu. " if self._get_menu(len(self.selected_menu) - 1).children: self.selected_menu.append(0) # If This item does not have a sub menu. Go up in the parent menu. elif len(self.selected_menu) == 2 and self.selected_menu[0] < len( self.menu_items) - 1: self.selected_menu = [ min(len(self.menu_items) - 1, self.selected_menu[0] + 1) ] if self.menu_items[self.selected_menu[0]].children: self.selected_menu.append(0) @kb.add('up', filter=in_sub_menu) def _(event: E) -> None: " Select previous (enabled) menu item or return to main menu. " # Look for previous enabled items in this sub menu. menu = self._get_menu(len(self.selected_menu) - 2) index = self.selected_menu[-1] previous_indexes = [ i for i, item in enumerate(menu.children) if i < index and not item.disabled ] if previous_indexes: self.selected_menu[-1] = previous_indexes[-1] elif len(self.selected_menu) == 2: # Return to main menu. self.selected_menu.pop() @kb.add('down', filter=in_sub_menu) def _(event: E) -> None: " Select next (enabled) menu item. " menu = self._get_menu(len(self.selected_menu) - 2) index = self.selected_menu[-1] next_indexes = [ i for i, item in enumerate(menu.children) if i > index and not item.disabled ] if next_indexes: self.selected_menu[-1] = next_indexes[0] @kb.add('enter') def _(event: E) -> None: " Click the selected menu item. " item = self._get_menu(len(self.selected_menu) - 1) if item.handler: event.app.layout.focus_last() item.handler() # Controls. self.control = FormattedTextControl(self._get_menu_fragments, key_bindings=kb, focusable=True, show_cursor=False) self.window = Window(height=1, content=self.control, style='class:menu-bar') submenu = self._submenu(0) submenu2 = self._submenu(1) submenu3 = self._submenu(2) @Condition def has_focus() -> bool: return get_app().layout.current_window == self.window self.container = FloatContainer( content=HSplit([ # The titlebar. self.window, # The 'body', like defined above. body, ]), floats=[ Float(xcursor=True, ycursor=True, content=ConditionalContainer( content=Shadow(body=submenu), filter=has_focus)), Float(attach_to_window=submenu, xcursor=True, ycursor=True, allow_cover_cursor=True, content=ConditionalContainer( content=Shadow(body=submenu2), filter=has_focus & Condition(lambda: len(self.selected_menu) >= 1))), Float(attach_to_window=submenu2, xcursor=True, ycursor=True, allow_cover_cursor=True, content=ConditionalContainer( content=Shadow(body=submenu3), filter=has_focus & Condition(lambda: len(self.selected_menu) >= 2))), # -- ] + (floats or []), key_bindings=key_bindings, )
def preview_element(my_app: "sqlApp"): help_text = """ Press Enter in the input box to page through the table. Alternatively, enter a filtering SQL statement and then press Enter to page through the results. """ formatter = TabularOutputFormatter() input_buffer = Buffer(name="previewbuffer", tempfile_suffix=".sql", multiline=False) input_control = BufferControl(buffer=input_buffer, include_default_input_processors=False, preview_search=False) input_window = Window(input_control, ) search_buffer = Buffer(name="previewsearchbuffer") search_field = SearchToolbar(search_buffer) output_field = TextArea( style="class:preview-output-field", text=help_text, height=D(preferred=50), search_field=search_field, wrap_lines=False, focusable=True, read_only=True, preview_search=True, input_processors=[ ConditionalProcessor( processor=HighlightIncrementalSearchProcessor(), filter=has_focus("previewsearchbuffer") | has_focus(search_field.control), ), HighlightSelectionProcessor(), ]) def refresh_results(window_height) -> bool: sql_conn = my_app.selected_object.conn if sql_conn.execution_status == executionStatus.FAIL: # Let's display the error message to the user output = sql_conn.execution_err else: crsr = sql_conn.cursor if crsr.description: cols = [col.name for col in crsr.description] else: cols = [] if len(cols): sql_conn.status = connStatus.FETCHING res = sql_conn.async_fetchmany(size=window_height - 4) output = formatter.format_output(res, cols, format_name="psql") output = "\n".join(output) else: sql_conn.status = connStatus.IDLE output = "No rows returned\n" # Add text to output buffer. output_field.buffer.set_document( Document(text=output, cursor_position=0), True) return True def accept(buff: Buffer) -> bool: obj = my_app.selected_object sql_conn = obj.conn catalog = None schema = None # TODO: Verify connected if obj.parent is not None: if type(obj.parent).__name__ == "myDBSchema": schema = obj.parent.name elif type(obj.parent).__name__ == "myDBCatalog": catalog = obj.parent.name if obj.parent.parent is not None: if type(obj.parent.parent).__name__ == "myDBCatalog": catalog = obj.parent.parent.name if catalog: catalog = (sql_conn.quotechar + "%s" + sql_conn.quotechar) % catalog if schema: schema = (sql_conn.quotechar + "%s" + sql_conn.quotechar) % schema name = (sql_conn.quotechar + "%s" + sql_conn.quotechar) % obj.name identifier = ".".join(list(filter(None, [catalog, schema, obj.name]))) query = sql_conn.preview_query(table=identifier, filter_query=buff.text, limit=my_app.preview_limit_rows) func = partial( refresh_results, window_height=output_field.window.render_info.window_height) # If status is IDLE, this is the first time we are executing. if sql_conn.query != query or sql_conn.status == connStatus.IDLE: # Exit the app to execute the query my_app.application.exit(result=["preview", query]) my_app.application.pre_run_callables.append(func) else: # No need to exit let's just go and fetch func() return True # Keep filter text input_buffer.accept_handler = accept def cancel_handler() -> None: sql_conn = my_app.selected_object.conn sql_conn.close_cursor() sql_conn.status = connStatus.IDLE input_buffer.text = "" output_field.buffer.set_document( Document(text=help_text, cursor_position=0), True) my_app.show_preview = False my_app.show_sidebar = True my_app.application.layout.focus(input_buffer) my_app.application.layout.focus("sidebarbuffer") return None cancel_button = Button(text="Done", handler=cancel_handler) container = HSplit([ Box(body=VSplit([input_window, cancel_button], padding=1), padding=1, style="class:preview-input-field"), Window(height=1, char="-", style="class:preview-divider-line"), output_field, search_field, ]) frame = Shadow(body=Frame(title="Table Preview", body=container, style="class:dialog.body", width=D(preferred=180, min=30), modal=True)) return ConditionalContainer(content=frame, filter=ShowPreview(my_app) & ~is_done)
wrap_lines=False, # completer=completion, complete_while_typing=True) placeholder_text = ("Nothing here yet:\n" " - Type \"help\" to see available commands.\n" " - Press \"?\" for the list of keybindings.") entry_placeholder = Label( FormattedText([("class:placeholder", placeholder_text)])) task_list = HSplit([entry_placeholder]) agenda_pane = ScrollablePane(task_list) show_kb_help = False bindings_help = ConditionalContainer(Box( Shadow(Frame(Label(""), "Key bindings:"))), filter=Condition(lambda: show_kb_help)) root_container = FloatContainer( content=HSplit([agenda_pane, HorizontalLine(), history_field, input_field]), floats=[ Float( xcursor=True, ycursor=True, content=CompletionsMenu(max_height=16, scroll_offset=1), ), Float(bindings_help), ], )