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 ##############################################################################
31 from rpc
import RPCProxy
33 from record
import ModelRecord
41 from sets
import Set
as set
43 class ModelList(list):
44 def __init__(self
, screen
):
45 super(ModelList
, self
).__init
__()
46 self
.lock_signal
= False
47 self
.__screen
= screen
49 def insert(self
, pos
, obj
):
50 super(ModelList
, self
).insert(pos
, obj
)
51 if not self
.lock_signal
:
52 self
.__screen
.signal('record-changed', ('record-added', pos
))
54 def append(self
, obj
):
55 super(ModelList
, self
).append(obj
)
56 if not self
.lock_signal
:
57 self
.__screen
.signal('record-changed', ('record-added', -1))
59 def move(self
, obj
, pos
):
60 self
.lock_signal
= True
61 if self
.__len
__() > pos
:
70 self
.lock_signal
= False
72 def remove(self
, obj
):
74 super(ModelList
, self
).remove(obj
)
75 if not self
.lock_signal
:
76 self
.__screen
.signal('record-changed', ('record-removed', idx
))
79 for obj
in range(len(self
)):
81 if not self
.lock_signal
:
82 self
.__screen
.signal('record-changed', ('record-removed', len(self
)))
84 def __setitem__(self
, key
, value
):
85 super(ModelList
, self
).__setitem
__(key
, value
)
86 if not self
.lock_signal
:
87 self
.__screen
.signal('record-changed', ('record-changed', key
))
89 class ModelRecordGroup(signal_event
.signal_event
):
90 def __init__(self
, resource
, fields
, ids
=[], parent
=None, context
={}):
91 super(ModelRecordGroup
, self
).__init
__()
93 self
._context
= context
94 self
._context
.update(rpc
.session
.context
)
95 self
.resource
= resource
96 self
.rpc
= RPCProxy(resource
)
99 self
.mfields_load(fields
.keys(), self
)
101 self
.models
= ModelList(self
)
102 self
.current_idx
= None
105 self
.model_removed
= []
108 def mfields_load(self
, fkeys
, models
):
110 fvalue
= models
.fields
[fname
]
111 modelfield
= field
.ModelField(fvalue
['type'])
112 fvalue
['name'] = fname
113 models
.mfields
[fname
] = modelfield(models
, fvalue
)
115 def model_move(self
, model
, position
=0):
116 self
.models
.move(model
, position
)
118 def set_sequence(self
, field
='sequence'):
120 for model
in self
.models
:
122 if index
>= model
[field
].get(model
):
124 model
[field
].set(model
, index
, modified
=True)
126 index
= model
[field
].get(model
)
131 for model
in self
.models
:
135 def writen(self
, edited_id
):
136 if not self
.on_write
:
138 new_ids
= getattr(self
.rpc
, self
.on_write
)(edited_id
, self
.context
)
139 model_idx
= self
.models
.index(self
[edited_id
])
143 for m
in self
.models
:
149 newmod
= ModelRecord(self
.resource
, id, parent
=self
.parent
, group
=self
)
153 new_index
= min(model_idx
, len(self
.models
)-1)
154 self
.model_add(newmod
, new_index
)
157 def pre_load(self
, ids
, display
=True):
161 self
.models
.lock_signal
= True
163 newmod
= ModelRecord(self
.resource
, id, parent
=self
.parent
, group
=self
)
164 self
.model_add(newmod
)
166 self
.signal('model-changed', newmod
)
168 self
.models
.lock_signal
= False
169 self
.signal('record-cleared')
172 def load_for(self
, values
):
174 self
.models
.lock_signal
= True
176 newmod
= ModelRecord(self
.resource
, value
['id'], parent
=self
.parent
, group
=self
)
178 self
.models
.append(newmod
)
179 newmod
.signal_connect(self
, 'record-changed', self
._record
_changed
)
181 self
.models
.lock_signal
= False
182 self
.signal('record-cleared')
184 def load(self
, ids
, display
=True):
188 return self
.pre_load(ids
, display
)
189 c
= rpc
.session
.context
.copy()
190 c
.update(self
.context
)
191 values
= self
.rpc
.read(ids
, self
.fields
.keys(), c
)
195 self
.load_for(values
)
196 if newmod
and display
:
197 self
.signal('model-changed', newmod
)
203 self
.model_removed
= []
205 def getContext(self
):
207 ctx
.update(self
._context
)
208 #ctx['active_ids'] = [model.id for model in self.models if model.id]
209 #if self.current_idx is not None:
210 # ctx['active_id'] = self.models[self.current_idx].id or False
212 # ctx['active_id'] = False
214 context
= property(getContext
)
216 def model_add(self
, model
, position
=-1):
220 if not model
.mgroup
is self
:
222 for mf
in model
.mgroup
.fields
:
223 fields
[model
.mgroup
.fields
[mf
]['name']] = model
.mgroup
.fields
[mf
]
224 self
.add_fields(fields
, self
)
225 self
.add_fields(self
.fields
, model
.mgroup
)
229 self
.models
.append(model
)
231 self
.models
.insert(position
, model
)
232 self
.current_idx
= position
233 model
.parent
= self
.parent
234 model
.signal_connect(self
, 'record-changed', self
._record
_changed
)
237 def model_new(self
, default
=True, domain
=[], context
={}):
238 newmod
= ModelRecord(self
.resource
, None, group
=self
,
239 parent
=self
.parent
, new
=True)
240 newmod
.signal_connect(self
, 'record-changed', self
._record
_changed
)
243 ctx
.update(self
.context
)
244 newmod
.default_get(domain
, ctx
)
245 self
.signal('model-changed', newmod
)
248 def model_remove(self
, model
):
249 idx
= self
.models
.index(model
)
250 self
.models
.remove(model
)
252 model
.parent
.modified
= True
254 self
.current_idx
= min(idx
, len(self
.models
)-1)
256 self
.current_idx
= None
258 def _record_changed(self
, model
, signal_data
):
259 self
.signal('model-changed', model
)
262 if self
.models
and self
.current_idx
is not None:
263 self
.current_idx
= (self
.current_idx
- 1) % len(self
.models
)
268 return self
.models
[self
.current_idx
]
271 if self
.models
and self
.current_idx
is not None:
272 self
.current_idx
= (self
.current_idx
+ 1) % len(self
.models
)
277 return self
.models
[self
.current_idx
]
279 def remove(self
, model
):
281 idx
= self
.models
.index(model
)
282 if self
.models
[idx
].id:
283 self
.model_removed
.append(self
.models
[idx
].id)
285 model
.parent
.modified
= True
286 self
.models
.remove(self
.models
[idx
])
290 def add_fields_custom(self
, fields
, models
):
292 for f
in fields
.keys():
293 if not f
in models
.fields
:
294 models
.fields
[f
] = fields
[f
]
295 models
.fields
[f
]['name'] = f
298 models
.fields
[f
].update(fields
[f
])
299 self
.mfields_load(to_add
, models
)
301 for m
in models
.models
:
302 m
.value
[fname
] = self
.mfields
[fname
].create(m
)
305 def add_fields(self
, fields
, models
, context
=None):
310 to_add
= self
.add_fields_custom(fields
, models
)
311 models
= models
.models
323 if len(old
) and len(to_add
):
324 ctx
.update(rpc
.session
.context
)
325 ctx
.update(self
.context
)
330 if fields
[f
]['type'] in ('image','binary'):
331 to_add_binary
.append(f
)
333 to_add_normal
.append(f
)
335 values
= self
.rpc
.read(old
, to_add_normal
, ctx
)
339 if 'id' not in to_add
:
341 self
[id].set(v
, signal
=False)
344 for b
in to_add_binary
:
346 for m
in self
.models
:
349 # values = self.rpc.read(old, to_add, ctx)
353 # if 'id' not in to_add:
355 # self[id].set(v, signal=False)
356 if len(new
) and len(to_add
):
357 ctx
.update(self
.context
)
358 values
= self
.rpc
.default_get(to_add
, ctx
)
363 mod
.set_default(values
)
366 return iter(self
.models
)
368 def get_by_id(self
, id):
369 for model
in self
.models
:
373 __getitem__
= get_by_id
376 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: