Skip to content

Commit 6ab4a42

Browse files
committed
oweditdomain: Add back merge selected items as a separate action
1 parent a813a04 commit 6ab4a42

File tree

1 file changed

+92
-8
lines changed

1 file changed

+92
-8
lines changed

Orange/widgets/data/oweditdomain.py

Lines changed: 92 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,13 @@
2323
QToolButton, QLineEdit, QAction, QActionGroup, QGroupBox,
2424
QStyledItemDelegate, QStyleOptionViewItem, QStyle, QSizePolicy, QToolTip,
2525
QDialogButtonBox, QPushButton, QCheckBox, QComboBox, QStackedLayout,
26-
QDialog, QRadioButton, QGridLayout, QLabel, QSpinBox, QDoubleSpinBox)
26+
QDialog, QRadioButton, QGridLayout, QLabel, QSpinBox, QDoubleSpinBox,
27+
QShortcut
28+
)
2729
from AnyQt.QtGui import QStandardItemModel, QStandardItem, QKeySequence, QIcon
2830
from AnyQt.QtCore import (
29-
Qt, QEvent, QSize, QModelIndex, QAbstractItemModel, QPersistentModelIndex
31+
Qt, QEvent, QSize, QModelIndex, QAbstractItemModel, QPersistentModelIndex,
32+
QRect
3033
)
3134
from AnyQt.QtCore import pyqtSignal as Signal, pyqtSlot as Slot
3235

@@ -1133,16 +1136,25 @@ def __init__(self, *args, **kwargs):
11331136
shortcut=QKeySequence(QKeySequence.Delete),
11341137
shortcutContext=Qt.WidgetShortcut,
11351138
)
1136-
self.merge_items = QAction(
1137-
"M", group,
1138-
objectName="action-merge-item",
1139+
self.merge_selected_items = QAction(
1140+
"=", group,
1141+
objectName="action-merge-selected-items",
11391142
toolTip="Merge selected items.",
11401143
shortcut=QKeySequence(Qt.ControlModifier | Qt.Key_Equal),
1144+
shortcutContext=Qt.WidgetShortcut,
1145+
enabled=False,
1146+
)
1147+
self.merge_items = QAction(
1148+
"ƒM", group,
1149+
objectName="action-activate-merge-dialog",
1150+
toolTip="Merge infrequent items.",
1151+
shortcut=QKeySequence(Qt.ControlModifier | Qt.MetaModifier | Qt.Key_Equal),
11411152
shortcutContext=Qt.WidgetShortcut
11421153
)
11431154

11441155
self.add_new_item.triggered.connect(self._add_category)
11451156
self.remove_item.triggered.connect(self._remove_category)
1157+
self.merge_selected_items.triggered.connect(self._merge_selected_categories)
11461158
self.merge_items.triggered.connect(self._merge_categories)
11471159

11481160
button1 = FixedSizeButton(
@@ -1162,18 +1174,27 @@ def __init__(self, *args, **kwargs):
11621174
accessibleName="Remove"
11631175
)
11641176
button5 = FixedSizeButton(
1177+
self, defaultAction=self.merge_selected_items,
1178+
accessibleName="Merge selected items"
1179+
)
1180+
button6 = FixedSizeButton(
11651181
self, defaultAction=self.merge_items,
1166-
accessibleName="Merge",
1182+
accessibleName="Merge infrequent",
11671183
)
1168-
self.values_edit.addActions([self.move_value_up, self.move_value_down,
1169-
self.add_new_item, self.remove_item])
1184+
1185+
self.values_edit.addActions([
1186+
self.move_value_up, self.move_value_down,
1187+
self.add_new_item, self.remove_item, self.merge_selected_items
1188+
])
11701189
hlayout.addWidget(button1)
11711190
hlayout.addWidget(button2)
11721191
hlayout.addSpacing(3)
11731192
hlayout.addWidget(button3)
11741193
hlayout.addWidget(button4)
11751194
hlayout.addSpacing(3)
11761195
hlayout.addWidget(button5)
1196+
hlayout.addWidget(button6)
1197+
11771198
hlayout.addStretch(10)
11781199
vlayout.addLayout(hlayout)
11791200

@@ -1184,6 +1205,8 @@ def __init__(self, *args, **kwargs):
11841205
QWidget.setTabOrder(button1, button2)
11851206
QWidget.setTabOrder(button2, button3)
11861207
QWidget.setTabOrder(button3, button4)
1208+
QWidget.setTabOrder(button4, button5)
1209+
QWidget.setTabOrder(button5, button6)
11871210

11881211
def set_data(self, var, transform=()):
11891212
raise NotImplementedError
@@ -1332,6 +1355,7 @@ def on_value_selection_changed(self):
13321355
len(rows) > 1 and \
13331356
not any(index.data(EditStateRole) != ItemEditState.NoState
13341357
for index in rows)
1358+
self.merge_selected_items.setEnabled(enable_merge)
13351359

13361360
if len(rows) == 1:
13371361
i = rows[0].row()
@@ -1455,6 +1479,66 @@ def complete_merge(text, merge_attributes):
14551479
dlg.get_merged_value_name(), dlg.get_merge_attributes()
14561480
)
14571481

1482+
def _merge_selected_categories(self):
1483+
"""
1484+
Merge selected categories into one.
1485+
1486+
Popup an editable combo box for selection/edit of a new value.
1487+
"""
1488+
view = self.values_edit
1489+
model = view.model() # type: QAbstractItemModel
1490+
rows = view.selectedIndexes() # type: List[QModelIndex]
1491+
if not len(rows) >= 2:
1492+
return # pragma: no cover
1493+
first_row = rows[0]
1494+
1495+
def mapRectTo(widget, parent, rect):
1496+
# type: (QWidget, QWidget, QRect) -> QRect
1497+
return QRect(
1498+
widget.mapTo(parent, rect.topLeft()),
1499+
rect.size(),
1500+
)
1501+
1502+
def mapRectToGlobal(widget, rect):
1503+
# type: (QWidget, QRect) -> QRect
1504+
return QRect(
1505+
widget.mapToGlobal(rect.topLeft()),
1506+
rect.size(),
1507+
)
1508+
view.scrollTo(first_row)
1509+
vport = view.viewport()
1510+
vrect = view.visualRect(first_row)
1511+
vrect = mapRectTo(vport, view, vrect)
1512+
vrect = vrect.intersected(vport.geometry())
1513+
vrect = mapRectToGlobal(vport, vrect)
1514+
1515+
cb = QComboBox(editable=True, insertPolicy=QComboBox.InsertAtBottom)
1516+
cb.setAttribute(Qt.WA_DeleteOnClose)
1517+
sh = QShortcut(QKeySequence(QKeySequence.Cancel), cb)
1518+
sh.activated.connect(cb.close)
1519+
cb.setParent(self, Qt.Popup)
1520+
cb.move(vrect.topLeft())
1521+
1522+
cb.addItems(
1523+
list(unique(str(row.data(Qt.EditRole)) for row in rows)))
1524+
prows = [QPersistentModelIndex(row) for row in rows]
1525+
1526+
def complete_merge(text):
1527+
# write the new text for edit role in all rows
1528+
with disconnected(model.dataChanged, self.on_values_changed):
1529+
for prow in prows:
1530+
if prow.isValid():
1531+
model.setData(QModelIndex(prow), text, Qt.EditRole)
1532+
cb.close()
1533+
self.variable_changed.emit()
1534+
1535+
cb.activated[str].connect(complete_merge)
1536+
size = cb.sizeHint().expandedTo(vrect.size())
1537+
cb.resize(size)
1538+
cb.show()
1539+
cb.raise_()
1540+
cb.setFocus(Qt.PopupFocusReason)
1541+
14581542

14591543
class ContinuousVariableEditor(VariableEditor):
14601544
# TODO: enable editing of display format...

0 commit comments

Comments
 (0)