Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions .appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#---------------------------------#

# version format
version: 2.1.{build}
version: 2.2.3.{build}

# branches to build
branches:
Expand Down Expand Up @@ -68,10 +68,13 @@ build: off

# scripts that run after cloning repository
install:
- C:\Python311-x64\python -m pip install --upgrade pip
- C:\Python311-x64\python -m pip install -r requirements-dev.txt
- C:\Python311-x64\python -m pip install -r requirements.txt
- C:\Python311-x64\python -m pip install robotframework
- C:\Python311-x64\python -m pip install .
- C:\Python311-x64\python -m build
# I don't know the exact name of wheel so use workaround
- powershell.exe C:\Python311-x64\python -m pip install (get-item .\dist\*.whl).FullName

#---------------------------------#
# tests configuration #
Expand All @@ -86,4 +89,7 @@ test_script:
artifacts:
- path: coverage_report.7z
name: coverage_report
- path: dist\*.whl
name: package


8 changes: 6 additions & 2 deletions .coveragerc
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
[paths]
source =
src/
%APPVEYOR_BUILD_FOLDER%\src

[run]
# include = ./src/*
source = src/
branch = True
relative_files = True
dynamic_context = test_function
Expand All @@ -24,6 +27,7 @@ skip_empty = True
exclude_lines =
if __name__ == '__main__':
if __name__ == '__main__' and 'robotide' not in sys.modules:
ignore_errors = True

[xml]
output = .coverage-reports/coverage.xml
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/fedora_41.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ jobs:
- name: Configure container environment
run: |
sudo dnf update -y
sudo dnf install -y git
sudo dnf install -y git python3-tkinter
git config --global --add safe.directory ${GITHUB_WORKSPACE}
- uses: actions/checkout@v3.3.0
with:
Expand Down Expand Up @@ -98,6 +98,7 @@ jobs:
path: |
.coverage.1
.coverage.2
.coverage.3
.coverage-reports/coverage.xml
.coverage-reports/htmlcov
- name: Install and run
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ jobs:
- name: Configure container environment
run: |
sudo dnf update -y
sudo dnf install -y git
sudo dnf install -y git python3-tkinter
git config --global --add safe.directory ${GITHUB_WORKSPACE}
- uses: actions/checkout@v3.3.0
with:
Expand Down Expand Up @@ -132,6 +132,7 @@ jobs:
path: |
.coverage.1
.coverage.2
.coverage.3
.coverage-reports/coverage.xml
.coverage-reports/htmlcov
- name: Install and run
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ and this project adheres to http://semver.org/spec/v2.0.0.html[Semantic Versioni
== https://github.com/robotframework/RIDE[Unreleased]

=== Added
- Added comments field to show comments in Tags section of Test Suites in Grid Editor.
- Added Auto-Save feature. Default is disabled with setting zero minutes in Preferences->Save.
- Added option on Tree (Project Explorer) context menu, to *Sort Keywords (Case Insensitive)*.
- Added on Text Editor, (Preferences->Text Editor) option to *Enable visible spaces* configurable with ``enable visible spaces`` in settings.cfg, with default ``True``.
Expand Down
2 changes: 1 addition & 1 deletion README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ Likewise, the current version of wxPython, is 4.2.5, but RIDE is known to work w

`pip install -U robotframework-ride`

(3.9 <= python <= 3.14) Install current development version (**2.2.3dev8**) with:
(3.9 <= python <= 3.14) Install current development version (**2.2.3dev9**) with:

`pip install -U https://github.com/robotframework/RIDE/archive/develop.zip`

Expand Down
150 changes: 76 additions & 74 deletions src/robotide/application/CHANGELOG.html

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/robotide/application/pluginconnector.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ def plugin_factory(application, plugin_class, silent=False):
try:
plugin = plugin_class(application)
except Exception as e:
print(e)
msg, traceback = utils.get_error_details()
if not silent:
print(e)
return BrokenPlugin(msg, traceback, plugin_class)
else:
return PluginConnector(plugin, application)
Expand Down
3 changes: 2 additions & 1 deletion src/robotide/application/releasenotes.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ def set_content(self, html_win, content):
</ul>
<p><strong>New Features and Fixes Highlights</strong></p>
<ul class="simple">
<li>Added comments field to show comments in Tags section of Test Suites in Grid Editor.</li>
<li>Added Auto-Save feature. Default is disabled with setting zero minutes in Preferences->Save.</li>
<li>Added option on Tree (Project Explorer) context menu, to <b>Sort Keywords (Case Insensitive)</b>.</li>
<li>Improved visibility of the Search action in <b>Find Usages</b> by adding <b>Search...</b> on the first row of the
Expand Down Expand Up @@ -251,7 +252,7 @@ def set_content(self, html_win, content):
<pre class="literal-block">python -m robotide.postinstall -install</pre>
<p>or</p>
<pre class="literal-block">ride_postinstall.py -install</pre>
<p>RIDE {VERSION} was released on 12/April/2026.</p>
<p>RIDE {VERSION} was released on 21/April/2026.</p>
<br/>
<!--
<h3>Celebrate the bank holiday, 1st December, Restoration of the Independence of Portugal (from Spain in 1640)!!</h3>
Expand Down
69 changes: 67 additions & 2 deletions src/robotide/editor/settingeditors.py
Original file line number Diff line number Diff line change
Expand Up @@ -422,21 +422,59 @@ def _saving(self, message):
_ = message
self._tags_display.saving()

def _create_controls(self):
sizer = wx.BoxSizer(wx.HORIZONTAL)
sizer.Add((5, 0))
width = max(len(self._controller.label), context.SETTING_LABEL_WIDTH)
label = Label(self, label=self._controller.label,
size=(width, context.SETTING_ROW_HEIGHT))
label.SetToolTip(get_english_label(self._language, self._controller.label))
sizer.Add(label)
value_sizer = wx.BoxSizer(wx.VERTICAL)
self._value_display = self._create_value_display()
self._comment_display = self._create_comment_display()
value_sizer.Add(self._value_display, 0, wx.EXPAND)
value_sizer.Add(self._comment_display, 0, wx.EXPAND)
self.update_value()
self._tooltip = self._get_tooltip()
sizer.Add(value_sizer, 1, wx.EXPAND)
self._add_edit(sizer)
sizer.Add(ButtonWithHandler(self, _('Clear'), mk_handler='Clear', handler=self.on_clear, fsize=self.font_size,
color_secondary_foreground=self.color_secondary_foreground,
color_secondary_background=self.color_secondary_background))
sizer.Layout()
self.SetSizer(sizer)

def _create_comment_display(self):
comment_display = CommentDisplay(self, self._controller)
comment_display.Bind(wx.EVT_LEFT_UP, self.on_left_up)
return comment_display

def _value_display_control(self):
self._tags_display = TagsDisplay(self, self._controller)
self._tags_display.Bind(wx.EVT_LEFT_UP, self.on_left_up)
self._tags_display.Bind(wx.EVT_KEY_DOWN, self.on_key)
return self._tags_display

def update_value(self):
if self._controller is None:
return
if self._controller.is_set:
self._value_display.set_value(self._controller, self.plugin)
self._comment_display.set_value(self._controller)
else:
self._value_display.clear_field()
self._comment_display.clear()
self.Refresh()
wx.CallAfter(self.GetParent().Layout)

def contains(self, text):
return False

def highlight(self, text):
""" Just ignoring it """
pass

def clear_highlight(self):
""" Just ignoring it """
pass

def close(self):
Expand All @@ -445,6 +483,33 @@ def close(self):
SettingEditor.close(self)


class CommentDisplay(wx.StaticText):
def __init__(self, parent, controller):
self._parent = parent
self._controller = controller
wx.StaticText.__init__(self, parent, label='')
self.SetForegroundColour(Colour(parent.color_secondary_foreground))
self.SetBackgroundColour(Colour(parent.color_background))
self.Hide()

def set_value(self, controller):
self._controller = controller
comment = controller.comment
if comment and len(comment) > 0:
comment_text = comment.as_list()
if comment_text:
comment_str = ' '.join(str(c).lstrip('# ').strip() for c in comment_text if c)
if comment_str:
self.SetLabel('# ' + comment_str)
self.Show()
return
self.clear()

def clear(self):
self.SetLabel('')
self.Hide()


class _AbstractListEditor(ListEditor):
_titles = []

Expand Down
40 changes: 9 additions & 31 deletions src/robotide/editor/tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ def __init__(self, parent, controller):
self._controller = controller
self._sizer = wx.BoxSizer()
self._tag_boxes = []
self._comment_display = None
self.SetAutoLayout(1)
self.SetupScrolling(scroll_y=False, scrollIntoView=False)
self.SetSizer(self._sizer)
Expand Down Expand Up @@ -63,10 +64,6 @@ def set_value(self, controller, plugin=None):
if not self._tag_boxes:
self._add_tags(list(controller))
else:
# in GTK you can have focus in a dead object
# this causes Segmentation Faults
# Thus instead of clearing old values and adding new ones
# modify the ones that exist
self._modify_values(controller)
self.build()

Expand Down Expand Up @@ -118,21 +115,14 @@ def GetSelection():
def get_height(self):
""" Seems that this method is never called """
_, height = self._sizer.GetSize()
# print(f"DEBUG: tags height={height}")
return height # DEBUG return self._sizer.height
return height


class TagBox(wx.TextCtrl):
tb_properties = None

def __init__(self, parent, tproperties):
wx.TextCtrl.__init__(self, parent, wx.ID_ANY, '', style=wx.TE_CENTER | wx.TE_NOHIDESEL)
"""
self.SetBackgroundColour(Colour(200, 222, 40))
self.SetOwnBackgroundColour(Colour(200, 222, 40))
self.SetForegroundColour(Colour(7, 0, 70))
self.SetOwnForegroundColour(Colour(7, 0, 70))
"""
self._bind()
self.set_properties(tproperties)

Expand All @@ -159,7 +149,7 @@ def _apply_properties(self):

def _get_size(self):
size = self.GetTextExtent(self.value)
offset = 13 if IS_WINDOWS else 26 # On GTK3 labels are bigger
offset = 13 if IS_WINDOWS else 26
return wx.Size(max(size[0]+offset, 75), max(size[1]+3, 25))

def _colorize(self):
Expand All @@ -182,25 +172,19 @@ def on_key_up(self, event):
self.SetValue('')

if event.GetKeyCode() != wx.WXK_RETURN:
# Don't send skip event if enter key is pressed
# On some platforms this event is sent too late and causes crash
event.Skip()

def _cancel_editing(self):
self.SetValue(self.tb_properties.text)
self._colorize()

def on_char(self, event):
# For some reason at least ESC and F<num> keys are considered chars.
# We only special case ESC, though.
if event.GetKeyCode() != wx.WXK_ESCAPE:
self.tb_properties.activate(self)
event.Skip()

def on_kill_focus(self, event):
self._update_value()
# Send skip event only if tagbox is empty and about to be destroyed
# On some platforms this event is sent too late and causes crash
if self and self.value != '':
event.Skip()

Expand Down Expand Up @@ -230,9 +214,8 @@ def properties(tag, controller):


class _TagBoxProperties(object):
# DEBUG: Use colours from settings
foreground_color = 'black' # Colour(7, 0, 70) #
background_color = 'gray' # Colour(200, 222, 40) 'white'
foreground_color = 'black'
background_color = 'gray'
enabled = True
add_new = False

Expand All @@ -256,7 +239,6 @@ def change_value(self, value):
self._tag.controller.execute(ctrlcommands.ChangeTag(self._tag, value))

def activate(self, tagbox):
""" Just ignore it """
pass


Expand All @@ -265,8 +247,7 @@ class TagBoxProperties(_TagBoxProperties):


class AddTagBoxProperties(_TagBoxProperties):
# DEBUG: Use colours from settings
foreground_color = 'gray' # Colour(200, 222, 40)
foreground_color = 'gray'
text = '<Add New>'
tooltip = 'Click to add new tag'
modifiable = False
Expand All @@ -282,21 +263,18 @@ def activate(self, tagbox):


class ForcedTagBoxProperties(_TagBoxProperties):
# DEBUG: Use colours from settings
foreground_color = 'red'
background_color = '#D3D3D3' # Colour(200, 222, 40)
background_color = '#D3D3D3'
enabled = False


class DefaultTagBoxProperties(_TagBoxProperties):
# DEBUG: Use colours from settings
foreground_color = '#666666'
background_color = '#D3D3D3' # Colour(200, 222, 40)
background_color = '#D3D3D3'
enabled = False


class TestTagBoxProperties(_TagBoxProperties):
# DEBUG: Use colours from settings
foreground_color = 'orange'
background_color = '#D3D3D3' # Colour(200, 222, 40)
background_color = '#D3D3D3'
enabled = False
2 changes: 1 addition & 1 deletion src/robotide/lib/isbinary/check.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ def is_decodable_as_unicode(bytes_to_check: bytes, /) -> bool:
try:
bytes_to_check.decode(encoding=detected_encoding["encoding"])
decodable_as_unicode = True
except (LookupError, UnicodeDecodeError):
except (LookupError, UnicodeDecodeError, TypeError):
pass

return decodable_as_unicode
Expand Down
2 changes: 1 addition & 1 deletion src/robotide/postinstall/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ def _create_desktop_shortcut_linux(frame=None):
desktop = {"de": "Desktop", "en": "Desktop", "es": "Escritorio",
"fi": r"Työpöytä", "fr": "Bureau", "it": "Scrivania",
"pt": r"Área de Trabalho", "zh": "Desktop"}
user = basename(expanduser('~'))
user = getuser()
DEFAULT_LANGUAGE = environ.get('LANG', '').split(':')
if DEFAULT_LANGUAGE is None:
DEFAULT_LANGUAGE = ['en_US']
Expand Down
2 changes: 1 addition & 1 deletion src/robotide/ui/fileexplorerplugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ def update_tree(self):
try:
self.tree_ctrl.ExpandPath(self._controller.data.source)
self.tree_ctrl.TreeCtrl.EnsureVisible(self.tree_ctrl.TreeCtrl.GetSelection())
except (RuntimeError, AttributeError):
except (AssertionError, RuntimeError, AttributeError):
pass
# self.on_size(wx.EVT_SIZE)
self.Refresh()
Expand Down
Loading
Loading