File: styled_date_editor.py

package info (click to toggle)
python-traitsui 4.4.0-1.3
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 3,680 kB
  • ctags: 6,394
  • sloc: python: 32,786; makefile: 16; sh: 5
file content (152 lines) | stat: -rw-r--r-- 5,480 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152

from pyface.qt import QtCore, QtGui
from pyface.qt.QtGui import QFont

from traits.api import Dict

# For a simple editor style, we just punt and use the same simple editor
# as in the default date_editor.
from date_editor import SimpleEditor
from date_editor import CustomEditor as DateCustomEditor


class CustomEditor(DateCustomEditor):

    dates = Dict()

    styles = Dict()

    def init(self, parent):
        self.control = QtGui.QCalendarWidget()

        if not self.factory.allow_future:
            self.control.setMaximumDate(QtCore.QDate.currentDate())

        if not self.factory.allow_past:
            self.control.setMinimumDate(QtCore.QDate.currentDate())

        if self.factory.dates_trait and self.factory.styles_trait:
            self.sync_value(self.factory.dates_trait, "dates", "from")
            self.sync_value(self.factory.styles_trait, "styles", "from")

        self.control.clicked.connect(self.update_object)

        return

    def _dates_changed(self, old, new):
        # Someone changed out the entire dict.  The easiest, most robust
        # way to handle this is to reset the text formats of all the dates
        # in the old dict, and then set the dates in the new dict.
        if old:
            [map(self._reset_formatting, dates) for dates in old.values()]
        if new:
            styles = getattr(self.object, self.factory.styles_trait, None)
            self._apply_styles(styles, new)

    def _dates_items_changed(self, event):
        # Handle the added and changed items
        groups_to_set = event.added
        groups_to_set.update(event.changed)
        styles = getattr(self.object, self.factory.styles_trait, None)
        self._apply_styles(styles, groups_to_set)

        # Handle the removed items by resetting them
        [map(self._reset_formatting, dates) for dates in event.removed.values()]

    def _styles_changed(self, old, new):
        groups = getattr(self.object, self.factory.dates_trait, {})
        if not new:
            # If no new styles, then reset all the dates to a default style
            [map(self._reset_formatting, dates) for dates in groups.values()]
        else:
            self._apply_styles(new, groups)
        return

    def _styles_items_changed(self, event):
        groups = getattr(self.object, self.factory.dates_trait)
        styles = getattr(self.object, self.factory.styles_trait)

        names_to_update = event.added.keys() + event.changed.keys()
        modified_groups = dict((name, groups[name]) for name in names_to_update)
        self._apply_styles(styles, modified_groups)

        names_to_reset = event.removed.keys()
        for name in names_to_reset:
            self._reset_formatting(groups[name])
        return

    #------------------------------------------------------------------------
    # Helper functions
    #------------------------------------------------------------------------

    def _apply_style(self, style, dates):
        """ **style** is a CellFormat, **dates** is a list of datetime.date """
        for dt in dates:
            qdt = QtCore.QDate(dt)
            textformat = self.control.dateTextFormat(qdt)
            self._apply_cellformat(style, textformat)
            self.control.setDateTextFormat(qdt, textformat)
        return

    def _apply_styles(self, style_dict, date_dict):
        """ Applies the proper style out of style_dict to every (name,date_list)
        in date_dict.
        """
        if not style_dict or not date_dict:
            return
        for groupname, dates in date_dict.items():
            cellformat = style_dict.get(groupname, None)
            if not cellformat:
                continue
            for dt in dates:
                qdt = QtCore.QDate(dt)
                textformat = self.control.dateTextFormat(qdt)
                self._apply_cellformat(cellformat, textformat)
                self.control.setDateTextFormat(qdt, textformat)
        return

    def _reset_formatting(self, dates):
        # Resets the text format on the given dates
        for dt in dates:
            qdt = QtCore.QDate(dt)
            self.control.setDateTextFormat(qdt, QtGui.QTextCharFormat())

    def _apply_cellformat(self, cf, textformat):
        """ Applies the formatting in the cellformat cf to the QTextCharFormat
        object provided.
        """
        if cf.italics is not None:
            textformat.setFontItalic(cf.italics)

        if cf.underline is not None:
            textformat.setFontUnderline(cf.underline)

        if cf.bold is not None:
            if cf.bold:
                weight = QFont.Bold
            else:
                weight = QFont.Normal
            textformat.setFontWeight(weight)

        if cf.bgcolor is not None:
            textformat.setBackground(self._color_to_brush(cf.bgcolor))

        if cf.fgcolor is not None:
            textformat.setForeground(self._color_to_brush(cf.fgcolor))

        return

    def _color_to_brush(self, color):
        """ Returns a QBrush with the color specified in **color** """
        brush = QtGui.QBrush()
        if isinstance(color, basestring) and hasattr(QtCore.Qt, color):
            col = getattr(QtCore.Qt, color)
        elif isinstance(color, tuple) and len(color) == 3:
            col = QtGui.QColor()
            col.setRgb(*color)
        else:
            raise RuntimeError("Invalid color specification '%r'" % color)

        brush.setColor(col)
        return brush