Skip to content

Commit 7448847

Browse files
Improves auto-complete in Grid Editor
1 parent 0f87189 commit 7448847

File tree

7 files changed

+69
-27
lines changed

7 files changed

+69
-27
lines changed

CHANGELOG.adoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ and this project adheres to http://semver.org/spec/v2.0.0.html[Semantic Versioni
1818
when selecting in Tree shows the filename in StatusBar.
1919

2020
=== Changed
21+
- Improved auto-complete in Grid Editor, to allow several matches
2122
- Changed some informative dialogs and JSON Editor to use the customized colors.
2223
- Modified import statements to allow running RIDE without Robot Framework installed or versions older than 6.0.
2324
- On Windows ignore false modification on files when opening Test Suites, causing confirmation dialog.

README.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ Likewise, the current version of wxPython, is 4.2.3, but RIDE is known to work w
4141

4242
`pip install -U robotframework-ride`
4343

44-
(3.8 <= python <= 3.13) Install current development version (**2.2dev25**) with:
44+
(3.8 <= python <= 3.13) Install current development version (**2.2dev26**) with:
4545

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

src/robotide/application/CHANGELOG.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
Added divided Status Bar. Left side for main window, right side for Plugins. Working example in Text Editor,
1515
when selecting in Tree shows the filename in StatusBar.
1616
</li></ul></div></div><div class="section"><div class="titlepage"><div><div><h3 class="title"><a id="_changed"></a>1.2. Changed</h3></div></div></div><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
17+
Improved auto-complete in Grid Editor, to allow several matches
18+
</li><li class="listitem">
1719
Changed some informative dialogs and JSON Editor to use the customized colors.
1820
</li><li class="listitem">
1921
Modified import statements to allow running RIDE without Robot Framework installed or versions older than 6.0.

src/robotide/application/releasenotes.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ def set_content(self, html_win, content):
172172
</ul>
173173
<p><strong>New Features and Fixes Highlights</strong></p>
174174
<ul class="simple">
175+
<li>Improved auto-complete in Grid Editor, to allow several matches.</li>
175176
<li>Fixed white blocks on Tree due to failed animation when test execution is too rapid, causing crash on Windows.</li>
176177
<li>Added Settings Editor button to Preferences dialog, to edit settings.cfg.</li>
177178
<li>Created backup of settings.cfg to allow recovering some settings when broken upgrades.</li>
@@ -237,7 +238,7 @@ def set_content(self, html_win, content):
237238
<pre class="literal-block">python -m robotide.postinstall -install</pre>
238239
<p>or</p>
239240
<pre class="literal-block">ride_postinstall.py -install</pre>
240-
<p>RIDE {VERSION} was released on 15/May/2025.</p>
241+
<p>RIDE {VERSION} was released on 18/May/2025.</p>
241242
<!-- <br/>
242243
<h3>May The Fourth Be With You!</h3>
243244
<h3>Celebrate the bank holiday, 10th June, Day of Portugal, Portuguese Communities and Camões!!</h3>

src/robotide/editor/contentassist.py

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -263,38 +263,39 @@ def on_focus_lost(self, event, set_value=True):
263263
event.Skip()
264264
if not self._popup.is_shown():
265265
return
266-
if self.gherkin_prefix:
267-
value = self.gherkin_prefix + self._popup.get_value() or self.GetValue()
268-
else:
269-
value = self._popup.get_value() or self.GetValue()
266+
value = self._get_popup_suggestion()
270267
if set_value and value:
271268
self.SetValue(value)
272269
self.SetInsertionPoint(len(value)) # DEBUG was self.Value
273270
else:
271+
# print(f"DEBUG: contentassist.py ContentAssistTextCtrlBase on_focus_lost CALL CLEAR {value}")
274272
self.Clear()
275273
self.hide()
276274

277-
def fill_suggestion(self):
275+
def _get_popup_suggestion(self, in_value=None):
278276
initial_value = self.GetValue()
279-
popup_value = self._popup.get_value()
280-
# print(f"DEBUG: contentassist.py ContentAssistTextCtrlBase fill_suggestion initial_value={initial_value} \n"
281-
# f"popup_value={popup_value}")
282-
if popup_value.lower() in initial_value.lower():
277+
if not in_value:
278+
popup_value = self._popup.get_value()
279+
else:
280+
popup_value = in_value
281+
if popup_value and popup_value.lower() in initial_value.lower():
283282
initial_value = initial_value.replace(initial_value, '')
284283
parts = initial_value.split()
285284
for p in parts:
286-
if popup_value.lower().startswith(p.strip('}])').lower()):
285+
if popup_value and popup_value.lower().startswith(p.strip('}])').lower()):
287286
idx = initial_value.index(p)
288287
initial_value = initial_value[:idx]
289-
# print(f"DEBUG: contentassist.py ContentAssistTextCtrlBase fill_suggestion FOUND p={p} "
290-
# f"new initial_value={initial_value}")
291288
break
292289
if self.gherkin_prefix:
293-
initial_value = initial_value.replace(self.gherkin_prefix,'') # Should be left replace
290+
initial_value = initial_value.replace(self.gherkin_prefix, '') # Should be left replace
294291
value = self.gherkin_prefix + initial_value + popup_value # or self.GetValue()
295292
else:
296293
value = initial_value + popup_value # or self.GetValue()
297-
print(f"DEBUG: contentassist.py ContentAssistTextCtrlBase fill_suggestion writting value={value}")
294+
return value
295+
296+
def fill_suggestion(self, value=None):
297+
value = self._get_popup_suggestion(value)
298+
# print(f"DEBUG: contentassist.py ContentAssistTextCtrlBase fill_suggestion writting value={value}")
298299
if value:
299300
wrapper_view = self.GetParent().GetParent()
300301
if hasattr(wrapper_view, 'open_cell_editor'):
@@ -621,15 +622,14 @@ def select_and_scroll(self, key_code):
621622
pos = self._selection + 14 if count - self._selection > 14 else count - 1
622623
elif key_code == wx.WXK_PAGEUP:
623624
pos = self._selection - 14 if self._selection > 14 else 0
624-
self._select_and_scroll(pos)
625+
return self._select_and_scroll(pos)
625626

626627
def _select_and_scroll(self, selection):
627628
self._selection = selection
628629
self._list.Select(self._selection)
629630
self._list.EnsureVisible(self._selection)
630631
value = self.get_value()
631-
if value:
632-
self._parent.SetValue(value)
632+
return value
633633

634634
def dismiss(self):
635635
if not self._list.HasFocus():

src/robotide/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,4 @@
1515
#
1616
# Automatically generated by `tasks.py`.
1717

18-
VERSION = 'v2.2dev25'
18+
VERSION = 'v2.2dev26'

utest/editor/test_z_kweditor_plugin.py

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -248,16 +248,16 @@ def setUp(self):
248248
self._registered_editors = {}
249249
self.creator = EditorCreator(self._register)
250250
self.creator.register_editors()
251-
251+
"""
252252
for ridx, rdata in enumerate(DATA):
253253
for cidx, cdata in enumerate(rdata):
254254
self._grid.kweditor.write_cell(ridx, cidx, cdata, update_history=False)
255-
255+
"""
256256
# Uncomment next line (and MainLoop in tests) if you want to see the app
257-
self.frame.Show()
257+
# self.frame.Show()
258258
self.SHOWING = True
259259
self.frame.Center()
260-
wx.CallLater(1000, self.app.MainLoop)
260+
# wx.CallLater(1000, self.app.MainLoop)
261261

262262
def _register(self, iclass, eclass):
263263
self._registered_editors[iclass] = eclass
@@ -294,6 +294,11 @@ def tearDown(self):
294294
if os.path.exists(DATADIR):
295295
shutil.rmtree(DATADIR, ignore_errors=True)
296296

297+
def setup_data(self):
298+
for ridx, rdata in enumerate(DATA):
299+
for cidx, cdata in enumerate(rdata):
300+
self._grid.kweditor.write_cell(ridx, cidx, cdata, update_history=False)
301+
297302
"""
298303
def test_enable(self):
299304
self.plugin.enable()
@@ -315,6 +320,8 @@ def test_disable(self):
315320
"""
316321

317322
def test_show(self):
323+
self.setup_data()
324+
self.frame.Show()
318325
# show = self.frame.Children
319326
# print(f"DEBUG: test_show is children={[n.Name for n in show]}")
320327
# tabs = self._grid.kweditor.GetParent().GetName()
@@ -323,10 +330,12 @@ def test_show(self):
323330
show = self._grid.kweditor.has_focus()
324331
assert show # is not None
325332
# Uncomment next lines if you want to see the app
326-
# wx.CallLater(5000, self.app.ExitMainLoop)
333+
wx.CallLater(5000, self.app.ExitMainLoop)
327334
# self.app.MainLoop()
328335

329336
def test_on_comment_cells(self):
337+
self.setup_data()
338+
self.frame.Show()
330339
# self.creator.editor_for(self.app.plugin, self._panel, self.frame.tree)
331340
self._grid.kweditor.SelectBlock(2, 2, 2, 2)
332341
sel = self._grid.kweditor.selection
@@ -342,6 +351,8 @@ def test_on_comment_cells(self):
342351
""" Clipboard tests moved from test_grid.py to here """
343352
@pytest.mark.skip()
344353
def test_copy_one_cell(self):
354+
self.setup_data()
355+
self.frame.Show()
345356
print("")
346357
for row in range(3):
347358
text = f"{row}: "
@@ -363,6 +374,8 @@ def test_copy_row(self):
363374

364375
@pytest.mark.skip()
365376
def test_copy_block(self):
377+
self.setup_data()
378+
self.frame.Show()
366379
self._copy_block_and_verify((0, 0, 2, 2), DATA)
367380
# Uncomment next lines if you want to see the app
368381
# wx.CallLater(5000, self.app.ExitMainLoop)
@@ -376,22 +389,28 @@ def _copy_block_and_verify(self, block, exp_content):
376389
self._verify_grid_content(DATA)
377390

378391
def test_cut_one_cell(self):
392+
self.setup_data()
393+
self.frame.Show()
379394
self._cut_block_and_verify((0, 0, 0, 0), [['kw1']],
380395
[['', '', '']] + DATA[1:])
381396
# Uncomment next lines if you want to see the app
382397
# wx.CallLater(5000, self.app.ExitMainLoop)
383398
# self.app.MainLoop()
384399

385400
def test_cut_row(self):
401+
self.setup_data()
402+
self.frame.Show()
386403
self._cut_block_and_verify((2, 0, 2, 2), [DATA[2]], DATA[:2])
387404
# Uncomment next lines if you want to see the app
388405
# wx.CallLater(5000, self.app.ExitMainLoop)
389406
# self.app.MainLoop()
390407

391408
def test_cut_block(self):
409+
self.setup_data()
410+
self.frame.Show()
392411
self._cut_block_and_verify((0, 0, 2, 2), DATA, [])
393412
# Uncomment next lines if you want to see the app
394-
# wx.CallLater(5000, self.app.ExitMainLoop)
413+
wx.CallLater(5000, self.app.ExitMainLoop)
395414
# self.app.MainLoop()
396415

397416
def _cut_block_and_verify(self, block, exp_clipboard, exp_grid):
@@ -401,6 +420,8 @@ def _cut_block_and_verify(self, block, exp_clipboard, exp_grid):
401420
self._verify_grid_content(exp_grid)
402421

403422
def test_undo_with_cut(self):
423+
self.setup_data()
424+
self.frame.Show()
404425
self._cut_block((0, 0, 0, 0))
405426
self._grid.kweditor.undo()
406427
self._verify_grid_content(DATA)
@@ -418,6 +439,8 @@ def test_undo_with_cut(self):
418439
# self.app.MainLoop()
419440

420441
def test_multiple_levels_of_undo(self):
442+
self.setup_data()
443+
self.frame.Show()
421444
self._cut_block((0, 0, 0, 0))
422445
self._cut_block((2, 0, 2, 2))
423446
# We have problems here. We need undo for each cell removed
@@ -436,6 +459,8 @@ def _cut_block(self, block):
436459
self._grid.kweditor.cut()
437460

438461
def test_paste_one_cell(self):
462+
self.setup_data()
463+
self.frame.Show()
439464
self._copy_and_paste_block((1, 0, 1, 0), (3, 0, 3, 0), DATA + [['kw2']])
440465
# These tests are not independent
441466
self._copy_and_paste_block((1, 0, 1, 0), (0, 3, 0, 3),
@@ -445,19 +470,25 @@ def test_paste_one_cell(self):
445470
# self.app.MainLoop()
446471

447472
def test_paste_row(self):
473+
self.setup_data()
474+
self.frame.Show()
448475
self._copy_and_paste_block((2, 0, 2, 2), (3, 1, 3, 1), DATA + [[''] + DATA[2]])
449476
# Uncomment next lines if you want to see the app
450477
# wx.CallLater(5000, self.app.ExitMainLoop)
451478
# self.app.MainLoop()
452479

453480
def test_paste_block(self):
481+
self.setup_data()
482+
self.frame.Show()
454483
self._copy_and_paste_block((0, 0, 2, 2), (4, 0, 4, 0), DATA + [['']] + DATA)
455484
# Uncomment next lines if you want to see the app
456485
# wx.CallLater(5000, self.app.ExitMainLoop)
457486
# self.app.MainLoop()
458487

459488
# @pytest.mark.skip()
460489
def test_paste_over(self):
490+
self.setup_data()
491+
self.frame.Show()
461492
self._copy_and_paste_block((1, 0, 1, 1), (0, 0, 0, 0), [DATA[1]] + DATA[1:])
462493
# Uncomment next lines if you want to see the app
463494
# wx.CallLater(5000, self.app.ExitMainLoop)
@@ -480,6 +511,8 @@ def _verify_grid_content(self, data):
480511
assert value == ''
481512

482513
def test_simple_undo(self):
514+
self.setup_data()
515+
self.frame.Show()
483516
self._grid.kweditor.SelectBlock(*(0, 0, 0, 0))
484517
self._grid.kweditor.cut()
485518
self._grid.kweditor.undo()
@@ -490,7 +523,8 @@ def test_simple_undo(self):
490523

491524
# @pytest.mark.skip()
492525
def test_contentassist_dialog(self):
493-
suggestions = SuggestionSource(None, self.app.project.controller)
526+
suggestions = SuggestionSource(None, self.test_case)
527+
suggestions.update_from_local(['No Operation', 'Log Many', 'Log', '${CURDIR}'], 'en')
494528
dlg = ContentAssistPopup(self._grid.kweditor, suggestions)
495529
dlg.show(600, 400, 20)
496530
result = dlg.content_assist_for('Log Many')
@@ -500,6 +534,10 @@ def test_contentassist_dialog(self):
500534
dlg._move_x_where_room(800)
501535
dlg._move_y_where_room(400, 20)
502536
# dlg.reset()
537+
value = dlg.content_assist_value('${CUR')
538+
dlg.select_and_scroll(wx.WXK_DOWN)
539+
dlg.dismiss()
540+
dlg.hide()
503541
# wx.CallLater(4000, dlg.hide)
504542
# Uncomment next lines if you want to see the app
505543
# wx.CallLater(5000, self.app.ExitMainLoop)

0 commit comments

Comments
 (0)