Bugfix:Toolbar attribute for menu and tree.
[openerp-client.git] / bin / modules / gui / window / tree.py
blob8215249163b543d460461895197b6b5aef8a9b0e
1 # -*- encoding: utf-8 -*-
2 ##############################################################################
4 # Copyright (c) 2004-2008 TINY SPRL. (http://tiny.be) All Rights Reserved.
6 # $Id$
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
13 # Service Company
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 ##############################################################################
31 import gtk
32 from gtk import glade
33 import gettext
34 import xmlrpclib
36 import common
37 import service
38 import view_tree
39 import rpc
40 import options
41 import win_export
43 class tree(object):
44 def __init__(self, view, model, res_id=False, domain=[], context={}, window=None, name=False):
45 self.glade = glade.XML(common.terp_path("terp.glade"),'win_tree_container',gettext.textdomain())
46 self.widget = self.glade.get_widget('win_tree_container')
47 self.widget.show_all()
48 self.model = view['model']
49 self.domain2 = domain
50 if view.get('field_parent', False):
51 self.domain = []
52 else:
53 self.domain = domain
54 self.view = view
55 self.window=window
57 self.context=context
59 self.tree_res = view_tree.view_tree(view, [], res_id, True, context=context)
60 self.tree_res.view.connect('row-activated', self.sig_open)
62 sel = self.tree_res.view.get_selection()
63 sel.connect('changed', self.expand_one)
65 if not name:
66 self.name = self.tree_res.name
67 else:
68 self.name = name
69 self.vp = self.glade.get_widget('main_tree_sw')
71 wid = self.glade.get_widget('widget_vbox')
72 if options.options['client.modepda'] and not self.tree_res.toolbar:
73 wid.hide()
74 else:
75 wid.show()
77 widget_sc = self.glade.get_widget('win_tree_sc')
78 #imagename = 'tinyerp.png'
80 widget_sc.connect('row-activated', self.sc_go)
81 self.tree_sc = view_tree.view_tree_sc(widget_sc, self.model)
82 self.handlers = {
83 'but_reload': self.sig_reload,
84 'but_switch': self.sig_edit,
85 'but_chroot': self.sig_chroot,
86 'but_open': self.sig_action,
87 'but_action': self.sig_action,
88 'but_print': self.sig_print,
89 'but_print_html': self.sig_print_html,
90 'but_close': self.sig_close,
91 'but_save_as': self.sig_save_as,
93 dict = {
94 'on_but_sc_go_clicked': self.sc_go,
95 'on_but_sc_add_clicked': self.sc_add,
96 'on_but_sc_del_clicked': self.sc_del,
97 'on_but_expand_collapse_clicked': self.expand_collapse_all,
98 'on_tbsc_clicked': self.sc_btn,
101 self.vp.add(self.tree_res.widget_get())
102 self.sig_reload()
104 for signal in dict:
105 self.glade.signal_connect(signal, dict[signal])
106 self.expand = True
108 def sig_reload(self, widget=None):
109 self.tree_sc.update()
110 ids = rpc.session.rpc_exec_auth('/object', 'execute', self.model, 'search', self.domain2)
111 if self.tree_res.toolbar:
112 icon_name = 'icon'
113 wid = self.glade.get_widget('tree_toolbar')
114 for w in wid.get_children():
115 wid.remove(w)
116 c = {}
117 c.update(rpc.session.context)
118 res_ids = rpc.session.rpc_exec_auth_try('/object', 'execute', self.view['model'], 'read', ids, ['name',icon_name], c)
119 rb = None
120 for r in res_ids:
121 rb = gtk.RadioToolButton(group=rb)
122 l = gtk.Label(r['name'])
123 rb.set_label_widget(l)
125 icon = gtk.Image()
126 if icon_name in r:
127 if hasattr(r[icon_name], 'startswith') and r[icon_name].startswith('STOCK_'):
128 icon.set_from_stock(getattr(gtk, r[icon_name]), gtk.ICON_SIZE_BUTTON)
129 else:
130 try:
131 icon.set_from_stock(r[icon_name], gtk.ICON_SIZE_BUTTON)
132 except:
133 pass
135 hb = gtk.HBox(spacing=6)
136 hb.pack_start(icon)
137 hb.pack_start(gtk.Label(r['name']))
138 rb.set_icon_widget(hb)
139 rb.show_all()
140 rb.set_data('id', r['id'])
141 rb.connect('clicked', self.menu_main_clicked)
142 self.menu_main_clicked(rb)
143 wid.insert(rb, -1)
144 else:
145 self.tree_res.ids = ids
146 self.tree_res.reload()
147 wid = self.glade.get_widget('tree_toolbar')
148 wid.hide()
149 wid = self.glade.get_widget('tree_vpaned')
150 wid.set_position(-1)
152 def menu_main_clicked(self, widget):
153 if widget.get_active():
154 id = widget.get_data('id')
156 ids = rpc.session.rpc_exec_auth('/object', 'execute', self.model, 'read', [id], [self.view['field_parent']])[0][self.view['field_parent']]
158 self.tree_res.ids = ids
159 self.tree_res.reload()
160 return False
162 def expand_collapse_all(self, widget):
163 if self.expand:
164 self.tree_res.view.expand_all()
165 else:
166 self.tree_res.view.collapse_all()
167 self.expand = not self.expand
168 if self.expand:
169 widget.set_stock_id('gtk-goto-bottom')
170 else:
171 widget.set_stock_id('gtk-goto-top')
173 def expand_one(self, selection):
174 model,iter = selection.get_selected_rows()
175 if iter:
176 self.tree_res.view.expand_row(iter[0],False)
178 def sig_print_html(self, widget=None, keyword='client_print_multi', id=None):
179 self.sig_action(keyword='client_print_multi', report_type='html')
181 def sig_print(self, widget=None, keyword='client_print_multi', id=None):
182 self.sig_action(keyword='client_print_multi')
184 def sig_action(self, widget=None, keyword='tree_but_action', id=None, report_type='pdf', warning=True):
185 ids = self.ids_get()
187 if not id and ids and len(ids):
188 id = ids[0]
189 if id:
190 ctx = self.context.copy()
191 if 'active_ids' in ctx:
192 del ctx['active_ids']
193 if 'active_id' in ctx:
194 del ctx['active_id']
195 obj = service.LocalService('action.main')
196 return obj.exec_keyword(keyword, {'model':self.model, 'id':id,
197 'ids':ids, 'report_type':report_type, 'window': self.window}, context=ctx,
198 warning=warning)
199 else:
200 common.message(_('No resource selected!'))
201 return False
203 def sig_open(self, widget, iter, path):
204 if not self.sig_action(widget, 'tree_but_open', warning=False):
205 if self.tree_res.view.row_expanded(iter):
206 self.tree_res.view.collapse_row(iter)
207 else:
208 self.tree_res.view.expand_row(iter, False)
211 def sig_remove(self, widget=None):
212 ids = self.ids_get()
213 if len(ids):
214 if common.sur(_('Are you sure you want\nto remove this record?')):
215 try:
216 rpc.session.rpc_exec_auth('/object', 'execute', self.model, 'unlink', ids)
217 self.sig_reload()
218 except xmlrpclib.Fault, err:
219 common.message(_('Error removing resource!'))
221 # TODO: improve with domain expr
222 def sig_chroot(self, widget=None):
223 ids = self.ids_get()
224 if len(ids) and self.domain:
225 id = ids[0]
226 datas = {'domain_field': self.domain[0][0], 'domain_value': id[0], 'res_id':id[0]}
227 obj = service.LocalService('gui.window')
228 obj.create(self.view, self.model, id[0], (self.domain[0],id[0]) )
229 else:
230 common.message(_('Unable to chroot: no tree resource selected'))
232 def sig_new(self, widget=None):
233 #datas = {'res_model':self.model, 'domain_field': self.domain[0], 'domain_value': self.id_get(), 'res_id':None}
234 # domain = self.domain
235 # if self.domain:
236 # id = self.id_get()
237 # if id:
238 # domain=(domain[0],id)
239 obj = service.LocalService('gui.window')
240 obj.create(None, self.model, None, self.domain)
242 def sig_edit(self, widget=None):
243 id = False
244 ids = self.ids_get()
245 if ids:
246 id = ids[0]
247 elif self.tree_res.toolbar:
248 wid = self.glade.get_widget('tree_toolbar')
249 for w in wid.get_children():
250 if w.get_active():
251 id = w.get_data('id')
252 if id:
253 obj = service.LocalService('gui.window')
254 obj.create(None, self.model, id, self.domain)
255 else:
256 common.message(_('No resource selected!'))
258 def domain_id_get(self, tree=False):
259 filter = []
260 if self.domain and self.view.get('field_parent', False):
261 filter = self.domain
262 res = rpc.session.rpc_exec_auth('/object', 'execute', self.model, 'search', filter)
263 return res
265 def sig_printscreen(self, widget=None):
266 ids = self.tree_res.ids
267 pass
269 def sc_btn(self, widget):
270 main = service.LocalService('gui.main')
271 main.shortcut_edit(widget, self.model)
273 def sc_del(self, widget):
274 id = self.tree_sc.sel_id_get()
275 if id!=None:
276 sc_id = int(self.tree_sc.value_get(2))
277 rpc.session.rpc_exec_auth('/object', 'execute', 'ir.ui.view_sc', 'unlink', [sc_id])
278 self.tree_sc.update()
280 def sc_add(self, widget):
281 ids = self.tree_res.sel_ids_get()
282 if len(ids):
283 res = rpc.session.rpc_exec_auth('/object', 'execute', self.model, 'name_get', ids, rpc.session.context)
284 for (id,name) in res:
285 uid = rpc.session.uid
286 rpc.session.rpc_exec_auth('/object', 'execute', 'ir.ui.view_sc', 'create', {'resource':self.model, 'user_id':uid, 'res_id':id, 'name':name})
287 self.tree_sc.update()
289 def sc_go(self, widget=None, *args):
290 id = self.tree_sc.sel_id_get()
291 if id!=None:
292 self.sig_action(None, 'tree_but_open', id)
294 def ids_get(self):
295 res = self.tree_res.sel_ids_get()
296 return res
298 def id_get(self):
299 try:
300 if hasattr(self, 'search'):
301 return self.search[self.search_pos]
302 else:
303 return None
304 except IndexError:
305 return None
307 def destroy(self):
308 pass
310 def sig_close(self, urgent=False):
311 return True
313 def sig_save_as(self, widget=None):
314 fields = []
315 win = win_export.win_export(self.model, self.tree_res.sel_ids_get(),
316 self.tree_res.fields, [], parent=self.window, context=self.context)
317 res = win.go()
320 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: