Skip to content

Commit

Permalink
Merge pull request biolab#2761 from kernc/rm-plotutils
Browse files Browse the repository at this point in the history
Remove dead orangeqt code; add gui.listView multiselection handling
  • Loading branch information
janezd authored Dec 8, 2017
2 parents a09c807 + 0831eb1 commit 7e6f9e5
Show file tree
Hide file tree
Showing 68 changed files with 88 additions and 11,684 deletions.
1 change: 0 additions & 1 deletion MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ recursive-include Orange/widgets *.png *.svg *.js *.css *.html
recursive-include Orange/widgets/tests *.tab
recursive-include Orange/widgets/data/tests *.tab
recursive-include Orange/widgets/tests/workflows *.ows
recursive-include Orange/widgets/utils/plot *.fs *.vs *.gs *.obj

recursive-include distribute *.svg *.desktop

Expand Down
63 changes: 37 additions & 26 deletions Orange/widgets/gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@
import warnings
import logging
from types import LambdaType
from collections import defaultdict
from collections import defaultdict, Sequence

import pkg_resources

from AnyQt import QtWidgets, QtCore, QtGui
from AnyQt.QtCore import Qt, QSize, pyqtSignal as Signal
from AnyQt.QtCore import Qt, QSize, QItemSelection, pyqtSignal as Signal
from AnyQt.QtGui import QCursor, QColor
from AnyQt.QtWidgets import (
QApplication, QStyle, QSizePolicy, QWidget, QLabel, QGroupBox, QSlider,
Expand Down Expand Up @@ -1084,7 +1084,7 @@ def listView(widget, master, value=None, model=None, box=None, callback=None,
connectControl(master, value, callback,
view.selectionModel().selectionChanged,
CallFrontListView(view),
CallBackListView(model, master, value))
CallBackListView(model, view, master, value))
misc.setdefault('addSpace', True)
miscellanea(view, bg, widget, **misc)
return view
Expand Down Expand Up @@ -2270,20 +2270,25 @@ def __call__(self, *value):


class CallBackListView(ControlledCallback):
def __init__(self, model, widget, attribute):
def __init__(self, model, view, widget, attribute):
super().__init__(widget, attribute)
self.model = model
self.view = view

# triggered by selectionModel().selectionChanged()
def __call__(self, newSelection, _):
def __call__(self, *_):
# This must be imported locally to avoid circular imports
from Orange.widgets.utils.itemmodels import PyListModel
indexes = newSelection.indexes()
if indexes:
value = newSelection.indexes()[0].row()
values = [i.row()
for i in self.view.selectionModel().selection().indexes()]
if values:
# FIXME: irrespective of PyListModel check, this might/should always
# callback with values!
if isinstance(self.model, PyListModel):
value = self.model[value]
self.acyclic_setattr(value)
values = [self.model[i] for i in values]
if self.view.selectionMode() == self.view.SingleSelection:
values = values[0]
self.acyclic_setattr(values)


class CallBackListBox:
Expand Down Expand Up @@ -2467,22 +2472,28 @@ def action(self, value):


class CallFrontListView(ControlledCallFront):
def action(self, value):
model = self.control.model()
if not isinstance(value, int):
if isinstance(value, str):
search_role = Qt.DisplayRole
elif isinstance(value, Variable):
search_role = TableVariable
else:
search_role = Qt.DisplayRole
value = str(value)
for i in range(model.rowCount()):
if model.data(model.index(i), search_role) == value:
value = i
break
sel_model = self.control.selectionModel()
sel_model.select(model.index(value), sel_model.ClearAndSelect)
def action(self, values):
view = self.control
model = view.model()
sel_model = view.selectionModel()

if not isinstance(values, Sequence):
values = [values]

selection = QItemSelection()
for value in values:
if not isinstance(value, int):
if isinstance(value, Variable):
search_role = TableVariable
else:
search_role = Qt.DisplayRole
value = str(value)
for i in range(model.rowCount()):
if model.data(model.index(i), search_role) == value:
value = i
break
selection.select(model.index(value), model.index(value))
sel_model.select(selection, sel_model.ClearAndSelect)


class CallFrontListBox(ControlledCallFront):
Expand Down
47 changes: 42 additions & 5 deletions Orange/widgets/tests/test_gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,62 @@ def test_checked_extension(self):


class TestListModel(GuiTest):
def test_select(self):
widget = OWWidget()
widget.foo = None
def setUp(self):
self.widget = OWWidget()
self.widget.foo = None
self.attrs = VariableListModel()
view = gui.listView(widget.controlArea, widget, "foo", model=self.attrs)
self.view = gui.listView(
self.widget.controlArea, self.widget, "foo", model=self.attrs)

def test_select_callback(self):
widget = self.widget
view = self.view

self.assertIsNone(widget.foo)

a, b, c = (ContinuousVariable(x) for x in "abc")
self.attrs[:] = [a, b, c]

view.setCurrentIndex(self.attrs.index(0, 0))
self.assertIs(widget.foo, a)
view.setCurrentIndex(self.attrs.index(2, 0))
self.assertIs(widget.foo, c)

view.setSelectionMode(view.MultiSelection)
sel_model = view.selectionModel()
sel_model.clear()
view.setCurrentIndex(self.attrs.index(1, 0))
self.assertEqual(widget.foo, [b])

def test_select_callfront(self):
widget = self.widget
view = self.view

a, b, c = (ContinuousVariable(x) for x in "abc")
self.attrs[:] = [a, b, c]

widget.foo = b
selection = view.selectedIndexes()
self.assertEqual(len(selection), 1)
self.assertEqual(selection[0].row(), 1)

class ComboBoxText(GuiTest):
view.setSelectionMode(view.MultiSelection)
widget.foo = [a, c]
selection = view.selectedIndexes()
self.assertEqual(len(selection), 2)
self.assertEqual({selection[0].row(), selection[1].row()}, {0, 2})

widget.foo = []
selection = view.selectedIndexes()
self.assertEqual(len(selection), 0)

widget.foo = [2, "b"]
selection = view.selectedIndexes()
self.assertEqual(len(selection), 2)
self.assertEqual({selection[0].row(), selection[1].row()}, {1, 2})


class ComboBoxTest(GuiTest):
def test_set_initial_value(self):
widget = OWWidget()
variables = [ContinuousVariable(x) for x in "abc"]
Expand Down
9 changes: 0 additions & 9 deletions Orange/widgets/utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,6 @@ def to_html(str):
getHtmlCompatibleString = to_html


def checksum(x):
if x is None:
return None
try:
return x.checksum()
except:
return float('nan')


def get_variable_values_sorted(variable):
"""
Return a list of sorted values for given attribute, if all its values can be
Expand Down
23 changes: 3 additions & 20 deletions Orange/widgets/utils/plot/__init__.py
Original file line number Diff line number Diff line change
@@ -1,27 +1,10 @@
"""
Plot classes and tools that were once used in Orange widgets
*************************
Plot classes and tools for use in Orange widgets
*************************
The main class of this module is :obj:`.OWPlot`, from which all plots
in visualization widgets should inherit.
This module also contains plot elements, which are normally used by the :obj:`.OWPlot`,
but can also be used directly or subclassed
Due to lack of maintenance (non-functioning), the majority of it has been
stripped in this commit
"""

from .owplotgui import *
from .owpalette import *
from .owconstants import *

try:
from .owcurve import *
from .owpoint import *
from .owlegend import *
from .owaxis import *
from .owplot import *
from .owtools import *
except (ImportError, RuntimeError):
pass
96 changes: 0 additions & 96 deletions Orange/widgets/utils/plot/generator.gs

This file was deleted.

8 changes: 0 additions & 8 deletions Orange/widgets/utils/plot/generator.vs

This file was deleted.

Loading

0 comments on commit 7e6f9e5

Please sign in to comment.