Skip to content

Commit f5404fe

Browse files
committed
Edit Domain: add custom format
1 parent 910d625 commit f5404fe

File tree

1 file changed

+58
-3
lines changed

1 file changed

+58
-3
lines changed

Orange/widgets/data/oweditdomain.py

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
77
"""
88
from __future__ import annotations
9+
10+
import re
911
import warnings
1012
from xml.sax.saxutils import escape
1113
from itertools import zip_longest, repeat, chain, groupby
@@ -64,7 +66,31 @@
6466
H = TypeVar("H", bound=Hashable) # pylint: disable=invalid-name
6567

6668
MAX_HINTS = 1000
67-
69+
CUSTOM_TOOLTIP = """
70+
%a Weekday abbreviated name
71+
%A Weekday full name
72+
%w Weekday as a number (0=Sunday, 6=Saturday)
73+
%d Day of the month (01-31)
74+
%b Month abbreviated name
75+
%B Month full name
76+
%m Month as a number (01-12)
77+
%y Year without century (00-99)
78+
%Y Year with century
79+
%H Hour (00-23)
80+
%I Hour (01-12)
81+
%p AM or PM
82+
%M Minute (00-59)
83+
%S Second (00-59)
84+
%f Microsecond (000000-999999)
85+
%z UTC offset in the form +HHMM or -HHMM
86+
%Z Time zone name
87+
%j Day of the year (001-366)
88+
%U Week number of the year (Sunday as the first day of the week)
89+
%W Week number of the year (Monday as the first day of the week)
90+
%c Locale's appropriate date and time representation
91+
%x Locale's appropriate date representation
92+
%X Locale's appropriate time representation
93+
"""
6894

6995
class _DataType:
7096
def __eq__(self, other):
@@ -1523,6 +1549,7 @@ class ContinuousVariableEditor(VariableEditor):
15231549

15241550

15251551
class TimeVariableEditor(VariableEditor):
1552+
CUSTOM_FORMAT_LABEL = "Custom format"
15261553
def __init__(self, parent=None, **kwargs):
15271554
super().__init__(parent, **kwargs)
15281555
form = self.layout().itemAt(0)
@@ -1532,8 +1559,14 @@ def __init__(self, parent=None, **kwargs):
15321559
Orange.data.TimeVariable.ADDITIONAL_FORMATS.items()
15331560
):
15341561
self.format_cb.addItem(item, StrpTime(item, *data))
1562+
self.format_cb.addItem(self.CUSTOM_FORMAT_LABEL)
15351563
self.format_cb.currentIndexChanged.connect(self.variable_changed)
1564+
self.custom_edit = QLineEdit()
1565+
self.custom_edit.setPlaceholderText("%Y-%m-%d %H:%M:%S")
1566+
self.custom_edit.setToolTip(CUSTOM_TOOLTIP)
1567+
self.custom_edit.textChanged.connect(self._on_custom_change)
15361568
form.insertRow(2, "Format:", self.format_cb)
1569+
form.insertRow(3, "Custom format:", self.custom_edit)
15371570

15381571
def set_data(self, var, transform=()):
15391572
super().set_data(var, transform)
@@ -1552,9 +1585,30 @@ def get_data(self):
15521585
var, tr = super().get_data()
15531586
if var is not None and (self.parent() is None or not isinstance(self.parent().var, Time)):
15541587
# do not add StrpTime when transforming from time to time
1555-
tr.insert(0, self.format_cb.currentData())
1588+
if self.format_cb.currentText() == self.CUSTOM_FORMAT_LABEL:
1589+
custom_text = self.custom_edit.text()
1590+
date_pat = r"%(-?)d|%(b|B)|%(-?)m|%(y|Y)|%(-?)j|%(-?)U|%(-?)W|%(a|A)|%w"
1591+
time_pat = r"%(-?)H|%(-?)I|%p|%(-?)M|%(-?)S|%f"
1592+
have_date = int(bool(re.search(date_pat, custom_text)))
1593+
have_time = int(bool(re.search(time_pat, custom_text)))
1594+
# this is done to ensure that the custom format is correct
1595+
if not have_date and not have_time:
1596+
trf = StrpTime(self.CUSTOM_FORMAT_LABEL, (None,),
1597+
have_date, have_time)
1598+
else:
1599+
trf = StrpTime(self.CUSTOM_FORMAT_LABEL, (custom_text,),
1600+
have_date, have_time)
1601+
else:
1602+
trf = self.format_cb.currentData()
1603+
tr.insert(0, trf)
15561604
return var, tr
15571605

1606+
def _on_custom_change(self):
1607+
if self.format_cb.currentText() != self.CUSTOM_FORMAT_LABEL:
1608+
self.format_cb.setCurrentIndex(self.format_cb.count() - 1)
1609+
else:
1610+
self.variable_changed.emit()
1611+
15581612

15591613
def variable_icon(var):
15601614
# type: (Union[Variable, Type[Variable], ReinterpretTransform]) -> QIcon
@@ -3080,4 +3134,5 @@ def column_str_repr_string(
30803134

30813135

30823136
if __name__ == "__main__": # pragma: no cover
3083-
WidgetPreview(OWEditDomain).run(Orange.data.Table("iris"))
3137+
WidgetPreview(OWEditDomain).run(Orange.data.Table(
3138+
"/Users/ajda/Desktop/test.csv"))

0 commit comments

Comments
 (0)