From 48ab39d187c3fafb56502090403d47c45ce6eaa7 Mon Sep 17 00:00:00 2001 From: ChelSlava Date: Mon, 30 Mar 2026 00:41:06 +0300 Subject: [PATCH 1/4] Add visible searching indicator to Find Usages dialog Closes #2672 The 'searching...' indicator is now shown as the first row in the results table, making it more visible to users who focus on the table rather than the dialog title. --- src/robotide/usages/usagesdialog.py | 53 +++++++++++++++++++++++------ 1 file changed, 42 insertions(+), 11 deletions(-) diff --git a/src/robotide/usages/usagesdialog.py b/src/robotide/usages/usagesdialog.py index 0d2e2e322..e98d9a4b3 100644 --- a/src/robotide/usages/usagesdialog.py +++ b/src/robotide/usages/usagesdialog.py @@ -30,6 +30,7 @@ def __init__(self, name, usages=None, prefix=None): self._dots = None self._name = name self._selection_listeners = [] + self._searching = False title = "'%s'" % name RIDEDialog.__init__(self, title=title, size=(650, 400)) # set Left to Right direction (while we don't have localization) @@ -51,19 +52,25 @@ def add_usage(self, usage): def begin_searching(self): from ..ui.searchdots import DottedSearch + self._searching = True self._dots = DottedSearch(self, self._update_searching) self._dots.start() def _update_searching(self, dots): + self.usages._searching = self._searching self.SetTitle(_("'%s' - %d matches found - Searching%s") % (self._name, self.usages.total_usages, dots)) self.usage_list.refresh_items() def end_searching(self): self._dots.stop() + self._searching = False + self.usages._searching = False self.SetTitle(_("'%s' - %d matches") % (self._name, self.usages.total_usages)) self.usage_list.refresh_items() def _usage_selected(self, idx): + if self._searching and idx == 0: + return for listener in self._selection_listeners: listener(self.usages.usage(idx).item.parent, self._name) @@ -103,8 +110,9 @@ def resource_import_usage_dialog(name, highlight, controller): class _UsagesListModel(ListModel): - def __init__(self, usages): + def __init__(self, usages, searching=False): self._usages = usages + self._searching = searching self._create_image_list() def _create_image_list(self): @@ -121,8 +129,12 @@ def images(self): return self._images def image(self, item): + if self._searching and item == 0: + return -1 + offset = 1 if self._searching else 0 + actual_item = item - offset # DEBUG: better mechanism for item type recognition - parent_type = self._usages[item].parent.__class__.__name__ + parent_type = self._usages[actual_item].parent.__class__.__name__ return {'TestCaseController': 0, 'UserKeywordController': 1, 'TestCaseFileController': 2, @@ -133,7 +145,10 @@ def add_usage(self, usage): self._usages.append(usage) def usage(self, idx): - return self._usages[idx] + if self._searching and idx == 0: + return None + offset = 1 if self._searching else 0 + return self._usages[idx - offset] @property def total_usages(self): @@ -141,35 +156,47 @@ def total_usages(self): @property def count(self): - return len(self._usages) + base_count = len(self._usages) + return base_count + 1 if self._searching else base_count class UsagesListModel(_UsagesListModel): - def __init__(self, usages): - _UsagesListModel.__init__(self, usages) + def __init__(self, usages, searching=False): + _UsagesListModel.__init__(self, usages, searching) self.headers = [_('Location'), _('Usage'), _('Source')] def item_text(self, row, col): + if self._searching and row == 0: + if col == 0: + return _("Searching...") + return "" u = self.usage(row) return [u.location, u.usage, u.source][col] class ResourceImportListModel(_UsagesListModel): - def __init__(self, usages): - _UsagesListModel.__init__(self, usages) + def __init__(self, usages, searching=False): + _UsagesListModel.__init__(self, usages, searching) self.headers = ['Name', 'Location'] # wxPyDeprecationWarning: Using deprecated class. Use ItemAttr instead self._cannot_rename_item_attr = wx.ItemAttr() # wx.ListItemAttr() self._cannot_rename_item_attr.SetBackgroundColour(wx.Colour(255, 64, 64)) def item_text(self, row, col): + if self._searching and row == 0: + if col == 0: + return _("Searching...") + return "" u = self.usage(row) return [u.name, u.location][col] def item_attributes(self, idx): - if self._usages[idx].can_be_renamed: + if self._searching and idx == 0: + return None + offset = 1 if self._searching else 0 + if self._usages[idx - offset].can_be_renamed: return None return self._cannot_rename_item_attr @@ -180,10 +207,14 @@ def total_usages(self): class RecursiveResourceImportListModel(_UsagesListModel): - def __init__(self, usages): - _UsagesListModel.__init__(self, usages) + def __init__(self, usages, searching=False): + _UsagesListModel.__init__(self, usages, searching) self.headers = [_('Imported name'), _('Imported Location'), _('Importing Name'), _('Importing Location')] def item_text(self, row, col): + if self._searching and row == 0: + if col == 0: + return _("Searching...") + return "" u = self.usage(row) return [u.res_name, u.res_src, u.name, u.location][col] From 3e38aabde24543b424b0c7423d71f423704d2f47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9lio=20Guilherme?= Date: Mon, 30 Mar 2026 00:11:40 +0100 Subject: [PATCH 2/4] Make visible spaces and newlines in Text Editor. (#3026) * Add options to make visible spaces and newlines in Text Editor. * Fix 'General' settings not available after upgrade (blocks startup) (#3013) - Add migration from settings version 8 to 9 that ensures General section exists with all required keys - Add safe access to General settings in application.py, mainframe.py, treeplugin.py, and dialog.py - Use .get() with fallback values instead of direct dictionary access - This prevents KeyError when user settings file is missing or corrupted Closes #3000 * Enable visible spaces and newlines in External/Code Editor. --------- Co-authored-by: ChelSlava --- AUTHORS.txt | 1 + CHANGELOG.adoc | 8 + README.adoc | 4 +- src/robotide/application/releasenotes.py | 10 +- src/robotide/editor/customsourceeditor.py | 11 +- src/robotide/editor/pythoneditor.py | 5 +- src/robotide/editor/texteditor.py | 15 +- src/robotide/preferences/configobj | 2 +- src/robotide/preferences/editors.py | 10 +- src/robotide/preferences/settings.cfg | 2 + src/robotide/version.py | 2 +- utest/editor/test_customsourceeditor.py | 15 +- .../.robot/ride_settings.cfg | 239 ------------------ utest/resources/setting_utils.py | 8 +- utest/settings/test_settings.py | 7 +- utest/zulu_misc/test_configobj.py | 8 +- 16 files changed, 78 insertions(+), 269 deletions(-) delete mode 100644 utest/resources/robotdata/test_project/with_project_settings_one/.robot/ride_settings.cfg diff --git a/AUTHORS.txt b/AUTHORS.txt index a05135db9..ed8a96cd5 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -32,6 +32,7 @@ Petr Hudeček Timothy Alexander @2Eagle2 @bale836 +@chelslava @fzuellich @ghost @goodwillcoding diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index de277de69..bb5262b57 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -8,6 +8,14 @@ and this project adheres to http://semver.org/spec/v2.0.0.html[Semantic Versioni == https://github.com/robotframework/RIDE[Unreleased] +=== Added +- Added on Text Editor, (Preferences->Text Editor) option to *Enable visible spaces* configurable with ``enable visible spaces`` in settings.cfg, with default ``True``. +- Added on Text Editor, (Preferences->Text Editor) option to *Enable visible newlines* configurable with ``enable visible newlines`` in settings.cfg, with default ``False``. +- Added on External/Code Editor, both enabled, ``visible spaces`` and ``visible newlines``. + +=== Fixed +- Fixed exception seen in console when selecting Tools->Library Finder... on a clean install. + === Changed - Changed isbinary to be internal library, instead of being dependency. diff --git a/README.adoc b/README.adoc index 543f916b5..3547b65f3 100644 --- a/README.adoc +++ b/README.adoc @@ -40,13 +40,13 @@ See the https://github.com/robotframework/RIDE/blob/master/doc/releasenotes/ride Currently, the unit tests are tested on Python 3.10, 3.11 and 3.14. We now have an experimental workflow on Fedora Linux 42, with wxPython 4.2.4 and Python 3.14. -Likewise, the current version of wxPython, is 4.2.4, but RIDE is known to work with 4.0.7, 4.1.1, 4.2.2, 4.2.3 and 4.2.4 versions. +Likewise, the current version of wxPython, is 4.2.5, but RIDE is known to work with 4.0.7, 4.1.1, 4.2.2, 4.2.3, 4.2.4 and 4.2.5 versions. (3.9 <= python <= 3.14) Install current released version (*2.2.2*) with: `pip install -U robotframework-ride` -(3.9 <= python <= 3.14) Install current development version (**2.2.3dev3**) with: +(3.9 <= python <= 3.14) Install current development version (**2.2.3dev4**) with: `pip install -U https://github.com/robotframework/RIDE/archive/develop.zip` diff --git a/src/robotide/application/releasenotes.py b/src/robotide/application/releasenotes.py index f3c96db1e..b59ddeedb 100644 --- a/src/robotide/application/releasenotes.py +++ b/src/robotide/application/releasenotes.py @@ -150,7 +150,7 @@ def set_content(self, html_win, content):

RIDE (Robot Framework IDE) {VERSION} is a new release with some enhancements and bug fixes. The reference for valid arguments is - Robot Framework current version, 7.4.1. However, + Robot Framework current version, 7.4.2. However, internal library code is originally based on version 3.1.2, but adapted for new versions.

  • This version supports Python 3.9 up to 3.14.
  • @@ -179,6 +179,10 @@ def set_content(self, html_win, content):

New Features and Fixes Highlights

    +
  • Added on Text Editor, (Preferences->Text Editor) options to Enable visible spaces and + Enable visible newlines.
  • +
  • Added on External/Code Editor, both enabled, visible spaces and visible newlines.
  • +
  • Fixed exception seen in console when selecting Tools->Library Finder... on a clean install.
  • The Test Suites Explorer can be visible or hidden with F12 (View->View Test Suites Explorer). Pane can be made floating or docked, by dragging or by double-clicking its top bar.
  • In File Explorer opening non-text files is done by the operating system registered app.
  • @@ -192,7 +196,7 @@ def set_content(self, html_win, content):
-

The minimal wxPython version is, 4.0.7, and RIDE supports the current version, 4.2.4, which we recommend. +

The minimal wxPython version is, 4.0.7, and RIDE supports the current version, 4.2.5, which we recommend.

Linux users are advised to install first wxPython from .whl package at wxPython.org, or by using the system package @@ -243,7 +247,7 @@ def set_content(self, html_win, content):

python -m robotide.postinstall -install

or

ride_postinstall.py -install
-

RIDE {VERSION} was released on 11/January/2026.

+

RIDE {VERSION} was released on 29/March/2026.


  • 🐞 - Rename Keywords, Find Usages/Find where used are not finding all occurrences. Please, double-check findings and changes.
  • @@ -179,6 +179,8 @@ def set_content(self, html_win, content):

    New Features and Fixes Highlights

      +
    • Improved visibility of the Search action in Find Usages by adding Search... on the first row of the +results table.
    • Added on Text Editor, (Preferences->Text Editor) options to Enable visible spaces and Enable visible newlines.
    • Added on External/Code Editor, both enabled, visible spaces and visible newlines.
    • @@ -247,7 +249,7 @@ def set_content(self, html_win, content):
      python -m robotide.postinstall -install

      or

      ride_postinstall.py -install
      -

      RIDE {VERSION} was released on 29/March/2026.

      +

      RIDE {VERSION} was released on 31/March/2026.