Skip to content

Commit f370866

Browse files
authored
Merge pull request #1468 from kernc/mergedata-settings
OWMergeData: replace list views with combos, save settings
2 parents 9e9c386 + f90f104 commit f370866

File tree

2 files changed

+63
-67
lines changed

2 files changed

+63
-67
lines changed

Orange/widgets/data/owmergedata.py

Lines changed: 62 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
11
import math
22
import itertools
3+
4+
from PyQt4.QtCore import Qt
35
from collections import defaultdict
46

57
from PyQt4 import QtGui
68
import numpy
79

810
import Orange
9-
from Orange.widgets import widget
10-
from Orange.widgets import gui
11+
from Orange.widgets import widget, gui, settings
1112
from Orange.widgets.utils import itemmodels
1213
from Orange.widgets.utils.sql import check_sql_input
1314

1415

15-
INSTANCEID = "Same source"
16-
INDEX = "Index"
16+
INSTANCEID = "Source position (index)"
17+
INDEX = "Position (index)"
1718

1819
class OWMergeData(widget.OWWidget):
1920
name = "Merge Data"
@@ -26,6 +27,9 @@ class OWMergeData(widget.OWWidget):
2627
outputs = [("Merged Data A+B", Orange.data.Table, ),
2728
("Merged Data B+A", Orange.data.Table, )]
2829

30+
attr_a = settings.Setting('', schema_only=True)
31+
attr_b = settings.Setting('', schema_only=True)
32+
2933
want_main_area = False
3034

3135
def __init__(self):
@@ -45,30 +49,24 @@ def __init__(self):
4549
# attribute A selection
4650
boxAttrA = gui.vBox(self, self.tr("Attribute A"), addToLayout=False)
4751
grid.addWidget(boxAttrA, 0, 0)
48-
self.attrViewA = QtGui.QListView(
49-
selectionMode=QtGui.QListView.SingleSelection
50-
)
5152

53+
self.attrViewA = gui.comboBox(boxAttrA, self, 'attr_a',
54+
orientation=Qt.Horizontal,
55+
sendSelectedValue=True,
56+
callback=self._invalidate)
5257
self.attrModelA = itemmodels.VariableListModel()
5358
self.attrViewA.setModel(self.attrModelA)
54-
self.attrViewA.selectionModel().selectionChanged.connect(
55-
self._selectedAttrAChanged)
56-
57-
boxAttrA.layout().addWidget(self.attrViewA)
5859

5960
# attribute B selection
6061
boxAttrB = gui.vBox(self, self.tr("Attribute B"), addToLayout=False)
6162
grid.addWidget(boxAttrB, 0, 1)
62-
self.attrViewB = QtGui.QListView(
63-
selectionMode=QtGui.QListView.SingleSelection
64-
)
6563

64+
self.attrViewB = gui.comboBox(boxAttrB, self, 'attr_b',
65+
orientation=Qt.Horizontal,
66+
sendSelectedValue=True,
67+
callback=self._invalidate)
6668
self.attrModelB = itemmodels.VariableListModel()
6769
self.attrViewB.setModel(self.attrModelB)
68-
self.attrViewB.selectionModel().selectionChanged.connect(
69-
self._selectedAttrBChanged)
70-
71-
boxAttrB.layout().addWidget(self.attrViewB)
7270

7371
# info A
7472
boxDataA = gui.vBox(self, self.tr("Data A Input"), addToLayout=False)
@@ -80,36 +78,43 @@ def __init__(self):
8078
grid.addWidget(boxDataB, 1, 1)
8179
self.infoBoxDataB = gui.widgetLabel(boxDataB, self.dataInfoText(None))
8280

83-
gui.rubber(self.buttonsArea)
84-
# resize
85-
self.resize(400, 500)
81+
gui.rubber(self)
8682

87-
def setAttrs(self):
88-
add = ()
89-
if self.dataA is not None and self.dataB is not None \
90-
and len(numpy.intersect1d(self.dataA.ids, self.dataB.ids)):
91-
add = (INSTANCEID,)
92-
if self.dataA is not None:
93-
self.attrModelA[:] = add + allvars(self.dataA)
94-
else:
95-
self.attrModelA[:] = []
96-
if self.dataB is not None:
97-
self.attrModelB[:] = add + allvars(self.dataB)
98-
else:
99-
self.attrModelB[:] = []
83+
def _setAttrs(self, model, data, othermodel, otherdata):
84+
model[:] = allvars(data) if data is not None else []
85+
86+
if data is not None and otherdata is not None and \
87+
len(numpy.intersect1d(data.ids, otherdata.ids)):
88+
for model_ in (model, othermodel):
89+
if len(model_) and model_[0] != INSTANCEID:
90+
model_.insert(0, INSTANCEID)
10091

10192
@check_sql_input
10293
def setDataA(self, data):
103-
#self.closeContext()
10494
self.dataA = data
105-
self.setAttrs()
95+
self._setAttrs(self.attrModelA, data, self.attrModelB, self.dataB)
96+
curr_index = -1
97+
if self.attr_a:
98+
curr_index = next((i for i, val in enumerate(self.attrModelA)
99+
if str(val) == self.attr_a), -1)
100+
if curr_index != -1:
101+
self.attrViewA.setCurrentIndex(curr_index)
102+
else:
103+
self.attr_a = INDEX
106104
self.infoBoxDataA.setText(self.dataInfoText(data))
107105

108106
@check_sql_input
109107
def setDataB(self, data):
110-
#self.closeContext()
111108
self.dataB = data
112-
self.setAttrs()
109+
self._setAttrs(self.attrModelB, data, self.attrModelA, self.dataA)
110+
curr_index = -1
111+
if self.attr_b:
112+
curr_index = next((i for i, val in enumerate(self.attrModelB)
113+
if str(val) == self.attr_b), -1)
114+
if curr_index != -1:
115+
self.attrViewB.setCurrentIndex(curr_index)
116+
else:
117+
self.attr_b = INDEX
113118
self.infoBoxDataB.setText(self.dataInfoText(data))
114119

115120
def handleNewSignals(self):
@@ -126,50 +131,40 @@ def dataInfoText(self, data):
126131
attributes = self.tr("%n variable(s)", None, nvariables)
127132
return "\n".join([instances, attributes])
128133

129-
def selectedIndexA(self):
130-
return selected_row(self.attrViewA)
131-
132-
def selectedIndexB(self):
133-
return selected_row(self.attrViewB)
134-
135134
def commit(self):
136-
indexA = self.selectedIndexA()
137-
indexB = self.selectedIndexB()
138135
AB, BA = None, None
139-
if indexA is not None and indexB is not None:
140-
varA = self.attrModelA[indexA]
141-
varB = self.attrModelB[indexB]
136+
if (self.attr_a and self.attr_b and
137+
self.dataA is not None and
138+
self.dataB is not None):
139+
varA = (self.attr_a if self.attr_a in (INDEX, INSTANCEID) else
140+
self.dataA.domain[self.attr_a])
141+
varB = (self.attr_b if self.attr_b in (INDEX, INSTANCEID) else
142+
self.dataB.domain[self.attr_b])
142143
AB = merge(self.dataA, varA, self.dataB, varB)
143144
BA = merge(self.dataB, varB, self.dataA, varA)
144145
self.send("Merged Data A+B", AB)
145146
self.send("Merged Data B+A", BA)
146147

147-
def _selectedAttrAChanged(self, *args):
148-
self._invalidate()
149-
150-
def _selectedAttrBChanged(self, *args):
151-
self._invalidate()
152-
153148
def _invalidate(self):
154149
self.commit()
155150

156151
def send_report(self):
157-
attr_a = self.selectedIndexA()
158-
attr_b = self.selectedIndexB()
152+
attr_a = None
153+
attr_b = None
154+
if self.dataA is not None:
155+
attr_a = self.attr_a
156+
if attr_a in self.dataA.domain:
157+
attr_a = self.dataA.domain[attr_a]
158+
if self.dataB is not None:
159+
attr_b = self.attr_b
160+
if attr_b in self.dataB.domain:
161+
attr_b = self.dataB.domain[attr_b]
159162
self.report_items((
160-
("Attribute A", attr_a and self.attrModelA[attr_a]),
161-
("Attribute B", attr_b and self.attrModelB[attr_b])
163+
("Attribute A", attr_a),
164+
("Attribute B", attr_b),
162165
))
163166

164167

165-
def selected_row(view):
166-
rows = view.selectionModel().selectedRows()
167-
if rows:
168-
return rows[0].row()
169-
else:
170-
return None
171-
172-
173168
def allvars(data):
174169
return (INDEX,) + data.domain.attributes + data.domain.class_vars + data.domain.metas
175170

Orange/widgets/visualize/owvenndiagram.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1068,6 +1068,7 @@ class GraphicsTextEdit(QGraphicsTextItem):
10681068

10691069
def __init__(self, *args, **kwargs):
10701070
super(GraphicsTextEdit, self).__init__(*args, **kwargs)
1071+
self.setCursor(Qt.IBeamCursor)
10711072
self.setTabChangesFocus(True)
10721073
self._edittrigger = GraphicsTextEdit.DoubleClicked
10731074
self._editing = False

0 commit comments

Comments
 (0)