Enhancing Attribute Editors
What are Attribute Editors?
Attribute editors format the way information is displayed depending on the type of the value. The displaying context of the value need not know the details of how to customize this value. Since the attribute editors handle this customization, we can ensure that the value will be displayed uniformly in different contexts.
To read more about the Attribute Editors, go
here.
Pipeline of method calls for auto-completion of date/times
The methods calls might be different depending on whether you are creating a new event or editing an existing event. The following order is a generalised one just to give a brief insight.
- GetControlValue() in parent class StringAttributeEditor in ./parcels/osaf/framework/attributeeditors/AttributeEditors.py
Gets the stored value for the date/time widgets of that event
- BeginControlEdit()
Called when you click on the date/time widget of an event in the Detail view of Chandler.
- onTextChanged()
Called when you edit/delete text already present in the widget
- findCompletionRange()
Checks whether auto-completion support is provided for that widget
- generateCompletionMatches() in class TimeAttributeEditor or class DateAttributeEditor depending on whether you are editing a date widget or a time widget
- parseTime() in class TimeAttributeEditor or parseDate() in class DateAttributeEditor
Parses the text and returns the completion matches
- manageCompletionList() in class StringAttributeEditor
- finishCompletion() in class DateAttributeEditor or class TimeAttributeEditor
Formats the value after the user selects the match for the list
- SetControlValue()
Sets the value in the date/time widget
DateAttributeEditor
DateAttributeEditor is used to format dates in the Detail view of Chandler. The start date and the end date widgets in the Detail view of Chandler are DateAttributeEditors.
DateAttributeEditor inherits from StringAttributeEditor() which uses a Text Control to edit attributes in string form.
class DateAttributeEditor (StringAttributeEditor):
The class has a list of tuples which contain the parseable natural language date strings and their localised version.
dateStr = [(u'Today',_(u'today')), (u'Tomorrow',_(u'tomorrow')),
(u'Yesterday',_(u'yesterday')), (u'EOW',_(u'end of week'))]
The weekday names in the US English locale and the current locale are obtained using
PyICU and their tuples are added to the list.
us_weekDays = PyICU.DateFormatSymbols(PyICU.Locale.getUS()).getWeekdays()
current_weekDays = PyICU.DateFormatSymbols().getWeekdays()
dateStr.extend(zip(us_weekDays,current_weekDays))
The month names in the US English locale and the current locale are obtained using
PyICU and their tuples are added to the list.
us_months = PyICU.DateFormatSymbols(PyICU.Locale.getUS()).getMonths()
current_months = PyICU.DateFormatSymbols().getMonths()
dateStr.extend(zip(us_months,current_months))
The list is then converted to a dictionary which helps to map the US English version of the natural language date strings to their localised verion.
textMatches = dict(dateStr)
To do the localized parsing, a new class method parseDate() is added.
parseDate() parses the date strings entered in the date widget using parsedatetime library. It first, searches the dictionary for natural language date strings. If found, the English version of the string is parsed using parsedatetime library. If not found the string is passed to parsedatetime library as it is. If a valid date tuple is returned, the date is converted to a proper localized format using pim.shortDateFormat() and yielded.
@classmethod
def parseDate(cls, target):
for matchKey in cls.textMatches:
if (cls.textMatches[matchKey]).startswith(target):
#natural language string for date found
cal = parsedatetime.Calendar()
(dateVar, invalidFlag) = cal.parse(matchKey)
#invalidFlag is True if the string cannot be parsed successfully
if dateVar is not None and invalidFlag is False:
dateStr = pim.shortDateFormat.format(datetime(*dateVar[:3]))
matchKey = cls.textMatches[matchKey]+ " : %s" % dateStr
yield matchKey
else:
cal = parsedatetime.Calendar()
(dateVar, invalidFlag) = cal.parse(target)
if dateVar is not None and invalidFlag is False:
yield pim.shortDateFormat.format(datetime(*dateVar[:3]))
break
To provide the user with all the auto-completion matches when he types text in the date widgets
, the method generateCompletionMatches() is implemented. This method calls parseDate() and returns the value yeilded by it.
def generateCompletionMatches(self, target):
return self.parseDate(target)
TimeAttributeEditor
The TimeAttributeEditor is used to format times in the Detail view of Chandler. The start time and the end time widgets are TimeAttributeEditors.
Like the DateAttributeEditor, the TimeAttributeEditor too inherits from StringAttributeEditor() which uses a Text Control to edit attributes in string form.
The TimeAttributeEditor is enhanced in a similar way as the DateAttributeEditor.
The list of natural language time strings which can be parsed is as follows :
textMatches = {'Lunch':_(u'lunch'),'Evening':_(u'evening'),'Noon':_(u'noon'),'Dinner':_(u'dinner'),
'Midnight':_(u'midnight'),'Breakfast':_(u'breakfast'),u'EOD':_(u'end of day'),
'Morning':_(u'morning'),'Tonight':_(u'tonight'),'Night':_(u'night'),'Now':_(u'now')}
Localization
Strings localized using PyICU
The weekday names and the month names are localized using
PyICU.
The dates displayed in the date/time widgets are also localized using pim which uses
PyICU.
Strings localized using gettext(_ function)
All the natural language date/time strings listed in the dictionaries (textMatches) above are the strings which are localized using gettext. For eg: 'lunch', 'morning', 'today', 'yesterday', 'now', 'midnight', etc.
Features not implemented and why?
Since the date/time strings and their localized verion are put in a dictionary manually, there is a set of very limited natural language date/time strings which can be localized.
Strings longer than one word in English are not included in this dictionary currently.
For example: 'Day before yesterday', 'Day after tomorrow', etc.
These strings are parsed correctly in English using the parsedatetime library, but no autocompletion/localization support is provided since these strings are not included in the dictionary.
--
DarshanaChhajed - 14 Sep 2006