1 # -*- encoding: utf-8 -*-
2 ##############################################################################
4 # Copyright (c) 2004-2008 TINY SPRL. (http://tiny.be) All Rights Reserved.
8 # WARNING: This program as such is intended to be used by professional
9 # programmers who take the whole responsability of assessing all potential
10 # consequences resulting from its eventual inadequacies and bugs
11 # End users who are looking for a ready-to-use solution with commercial
12 # garantees and support are strongly adviced to contract a Free Software
15 # This program is Free Software; you can redistribute it and/or
16 # modify it under the terms of the GNU General Public License
17 # as published by the Free Software Foundation; either version 2
18 # of the License, or (at your option) any later version.
20 # This program is distributed in the hope that it will be useful,
21 # but WITHOUT ANY WARRANTY; without even the implied warranty of
22 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 # GNU General Public License for more details.
25 # You should have received a copy of the GNU General Public License
26 # along with this program; if not, write to the Free Software
27 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 ##############################################################################
41 from tools
import date_mapping
44 from mx
.DateTime
import DateTime
47 class DecoratorRenderer(gtk
.GenericCellRenderer
):
48 def __init__(self
, renderer1
, callback
, format
):
49 self
.__gobject
_init
__()
50 self
.renderer1
= renderer1
51 self
.set_property("mode", renderer1
.get_property("mode"))
52 self
.callback
= callback
54 self
.regex
= self
.initial_value
= self
.format
55 for key
,val
in date_mapping
.items():
56 self
.regex
= self
.regex
.replace(key
, val
[1])
57 self
.initial_value
= self
.initial_value
.replace(key
, val
[0])
58 self
.regex
= '^'+self
.regex
+'$'
60 def set_property(self
, name
, value
):
61 if name
not in ('editable', ):
62 return super(DecoratorRenderer
, self
).set_property(name
, value
)
64 return self
.renderer1
.set_property(name
, value
)
66 def get_property(self
, name
):
67 if name
in ('editable', ):
68 return self
.renderer1
.get_property(name
)
70 return super(DecoratorRenderer
, self
).get_property(name
)
72 def on_get_size(self
, widget
, cell_area
=None):
73 return self
.renderer1
.get_size(widget
, cell_area
)
75 def on_render(self
, window
, widget
, background_area
, cell_area
, expose_area
, flags
):
76 return self
.renderer1
.render(window
, widget
, background_area
, cell_area
, expose_area
, flags
)
78 def on_activate(self
, event
, widget
, path
, background_area
, cell_area
, flags
):
79 return self
.renderer1
.activate(event
, widget
, path
, background_area
, cell_area
, flags
)
81 def on_start_editing(self
, event
, widget
, path
, background_area
, cell_area
, flags
):
83 event
= gtk
.gdk
.Event(gtk
.keysyms
.Tab
)
85 editable
= self
.renderer1
.start_editing(event
, widget
, path
, background_area
, cell_area
, flags
)
86 self
.editable
= editable
87 self
.callback
.display(editable
)
89 if not editable
.get_text():
90 editable
.set_text(self
.initial_value
)
91 self
.regex
= re
.compile(self
.regex
)
93 assert self
.regex
.match(self
.initial_value
), 'Error, the initial value should be validated by regex'
94 editable
.set_width_chars(len(self
.initial_value
))
95 editable
.set_max_length(len(self
.initial_value
))
97 editable
.connect('key-press-event', self
._on
_key
_press
)
100 self
._interactive
_input
= True
101 self
.mode_cmd
= False
102 gobject
.idle_add(editable
.set_position
, 0)
105 def _on_delete_text(self
, editable
, start
, end
):
106 while (start
>0) and (self
.initial_value
[start
] not in ['_','0','X']):
108 text
= editable
.get_text()
109 text
= text
[:start
] + self
.initial_value
[start
:end
] + text
[end
:]
110 editable
.set_text(text
)
111 gobject
.idle_add(editable
.set_position
, start
)
114 def date_get(self
, editable
):
115 tt
= time
.strftime(self
.format
, time
.localtime())
116 tc
= editable
.get_text()
117 if tc
==self
.initial_value
:
119 for a
in range(len(self
.initial_value
)):
120 if self
.initial_value
[a
] == tc
[a
]:
121 tc
= tc
[:a
] + tt
[a
] + tc
[a
+1:]
123 editable
.set_text(tc
)
124 return time
.strptime(tc
, self
.format
)
127 editable
.set_text(tc
)
128 return time
.strptime(tc
, self
.format
)
130 def _on_key_press(self
, editable
, event
):
131 if event
.keyval
in (gtk
.keysyms
.Tab
, gtk
.keysyms
.Escape
, gtk
.keysyms
.Return
):
133 self
.mode_cmd
= False
134 if self
.callback
: self
.callback
.process(self
, event
)
135 #self.stop_emission("key-press-event")
139 elif event
.keyval
in (ord('+'),ord('-'),ord('=')):
141 self
.date_get(editable
)
142 if self
.callback
: self
.callback
.event(self
, event
)
145 if self
.callback
: self
.callback
.event(self
, event
)
148 if event
.keyval
in (gtk
.keysyms
.BackSpace
,):
149 pos
= editable
.get_position()
150 self
._on
_delete
_text
(editable
, max(0,pos
-1), pos
)
152 if event
.keyval
in (gtk
.keysyms
.Delete
,):
153 pos
= editable
.get_position()
154 text
= editable
.get_text()
155 self
._on
_delete
_text
(editable
, pos
, len(text
))
158 if event
.keyval
>=ord('0') and event
.keyval
<=ord('9'):
159 pos
= editable
.get_position()
160 text
= editable
.get_text()
161 text
= text
[:pos
] + chr(event
.keyval
) + text
[pos
+ 1:]
162 if self
.regex
.match(text
):
164 while (pos
<len(self
.initial_value
)) and (self
.initial_value
[pos
] not in ['_','0','X']):
166 editable
.set_text(text
)
168 gobject
.idle_add(editable
.set_position
, pos
)
174 def date_set(self
, dt
):
176 self
.editable
.set_text( dt
.strftime(self
.format
) )
178 self
.editable
.set_text(self
.initial_value
)
181 class date_callback(object):
182 def __init__(self
, treeview
=None):
184 self
.treeview
= treeview
186 def event(self
, widget
, event
):
187 if event
.keyval
in (gtk
.keysyms
.BackSpace
,):
188 self
.value
= self
.value
[:-1]
190 self
.value
= self
.value
+chr(event
.keyval
)
194 def display(self
, widget
):
197 self
.treeview
.warn('misc-message', '<b>' + str(tools
.to_xml(self
.value
))+"</b>")
199 self
.treeview
.warn('misc-message', _("Press <i>'+'</i>, <i>'-'</i> or <i>'='</i> for special date operations."))
201 def process(self
, widget
, event
):
202 if (not event
.keyval
== gtk
.keysyms
.Escape
) or not event
:
204 for r
,f
in tools
.date_operation
.items():
205 groups
= re
.match(r
, cmd
)
207 dt
= widget
.date_get(widget
.editable
)
209 dt
= time
.strftime(widget
.format
, time
.localtime())
210 dt
= time
.strptime(dt
, widget
.format
)
211 widget
.date_set(f(dt
,groups
))