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 ##############################################################################
45 from gtk
.gdk
import Color
54 from observator
import oregistry
55 from widget
.screen
import Screen
59 def __init__(self
, model
, res_id
=False, domain
=None, view_type
=None,
60 view_ids
=None, window
=None, context
=None, name
=False, limit
=80,
63 view_type
= ['form','tree']
74 self
.previous_action
= None
75 self
.glade
= glade
.XML(common
.terp_path("openerp.glade"),'win_form_container',gettext
.textdomain())
76 self
.widget
= self
.glade
.get_widget('win_form_container')
77 self
.widget
.show_all()
80 self
.context
= context
82 self
.screen
= Screen(self
.model
, view_type
=view_type
,
83 context
=self
.context
, view_ids
=view_ids
, domain
=domain
,
84 hastoolbar
=options
.options
['form.toolbar'], show_search
=True,
85 window
=self
.window
, limit
=limit
, readonly
=bool(auto_refresh
))
86 self
.screen
.signal_connect(self
, 'record-message', self
._record
_message
)
87 self
.screen
.widget
.show()
88 oregistry
.add_receiver('misc-message', self
._misc
_message
)
91 self
.name
= self
.screen
.current_view
.title
95 vp
.set_shadow_type(gtk
.SHADOW_NONE
)
96 vp
.add(self
.screen
.widget
)
98 self
.sw
= gtk
.ScrolledWindow()
99 self
.sw
.set_shadow_type(gtk
.SHADOW_NONE
)
100 self
.sw
.set_policy(gtk
.POLICY_AUTOMATIC
, gtk
.POLICY_AUTOMATIC
)
104 self
.has_backup
= False
107 self
.widget
.pack_start(self
.sw
)
109 'but_new': self
.sig_new
,
110 'but_copy': self
.sig_copy
,
111 'but_save': self
.sig_save
,
112 'but_save_as': self
.sig_save_as
,
113 'but_import': self
.sig_import
,
114 'but_print_repeat': self
.sig_print_repeat
,
115 'but_remove': self
.sig_remove
,
116 'but_search': self
.sig_search
,
117 'but_previous': self
.sig_previous
,
118 'but_next': self
.sig_next
,
119 'but_goto_id': self
.sig_goto
,
120 'but_log': self
.sig_logs
,
121 'but_print': self
.sig_print
,
122 'but_reload': self
.sig_reload
,
123 'but_print_html': self
.sig_print_html
,
124 'but_action': self
.sig_action
,
125 'but_switch': self
.sig_switch
,
126 'but_attach': self
.sig_attach
,
127 'but_close': self
.sig_close
,
129 if 'tree' in view_type
:
130 self
.handlers
['radio_tree'] = self
.sig_switch_tree
131 if 'form' in view_type
:
132 self
.handlers
['radio_form'] = self
.sig_switch_form
133 if 'graph' in view_type
:
134 self
.handlers
['radio_graph'] = self
.sig_switch_graph
135 if 'calendar' in view_type
:
136 self
.handlers
['radio_calendar'] = self
.sig_switch_calendar
138 if isinstance(res_id
, int):
140 self
.screen
.load(res_id
)
142 if self
.screen
.current_view
.view_type
== 'form':
143 self
.sig_new(autosave
=False)
144 if self
.screen
.current_view
.view_type
in ('tree', 'graph'):
145 self
.screen
.search_filter()
147 if auto_refresh
and int(auto_refresh
):
148 gobject
.timeout_add(int(auto_refresh
) * 1000, self
.sig_reload
)
150 def sig_switch_form(self
, widget
=None):
151 return self
.sig_switch(widget
, 'form')
153 def sig_switch_tree(self
, widget
=None):
154 return self
.sig_switch(widget
, 'tree')
156 def sig_switch_calendar(self
, widget
=None):
157 return self
.sig_switch(widget
, 'calendar')
159 def sig_switch_graph(self
, widget
=None):
160 return self
.sig_switch(widget
, 'graph')
162 def sig_goto(self
, *args
):
163 if not self
.modified_save():
165 glade2
= glade
.XML(common
.terp_path("openerp.glade"),'dia_goto_id',gettext
.textdomain())
166 widget
= glade2
.get_widget('goto_spinbutton')
167 win
= glade2
.get_widget('dia_goto_id')
168 win
.set_transient_for(self
.window
)
173 if response
== gtk
.RESPONSE_OK
:
174 self
.screen
.load( [int(widget
.get_value())] )
177 oregistry
.remove_receiver('misc-message', self
._misc
_message
)
178 self
.screen
.signal_unconnect(self
)
179 self
.screen
.destroy()
188 return self
.screen
.ids_get()
191 return self
.screen
.id_get()
193 def sig_attach(self
, widget
=None):
194 id = self
.screen
.id_get()
197 win
= win_attach
.win_attach(self
.model
, id, parent
=self
.window
)
200 self
.message_state(_('No record selected ! You can only attach to existing record.'), color
='red')
203 def sig_switch(self
, widget
=None, mode
=None):
204 if not self
.modified_save():
206 if mode
<>self
.screen
.current_view
.view_type
:
207 self
.screen
.switch_view(mode
=mode
)
210 return self
.screen
.id_get()
212 def sig_logs(self
, widget
=None):
215 self
.message_state(_('You have to select a record !'), color
='red')
217 res
= rpc
.session
.rpc_exec_auth('/object', 'execute', self
.model
, 'perm_read', [id])
222 ('create_uid', _('Creation User')),
223 ('create_date', _('Creation Date')),
224 ('write_uid', _('Latest Modification by')),
225 ('write_date', _('Latest Modification Date'))
227 for (key
,val
) in todo
:
228 if line
[key
] and key
in ('create_uid','write_uid','uid'):
229 line
[key
] = line
[key
][1]
230 message
+=val
+': '+str(line
[key
] or '/')+'\n'
231 common
.message(message
)
234 def sig_remove(self
, widget
=None):
235 if not self
._id
_get
():
236 msg
= _('Record is not saved ! \n Do You want to Clear Current Record ?')
238 if self
.screen
.current_view
.view_type
== 'form':
239 msg
= _('Are you sure to remove this record ?')
241 msg
= _('Are you sure to remove those records ?')
243 id = self
.screen
.remove(unlink
=True)
245 self
.message_state(_('Resources cleared.'), color
='darkgreen')
247 self
.message_state(_('Resources successfully removed.'), color
='darkgreen')
249 def sig_import(self
, widget
=None):
251 while(self
.screen
.view_to_load
):
252 self
.screen
.load_view_to_load()
253 win
= win_import
.win_import(self
.model
, self
.screen
.fields
, fields
, parent
=self
.window
)
256 def sig_save_as(self
, widget
=None):
258 while(self
.screen
.view_to_load
):
259 self
.screen
.load_view_to_load()
260 win
= win_export
.win_export(self
.model
, self
.screen
.ids_get(), self
.screen
.fields
, fields
, parent
=self
.window
, context
=self
.context
)
263 def sig_new(self
, widget
=None, autosave
=True):
265 if not self
.modified_save():
268 self
.message_state('')
270 def sig_copy(self
, *args
):
271 if not self
.modified_save():
273 res_id
= self
._id
_get
()
274 ctx
= self
.context
.copy()
275 ctx
.update(rpc
.session
.context
)
276 new_id
= rpc
.session
.rpc_exec_auth('/object', 'execute', self
.model
, 'copy', res_id
, {}, ctx
)
278 self
.screen
.load([new_id
])
279 self
.message_state(_('Working now on the duplicated document !'))
281 def _form_save(self
, auto_continue
=True):
284 def sig_save(self
, widget
=None, sig_new
=True, auto_continue
=True):
285 id = self
.screen
.save_current()
287 self
.message_state(_('Document Saved.'), color
="darkgreen")
289 self
.message_state(_('Invalid form, correct red fields !'), color
="red")
292 def sig_previous(self
, widget
=None):
293 if not self
.modified_save():
295 self
.screen
.display_prev()
296 self
.message_state('')
298 def sig_next(self
, widget
=None):
299 if not self
.modified_save():
301 self
.screen
.display_next()
302 self
.message_state('')
304 def sig_reload(self
, test_modified
=True):
305 if not hasattr(self
, 'screen'):
307 if test_modified
and self
.screen
.is_modified():
308 res
= common
.sur_3b(_('This record has been modified\n' \
309 'do you want to save it ?'))
316 if self
.screen
.current_view
.view_type
== 'form':
317 self
.screen
.cancel_current()
318 self
.screen
.display()
320 id = self
.screen
.id_get()
321 self
.screen
.search_filter()
322 for model
in self
.screen
.models
:
324 self
.screen
.current_model
= model
325 self
.screen
.display()
327 self
.message_state('')
330 def sig_action(self
, keyword
='client_action_multi', previous
=False, report_type
='pdf', adds
={}):
331 ids
= self
.screen
.ids_get()
332 if self
.screen
.current_model
:
333 id = self
.screen
.current_model
.id
336 if self
.screen
.current_view
.view_type
== 'form':
337 id = self
.screen
.save_current()
341 if self
.screen
.current_view
.view_type
== 'tree':
342 sel_ids
= self
.screen
.current_view
.sel_ids_get()
346 obj
= service
.LocalService('action.main')
347 if previous
and self
.previous_action
:
348 obj
._exec
_action
(self
.previous_action
[1], {'model':self
.screen
.resource
, 'id': id or False, 'ids':ids
, 'report_type': report_type
}, self
.screen
.context
)
350 res
= obj
.exec_keyword(keyword
, {'model':self
.screen
.resource
, 'id': id or False, 'ids':ids
, 'report_type': report_type
}, adds
, self
.screen
.context
)
352 self
.previous_action
= res
353 self
.sig_reload(test_modified
=False)
355 self
.message_state(_('You must select one or several records !'),color
='red')
357 def sig_print_repeat(self
):
358 self
.sig_action('client_print_multi', True)
360 def sig_print_html(self
):
361 self
.sig_action('client_print_multi', report_type
='html')
364 self
.sig_action('client_print_multi', adds
={_('Print Screen'): {'report_name':'printscreen.list', 'name':_('Print Screen'), 'type':'ir.actions.report.xml'}})
366 def sig_search(self
, widget
=None):
367 if not self
.modified_save():
370 win
= win_search
.win_search(self
.model
, domain
=self
.domain
, context
=self
.context
, parent
=self
.window
)
374 self
.screen
.load(res
)
376 def message_state(self
, message
, context
='message', color
=None):
377 sb
= self
.glade
.get_widget('stat_state')
378 if color
is not None:
379 message
= '<span foreground="%s">%s</span>' % (color
, message
)
380 sb
.set_label(message
)
382 def _record_message(self
, screen
, signal_data
):
383 if not signal_data
[3]:
384 msg
= _('No record selected')
387 if signal_data
[0]>=0:
388 name
= str(signal_data
[0]+1)
389 name2
= _('New document')
391 name2
= _('Editing document (id: ')+str(signal_data
[3])+')'
392 msg
= _('Record: ') + name
+ ' / ' + str(signal_data
[1]) + \
393 _(' of ') + str(signal_data
[2]) + ' - ' + name2
394 sb
= self
.glade
.get_widget('stat_form')
395 cid
= sb
.get_context_id('message')
398 def _misc_message(self
, obj
, message
, color
=None):
399 self
.message_state(message
, color
=color
)
401 def modified_save(self
, reload=True):
402 if self
.screen
.is_modified():
403 value
= common
.sur_3b(_('This record has been modified\ndo you want to save it ?'))
405 return self
.sig_save()
408 self
.sig_reload(test_modified
=False)
414 def sig_close(self
, urgent
=False):
415 return self
.modified_save(reload=False)
417 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: