~openerp/openobject-client/6.0

1004 by pap(openerp)
Changed encoding to coding ref: PEP: 0263
1
# -*- coding: utf-8 -*-
330 by ced
Add minimal new view type calendar
2
##############################################################################
1082 by nch at tinyerp
[IMP]:speed improvement in calendar widget
3
#
724 by Christophe Simonis
better calendar view (part 2)
4
#    OpenERP, Open Source Management Solution
1087.1.1 by Stephane Wirtel
[FIX] Change the year of the copyright
5
#    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
718 by Christophe Simonis
passing in GPL-3
6
#
7
#    This program is free software: you can redistribute it and/or modify
1001 by PSO(OpenERP)
changed licencing
8
#    it under the terms of the GNU Affero General Public License as
9
#    published by the Free Software Foundation, either version 3 of the
10
#    License, or (at your option) any later version.
718 by Christophe Simonis
passing in GPL-3
11
#
12
#    This program is distributed in the hope that it will be useful,
13
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
14
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1001 by PSO(OpenERP)
changed licencing
15
#    GNU Affero General Public License for more details.
718 by Christophe Simonis
passing in GPL-3
16
#
1001 by PSO(OpenERP)
changed licencing
17
#    You should have received a copy of the GNU Affero General Public License
1082 by nch at tinyerp
[IMP]:speed improvement in calendar widget
18
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
330 by ced
Add minimal new view type calendar
19
#
20
##############################################################################
21
22
from widget.view import interface
681 by hda at tinyerp
bugfix
23
from tools import ustr, node_attributes
330 by ced
Add minimal new view type calendar
24
import gtk
582.1.12 by Fabien Pinckaers
Calendar Widget, Proof of Concept
25
import gtk.glade
26
import gettext
27
import common
990.5.1 by Xavier ALT
[IMP] various calendar view improvements
28
import gobject
1387 by Harry (OpenERP)
[FIX] calendar: could not possible to backup/forward days in calendar view
29
from mx import DateTime
730.1.8 by Xavier ALT
[FIX] Some bugfix for Calendar
30
from datetime import datetime, date
582.1.12 by Fabien Pinckaers
Calendar Widget, Proof of Concept
31
32
from SpiffGtkWidgets import Calendar
1248.5.1 by pap(openerp)
date get rid of mx.datetime
33
from datetime import datetime
34
from dateutil.relativedelta import relativedelta
650 by Christophe Simonis
calendar widget: add events
35
import time
681 by hda at tinyerp
bugfix
36
import math
650 by Christophe Simonis
calendar widget: add events
37
990.5.1 by Xavier ALT
[IMP] various calendar view improvements
38
import rpc
39
from rpc import RPCProxy
1371 by nch at tinyerp
[REF]:added logger instead of print
40
import logging
990.5.1 by Xavier ALT
[IMP] various calendar view improvements
41
import widget.model.field as wmodel_fields
1849.1.1 by Anup(OpenERP)
[FIX] calendar_gtk : Calendar view now respects the timezone(Case:4721)
42
import tools
990.5.1 by Xavier ALT
[IMP] various calendar view improvements
43
650 by Christophe Simonis
calendar widget: add events
44
COLOR_PALETTE = ['#f57900', '#cc0000', '#d400a8', '#75507b', '#3465a4', '#73d216', '#c17d11', '#edd400',
45
                 '#fcaf3e', '#ef2929', '#ff00c9', '#ad7fa8', '#729fcf', '#8ae234', '#e9b96e', '#fce94f',
46
                 '#ff8e00', '#ff0000', '#b0008c', '#9000ff', '#0078ff', '#00ff00', '#e6ff00', '#ffff00',
47
                 '#905000', '#9b0000', '#840067', '#510090', '#0000c9', '#009b00', '#9abe00', '#ffc900',]
48
49
_colorline = ['#%02x%02x%02x' % (25+((r+10)%11)*23,5+((g+1)%11)*20,25+((b+4)%11)*23) for r in range(11) for g in range(11) for b in range(11) ]
1899 by Jay Vora
[FIX] Fixed the regression caused by commit revision 1867 (Case 17889)
50
51
DT_SERVER_FORMATS = {
52
          'datetime': '%Y-%m-%d %H:%M:%S',
53
          'date': '%Y-%m-%d',
54
          'time': '%H:%M:%S'
55
        }
56
650 by Christophe Simonis
calendar widget: add events
57
def choice_colors(n):
58
    if n > len(COLOR_PALETTE):
59
        return _colorline[0:-1:len(_colorline)/(n+1)]
60
    elif n:
61
        return COLOR_PALETTE[:n]
62
    return []
63
725 by Christophe Simonis
better calendar view (part 3)
64
class TinyEvent(Calendar.Event):
650 by Christophe Simonis
calendar widget: add events
65
    def __init__(self, **kwargs):
66
        for k, v in kwargs.items():
67
            setattr(self, k, v)
1082 by nch at tinyerp
[IMP]:speed improvement in calendar widget
68
69
        super(TinyEvent, self).__init__(**kwargs)
650 by Christophe Simonis
calendar widget: add events
70
71
    def __repr__(self):
72
        r = []
73
        for x in self.__dict__:
74
            r.append("%s: %r" % (x, self.__dict__[x]))
935 by Christophe Simonis
[FIX] calendar works !
75
        return '<TinyEvent::\n\t' + "\n\t".join(r) + '\n>'
582.1.12 by Fabien Pinckaers
Calendar Widget, Proof of Concept
76
656 by Christophe Simonis
refactor generation of the calendar
77
class TinyCalModel(Calendar.Model):
78
    def add_events(self, events):
79
        for event in events:
80
            assert event    is not None
81
            assert event.id is None
82
            self.events[self.next_event_id] = event
83
            event.id = self.next_event_id
84
            self.next_event_id += 1
990.5.1 by Xavier ALT
[IMP] various calendar view improvements
85
        # Force view update
86
        self.emit('event-added', None)
656 by Christophe Simonis
refactor generation of the calendar
87
935 by Christophe Simonis
[FIX] calendar works !
88
    def remove_events(self):
89
        self.events = {}
990.5.1 by Xavier ALT
[IMP] various calendar view improvements
90
        # Force view update
91
        self.emit('event-removed', None)
935 by Christophe Simonis
[FIX] calendar works !
92
582.1.12 by Fabien Pinckaers
Calendar Widget, Proof of Concept
93
94
class ViewCalendar(object):
724 by Christophe Simonis
better calendar view (part 2)
95
    TV_COL_ID = 0
96
    TV_COL_COLOR = 1
97
    TV_COL_LABEL = 2
990.5.1 by Xavier ALT
[IMP] various calendar view improvements
98
    TV_COL_TOGGLE = 3
724 by Christophe Simonis
better calendar view (part 2)
99
582.1.12 by Fabien Pinckaers
Calendar Widget, Proof of Concept
100
    def __init__(self, model, axis, fields, attrs):
723 by Christophe Simonis
better calendar view (part 1)
101
        self.glade = gtk.glade.XML(common.terp_path("openerp.glade"),'widget_view_calendar', gettext.textdomain())
582.1.12 by Fabien Pinckaers
Calendar Widget, Proof of Concept
102
        self.widget = self.glade.get_widget('widget_view_calendar')
609 by Fabien Pinckaers
Removed Print Statement
103
656 by Christophe Simonis
refactor generation of the calendar
104
        self._label_current = self.glade.get_widget('label_current')
105
        self._radio_month = self.glade.get_widget('radio_month')
106
        self._radio_week = self.glade.get_widget('radio_week')
107
        self._radio_day = self.glade.get_widget('radio_day')
108
        self._small_calendar = self.glade.get_widget('calendar_small')
724 by Christophe Simonis
better calendar view (part 2)
109
        self._calendar_treeview = self.glade.get_widget('calendar_treeview')
1082 by nch at tinyerp
[IMP]:speed improvement in calendar widget
110
1369.1.5 by nch at tinyerp
[IMP] Calendar, parser : view mode : day, week, month in calendar view
111
        mode = attrs.get('mode','month')
1371 by nch at tinyerp
[REF]:added logger instead of print
112
        self.log = logging.getLogger('calender')
582.1.12 by Fabien Pinckaers
Calendar Widget, Proof of Concept
113
        self.fields = fields
114
        self.attrs = attrs
115
        self.axis = axis
725 by Christophe Simonis
better calendar view (part 3)
116
        self.screen = None
1369.1.5 by nch at tinyerp
[IMP] Calendar, parser : view mode : day, week, month in calendar view
117
        if mode == 'day':
118
            self._radio_day.set_active(True)
119
        elif mode == 'week':
120
            self._radio_week.set_active(True)
121
        else:
122
            self._radio_month.set_active(True)
123
        self.mode = mode
582.1.12 by Fabien Pinckaers
Calendar Widget, Proof of Concept
124
935 by Christophe Simonis
[FIX] calendar works !
125
        self.cal_model = TinyCalModel()
1369.1.5 by nch at tinyerp
[IMP] Calendar, parser : view mode : day, week, month in calendar view
126
        self.cal_view = Calendar.Calendar(self.cal_model, mode)
725 by Christophe Simonis
better calendar view (part 3)
127
        self.cal_view.connect('event-clicked', self._on_event_clicked)
730.1.6 by Xavier ALT
[IMP] calendar: when click on inactive day (month view) redisplay whole view
128
        self.cal_view.connect('do_month_back_forward', self._back_forward)
730.1.8 by Xavier ALT
[FIX] Some bugfix for Calendar
129
        self.cal_view.connect('day-selected', self._change_small)
656 by Christophe Simonis
refactor generation of the calendar
130
582.1.12 by Fabien Pinckaers
Calendar Widget, Proof of Concept
131
        vbox = self.glade.get_widget('cal_vbox')
132
        vbox.pack_start(self.cal_view)
133
        vbox.show_all()
134
601 by Fabien Pinckaers
Bugfixes
135
        self.process = False
582.1.12 by Fabien Pinckaers
Calendar Widget, Proof of Concept
136
        self.glade.signal_connect('on_but_forward_clicked', self._back_forward, 1)
137
        self.glade.signal_connect('on_but_back_clicked', self._back_forward, -1)
723 by Christophe Simonis
better calendar view (part 1)
138
        self.glade.signal_connect('on_but_today_clicked', self._today)
1369.1.37 by nch at tinyerp
[FIX]:double click on a date in calender view's small calender generates a traceback of missing arguments. It should go to the day clicked
139
        self.glade.signal_connect('on_calendar_small_day_selected_double_click', self._change_small, False,False)
601 by Fabien Pinckaers
Bugfixes
140
        self.glade.signal_connect('on_button_day_clicked', self._change_view, 'day')
141
        self.glade.signal_connect('on_button_week_clicked', self._change_view, 'week')
142
        self.glade.signal_connect('on_button_month_clicked', self._change_view, 'month')
1082 by nch at tinyerp
[IMP]:speed improvement in calendar widget
143
1248.5.1 by pap(openerp)
date get rid of mx.datetime
144
        self.date = datetime.today()
582.1.12 by Fabien Pinckaers
Calendar Widget, Proof of Concept
145
650 by Christophe Simonis
calendar widget: add events
146
        self.string = attrs.get('string', '')
681 by hda at tinyerp
bugfix
147
        self.date_start = attrs.get('date_start')
650 by Christophe Simonis
calendar widget: add events
148
        self.date_delay = attrs.get('date_delay')
149
        self.date_stop = attrs.get('date_stop')
150
        self.color_field = attrs.get('color')
990.5.1 by Xavier ALT
[IMP] various calendar view improvements
151
        self.color_field_custom = attrs.get('color_custom', 'color')
152
        self.color_model = False
153
        self.color_filters = {}
154
        self.colors = {}
155
650 by Christophe Simonis
calendar widget: add events
156
        self.day_length = int(attrs.get('day_length', 8))
157
        self.models = None
990.5.1 by Xavier ALT
[IMP] various calendar view improvements
158
        self.models_record_group = None
681 by hda at tinyerp
bugfix
159
724 by Christophe Simonis
better calendar view (part 2)
160
        if self.color_field:
990.5.1 by Xavier ALT
[IMP] various calendar view improvements
161
            self.color_model = gtk.ListStore(str, str, str, gobject.TYPE_BOOLEAN)
162
            self._calendar_treeview.set_model(self.color_model)
724 by Christophe Simonis
better calendar view (part 2)
163
            self._calendar_treeview.get_selection().set_mode(gtk.SELECTION_NONE)
164
165
            for c in (self.TV_COL_ID, self.TV_COL_COLOR):
166
                column = gtk.TreeViewColumn(None, gtk.CellRendererText(), text=c)
167
                self._calendar_treeview.append_column(column)
1082 by nch at tinyerp
[IMP]:speed improvement in calendar widget
168
                column.set_visible(False)
990.5.1 by Xavier ALT
[IMP] various calendar view improvements
169
170
            # Row toogle
171
            renderer = gtk.CellRendererToggle()
172
            renderer.set_property('activatable', True)
173
            renderer.connect('toggled', self._treeview_toggled, self.color_model, self.color_filters)
174
            column = gtk.TreeViewColumn(None, renderer)
175
            column.add_attribute(renderer, "active", self.TV_COL_TOGGLE)
176
            column.set_cell_data_func(renderer, self._treeview_setter)
177
            self._calendar_treeview.append_column(column)
724 by Christophe Simonis
better calendar view (part 2)
178
179
            renderer = gtk.CellRendererText()
180
            column = gtk.TreeViewColumn(None, renderer, text=self.TV_COL_LABEL)
181
            col_label = gtk.Label('')
182
            col_label.set_markup('<b>%s</b>' % self.fields[self.color_field]['string'])
183
            col_label.show()
184
            column.set_widget(col_label)
185
            column.set_cell_data_func(renderer, self._treeview_setter)
186
            self._calendar_treeview.append_column(column)
1082 by nch at tinyerp
[IMP]:speed improvement in calendar widget
187
990.5.1 by Xavier ALT
[IMP] various calendar view improvements
188
    def _treeview_toggled(self, renderer, path, model, color_filters):
189
        it = model.get_iter(path)
190
        curval = model.get(it, self.TV_COL_TOGGLE)[0]
191
        newval = not curval
192
        model.set(it, self.TV_COL_TOGGLE, newval)
193
194
        value = model.get(it, self.TV_COL_ID)
195
        if isinstance(value, (tuple,list)):
196
            value = value[0]
197
198
        # update filters
199
        if not newval:
200
            # remove from filter
201
            try:
202
                color_filters.pop(value)
203
            except KeyError:
204
                # item anymore in dictionary
205
                pass
206
        else:
207
            # add to filter
208
            color_filters[value] = True
209
210
        self.display(None, force=True)
724 by Christophe Simonis
better calendar view (part 2)
211
212
    def _treeview_setter(self, column, cell, store, iter):
213
        color = store.get_value(iter, self.TV_COL_COLOR)
990.5.1 by Xavier ALT
[IMP] various calendar view improvements
214
        if isinstance(cell, gtk.CellRendererText):
215
            cell.set_property('background', str(color))
216
        elif isinstance(cell, gtk.CellRendererToggle):
217
            cell.set_property('cell-background', str(color))
724 by Christophe Simonis
better calendar view (part 2)
218
219
    def add_to_treeview(self, name, value, color):
220
        value = str(value)
221
        model = self._calendar_treeview.get_model()
222
        for row in model:
1927.3.1 by Naresh(OpenERP)
[FIX]:color problem in calendar view
223
            if row[self.TV_COL_ID] == value :# id already in the treeview
224
                if row[self.TV_COL_COLOR] != color: # the color assigned is the old one 
225
                    row[self.TV_COL_COLOR] = color  #replace it with new one.
226
                return  
724 by Christophe Simonis
better calendar view (part 2)
227
        iter = model.append()
990.5.1 by Xavier ALT
[IMP] various calendar view improvements
228
        model.set(iter, self.TV_COL_ID, value,
229
                        self.TV_COL_COLOR, color,
230
                        self.TV_COL_LABEL, name,
231
                        self.TV_COL_TOGGLE, False)
650 by Christophe Simonis
calendar widget: add events
232
990.5.1 by Xavier ALT
[IMP] various calendar view improvements
233
    def _change_small(self, widget, date_selected, hippo_event, *args, **argv):
730.1.8 by Xavier ALT
[FIX] Some bugfix for Calendar
234
        if isinstance(widget, gtk.Calendar):
235
            t = list(widget.get_date())
236
            t[1] += 1
237
        else:
990.5.1 by Xavier ALT
[IMP] various calendar view improvements
238
            t = list(date_selected.timetuple()[:3])
1248.5.1 by pap(openerp)
date get rid of mx.datetime
239
        self.date = datetime(*t[0:6])
582.1.12 by Fabien Pinckaers
Calendar Widget, Proof of Concept
240
        self.display(None)
990.5.1 by Xavier ALT
[IMP] various calendar view improvements
241
242
        # if action = double click
1369.1.37 by nch at tinyerp
[FIX]:double click on a date in calender view's small calender generates a traceback of missing arguments. It should go to the day clicked
243
        if hippo_event and hippo_event.button == 1:
990.5.1 by Xavier ALT
[IMP] various calendar view improvements
244
            if hippo_event.count == 1: # simple clic
245
                # simply display new current day
246
                return
247
            elif hippo_event.count >= 2: # double clic or more
248
                self.screen.context.update({'default_' +self.date_start:self.date.strftime('%Y-%m-%d %H:%M:%S')})
249
                self.screen.switch_view(mode='form')
250
                self.screen.new()
582.1.12 by Fabien Pinckaers
Calendar Widget, Proof of Concept
251
723 by Christophe Simonis
better calendar view (part 1)
252
    def _today(self, widget, *args, **argv):
1248.5.1 by pap(openerp)
date get rid of mx.datetime
253
        self.date = datetime.today()
582.1.12 by Fabien Pinckaers
Calendar Widget, Proof of Concept
254
        self.display(None)
255
256
    def _back_forward(self, widget, type, *args, **argv):
990.5.1 by Xavier ALT
[IMP] various calendar view improvements
257
        relatime = DateTime.RelativeDateTime
258
        if self.mode == 'day':
1248.5.1 by pap(openerp)
date get rid of mx.datetime
259
            self.date = self.date + relativedelta(days=type)
990.5.1 by Xavier ALT
[IMP] various calendar view improvements
260
        if self.mode == 'week':
1248.5.1 by pap(openerp)
date get rid of mx.datetime
261
            self.date = self.date + relativedelta(weeks=type)
990.5.1 by Xavier ALT
[IMP] various calendar view improvements
262
        if self.mode == 'month':
1248.5.1 by pap(openerp)
date get rid of mx.datetime
263
            self.date = self.date + relativedelta(months=type)
1082 by nch at tinyerp
[IMP]:speed improvement in calendar widget
264
        self.screen.search_filter()
582.1.12 by Fabien Pinckaers
Calendar Widget, Proof of Concept
265
        self.display(None)
266
267
    def _change_view(self, widget, type, *args, **argv):
606 by Christophe Simonis
bugfix with calendar
268
        if self.process or self.mode == type:
601 by Fabien Pinckaers
Bugfixes
269
            return True
270
        self.process = True
582.1.12 by Fabien Pinckaers
Calendar Widget, Proof of Concept
271
        self.mode = type
990.5.1 by Xavier ALT
[IMP] various calendar view improvements
272
        self.display(None, force=True)
601 by Fabien Pinckaers
Bugfixes
273
        self.process = False
582.1.12 by Fabien Pinckaers
Calendar Widget, Proof of Concept
274
        return True
275
725 by Christophe Simonis
better calendar view (part 3)
276
    def _on_event_clicked(self, calendar, calendar_event, hippo_event):
990.5.1 by Xavier ALT
[IMP] various calendar view improvements
277
        if hippo_event.button == 1 and hippo_event.count >= 2:
278
            # user have double clicked
725 by Christophe Simonis
better calendar view (part 3)
279
            self.screen.current_model = calendar_event.model
280
            self.screen.switch_view(mode='form')
1082 by nch at tinyerp
[IMP]:speed improvement in calendar widget
281
656 by Christophe Simonis
refactor generation of the calendar
282
    def __update_colors(self):
283
        if self.color_field:
990.5.1 by Xavier ALT
[IMP] various calendar view improvements
284
            self.colors = self._get_colors(self.models, self.color_field, self.color_field_custom)
285
286
    def _get_colors(self, models, color_field, color_field_custom):
287
        auto_color_count = 0 # how many color do we need to generate auto.
288
        colors = {}
289
290
        for model in models:
291
            name = value = key = model.value[color_field]
1803 by Thibault Francois
[REVERT] no needed change from the previous merge
292
990.5.1 by Xavier ALT
[IMP] various calendar view improvements
293
            if isinstance(key, (tuple, list)):
294
                value, name = key
295
                key = tuple(key)
1803 by Thibault Francois
[REVERT] no needed change from the previous merge
296
990.5.1 by Xavier ALT
[IMP] various calendar view improvements
297
            if key in colors:
298
                # already present skip
299
                continue
300
301
            # if field is many2one, try to get color from object
302
            # 'color' field
303
            field_color = None
304
            field_widget = model.mgroup.mfields.get(color_field, False)
1803 by Thibault Francois
[REVERT] no needed change from the previous merge
305
            if field_widget and field_widget.attrs['type'] == 'many2one':
990.5.1 by Xavier ALT
[IMP] various calendar view improvements
306
                fproxy = RPCProxy(field_widget.attrs['relation'])
307
                try:
308
                    fdata = fproxy.read(value, [color_field_custom])
309
                    if fdata:
310
                        field_color = fdata.get(color_field_custom) and str(fdata.get(color_field_custom)) or None
311
                except Exception, e:
312
                    #TODO: Need to limit exception
1371 by nch at tinyerp
[REF]:added logger instead of print
313
                    self.log.exception(e)
990.5.1 by Xavier ALT
[IMP] various calendar view improvements
314
                    pass
315
316
            if not field_color:
317
                # increment total color to generate
318
                auto_color_count += 1
319
320
            colors[key] = (name, value, field_color)
321
322
        auto_colors = choice_colors(auto_color_count)
323
        colors_idx = 0
324
        for key, value in colors.items():
325
            color_value = value[2]
326
            if not color_value:
327
                color_value = auto_colors[colors_idx]
328
                colors_idx += 1
329
            colors[key] = (value[0], value[1], color_value)
330
        # return new colors
331
        return colors
332
333
    def display(self, models, force=False):
582.1.12 by Fabien Pinckaers
Calendar Widget, Proof of Concept
334
        if models:
650 by Christophe Simonis
calendar widget: add events
335
            self.models = models.models
990.5.1 by Xavier ALT
[IMP] various calendar view improvements
336
            self.models_record_group = models
1369.1.67 by RGA(OpenERP)
[FIX] Calendar view: display two entry of same event(record)
337
            model_lst = [model for model in self.models if not isinstance(model.id, int)]
338
            if model_lst:
339
                self.models = model_lst
1791 by Olivier Dony
[MERGE] backport of trunk fixes for calendar refresh and custom filters
340
            self.cal_model.remove_events()
935 by Christophe Simonis
[FIX] calendar works !
341
            if self.models:
342
                self.__update_colors()
343
                self.cal_model.add_events(self.__get_events())
991 by HDA(OpenERP)
[Merged]
344
                self.refresh()
990.5.1 by Xavier ALT
[IMP] various calendar view improvements
345
        elif force == True:
346
            self.cal_model.remove_events()
347
            self.cal_model.add_events(self.__get_events())
656 by Christophe Simonis
refactor generation of the calendar
348
        self.refresh()
349
350
    def refresh(self):
1248.5.1 by pap(openerp)
date get rid of mx.datetime
351
        t = self.date.timetuple()
864 by Stephane Wirtel
[FIX] Encoding error with the local settings
352
        from tools import ustr
353
        from locale import getlocale
354
        sysencoding = getlocale()[1]
935 by Christophe Simonis
[FIX] calendar works !
355
990.5.1 by Xavier ALT
[IMP] various calendar view improvements
356
        if self.mode == 'month':
656 by Christophe Simonis
refactor generation of the calendar
357
            self.cal_view.range = self.cal_view.RANGE_MONTH
864 by Stephane Wirtel
[FIX] Encoding error with the local settings
358
            self._label_current.set_text(ustr(self.date.strftime('%B %Y'), sysencoding))
990.5.1 by Xavier ALT
[IMP] various calendar view improvements
359
        elif self.mode == 'week':
656 by Christophe Simonis
refactor generation of the calendar
360
            self.cal_view.range = self.cal_view.RANGE_WEEK
361
            self._label_current.set_text(_('Week') + ' ' + self.date.strftime('%W, %Y'))
990.5.1 by Xavier ALT
[IMP] various calendar view improvements
362
        elif self.mode == 'day':
656 by Christophe Simonis
refactor generation of the calendar
363
            self.cal_view.range = self.cal_view.RANGE_CUSTOM
935 by Christophe Simonis
[FIX] calendar works !
364
            d1 = datetime(*t[:3])
365
            d2 = Calendar.util.end_of_day(d1)
366
            self.cal_view.active_range = self.cal_view.visible_range = d1, d2
864 by Stephane Wirtel
[FIX] Encoding error with the local settings
367
            self._label_current.set_text(ustr(self.date.strftime('%A %x'), sysencoding))
681 by hda at tinyerp
bugfix
368
935 by Christophe Simonis
[FIX] calendar works !
369
        self.cal_view.selected = date(*list(t)[:3])
656 by Christophe Simonis
refactor generation of the calendar
370
        self._small_calendar.select_month(t[1]-1,t[0])
371
        self._small_calendar.select_day(t[2])
1082 by nch at tinyerp
[IMP]:speed improvement in calendar widget
372
656 by Christophe Simonis
refactor generation of the calendar
373
        self.cal_view.refresh()
374
375
376
    def __get_events(self):
990.5.1 by Xavier ALT
[IMP] various calendar view improvements
377
        do_color_filtering = len(self.color_filters.keys()) and True or False
378
        color_filters = self.color_filters
379
656 by Christophe Simonis
refactor generation of the calendar
380
        events = []
381
        for model in self.models:
990.5.1 by Xavier ALT
[IMP] various calendar view improvements
382
            filter_state = 'keep'
383
            if do_color_filtering:
384
                model_value = model.value.get(self.color_field, False)
385
                if isinstance(model_value, (tuple,list)):
386
                    model_value = str(model_value[0])
387
                if model_value and model_value not in color_filters:
388
                    filter_state = 'skip'
389
390
            if filter_state == 'skip':
391
                # We need to skip this item
392
                continue
393
394
725 by Christophe Simonis
better calendar view (part 3)
395
            e = self.__get_event(model)
396
            if e:
397
                if e.color_info:
398
                    self.add_to_treeview(*e.color_info)
399
                events.append(e)
656 by Christophe Simonis
refactor generation of the calendar
400
        return events
650 by Christophe Simonis
calendar widget: add events
401
402
    def __convert(self, event):
403
        # method from eTiny
404
        fields = [x for x in [self.date_start, self.date_stop] if x]
405
        for fld in fields:
406
            typ = self.fields[fld]['type']
407
            fmt = DT_SERVER_FORMATS[typ]
408
            if event[fld] and fmt:
990.3.40 by Jay(Open ERP)
[FIX] Calendar : Corrected datetime parsing
409
                event[fld] = time.strptime(event[fld][:19], fmt)
681 by hda at tinyerp
bugfix
410
1568.1.2 by Julien Thewys
[REF] Adapted previous fix so that it is also appropriate for web client.
411
            # default start/stop time is 9:00 AM / 5:00 PM
1568.1.1 by Julien Thewys
[FIX] Fixed display of calendar event when boundaries are of type date.
412
            # if you set it to 0:00, then Calendar.Event removes 1 second to date_stop,
413
            # which sets it back to the day before at 23:59:59
1568.1.2 by Julien Thewys
[REF] Adapted previous fix so that it is also appropriate for web client.
414
            if typ == 'date' and event[fld]:
415
                ds = list(event[fld])
416
                if fld == self.date_start:
789 by Husen Daudi
fixed date less than 1900 problem (ref:pso)
417
                    ds[3] = 9
1568.1.2 by Julien Thewys
[REF] Adapted previous fix so that it is also appropriate for web client.
418
                elif fld == self.date_stop:
419
                    ds[3] = 17
420
                event[fld] = tuple(ds)
650 by Christophe Simonis
calendar widget: add events
421
725 by Christophe Simonis
better calendar view (part 3)
422
    def __get_event(self, model):
1082 by nch at tinyerp
[IMP]:speed improvement in calendar widget
423
725 by Christophe Simonis
better calendar view (part 3)
424
        event = model.value.copy()
1849.1.1 by Anup(OpenERP)
[FIX] calendar_gtk : Calendar view now respects the timezone(Case:4721)
425
        # Converts the dates according to the timezone in calendar view
1899 by Jay Vora
[FIX] Fixed the regression caused by commit revision 1867 (Case 17889)
426
        for dt_field in [self.date_start, self.date_stop]:
427
            if not dt_field:
428
                continue
429
            dt_format = DT_SERVER_FORMATS[self.fields[dt_field]['type']]
430
            event[dt_field] = tools.datetime_util.server_to_local_timestamp(event.get(dt_field), dt_format, dt_format, tz_offset=True, ignore_unparsable_time=False)
431
        
725 by Christophe Simonis
better calendar view (part 3)
432
        self.__convert(event)
650 by Christophe Simonis
calendar widget: add events
433
1082 by nch at tinyerp
[IMP]:speed improvement in calendar widget
434
        caption = ''
435
        description = []
436
        starts = None
437
        ends = None
681 by hda at tinyerp
bugfix
438
650 by Christophe Simonis
calendar widget: add events
439
        if self.axis:
681 by hda at tinyerp
bugfix
440
650 by Christophe Simonis
calendar widget: add events
441
            f = self.axis[0]
442
            s = event[f]
681 by hda at tinyerp
bugfix
443
650 by Christophe Simonis
calendar widget: add events
444
            if isinstance(s, (tuple, list)): s = s[-1]
681 by hda at tinyerp
bugfix
445
725 by Christophe Simonis
better calendar view (part 3)
446
            caption = ustr(s)
681 by hda at tinyerp
bugfix
447
650 by Christophe Simonis
calendar widget: add events
448
            for f in self.axis[1:]:
449
                s = event[f]
450
                if isinstance(s, (tuple, list)): s = s[-1]
681 by hda at tinyerp
bugfix
451
650 by Christophe Simonis
calendar widget: add events
452
                description += [ustr(s)]
453
454
        starts = event.get(self.date_start)
455
        ends = event.get(self.date_delay) or 1.0
456
        span = 0
681 by hda at tinyerp
bugfix
457
650 by Christophe Simonis
calendar widget: add events
458
        if starts and ends:
681 by hda at tinyerp
bugfix
459
650 by Christophe Simonis
calendar widget: add events
460
            n = 0
928 by Fabien Pinckaers
bugfix
461
            h = ends or 1
681 by hda at tinyerp
bugfix
462
650 by Christophe Simonis
calendar widget: add events
463
            if ends == self.day_length: span = 1
681 by hda at tinyerp
bugfix
464
650 by Christophe Simonis
calendar widget: add events
465
            if ends > self.day_length:
466
                n = ends / self.day_length
467
                h = ends % self.day_length
681 by hda at tinyerp
bugfix
468
650 by Christophe Simonis
calendar widget: add events
469
                n = int(math.floor(n))
681 by hda at tinyerp
bugfix
470
990 by Jay(Open ERP)
[FIX] Calendar problem for days stripline
471
                if n > 0:
472
                    if not h:
473
                        n = n - 1
474
                    span = n + 1
1371 by nch at tinyerp
[REF]:added logger instead of print
475
1248.5.1 by pap(openerp)
date get rid of mx.datetime
476
            ends= time.localtime(time.mktime(starts)+(h * 60 * 60) + (n * 24 * 60 * 60))
681 by hda at tinyerp
bugfix
477
650 by Christophe Simonis
calendar widget: add events
478
        if starts and self.date_stop:
681 by hda at tinyerp
bugfix
479
650 by Christophe Simonis
calendar widget: add events
480
            ends = event.get(self.date_stop)
481
            if not ends:
482
                ends = time.localtime(time.mktime(starts) + 60 * 60)
681 by hda at tinyerp
bugfix
483
650 by Christophe Simonis
calendar widget: add events
484
            tds = time.mktime(starts)
485
            tde = time.mktime(ends)
681 by hda at tinyerp
bugfix
486
650 by Christophe Simonis
calendar widget: add events
487
            if tds >= tde:
488
                tde = tds + 60 * 60
489
                ends = time.localtime(tde)
681 by hda at tinyerp
bugfix
490
650 by Christophe Simonis
calendar widget: add events
491
            n = (tde - tds) / (60 * 60)
681 by hda at tinyerp
bugfix
492
650 by Christophe Simonis
calendar widget: add events
493
            if n > self.day_length:
935 by Christophe Simonis
[FIX] calendar works !
494
                span = math.floor(n / 24.)
1082 by nch at tinyerp
[IMP]:speed improvement in calendar widget
495
725 by Christophe Simonis
better calendar view (part 3)
496
        if not starts:
497
            return None
1082 by nch at tinyerp
[IMP]:speed improvement in calendar widget
498
900 by Christophe Simonis
[FIX] calendar view: allow all fields (whatever the type) to be the color key
499
        color_key = event.get(self.color_field)
500
        if isinstance(color_key, list):
501
            color_key = tuple(color_key)
725 by Christophe Simonis
better calendar view (part 3)
502
        color_info = self.colors.get(color_key)
503
900 by Christophe Simonis
[FIX] calendar view: allow all fields (whatever the type) to be the color key
504
        color = color_info and color_info[2] or 'black'
725 by Christophe Simonis
better calendar view (part 3)
505
650 by Christophe Simonis
calendar widget: add events
506
        description = ', '.join(description).strip()
725 by Christophe Simonis
better calendar view (part 3)
507
        all_day = span > 0
508
        return TinyEvent(model=model,
509
                         caption=caption.strip(),
1082 by nch at tinyerp
[IMP]:speed improvement in calendar widget
510
                         start=datetime(*starts[:7]),
511
                         end=datetime(*ends[:7]),
512
                         description=description,
725 by Christophe Simonis
better calendar view (part 3)
513
                         dayspan=span,
514
                         all_day=all_day,
515
                         color_info=color_info,
516
                         bg_color = (all_day or self.mode != 'month') and color or 'white',
517
                         text_color = (all_day or self.mode != 'month') and 'black' or color,
724 by Christophe Simonis
better calendar view (part 2)
518
        )
650 by Christophe Simonis
calendar widget: add events
519
520
990.5.1 by Xavier ALT
[IMP] various calendar view improvements
521
330 by ced
Add minimal new view type calendar
522
class parser_calendar(interface.parser_interface):
541 by Christophe Simonis
convert tabs to 4 spaces
523
    def parse(self, model, root_node, fields):
650 by Christophe Simonis
calendar widget: add events
524
        attrs = node_attributes(root_node)
582.1.12 by Fabien Pinckaers
Calendar Widget, Proof of Concept
525
        self.title = attrs.get('string', 'Calendar')
526
527
        axis = []
528
        axis_data = {}
1421 by nch at tinyerp
[IMP]:dom to etree
529
        for node in root_node:
650 by Christophe Simonis
calendar widget: add events
530
            node_attrs = node_attributes(node)
1421 by nch at tinyerp
[IMP]:dom to etree
531
            if node.tag == 'field':
582.1.12 by Fabien Pinckaers
Calendar Widget, Proof of Concept
532
                axis.append(str(node_attrs['name']))
533
                axis_data[str(node_attrs['name'])] = node_attrs
534
535
        view = ViewCalendar(model, axis, fields, attrs)
536
537
        return view, {}, [], ''
542 by Christophe Simonis
add encoding comment and vim comment
538
539
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
540