2626 QSizePolicy , QAbstractItemView , QComboBox , QFormLayout , QLineEdit ,
2727 QHBoxLayout , QVBoxLayout , QStackedWidget , QStyledItemDelegate ,
2828 QPushButton , QMenu , QListView , QFrame , QLabel )
29- from AnyQt .QtGui import QKeySequence
29+ from AnyQt .QtGui import QKeySequence , QColor
3030from AnyQt .QtCore import Qt , pyqtSignal as Signal , pyqtProperty as Property
3131from orangewidget .utils .combobox import ComboBoxSearch
3232
3333import Orange
34+ from Orange .data .util import get_unique_names
3435from Orange .widgets import gui
3536from Orange .widgets .settings import ContextSetting , DomainContextHandler
3637from Orange .widgets .utils import itemmodels , vartype
5556
5657StringDescriptor = namedtuple ("StringDescriptor" , ["name" , "expression" ])
5758
59+ #warningIcon = gui.createAttributePixmap('!', QColor((202, 0, 32)))
5860
5961def make_variable (descriptor , compute_value ):
6062 if isinstance (descriptor , ContinuousDescriptor ):
@@ -390,6 +392,10 @@ class Error(OWWidget.Error):
390392 more_values_needed = Msg ("Categorical feature {} needs more values." )
391393 invalid_expressions = Msg ("Invalid expressions: {}." )
392394
395+ class Warning (OWWidget .Warning ):
396+ renamed_var = Msg ("Recently added variable has been renamed, "
397+ "to avoid duplicates.\n " )
398+
393399 def __init__ (self ):
394400 super ().__init__ ()
395401 self .data = None
@@ -427,16 +433,8 @@ def unique_name(fmt, reserved):
427433 candidates = (fmt .format (i ) for i in count (1 ))
428434 return next (c for c in candidates if c not in reserved )
429435
430- def reserved_names ():
431- varnames = []
432- if self .data is not None :
433- varnames = [var .name for var in
434- self .data .domain .variables + self .data .domain .metas ]
435- varnames += [desc .name for desc in self .featuremodel ]
436- return set (varnames )
437-
438436 def generate_newname (fmt ):
439- return unique_name (fmt , reserved_names ())
437+ return unique_name (fmt , self . reserved_names ())
440438
441439 menu = QMenu (self .addbutton )
442440 cont = menu .addAction ("Numeric" )
@@ -531,8 +529,18 @@ def _on_selectedVariableChanged(self, selected, *_):
531529
532530 def _on_modified (self ):
533531 if self .currentIndex >= 0 :
532+ self .Warning .clear ()
534533 editor = self .editorstack .currentWidget ()
535- self .featuremodel [self .currentIndex ] = editor .editorData ()
534+ proposed = editor .editorData ().name
535+ unique = get_unique_names (self .reserved_names (self .currentIndex ),
536+ proposed )
537+
538+ feature = editor .editorData ()
539+ if editor .editorData ().name != unique :
540+ self .Warning .renamed_var ()
541+ feature = feature .__class__ (unique , * feature [1 :])
542+
543+ self .featuremodel [self .currentIndex ] = feature
536544 self .descriptors = list (self .featuremodel )
537545
538546 def setDescriptors (self , descriptors ):
@@ -542,6 +550,15 @@ def setDescriptors(self, descriptors):
542550 self .descriptors = descriptors
543551 self .featuremodel [:] = list (self .descriptors )
544552
553+ def reserved_names (self , idx_ = None ):
554+ varnames = []
555+ if self .data is not None :
556+ varnames = [var .name for var in
557+ self .data .domain .variables + self .data .domain .metas ]
558+ varnames += [desc .name for idx , desc in enumerate (self .featuremodel )
559+ if idx != idx_ ]
560+ return set (varnames )
561+
545562 @Inputs .data
546563 @check_sql_input
547564 def setData (self , data = None ):
0 commit comments