1
# -*- encoding: utf-8 -*-
2
##############################################################################
4
# OpenERP, Open Source Management Solution
5
# Copyright (C) 2004-2008 Tiny SPRL (<http://tiny.be>). All Rights Reserved
8
# This program is free software: you can redistribute it and/or modify
9
# it under the terms of the GNU General Public License as published by
10
# the Free Software Foundation, either version 3 of the License, or
11
# (at your option) any later version.
13
# This program is distributed in the hope that it will be useful,
14
# but WITHOUT ANY WARRANTY; without even the implied warranty of
15
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
# GNU General Public License for more details.
18
# You should have received a copy of the GNU General Public License
19
# along with this program. If not, see <http://www.gnu.org/licenses/>.
21
##############################################################################
33
import tools.datetime_util
35
from mx.DateTime import DateTime
38
class DecoratorRenderer(gtk.GenericCellRenderer):
39
def __init__(self, renderer1, callback, format):
40
self.__gobject_init__()
41
self.renderer1 = renderer1
42
self.set_property("mode", renderer1.get_property("mode"))
43
self.callback = callback
45
self.regex = self.initial_value = self.format
46
for key,val in tools.datetime_util.date_mapping.items():
47
self.regex = self.regex.replace(key, val[1])
48
self.initial_value = self.initial_value.replace(key, val[0])
49
self.regex = '^'+self.regex+'$'
51
def _is_not_generic_property(self, name):
52
return name in ('editable', 'text', 'foreground', 'background')
54
def set_property(self, name, value):
55
if not self._is_not_generic_property(name):
56
return super(DecoratorRenderer, self).set_property(name, value)
58
return self.renderer1.set_property(name, value)
60
def get_property(self, name):
61
if self._is_not_generic_property(name):
62
return self.renderer1.get_property(name)
64
return super(DecoratorRenderer, self).get_property(name)
66
def on_get_size(self, widget, cell_area=None):
67
return self.renderer1.get_size(widget, cell_area)
69
def on_render(self, window, widget, background_area, cell_area, expose_area, flags):
70
return self.renderer1.render(window, widget, background_area, cell_area, expose_area, flags)
72
def on_activate(self, event, widget, path, background_area, cell_area, flags):
73
return self.renderer1.activate(event, widget, path, background_area, cell_area, flags)
75
def on_start_editing(self, event, widget, path, background_area, cell_area, flags):
76
if not self.get_property('editable'):
79
event = gtk.gdk.Event(gtk.keysyms.Tab)
81
editable = self.renderer1.start_editing(event, widget, path, background_area, cell_area, flags)
82
self.editable = editable
83
self.callback.display(editable)
85
if not editable.get_text():
86
editable.set_text(self.initial_value)
87
self.regex = re.compile(self.regex)
89
assert self.regex.match(self.initial_value), 'Error, the initial value should be validated by regex'
90
editable.set_width_chars(len(self.initial_value))
91
editable.set_max_length(len(self.initial_value))
93
editable.connect('key-press-event', self._on_key_press)
96
self._interactive_input = True
98
gobject.idle_add(editable.set_position, 0)
101
def _on_delete_text(self, editable, start, end):
102
while (start>0) and (self.initial_value[start] not in ['_','0','X']):
104
text = editable.get_text()
105
text = text[:start] + self.initial_value[start:end] + text[end:]
106
editable.set_text(text)
107
gobject.idle_add(editable.set_position, start)
110
def date_get(self, editable):
111
tt = time.strftime(self.format, time.localtime())
112
tc = editable.get_text()
113
if tc==self.initial_value:
115
for a in range(len(self.initial_value)):
116
if self.initial_value[a] == tc[a]:
117
tc = tc[:a] + tt[a] + tc[a+1:]
119
editable.set_text(tc)
120
return tools.datetime_util.strptime(tc, self.format)
123
editable.set_text(tc)
124
return tools.datetime_util.strptime(tc, self.format)
126
def _on_key_press(self, editable, event):
127
if event.keyval in (gtk.keysyms.Tab, gtk.keysyms.Escape, gtk.keysyms.Return):
129
self.mode_cmd = False
130
if self.callback: self.callback.process(self, event)
131
#self.stop_emission("key-press-event")
135
elif event.keyval in (ord('+'),ord('-'),ord('=')):
137
self.date_get(editable)
138
if self.callback: self.callback.event(self, event)
141
if self.callback: self.callback.event(self, event)
144
if event.keyval in (gtk.keysyms.BackSpace,):
145
pos = editable.get_position()
146
self._on_delete_text(editable, max(0,pos-1), pos)
148
if event.keyval in (gtk.keysyms.Delete,):
149
pos = editable.get_position()
150
text = editable.get_text()
151
self._on_delete_text(editable, pos, len(text))
154
if event.keyval>=ord('0') and event.keyval<=ord('9'):
155
pos = editable.get_position()
156
text = editable.get_text()
157
text = text[:pos] + chr(event.keyval) + text[pos + 1:]
158
if self.regex.match(text):
160
while (pos<len(self.initial_value)) and (self.initial_value[pos] not in ['_','0','X']):
162
editable.set_text(text)
164
gobject.idle_add(editable.set_position, pos)
170
def date_set(self, dt):
172
self.editable.set_text( dt.strftime(self.format) )
174
self.editable.set_text(self.initial_value)
177
class date_callback(object):
178
def __init__(self, treeview=None):
180
self.treeview = treeview
182
def event(self, widget, event):
183
if event.keyval in (gtk.keysyms.BackSpace,):
184
self.value = self.value[:-1]
186
self.value = self.value+chr(event.keyval)
190
def display(self, widget):
193
self.treeview.warn('misc-message', '<b>' + str(tools.to_xml(self.value))+"</b>")
195
self.treeview.warn('misc-message', _("Press <i>'+'</i>, <i>'-'</i> or <i>'='</i> for special date operations."))
197
def process(self, widget, event):
198
if (not event) or event.keyval != gtk.keysyms.Escape:
200
for r,f in tools.datetime_util.date_operation.items():
201
groups = re.match(r, cmd)
203
dt = widget.date_get(widget.editable)
205
dt = time.strftime(widget.format, time.localtime())
206
dt = tools.datetime_util.strptime(dt, widget.format)
207
widget.date_set(f(dt,groups))
212
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: