Skip to content

Commit

Permalink
Merge pull request #310 from ales-erjavec/renumbering-on-paste
Browse files Browse the repository at this point in the history
[FIX] schemeedit: Avoid replicated node renumbering on paste
  • Loading branch information
janezd authored Sep 28, 2024
2 parents 054b16a + 75b6d90 commit 35d517f
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 3 deletions.
2 changes: 2 additions & 0 deletions i18n/si/msgs.jaml
Original file line number Diff line number Diff line change
Expand Up @@ -2046,6 +2046,8 @@ document/schemeedit.py:
Cs: false
Co: false
Cn: false
def `remove_copy_number`:
\s+\(\d+\)\s*$: false
def `uniquify`:
{item}-{_}: false
document/suggestions.py:
Expand Down
25 changes: 22 additions & 3 deletions orangecanvas/document/schemeedit.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import io
import logging
import itertools
import re
import sys
import unicodedata
import copy
Expand Down Expand Up @@ -2169,10 +2170,14 @@ def __paste(self, nodedups, linkdups, pos: Optional[QPointF] = None,
return

# find unique names for new nodes
allnames = {node.title for node in scheme.nodes + nodedups}
allnames = {node.title for node in scheme.nodes}

for nodedup in nodedups:
nodedup.title = uniquify(
nodedup.title, allnames, pattern="{item} ({_})", start=1)
remove_copy_number(nodedup.title), allnames,
pattern="{item} ({_})", start=1
)
allnames.add(nodedup.title)

if pos is not None:
# top left of nodedups brect
Expand Down Expand Up @@ -2551,11 +2556,25 @@ def can_insert_node(new_node_desc, original_link):
for input in original_link.sink_node.input_channels())


def remove_copy_number(name):
"""
>>> remove_copy_number("foo (1)")
foo
"""
match = re.search(r"\s+\(\d+\)\s*$", name)
if match:
return name[:match.start()]
return name


def uniquify(item, names, pattern="{item}-{_}", start=0):
# type: (str, Container[str], str, int) -> str
candidates = (pattern.format(item=item, _=i)
for i in itertools.count(start))
candidates = itertools.dropwhile(lambda item: item in names, candidates)
candidates = itertools.dropwhile(
lambda item: item in names,
itertools.chain((item,), candidates)
)
return next(candidates)


Expand Down
10 changes: 10 additions & 0 deletions orangecanvas/document/tests/test_schemeedit.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Tests for scheme document.
"""
import re
import sys
import unittest
from unittest import mock
Expand Down Expand Up @@ -408,6 +409,15 @@ def test_duplicate(self):
a.trigger()
self.assertEqual(len(workflow.nodes), 2 * nnodes)
self.assertEqual(len(workflow.links), 2 * nlinks)
w.selectAll()
a.trigger()
self.assertEqual(len(workflow.nodes), 4 * nnodes)
self.assertEqual(len(workflow.links), 4 * nlinks)
self.assertEqual(len(workflow.nodes),
len(set(n.title for n in workflow.nodes)))
match = re.compile(r"\(\d+\)\s*\(\d+\)")
self.assertFalse(any(match.search(n.title) for n in workflow.nodes),
"Duplicated renumbering ('foo (2) (1)')")

def test_copy_paste(self):
w = self.w
Expand Down

0 comments on commit 35d517f

Please sign in to comment.