def _create_include_line(self, panel): include_line = self._horizontal_sizer() include_line.Add(Label(panel, label='Include', size=(80, -1))) self._tags_to_include_text = wx.TextCtrl(panel, value='', size=(400, -1), style=wx.TE_PROCESS_ENTER) self._tags_to_include_text.Bind(wx.EVT_TEXT_ENTER, self.OnSearchTags) include_line.Add(self._tags_to_include_text) return include_line
def _create_buttons(self): sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add( Label(self, label='Add Import', size=wx.Size(120, 20), style=wx.ALIGN_CENTER)) for label in self._buttons: sizer.Add(ButtonWithHandler(self, label, width=120), 0, wx.ALL, 1) return sizer
def _create_editor(self, value, label, settings): sizer = wx.BoxSizer(wx.HORIZONTAL) if self._label: sizer.Add(Label(self, label=self._label, size=(80, -1)), 0, self._sizer_flags_for_label, 5) self._editor = self._get_text_ctrl() self._editor.AppendText(value) sizer.Add(self._editor, 1, self._sizer_flags_for_editor, 3) self._sizer.Add(sizer, 1, wx.EXPAND) wx.EVT_KEY_DOWN(self._editor, self.on_key_down)
def _create_source_label(self, source): sizer = wx.BoxSizer(wx.HORIZONTAL) sizer.Add((5, 0)) sizer.Add(Label(self, label='Source', size=(context.SETTING_LABEL_WIDTH, context.SETTING_ROW_HEIGTH))) self._source = wx.TextCtrl(self, style=wx.TE_READONLY | wx.NO_BORDER) self._source.SetBackgroundColour(self.BackgroundColour) self._source.SetValue(source) self._source.SetMaxSize(wx.Size(-1, context.SETTING_ROW_HEIGTH)) sizer.Add(self._source, 1, wx.EXPAND) return sizer
def _create_editor(self, value, label, settings): sizer = wx.BoxSizer(wx.HORIZONTAL) if self._label: sizer.Add(Label(self, label=self._label, size=(80, -1)), 0, self._sizer_flags_for_label, 5) self._editor = self._get_text_ctrl() # self._editor.SetDefaultStyle(wx.TextAttr(wx.TEXT_ATTR_CHARACTER)) self._editor.AppendText(value) sizer.Add(self._editor, 1, self._sizer_flags_for_editor, 3) self._sizer.Add(sizer, 1, wx.EXPAND) self._editor.Bind(wx.EVT_KEY_DOWN, self.on_key_down)
def _create_column_selector(self, cols): sizer = wx.BoxSizer(wx.VERTICAL) col_label = Label(self, label="Columns", size=(80, -1)) sizer.Add(col_label, 0, wx.ALL, 5) combo = wx.ComboBox(self, value=str(cols), size=(60, 25), choices=[str(i) for i in range(1, 11)]) combo.SetToolTip(wx.ToolTip("Number of columns that are shown in this " "editor. Selected value is stored and used" " globally.")) self.Bind(wx.EVT_COMBOBOX, self.OnColumns, source=combo) sizer.Add(combo) return sizer
def comma_separated_value_editor(parent, settings, name, label, help=''): initial_value = ', '.join(settings.get(name, "")) editor = TextField(parent, initial_value) MySetToolTip(editor, help) def set_value(): new_value = [token.strip() for token in editor.GetValue().split(',') if token.strip()] settings.set(name, new_value) editor.Bind(wx.EVT_KILL_FOCUS, lambda evt: set_value()) return Label(parent, label=label), editor
def ArgumentsPanel(self, parent): panel = wx.Panel(parent, wx.ID_ANY) label = Label(panel, label="Arguments: ") self._arguments = wx.TextCtrl( panel, wx.ID_ANY, size=(-1, -1), value=self.arguments) self._arguments.SetToolTipString( "Arguments for the test run. Arguments are space separated list.") self._arguments.Bind(wx.EVT_TEXT, self.OnArgumentsChanged) sizer = wx.BoxSizer(wx.HORIZONTAL) sizer.Add(label, 0, wx.ALL | wx.EXPAND) sizer.Add(self._arguments, 1, wx.ALL | wx.EXPAND) panel.SetSizerAndFit(sizer) self._validate_arguments(self.arguments or u'') return panel
def _create_font_editor(self): f = IntegerChoiceEditor(self._settings, 'font size', 'Font Size', [str(i) for i in range(8, 16)]) sizer = wx.FlexGridSizer(rows=2, cols=2, hgap=30) sizer.AddMany([f.label(self), f.chooser(self)]) if 'fixed font' in self._settings: sizer.Add(Label(self, label='Use fixed width font')) editor = wx.CheckBox(self) editor.SetValue(self._settings['fixed font']) editor.Bind( wx.EVT_CHECKBOX, lambda evt: self._settings.set( 'fixed font', editor.GetValue())) sizer.Add(editor) return sizer
def _create_controls(self): sizer = wx.BoxSizer(wx.HORIZONTAL) sizer.Add((5, 0)) sizer.Add(Label( self, label=self._controller.label, size=(context.SETTING_LABEL_WIDTH, context.SETTING_ROW_HEIGTH))) self._value_display = self._create_value_display() self.update_value() self._tooltip = self._get_tooltip() sizer.Add(self._value_display, 1, wx.EXPAND) self._add_edit(sizer) sizer.Add(ButtonWithHandler(self, 'Clear')) sizer.Layout() self.SetSizer(sizer)
def _build_local_toolbar(self): toolbar = wx.ToolBar(self.panel, wx.ID_ANY, style=wx.TB_HORIZONTAL | wx.TB_HORZ_TEXT) profileLabel = Label(toolbar, label="Execution Profile: ") choices = self._test_runner.get_profile_names() self.choice = wx.Choice(toolbar, wx.ID_ANY, choices=choices) self.choice.SetToolTip(wx.ToolTip("Choose which method to use for " "running the tests")) toolbar.AddControl(profileLabel) toolbar.AddControl(self.choice) toolbar.AddSeparator() reportImage = getReportIconBitmap() logImage = getLogIconBitmap() # DEBUG wxPhoenix toolbar.AddLabelTool( self.MyAddTool(toolbar, ID_SHOW_REPORT, " Report", reportImage, shortHelp=localize_shortcuts("View Robot Report in " "Browser (CtrlCmd-R)")) self.MyAddTool(toolbar, ID_SHOW_LOG, " Log", logImage, shortHelp=localize_shortcuts("View Robot Log in" " Browser (CtrlCmd-L)")) toolbar.AddSeparator() # the toolbar API doesn't give us a way to specify padding which # is why the label has a couple spaces after the colon. gross, # but effective. self.savecb = wx.CheckBox(toolbar, ID_AUTOSAVE, " Autosave ") self.savecb.SetToolTip(wx.ToolTip("Automatically save all changes " "before running")) self.savecb.SetValue(self.auto_save) toolbar.AddControl(self.savecb) self.pause_after_failure_cb = wx.CheckBox(toolbar, ID_PAUSE_ON_FAILURE, " Pause on failure ") self.pause_after_failure_cb.SetToolTip(wx.ToolTip("Automatically pause" " after failing " "keyword")) self.pause_after_failure_cb.SetValue(False) toolbar.AddControl(self.pause_after_failure_cb) self.show_log_messages_checkbox = wx.CheckBox(toolbar, ID_SHOW_MESSAGE_LOG, " Show message log ") self.show_log_messages_checkbox.SetToolTip(wx.ToolTip("Show or hide " "message log")) self.show_log_messages_checkbox.SetValue(self.show_message_log) toolbar.AddControl(self.show_log_messages_checkbox) toolbar.EnableTool(ID_SHOW_LOG, False) toolbar.EnableTool(ID_SHOW_REPORT, False) toolbar.Realize() self._bind_toolbar_events(toolbar) return toolbar
def create_syntax_colorization_help(self): if self._syntax_colorization_help_exists: return label = Label( self, label="Syntax colorization disabled due to missing requirements.") link = HyperlinkCtrl(self, -1, label="Get help", url="") link.Bind(EVT_HYPERLINK, self.show_help_dialog) flags = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT syntax_colorization_help_sizer = wx.BoxSizer(wx.VERTICAL) syntax_colorization_help_sizer.AddMany([(label, 0, flags), (link, 0, flags)]) self.editor_toolbar.add_expanding(syntax_colorization_help_sizer) self.Layout() self._syntax_colorization_help_exists = True
def ArgumentsPanel(self, parent): panel = wx.Panel(parent, wx.ID_ANY) label = Label(panel, label="Arguments: ") try: self._arguments = wx.TextCtrl( panel, wx.ID_ANY, size=(-1, -1), value=self.arguments) except UnicodeDecodeError: self._arguments = wx.TextCtrl( panel, wx.ID_ANY, size=(-1, -1), value="removed due unicode_error (delete this)") self._arguments.SetToolTip("Arguments for the test run. " "Arguments are space separated list.") self._arguments.Bind(wx.EVT_TEXT, self.OnArgumentsChanged) sizer = wx.BoxSizer(wx.HORIZONTAL) sizer.Add(label, 0, wx.ALL | wx.EXPAND) sizer.Add(self._arguments, 1, wx.ALL | wx.EXPAND) panel.SetSizerAndFit(sizer) self._validate_arguments(self.arguments or u'') return panel
def _get_log_options_panel(self, parent): collapsible_pane = wx.CollapsiblePane( parent, wx.ID_ANY, 'Log options', style=wx.CP_DEFAULT_STYLE | wx.CP_NO_TLW_RESIZE) collapsible_pane.Bind(wx.EVT_COLLAPSIBLEPANE_CHANGED, self.OnCollapsiblePaneChanged, collapsible_pane) pane = collapsible_pane.GetPane() pane.SetBackgroundColour(self._mysettings.color_background) pane.SetForegroundColour(self._mysettings.color_foreground) label = Label(pane, label="Output directory: ") self._output_directory_text_ctrl = \ self._create_text_ctrl(pane, self.output_directory, "removed due unicode_error (delete this)", self.OnOutputDirectoryChanged) self._output_directory_text_ctrl.SetBackgroundColour(self._mysettings.color_secondary_background) self._output_directory_text_ctrl.SetForegroundColour(self._mysettings.color_secondary_foreground) button = ButtonWithHandler(pane, "...", self._handle_select_directory) button.SetBackgroundColour(self._mysettings.color_secondary_background) button.SetForegroundColour(self._mysettings.color_secondary_foreground) horizontal_sizer = wx.BoxSizer(wx.HORIZONTAL) horizontal_sizer.Add(label, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT, 10) horizontal_sizer.Add(self._output_directory_text_ctrl, 1, wx.EXPAND) horizontal_sizer.Add(button, 0, wx.LEFT | wx.RIGHT, 10) suite_name_outputs_cb = self._create_checkbox( pane, self.are_log_names_with_suite_name, "Add suite name to log names", self.OnSuiteNameOutputsCheckBox) timestamp_outputs_cb = self._create_checkbox( pane, self.are_log_names_with_timestamp, "Add timestamp to log names", self.OnTimestampOutputsCheckbox) save_logs_cb = self._create_checkbox( pane, self.are_saving_logs, "Save Console and Message logs", self.OnSaveLogsCheckbox) vertical_sizer = wx.BoxSizer(wx.VERTICAL) vertical_sizer.Add(horizontal_sizer, 0, wx.EXPAND) vertical_sizer.Add(suite_name_outputs_cb, 0, wx.LEFT | wx.TOP, 10) vertical_sizer.Add(timestamp_outputs_cb, 0, wx.LEFT | wx.TOP, 10) vertical_sizer.Add(save_logs_cb, 0, wx.LEFT | wx.TOP | wx.BOTTOM, 10) pane.SetSizer(vertical_sizer) return collapsible_pane
def _label_for(self, name): label = ('%s: ' % name).capitalize() return Label(self, label=label)
def boolean_editor(parent, settings, name, label, help=''): editor = _create_checkbox_editor(parent, settings, name, help) label = Label(parent, label=label) return label, editor
class SourceEditor(wx.Panel): def __init__(self, parent, title, data_validator): wx.Panel.__init__(self, parent) self._syntax_colorization_help_exists = False self._data_validator = data_validator self._data_validator.set_editor(self) self._parent = parent self._create_ui(title) self._data = None self._dirty = False self._positions = {} def is_focused(self): foc = wx.Window.FindFocus() return any(elem == foc for elem in [self] + list(self.GetChildren())) def _create_ui(self, title): self.SetSizer(VerticalSizer()) self._create_editor_toolbar() self._create_editor_text_control() self._parent.add_tab(self, title, allow_closing=False) def _create_editor_toolbar(self): # needs extra container, since we might add helper text about syntax colorization self.editor_toolbar = HorizontalSizer() default_components = HorizontalSizer() default_components.add_with_padding( ButtonWithHandler(self, 'Apply Changes', handler=lambda e: self.save())) self._create_search(default_components) self.editor_toolbar.add_expanding(default_components) self.Sizer.add_expanding(self.editor_toolbar, propotion=0) def _create_search(self, container_sizer): container_sizer.AddSpacer(20) self._search_field = TextField(self, '', process_enters=True) self._search_field.Bind(wx.EVT_TEXT_ENTER, self.OnFind) container_sizer.add_with_padding(self._search_field) container_sizer.add_with_padding( ButtonWithHandler(self, 'Search', handler=self.OnFind)) self._search_field_notification = Label(self, label='') container_sizer.add_with_padding(self._search_field_notification) def create_syntax_colorization_help(self): if self._syntax_colorization_help_exists: return label = Label( self, label="Syntax colorization disabled due to missing requirements.") link = wx.HyperlinkCtrl(self, -1, label="Get help", url="") link.Bind(wx.EVT_HYPERLINK, self.show_help_dialog) flags = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT syntax_colorization_help_sizer = wx.BoxSizer(wx.VERTICAL) syntax_colorization_help_sizer.AddMany([(label, 0, flags), (link, 0, flags)]) self.editor_toolbar.add_expanding(syntax_colorization_help_sizer) self.Layout() self._syntax_colorization_help_exists = True def show_help_dialog(self, event): content = """<h1>Syntax colorization</h1> <p> Syntax colorization for Text Edit uses <a href='http://pygments.org/'>Pygments</a> syntax highlighter. </p> <p> Install Pygments from command line with: <pre> pip install pygments </pre> Or: <pre> easy_install pygments </pre> Then, restart RIDE. </p> <p> If you do not have pip or easy_install, <a href='http://pythonhosted.org/an_example_pypi_project/setuptools.html#installing-setuptools-and-easy-install'>follow these instructions</a>. </p> <p> For more information about installing Pygments, <a href='http://pygments.org/download/'>see the site</a>. </p> """ HtmlDialog("Getting syntax colorization", content).Show() def store_position(self): if self._editor: self._positions[ self.datafile_controller] = self._editor.GetCurrentPos() def set_editor_caret_position(self): position = self._positions.get(self.datafile_controller, None) if position: self._editor.SetFocus() self._editor.SetCurrentPos(position) self._editor.SetSelection(position, position) @property def dirty(self): return self._dirty @property def datafile_controller(self): return self._data._data if self._data else None def OnFind(self, event): if self._editor: self._find() def OnFindBackwards(self, event): if self._editor: self._find(forward=False) def _find(self, forward=True): txt = self._search_field.GetValue() position = self._find_text_position(forward, txt) self._show_search_results(position, txt) # FIXME: This must be cleaned up def _find_text_position(self, forward, txt): file_end = len(self._editor.utf8_text) search_end = file_end if forward else 0 anchor = self._editor.GetAnchor() anchor += 1 if forward else 0 position = self._editor.FindText(anchor, search_end, txt, 0) if position == -1: start, end = (0, file_end) if forward else (file_end - 1, 0) position = self._editor.FindText(start, end, txt, 0) return position def _show_search_results(self, position, txt): if position != -1: self._editor.SetSelection(position, position + len(txt)) self._search_field_notification.SetLabel('') else: self._search_field_notification.SetLabel('No matches found.') def open(self, data): self.reset() self._data = data if not self._editor: self._stored_text = self._data.content else: self._editor.set_text(self._data.content) self.set_editor_caret_position() def selected(self, data): if not self._editor: self._create_editor_text_control(self._stored_text) if self._data == data: return self.open(data) def reset(self): self._dirty = False def save(self, *args): if self.dirty: if not self._data_validator.validate_and_update( self._data, self._editor.utf8_text): return False return True def delete(self): if self._editor.GetSelectionStart() == self._editor.GetSelectionEnd(): self._editor.CharRight() self._editor.DeleteBack() def cut(self): self._editor.Cut() def copy(self): self._editor.Copy() def paste(self): focus = wx.Window.FindFocus() if focus == self._editor: self._editor.Paste() elif focus == self._search_field: self._search_field.Paste() def select_all(self): self._editor.SelectAll() def undo(self): self._editor.Undo() def redo(self): self._editor.Redo() def remove_and_store_state(self): if self._editor: self.store_position() self._stored_text = self._editor.GetText() self._editor.Destroy() self._editor = None def _create_editor_text_control(self, text=None): self._editor = RobotDataEditor(self) self.Sizer.add_expanding(self._editor) self.Sizer.Layout() if text is not None: self._editor.set_text(text) self._editor.Bind(wx.EVT_KEY_UP, self.OnEditorKey) self._editor.Bind(wx.EVT_KILL_FOCUS, self.LeaveFocus) self._editor.Bind(wx.EVT_SET_FOCUS, self.GetFocus) def LeaveFocus(self, event): self._editor.SetCaretPeriod(0) self.save() def GetFocus(self, event): self._editor.SetCaretPeriod(500) event.Skip() def _revert(self): self.reset() self._editor.set_text(self._data.content) def OnEditorKey(self, event): if not self.dirty and self._editor.GetModify(): self._mark_file_dirty() event.Skip() def _mark_file_dirty(self): if self._data: self._dirty = True self._data.mark_data_dirty()
class ReviewDialog(wx.Frame): def __init__(self, controller, frame): wx.Frame.__init__(self, frame, title="Search unused keywords", style=wx.SYSTEM_MENU | wx.CAPTION | wx.CLOSE_BOX | wx.CLIP_CHILDREN | wx.FRAME_FLOAT_ON_PARENT) # set Left to Right direction (while we don't have localization) self.SetLayoutDirection(wx.Layout_LeftToRight) self.index = 0 self.frame = frame self._search_model = ResultModel() self._runner = ReviewRunner(controller, self._search_model) self._build_ui() self._make_bindings() self._set_default_values() self.CenterOnParent() def _build_ui(self): self.SetSize((800, 600)) self.SetBackgroundColour( wx.SystemSettings.GetColour(wx.SYS_COLOUR_3DFACE)) self.SetSizer(wx.BoxSizer(wx.VERTICAL)) self._build_header() self._build_filter() self._build_notebook() self._build_unused_keywords() self._build_controls() def _build_header(self): label_introduction = wx.StaticText( self, label= 'This dialog helps you finding unused keywords within your opened proj' 'ect.\nIf you want, you can restrict the search to a set of files with' ' the filter.') label_filter_is = wx.StaticText(self, label='Filter is') self.label_filter_status = wx.StaticText(self, label='inactive') header_sizer = wx.BoxSizer(wx.HORIZONTAL) header_sizer.Add(label_introduction, 0, wx.ALL | wx.EXPAND, 3) header_sizer.AddStretchSpacer(1) header_sizer.Add(label_filter_is, 0, wx.LEFT | wx.TOP | wx.BOTTOM | wx.ALIGN_BOTTOM, 3) header_sizer.Add(self.label_filter_status, 0, wx.ALL | wx.ALIGN_BOTTOM | wx.ALIGN_RIGHT, 3) self.Sizer.Add(header_sizer, 0, wx.ALL | wx.EXPAND, 3) def _build_filter(self): self._filter_pane = MyCollapsiblePane(self, label="Filter", style=wx.CP_DEFAULT_STYLE | wx.CP_NO_TLW_RESIZE) self._filter_input = wx.TextCtrl(self._filter_pane.GetPane(), size=(-1, 20)) self._filter_regex_switch = wx.CheckBox(self._filter_pane.GetPane(), wx.ID_ANY, label="Use RegEx") self._filter_info = wx.StaticText( self._filter_pane.GetPane(), label= 'Here you can define one or more strings separated by comma (e.g. common,abc,123).\nThe filter matches if at least one string is part of the filename.\nIf you don\'t enter any strings, all opened files are included' ) filter_source_box = wx.StaticBox(self._filter_pane.GetPane(), label="Search") self._filter_source_testcases = wx.CheckBox( self._filter_pane.GetPane(), wx.ID_ANY, label="Test case files") self._filter_source_resources = wx.CheckBox( self._filter_pane.GetPane(), wx.ID_ANY, label="Resource files") self._filter_mode = wx.RadioBox(self._filter_pane.GetPane(), label="Mode", choices=["exclude", "include"]) self._filter_test_button = wx.Button(self._filter_pane.GetPane(), wx.ID_INFO, label="Test the filter") filter_box_sizer = wx.BoxSizer(wx.HORIZONTAL) filter_box_sizer.SetSizeHints(self._filter_pane.GetPane()) filter_source_sizer = wx.StaticBoxSizer(filter_source_box, wx.VERTICAL) checkbox_border = 0 if IS_MAC else 3 filter_source_sizer.Add(self._filter_source_testcases, 0, wx.ALL, checkbox_border) filter_source_sizer.Add(self._filter_source_resources, 0, wx.ALL, checkbox_border) filter_options = wx.BoxSizer(wx.VERTICAL) filter_options.Add(filter_source_sizer, 0, wx.BOTTOM | wx.RIGHT | wx.LEFT | wx.EXPAND, 3) filter_options.Add(self._filter_mode, 0, wx.ALL | wx.EXPAND, 3) filter_input_sizer = wx.BoxSizer(wx.VERTICAL) filter_input_sizer.SetMinSize((600, -1)) filter_input_sizer.Add(self._filter_info, 0, wx.ALL | wx.ALIGN_LEFT, 3) filter_input_sizer.Add(self._filter_input, 0, wx.ALL | wx.EXPAND, 3) filter_input_sizer.Add(self._filter_regex_switch, 0, wx.ALL | wx.ALIGN_RIGHT, 3) filter_input_sizer.Add(self._filter_test_button, 0, wx.ALL | wx.ALIGN_CENTER, 3) filter_box_sizer.Add(filter_options, 0, wx.ALL | wx.EXPAND, 3) filter_box_sizer.Add(filter_input_sizer, 0, wx.ALL | wx.EXPAND, 3) self._filter_pane.GetPane().SetSizer(filter_box_sizer) self.Sizer.Add(self._filter_pane, 0, wx.ALL | wx.EXPAND, 3) def _build_unused_keywords(self): panel_unused_kw = wx.Panel(self._notebook) sizer_unused_kw = wx.BoxSizer(wx.VERTICAL) panel_unused_kw.SetSizer(sizer_unused_kw) self._unused_kw_list = ResultListCtrl(panel_unused_kw, style=wx.LC_REPORT) self._unused_kw_list.InsertColumn(0, "Keyword", width=400) self._unused_kw_list.InsertColumn(1, "File", width=250) self._unused_kw_list.SetMinSize((650, 250)) self._unused_kw_list.set_dialog(self) self._delete_button = wx.Button(panel_unused_kw, wx.ID_ANY, 'Delete marked keywords') sizer_unused_kw.Add(self._unused_kw_list, 1, wx.ALL | wx.EXPAND, 3) unused_kw_controls = wx.BoxSizer(wx.HORIZONTAL) unused_kw_controls.AddStretchSpacer(1) unused_kw_controls.Add(self._delete_button, 0, wx.ALL | wx.ALIGN_RIGHT, 3) sizer_unused_kw.Add(unused_kw_controls, 0, wx.ALL | wx.EXPAND, 3) self._notebook.AddPage(panel_unused_kw, "Unused Keywords") def _build_controls(self): self._search_button = ButtonWithHandler(self, 'Search') self._abort_button = ButtonWithHandler(self, 'Abort') self._status_label = Label(self, label='') controls = wx.BoxSizer(wx.HORIZONTAL) controls.Add(self._search_button, 0, wx.ALL, 3) controls.Add(self._abort_button, 0, wx.ALL, 3) controls.Add(self._status_label, 1, wx.ALL | wx.EXPAND, 3) self.Sizer.Add(controls, 0, wx.ALL | wx.EXPAND, 3) def _build_notebook(self): self._notebook = wx.Notebook(self, wx.ID_ANY, style=wx.NB_TOP) self.Sizer.Add(self._notebook, 1, wx.ALL | wx.EXPAND, 3) def _make_bindings(self): self.Bind(wx.EVT_CLOSE, self._close_dialog) self.Bind(wx.EVT_TEXT, self._update_filter, self._filter_input) self.Bind(wx.EVT_RADIOBOX, self._update_filter_mode, self._filter_mode) self.Bind(wx.EVT_CHECKBOX, self._update_filter_source_testcases, self._filter_source_testcases) self.Bind(wx.EVT_CHECKBOX, self._update_filter_source_resources, self._filter_source_resources) self.Bind(wx.EVT_BUTTON, self.OnDeletemarkedkeywords, self._delete_button) self.Bind(wx.EVT_BUTTON, self.OnShowfilestobesearched, self._filter_test_button) self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnResultSelected, self._unused_kw_list) self.Bind(wx.EVT_CHECKBOX, self._update_filter_regex, self._filter_regex_switch) self.Bind(wx.EVT_COLLAPSIBLEPANE_CHANGED, self._toggle_filter_active, self._filter_pane) def _set_default_values(self): check_testcases = True self._filter_source_testcases.SetValue(check_testcases) self._runner.set_filter_source_testcases(check_testcases) check_resources = True self._filter_source_resources.SetValue(check_resources) self._runner.set_filter_source_resources(check_resources) filter_mode = 0 self._filter_mode.SetSelection(filter_mode) self._runner.set_filter_mode(filter_mode == 0) use_regex = False self._filter_regex_switch.SetValue(use_regex) self._runner.set_filter_use_regex(use_regex) filter_string = '' self._filter_input.ChangeValue(filter_string) self._runner.parse_filter_string(filter_string) self._disable_filter() self._abort_button.Disable() self._delete_button.Disable() def _update_filter(self, event): self._runner.parse_filter_string(event.GetString()) def _update_filter_mode(self, event): self._runner.set_filter_mode(event.GetInt() == 0) def _update_filter_source_testcases(self, event): self._runner.set_filter_source_testcases( self._filter_source_testcases.IsChecked()) def _update_filter_source_resources(self, event): self._runner.set_filter_source_resources( self._filter_source_resources.IsChecked()) def _update_filter_regex(self, event): self._runner.set_filter_use_regex( self._filter_regex_switch.IsChecked()) def _toggle_filter_active(self, event): if event.GetCollapsed(): self._disable_filter() else: self._enable_filter() self._filter_pane.on_change(event) def _disable_filter(self): self._runner.set_filter_active(False) self.label_filter_status.SetLabel('inactive') self.label_filter_status.SetForegroundColour(wx.RED) def _enable_filter(self): self._runner.set_filter_active(True) self.label_filter_status.SetLabel('active') self.label_filter_status.SetForegroundColour((0, 200, 0)) def OnSearch(self, event): self.begin_searching() self._runner._run_review() def OnAbort(self, event): self.end_searching() def OnDeletemarkedkeywords(self, event): item = self._unused_kw_list.get_next_checked_item() while item: index = item[0] kw = item[1] listitem = item[2] item_id = listitem.GetData() self._unused_kw_list.DeleteItem(index) self._unused_kw_list.RemoveClientData(item_id) kw.delete() self._update_notebook_text("Unused Keywords (%d)" % self._unused_kw_list.GetItemCount()) self.update_status("") item = self._unused_kw_list.get_next_checked_item() self.item_in_kw_list_checked() def OnShowfilestobesearched(self, event): df_list = self._runner._get_datafile_list() if not df_list: string_list = "(None)" else: string_list = "\n".join(df.name for df in df_list) message = "Keywords of the following files will be included in the search:\n\n" + string_list wx.MessageDialog(self, message=message, caption="Included files", style=wx.OK | wx.ICON_INFORMATION).ShowModal() def OnResultSelected(self, event): self.frame.tree.select_node_by_data( self._unused_kw_list.GetClientData(event.GetData())) def item_in_kw_list_checked(self): if self._unused_kw_list.get_number_of_checked_items() > 0: self._delete_button.Enable() else: self._delete_button.Disable() def show_dialog(self): if not self.IsShown(): self._clear_search_results() self.Show() self.Raise() def _close_dialog(self, event): if self._search_model.searching: self.end_searching() if event.CanVeto(): self.Hide() else: self.Destroy() def begin_searching(self): self._abort_button.Enable() self._search_button.Disable() self._filter_pane.Disable() self._unused_kw_list.Disable() self._clear_search_results() self._dots = DottedSearch(self, self._update_unused_keywords) self._dots.start() def _clear_search_results(self): self._unused_kw_list.ClearAll() self._update_notebook_text('Unused Keywords') self._delete_button.Disable() self._status_label.SetLabel('') self._search_model.clear_search() def add_result_unused_keyword(self, index, keyword): keyword_info = keyword.info if wx.VERSION >= (3, 0, 3, ''): # DEBUG wxPhoenix self._unused_kw_list.InsertItem(index, keyword_info.name) else: self._unused_kw_list.InsertStringItem(index, keyword_info.name) filename = os.path.basename(keyword_info.item.source) if wx.VERSION >= (3, 0, 3, ''): # DEBUG wxPhoenix self._unused_kw_list.SetItem(index, 1, filename) else: self._unused_kw_list.SetStringItem(index, 1, filename) self._unused_kw_list.SetItemData(index, index) self._unused_kw_list.SetClientData(index, keyword) def _update_unused_keywords(self, dots): count_before = self._unused_kw_list.GetItemCount() for index, kw in list(enumerate( self._search_model.keywords))[count_before:]: self.add_result_unused_keyword(index, kw) self.update_status("Searching.%s \t- %s" % (dots, self._search_model.status)) if not self._search_model.searching: self.end_searching() def _update_notebook_text(self, new_text): self._notebook.SetPageText(0, new_text) def update_status(self, message, increase=1): self._status_label.SetLabel(message) def end_searching(self): self._dots.stop() self._search_model.end_search() self._update_notebook_text('Unused Keywords (%d)' % (self._unused_kw_list.GetItemCount())) self.update_status("Search finished - Found %d Unused Keywords" % (self._unused_kw_list.GetItemCount())) self._unused_kw_list.Enable() self._abort_button.Disable() self._filter_pane.Enable() self._search_button.Enable() def send_radiobox_event(self, mycontrol): cmd = wx.CommandEvent(wx.EVT_RADIOBOX.evtType[0]) cmd.SetEventObject(mycontrol) cmd.SetId(mycontrol.GetId()) mycontrol.GetEventHandler().ProcessEvent(cmd)
def _add_label(self, sizer, text): label = Label(self, label=text, size=(110, -1)) sizer.Add(label, flag=wx.CENTER | wx.ALL, border=3)
class SourceEditor(wx.Panel): def __init__(self, parent, title, data_validator): wx.Panel.__init__(self, parent) self._syntax_colorization_help_exists = False self._data_validator = data_validator self._data_validator.set_editor(self) self._parent = parent self._title = title self._tab_size = self._parent._app.settings.get( 'txt number of spaces', 4) self._create_ui(title) self._data = None self._dirty = False self._position = None self._showing_list = False self._tab_open = None # self._autocomplete = None PUBLISHER.subscribe(self.OnSettingsChanged, RideSettingsChanged) PUBLISHER.subscribe(self.OnTabChange, RideNotebookTabChanging) def is_focused(self): # foc = wx.Window.FindFocus() # return any(elem == foc for elem in [self]+list(self.GetChildren())) return self._tab_open == self._title def OnTabChange(self, message): self._tab_open = message.newtab def _create_ui(self, title): self.SetSizer(VerticalSizer()) self._create_editor_toolbar() self._create_editor_text_control() self._parent.add_tab(self, title, allow_closing=False) def _create_editor_toolbar(self): # needs extra container, since we might add helper # text about syntax colorization self.editor_toolbar = HorizontalSizer() default_components = HorizontalSizer() default_components.add_with_padding( ButtonWithHandler(self, 'Apply Changes', handler=lambda e: self.save())) self._create_search(default_components) self.editor_toolbar.add_expanding(default_components) self.Sizer.add_expanding(self.editor_toolbar, propotion=0) def _create_search(self, container_sizer): container_sizer.AddSpacer(20) self._search_field = TextField(self, '', process_enters=True) self._search_field.Bind(wx.EVT_TEXT_ENTER, self.OnFind) container_sizer.add_with_padding(self._search_field) container_sizer.add_with_padding( ButtonWithHandler(self, 'Search', handler=self.OnFind)) self._search_field_notification = Label(self, label='') container_sizer.add_with_padding(self._search_field_notification) def create_syntax_colorization_help(self): if self._syntax_colorization_help_exists: return label = Label( self, label="Syntax colorization disabled due to missing requirements.") link = HyperlinkCtrl(self, -1, label="Get help", url="") link.Bind(EVT_HYPERLINK, self.show_help_dialog) flags = wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT syntax_colorization_help_sizer = wx.BoxSizer(wx.VERTICAL) syntax_colorization_help_sizer.AddMany([(label, 0, flags), (link, 0, flags)]) self.editor_toolbar.add_expanding(syntax_colorization_help_sizer) self.Layout() self._syntax_colorization_help_exists = True def show_help_dialog(self, event): content = """<h1>Syntax colorization</h1> <p> Syntax colorization for Text Edit uses <a href='http://pygments.org/'>Pygments</a> syntax highlighter. </p> <p> Install Pygments from command line with: <pre> pip install pygments </pre> Or: <pre> easy_install pygments </pre> Then, restart RIDE. </p> <p> If you do not have pip or easy_install, <a href='http://pythonhosted.org/an_example_pypi_project/setuptools.html#installing-setuptools-and-easy-install'>follow these instructions</a>. </p> <p> For more information about installing Pygments, <a href='http://pygments.org/download/'>see the site</a>. </p> """ HtmlDialog("Getting syntax colorization", content).Show() def store_position(self, force=False): if self._editor and self.datafile_controller: cur_pos = self._editor.GetCurrentPos() if cur_pos > 0: # Cheating because it always go to zero self._position = cur_pos self._editor.GotoPos(self._position) def set_editor_caret_position(self): if not self.is_focused(): # DEBUG was typing text when at Grid Editor return position = self._position self._editor.SetFocus() if position: self._editor.SetCurrentPos(position) self._editor.SetSelection(position, position) self._editor.SetAnchor(position) self._editor.GotoPos(position) self._editor.Refresh() self._editor.Update() @property def dirty(self): return self._dirty @property def datafile_controller(self): return self._data._data if self._data else None def OnFind(self, event): if self._editor: text = self._editor.GetSelectedText() if len(text) > 0 and text.lower() != self._search_field.GetValue( ).lower(): self._search_field.SelectAll() self._search_field.Clear() self._search_field.Update() self._search_field.SetValue(text) self._search_field.SelectAll() self._search_field.Update() self._find() def OnFindBackwards(self, event): if self._editor: self._find(forward=False) def _find(self, forward=True): txt = self._search_field.GetValue().encode('utf-8') position = self._find_text_position(forward, txt) self._show_search_results(position, txt) # FIXME: This must be cleaned up def _find_text_position(self, forward, txt): file_end = len(self._editor.utf8_text) search_end = file_end if forward else 0 anchor = self._editor.GetAnchor() anchor += 1 if forward else 0 position = self._editor.FindText(anchor, search_end, txt, 0) if position == -1: start, end = (0, file_end) if forward else (file_end - 1, 0) position = self._editor.FindText(start, end, txt, 0) return position def _show_search_results(self, position, txt): if position != -1: self._editor.SetCurrentPos(position) self._editor.SetSelection(position, position + len(txt)) self._editor.ScrollToLine(self._editor.GetCurrentLine()) self._search_field_notification.SetLabel('') else: self._search_field_notification.SetLabel('No matches found.') def OnContentAssist(self, event): self._showing_list = False if not self.is_focused(): return self.store_position() selected = self._editor.get_selected_or_near_text() sugs = [ s.name for s in self._suggestions.get_suggestions(selected or '') ] if sugs: self._editor.AutoCompSetDropRestOfWord(True) self._editor.AutoCompSetSeparator(ord(';')) self._editor.AutoCompShow(0, ";".join(sugs)) self._showing_list = True def open(self, data): self.reset() self._data = data try: self._suggestions = SuggestionSource(None, data._data.tests[0]) except IndexError: # It is a new project, no content yet self._suggestions = SuggestionSource(None, BuiltInLibrariesSuggester()) if not self._editor: self._stored_text = self._data.content else: self._editor.set_text(self._data.content) self.set_editor_caret_position() def selected(self, data): if not self._editor: self._create_editor_text_control(self._stored_text) if self._data == data: return self.open(data) def auto_ident(self): if not self.is_focused(): return line, _ = self._editor.GetCurLine() lenline = len(line) linenum = self._editor.GetCurrentLine() if lenline > 0: idx = 0 while idx < lenline and line[idx] == ' ': idx += 1 tsize = idx // self._tab_size if 3 < idx < lenline and line.strip().startswith("FOR"): tsize += 1 elif linenum > 0 and tsize == 0: # Advance if first task/test case or keyword prevline = self._editor.GetLine(linenum - 1).lower() if prevline.startswith("**") and not ( "variables" in prevline or "settings" in prevline): tsize = 1 self._editor.NewLine() while tsize > 0: self.write_ident() tsize -= 1 else: self._editor.NewLine() pos = self._editor.GetCurrentLine() self._editor.SetCurrentPos(self._editor.GetLineEndPosition(pos)) self.store_position() def deindent_block(self): start, end = self._editor.GetSelection() caret = self._editor.GetCurrentPos() ini_line = self._editor.LineFromPosition(start) end_line = self._editor.LineFromPosition(end) count = 0 self._editor.SelectNone() line = ini_line inconsistent = False self._editor.BeginUndoAction() while line <= end_line: inconsistent = False pos = self._editor.PositionFromLine(line) self._editor.SetCurrentPos(pos) self._editor.SetSelection(pos, pos) self._editor.SetInsertionPoint(pos) content = self._editor.GetRange(pos, pos + self._tab_size) if content == (' ' * self._tab_size): self._editor.DeleteRange(pos, self._tab_size) count += 1 line += 1 else: inconsistent = True break self._editor.EndUndoAction() if inconsistent: self._editor.Undo() return new_start = max(0, start - self._tab_size) new_end = max(0, end - (count * self._tab_size)) if caret == start: ini = new_start fini = new_end else: ini = new_end fini = new_start self._editor.SetSelection(new_start, new_end) self._editor.SetCurrentPos(ini) self._editor.SetAnchor(fini) def indent_block(self): start, end = self._editor.GetSelection() caret = self._editor.GetCurrentPos() ini_line = self._editor.LineFromPosition(start) end_line = self._editor.LineFromPosition(end) count = 0 self._editor.SelectNone() line = ini_line while line <= end_line: pos = self._editor.PositionFromLine(line) self._editor.SetCurrentPos(pos) self._editor.SetSelection(pos, pos) self._editor.SetInsertionPoint(pos) self.write_ident() count += 1 line += 1 new_start = start + self._tab_size new_end = end + (count * self._tab_size) if caret == start: ini = new_start fini = new_end else: ini = new_end fini = new_start self._editor.SetSelection(new_start, new_end) self._editor.SetCurrentPos(ini) self._editor.SetAnchor(fini) def write_ident(self): spaces = ' ' * self._tab_size self._editor.WriteText(spaces) def reset(self): self._dirty = False def save(self, *args): self.store_position() if self.dirty and not self._data_validator.validate_and_update( self._data, self._editor.utf8_text): return False self.GetFocus(None) return True def delete(self): if IS_WINDOWS: if self._editor.GetSelectionStart( ) == self._editor.GetSelectionEnd(): self._editor.CharRight() self._editor.DeleteBack() def cut(self): self._editor.Cut() def copy(self): self._editor.Copy() def paste(self): focus = wx.Window.FindFocus() if focus == self._editor: self._editor.Paste() elif focus == self._search_field: self._search_field.Paste() def select_all(self): self._editor.SelectAll() def undo(self): self._editor.Undo() self.store_position() def redo(self): self._editor.Redo() self.store_position() def remove_and_store_state(self): if self._editor: self.store_position() self._stored_text = self._editor.GetText() def _create_editor_text_control(self, text=None): self._editor = RobotDataEditor(self) self.Sizer.add_expanding(self._editor) self.Sizer.Layout() if text is not None: self._editor.set_text(text) self._editor.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self._editor.Bind(wx.EVT_CHAR, self.OnChar) self._editor.Bind(wx.EVT_KEY_UP, self.OnEditorKey) self._editor.Bind(wx.EVT_KILL_FOCUS, self.LeaveFocus) self._editor.Bind(wx.EVT_SET_FOCUS, self.GetFocus) # TODO Add here binding for keyword help def LeaveFocus(self, event): self._editor.AcceptsFocusFromKeyboard() self.store_position() self._editor.SetCaretPeriod(0) def GetFocus(self, event): self._editor.SetFocus() self._editor.AcceptsFocusFromKeyboard() self._editor.SetCaretPeriod(500) if self._position: self.set_editor_caret_position() if event: event.Skip() def _revert(self): self.reset() self._editor.set_text(self._data.content) def OnEditorKey(self, event): if not self.is_focused(): # DEBUG was typing text when at Grid Editor return keycode = event.GetKeyCode() if (keycode >= ord(' ')) and not self.dirty and self._editor.GetModify(): self._mark_file_dirty() event.Skip() def OnKeyDown(self, event): if not self.is_focused(): self.GetFocus(None) keycode = event.GetUnicodeKey() if event.GetKeyCode( ) == wx.WXK_TAB and not event.ControlDown() and not event.ShiftDown(): selected = self._editor.GetSelection() if selected[0] == selected[1]: self.write_ident() else: self.indent_block() elif event.GetKeyCode() == wx.WXK_TAB and event.ShiftDown(): selected = self._editor.GetSelection() if selected[0] == selected[1]: pos = self._editor.GetCurrentPos() self._editor.SetCurrentPos(max(0, pos - self._tab_size)) self.store_position() if not event.ControlDown(): # No text selection pos = self._editor.GetCurrentPos() self._editor.SetSelection(pos, pos) else: self.deindent_block() elif event.GetKeyCode() in [wx.WXK_RETURN, wx.WXK_NUMPAD_ENTER]: if not self._showing_list: self.auto_ident() else: self._showing_list = False event.Skip() elif keycode in (ord('1'), ord('2'), ord('5')) and event.ControlDown(): self.execute_variable_creator(list_variable=(keycode == ord('2')), dict_variable=(keycode == ord('5'))) self.store_position() else: event.Skip() def OnChar(self, event): if not self.is_focused(): return keycode = event.GetUnicodeKey() if chr(keycode) in ['[', '{', '(', "'", '\"', '`']: self.execute_enclose_text(chr(keycode)) self.store_position() else: event.Skip() def execute_variable_creator(self, list_variable=False, dict_variable=False): from_, to_ = self._editor.GetSelection() text = self._editor.SelectedText size = len(bytes(text, encoding='utf-8')) to_ = from_ + size if list_variable: symbol = '@' elif dict_variable: symbol = '&' else: symbol = '$' if size == 0: self._editor.SetInsertionPoint(to_) self._editor.InsertText(from_, self._variable_creator_value(symbol)) self._editor.SetInsertionPoint(from_ + 2) else: self._editor.DeleteRange(from_, size) self._editor.SetInsertionPoint(from_) self._editor.ReplaceSelection( self._variable_creator_value(symbol, text)) self._editor.SetSelection(from_ + 2, from_ + size + 2) @staticmethod def _variable_creator_value(symbol, value=''): return symbol + '{' + value + '}' def execute_enclose_text(self, keycode): from_, to_ = self._editor.GetSelection() text = self._editor.SelectedText size = len(bytes(text, encoding='utf-8')) to_ = from_ + size if size == 0: self._editor.SetInsertionPoint(to_) self._editor.InsertText(from_, self._enclose_text(keycode)) pos = self._editor.GetCurrentPos() self._editor.SetSelection(pos + 1, pos + 1) else: self._editor.DeleteRange(from_, size) self._editor.SetInsertionPoint(from_) self._editor.ReplaceSelection(self._enclose_text(keycode, text)) self._editor.SetSelection(from_ + 1, from_ + size + 1) @staticmethod def _enclose_text(open_symbol, value=''): if open_symbol == '[': close_symbol = ']' elif open_symbol == '{': close_symbol = '}' elif open_symbol == '(': close_symbol = ')' else: close_symbol = open_symbol return open_symbol + value + close_symbol def execute_comment(self, event): cursor = self._editor.GetCurrentPos() line, pos = self._editor.GetCurLine() spaces = ' ' * self._tab_size comment = 'Comment' + spaces cpos = cursor + len(comment) lenline = len(line) if lenline > 0: idx = 0 while idx < lenline and line[idx] == ' ': idx += 1 self._editor.InsertText(cursor - pos + idx, comment) else: self._editor.InsertText(cursor, comment) self._editor.SetCurrentPos(cpos) self._editor.SetSelection(cpos, cpos) self.store_position() def execute_uncomment(self, event): cursor = self._editor.GetCurrentPos() line, pos = self._editor.GetCurLine() spaces = ' ' * self._tab_size comment = 'Comment' + spaces cpos = cursor - len(comment) lenline = len(line) if lenline > 0: idx = 0 while idx < lenline and line[idx] == ' ': idx += 1 if (line[idx:len(comment) + idx]).lower() == comment.lower(): self._editor.DeleteRange(cursor - pos + idx, len(comment)) self._editor.SetCurrentPos(cpos) self._editor.SetSelection(cpos, cpos) self.store_position() def OnSettingsChanged(self, data): """Update tab size if txt spaces size setting is modified""" _, setting = data.keys if setting == 'txt number of spaces': self._tab_size = self._parent._app.settings.get( 'txt number of spaces', 4) def _mark_file_dirty(self): if self._data: self._dirty = True self._data.mark_data_dirty()
# limitations under the License. import os import wx from wx.lib.filebrowsebutton import DirBrowseButton from robotide.controller.ctrlcommands import CreateNewResource,\ AddTestDataDirectory, AddTestCaseFile, CreateNewDirectoryProject,\ CreateNewFileProject, SetFileFormat, SetFileFormatRecuresively from robotide.utils import overrides from robotide.widgets import Label, Dialog from robotide.validators import NonEmptyValidator, NewSuitePathValidator,\ SuiteFileNameValidator # This hack needed to set same label width as with other labels DirBrowseButton.createLabel = lambda self:\ Label(self, size=(110, -1), label=self.labelText) class _CreationDialog(Dialog): def __init__(self, default_dir, title): sizer = self._init_dialog(title) label_sizer = wx.BoxSizer(wx.VERTICAL) self._name_editor = self._create_name_editor(label_sizer) self._parent_chooser = self._create_parent_chooser( label_sizer, default_dir) self._path_display = self._create_path_display(label_sizer, default_dir) radio_group_sizer = wx.BoxSizer(wx.VERTICAL) self._type_chooser = self._create_type_chooser(radio_group_sizer) self._format_chooser = self._create_format_chooser(radio_group_sizer) edit_sizer = wx.BoxSizer(wx.HORIZONTAL)
def _get_name(self, plugin): return Label(self, label=plugin.name)
def _add_source_filter(self, sizer): sizer.Add(Label(self, label='Source: ')) self._source_filter = wx.ComboBox(self, value=ALL_KEYWORDS, size=(300, -1), choices=self._get_sources(), style=wx.CB_READONLY) sizer.Add(self._source_filter)
def __init__(self, parent): Label.__init__(self, parent) self.SetFont(Font().fixed)
def _add_pattern_filter(self, sizer): sizer.Add(Label(self, label='Search term: ')) self._search_control = wx.SearchCtrl(self, size=(200,-1), style=wx.TE_PROCESS_ENTER) sizer.Add(self._search_control)
def _label_for(self, setting): label = ('%s: ' % setting.name).capitalize() return Label(self, label=label)
def _create_label(self, label_text): return Label(self, label=label_text, size=(80, -1))
def _create_help(self, sizer): help = "Provide format for initialization file in directory\n\"%s\"." \ % self._controller.directory sizer.Add(Label(self, label=help), flag=wx.ALL, border=5)
class ProgressBar(wx.Panel): """A progress bar for the test runner plugin""" def __init__(self, parent): wx.Panel.__init__(self, parent, wx.ID_ANY) self._sizer = wx.BoxSizer(wx.HORIZONTAL) self._gauge = wx.Gauge(self, size=(100, 10)) self._label = Label(self) self._sizer.Add(self._label, 1, wx.EXPAND | wx.LEFT, 10) self._sizer.Add(self._gauge, 0, wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, 10) self._sizer.Layout() self.SetSizer(self._sizer) self._gauge.Hide() self._default_colour = parent.GetBackgroundColour() self._timer = wx.Timer(self) self.Bind(wx.EVT_TIMER, self.OnTimer) self._initialize_state() def _initialize_state(self): self._pass = 0 self._fail = 0 self._current_keywords = [] def set_current_keyword(self, name): self._current_keywords.append(name) def empty_current_keyword(self): if self._current_keywords: self._current_keywords.pop() def OnTimer(self, event): """A handler for timer events; it updates the statusbar""" self._gauge.Show() self._gauge.Pulse() self._update_message() def Start(self): """Signals the start of a test run; initialize progressbar.""" self._initialize_state() self._start_time = time.time() self._gauge.Show() self._sizer.Layout() self.SetBackgroundColour(self._default_colour) self._timer.Start(50) def Stop(self): """Signals the end of a test run""" self._gauge.Hide() self._timer.Stop() def add_pass(self): """Add one to the passed count""" self._pass += 1 def add_fail(self): """Add one to the failed count""" self._fail += 1 def _update_message(self): """Update the displayed elapsed time, passed and failed counts""" elapsed = time.time() - self._start_time message = "elapsed time: %s pass: %s fail: %s" % ( secondsToString(elapsed), self._pass, self._fail) message += self._get_current_keyword_text() self._label.SetLabel(message) if self._fail > 0: self.SetBackgroundColour("#FF8E8E") elif self._pass > 0: self.SetBackgroundColour("#9FCC9F") # not sure why this is required, but without it the background # colors don't look right on Windows self.Refresh() def _get_current_keyword_text(self): if not self._current_keywords: return '' return ' current keyword: ' + \ self._fix_size(' -> '.join(self._current_keywords), 50) def _fix_size(self, text, max_length): if len(text) <= max_length: return text return '...' + text[3 - max_length:]
def _get_description(self, plugin): desc = Label(self, label=plugin.doc) if plugin.error: desc.SetForegroundColour("firebrick") return desc