Skip to content

Commit

Permalink
OWSelectRows: Connect time in calendar; Add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
aturanjanin committed Jun 17, 2020
1 parent 208632b commit 9a37e9a
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 15 deletions.
33 changes: 23 additions & 10 deletions Orange/widgets/data/owselectrows.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,15 +145,21 @@ def _plural(s):
class CalendarWidgetWithTime(QCalendarWidget):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
timeedit = QDateTimeEdit(displayFormat="hh:mm:ss")
self.timeedit = QDateTimeEdit(displayFormat="hh:mm:ss")
self.timeedit.setTime(self.parent().min_datetime.time())

self._time_layout = sublay = QHBoxLayout()
sublay.setContentsMargins(6, 6, 6, 6)
sublay.addStretch(1)
sublay.addWidget(QLabel("Time: "))
sublay.addWidget(timeedit)
sublay.addWidget(self.timeedit)
sublay.addStretch(1)
self.layout().addLayout(sublay)
self.parent = self.parent()
self.timeedit.dateTimeChanged.connect(self.set_time)

def set_time(self):
self.parent.set_datetime(self.parent.date(), self.timeedit.time())

def minimumSize(self):
return self.sizeHint()
Expand Down Expand Up @@ -533,7 +539,7 @@ def add_numeric(contents):
widget.set_datetime(lc[0])
box.controls = [widget]
box.layout().addWidget(widget)
self._box = []
self._box = box
if oper > 5:
gui.widgetLabel(box, " and ")
widget_ = DateTimeWidget(self, var_idx, datetime_format)
Expand All @@ -548,11 +554,17 @@ def add_numeric(contents):
self.conditions_changed()

def _invalidate_dates(self):
if getattr(self, "_box", None):
widget, widget_ = self._box.controls[0], self._box.controls[1]
widget = self._box.controls[0]
if len(self._box.controls) > 1:
widget_ = self._box.controls[1]
if widget.dateTime() > widget_.dateTime():
widget_.setDateTime(widget.dateTime())
widget_.dateTimeChanged.connect(self.conditions_changed)
if widget.format == (1, 1):
widget._calendarWidget.timeedit.setTime(widget.time())
widget_._calendarWidget.timeedit.setTime(widget_.time())
elif widget.format == (1, 1):
widget._calendarWidget.timeedit.setTime(widget.time())

@Inputs.data
def set_data(self, data):
Expand Down Expand Up @@ -885,13 +897,13 @@ def set_format(self):
str_format = Qt.ISODate
if self.have_date and self.have_time:
self.setDisplayFormat("yyyy-MM-dd hh:mm:ss")
self.setCalendarPopup(True)
self._calendarWidget = CalendarWidgetWithTime(self)
self.setCalendarWidget(self._calendarWidget)
c_format = "%Y-%m-%d %H:%M:%S"
min_datetime, max_datetime = self.find_range(self.column, c_format)
self.min_datetime = QDateTime.fromString(min_datetime, str_format)
self.max_datetime = QDateTime.fromString(max_datetime, str_format)
self.setCalendarPopup(True)
self._calendarWidget = CalendarWidgetWithTime(self)
self.setCalendarWidget(self._calendarWidget)
self.setDateTimeRange(self.min_datetime, self.max_datetime)

elif self.have_date and not self.have_time:
Expand All @@ -909,9 +921,10 @@ def set_format(self):
self.max_datetime = QTime.fromString(max_datetime, str_format)
self.setTimeRange(self.min_datetime, self.max_datetime)

def set_datetime(self, datetime):
def set_datetime(self, datetime, time=None):
if self.have_date and self.have_time:
self.setDateTime(datetime if datetime else self.min_datetime)
self.setDateTime(QDateTime(datetime, time)) if datetime and time \
else self.setDateTime(datetime if datetime else self.min_datetime)
elif self.have_date and not self.have_time:
self.setDate(datetime if datetime else self.min_datetime)
elif not self.have_date and self.have_time:
Expand Down
52 changes: 47 additions & 5 deletions Orange/widgets/data/tests/test_owselectrows.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import time
from unittest.mock import Mock, patch

from AnyQt.QtCore import QLocale, Qt
from AnyQt.QtCore import QLocale, Qt, QDate
from AnyQt.QtTest import QTest
from AnyQt.QtWidgets import QLineEdit, QComboBox

Expand All @@ -15,7 +15,7 @@
from Orange.preprocess import discretize
from Orange.widgets.data import owselectrows
from Orange.widgets.data.owselectrows import (
OWSelectRows, FilterDiscreteType, SelectRowsContextHandler)
OWSelectRows, FilterDiscreteType, SelectRowsContextHandler, DateTimeWidget)
from Orange.widgets.tests.base import WidgetTest, datasets

from Orange.data.filter import FilterContinuous, FilterString
Expand Down Expand Up @@ -430,6 +430,42 @@ def test_keep_operator(self):
self.assertEqual(
self.widget.cond_list.cellWidget(0, 1).currentText(), "is")

def test_calendar_dates(self):
data = Table(test_filename("datasets/cyber-security-breaches.tab"))
self.send_signal(self.widget.Inputs.data, data)
simulate.combobox_activate_item(
self.widget.cond_list.cellWidget(0, 0), "Date_Posted_or_Updated",
delay=0)
value_combo = self.widget.cond_list.cellWidget(0, 2).children()[1]
self.assertIsInstance(value_combo, DateTimeWidget)

# first displayed date is min date
self.assertEqual(value_combo.date(), QDate(2014, 1, 23))
self.assertEqual(len(self.get_output("Matching Data")), 691)
self.widget.remove_all_button.click()
self.enterFilter("Date_Posted_or_Updated", "is below",
QDate(2014, 4, 17))
self.assertEqual(len(self.get_output("Matching Data")), 840)
self.enterFilter("Date_Posted_or_Updated", "is greater than",
QDate(2014, 6, 30))
self.assertIsNone(self.get_output("Matching Data"))
self.widget.remove_all_button.click()
# date is in range min-max date
self.enterFilter("Date_Posted_or_Updated", "equals", QDate(2013, 1, 1))
self.assertEqual(self.widget.conditions[0][2][0], QDate(2014, 1, 23))
self.enterFilter("Date_Posted_or_Updated", "equals", QDate(2015, 1, 1))
self.assertEqual(self.widget.conditions[1][2][0], QDate(2014, 6, 30))
self.widget.remove_all_button.click()
# no date crossings
self.enterFilter("Date_Posted_or_Updated", "is between",
QDate(2014, 4, 17), QDate(2014, 1, 23))
self.assertEqual(self.widget.conditions[0][2],
(QDate(2014, 4, 17), QDate(2014, 4, 17)))
self.widget.remove_all_button.click()
self.enterFilter("Date_Posted_or_Updated", "is between",
QDate(2014, 4, 17), QDate(2014, 4, 30))
self.assertEqual(len(self.get_output("Matching Data")), 58)

@patch.object(owselectrows.QMessageBox, "question",
return_value=owselectrows.QMessageBox.Ok)
def test_add_all(self, msgbox):
Expand Down Expand Up @@ -551,9 +587,13 @@ def __get_value_widgets(self, row):
if isinstance(value_inputs, QComboBox):
value_inputs = [value_inputs]
else:
value_inputs = [
w for w in value_inputs.children()
if isinstance(w, QLineEdit)]
value_input = []
for widget in value_inputs.children():
if isinstance(widget, QLineEdit):
value_input.append(widget)
elif isinstance(widget, DateTimeWidget):
value_input.append(widget)
return value_input
return value_inputs

@staticmethod
Expand All @@ -564,5 +604,7 @@ def __set_value(widget, value):
QTest.keyClick(widget, Qt.Key_Enter)
elif isinstance(widget, QComboBox):
simulate.combobox_activate_item(widget, value)
elif isinstance(widget, DateTimeWidget):
widget.setDate(value)
else:
raise ValueError("Unsupported widget {}".format(widget))

0 comments on commit 9a37e9a

Please sign in to comment.