Skip to content

Commit

Permalink
OWSelectRows: Add calendar popup for TimeVariables
Browse files Browse the repository at this point in the history
  • Loading branch information
aturanjanin committed May 21, 2020
1 parent 56a106f commit 949cd18
Showing 1 changed file with 53 additions and 16 deletions.
69 changes: 53 additions & 16 deletions Orange/widgets/data/owselectrows.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
import enum
from collections import OrderedDict
from datetime import datetime
from itertools import chain

import numpy as np

from AnyQt.QtWidgets import (
QWidget, QTableWidget, QHeaderView, QComboBox, QLineEdit, QToolButton,
QMessageBox, QMenu, QListView, QGridLayout, QPushButton, QSizePolicy,
QLabel, QHBoxLayout)
QLabel, QHBoxLayout, QDateEdit)
from AnyQt.QtGui import (
QDoubleValidator, QRegExpValidator, QStandardItemModel, QStandardItem,
QFontMetrics, QPalette
)
from AnyQt.QtCore import Qt, QPoint, QRegExp, QPersistentModelIndex, QLocale
QDoubleValidator, QStandardItemModel, QStandardItem, QFontMetrics, QPalette)
from AnyQt.QtCore import Qt, QPoint, QPersistentModelIndex, QLocale, QDate
from orangewidget.utils.combobox import ComboBoxSearch

from Orange.data import (
Expand Down Expand Up @@ -68,7 +67,7 @@ def decode_setting(self, setting, value, domain=None):
op, values = condition[-2:]

var = attr in domain and domain[attr]
if var and var.is_continuous and not isinstance(var, TimeVariable):
if var and var.is_continuous:
values = [QLocale().toString(float(i), 'f') for i in values]
value[i] = (attr, op, values)
return value
Expand Down Expand Up @@ -362,8 +361,13 @@ def set_new_operators(self, attr_combo, adding_all,

@staticmethod
def _get_lineedit_contents(box):
return [child.text() for child in getattr(box, "controls", [box])
if isinstance(child, QLineEdit)]
contents = []
for child in getattr(box, "controls", [box]):
if isinstance(child, QLineEdit):
contents.append(child.text())
elif isinstance(child, CalendarPopup):
contents.append(child.date())
return contents

@staticmethod
def _get_value_contents(box):
Expand All @@ -384,6 +388,8 @@ def _get_value_contents(box):
names.append(item.text())
child.desc_text = ', '.join(names)
child.set_text()
elif isinstance(child, CalendarPopup):
cont.append(child.date())
elif isinstance(child, QLabel) or child is None:
pass
else:
Expand Down Expand Up @@ -419,10 +425,10 @@ def add_numeric(contents):
le.setValidator(OWSelectRows.QDoubleValidatorEmpty())
return le

def add_datetime(contents):
le = add_textual(contents)
le.setValidator(QRegExpValidator(QRegExp(TimeVariable.REGEX)))
return le
def add_datetime(calendar, contents):
calendar.setDate(contents) if contents else calendar.set_date(var_idx)
calendar.dateChanged.connect(self.conditions_changed)
return calendar

box = self.cond_list.cellWidget(oper_combo.row, 2)
lc = ["", ""]
Expand All @@ -433,6 +439,7 @@ def add_datetime(contents):
var = None
else:
var = self.data.domain[attr_name]
var_idx = self.data.domain.index(attr_name)
vtype = vartype(var)
if selected_values is not None:
lc = list(selected_values) + ["", ""]
Expand Down Expand Up @@ -465,17 +472,25 @@ def add_datetime(contents):
box = gui.hBox(self, addToLayout=False)
box.var_type = vtype
self.cond_list.setCellWidget(oper_combo.row, 2, box)
if vtype in (2, 4): # continuous, time:
validator = add_datetime if isinstance(var, TimeVariable) else add_numeric
box.controls = [validator(lc[0])]
if vtype == 2: # continuous:
box.controls = [add_numeric(lc[0])]
if oper > 5:
gui.widgetLabel(box, " and ")
box.controls.append(validator(lc[1]))
box.controls.append(add_numeric(lc[1]))
elif vtype == 3: # string:
box.controls = [add_textual(lc[0])]
if oper in [6, 7]:
gui.widgetLabel(box, " and ")
box.controls.append(add_textual(lc[1]))
elif vtype == 4: # time:
calendar = CalendarPopup(self)
box.controls = [add_datetime(calendar, lc[0])]
box.layout().addWidget(calendar)
if oper > 5:
gui.widgetLabel(box, " and ")
calendar_ = CalendarPopup(self)
box.layout().addWidget(calendar_)
box.controls.append(add_datetime(calendar_, lc[1]))
else:
box.controls = []
if not adding_all:
Expand Down Expand Up @@ -542,6 +557,7 @@ def _values_to_floats(self, attr, values):
if not all(values):
return None
if isinstance(attr, TimeVariable):
values = (value.toString("yyyy-MM-dd") for value in values)
parse = lambda x: (attr.parse(x), True)
else:
parse = QLocale().toDouble
Expand Down Expand Up @@ -794,5 +810,26 @@ def resizeEvent(self, QResizeEvent):
self.set_text()


class CalendarPopup(QDateEdit):
def __init__(self, parent):
QDateEdit.__init__(self, parent)

self.data = parent.data
self.setDateRange(QDate(1900, 1, 1), QDate(2100, 12, 31))
self.setDisplayFormat("yyyy-MM-dd")
self.setCalendarPopup(True)
self.setSizePolicy(
QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
)

def set_date(self, col_idx):
# set the earliest date of the column
column = self.data[:, col_idx]
if not column.has_missing():
date_list = [date for dates in list(column) for date in dates]
date = datetime.fromtimestamp(min(date_list)).strftime("%Y-%m-%d")
self.setDate(QDate.fromString(date, format=Qt.ISODate))


if __name__ == "__main__": # pragma: no cover
WidgetPreview(OWSelectRows).run(Table("heart_disease"))

0 comments on commit 949cd18

Please sign in to comment.