1 """Components for the managing and visualizing L{qubx.trialset.TrialSet}s.
2
3 Copyright 2012-2014 Research Foundation State University of New York
4 This file is part of QUB Express.
5
6 QUB Express is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 QUB Express is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License,
17 named LICENSE.txt, in the QUB Express program directory. If not, see
18 <http://www.gnu.org/licenses/>.
19
20
21 """
22
23 import os
24 import traceback
25
26 import gtk
27 import gobject
28
29 import qubx.global_namespace
30 import qubx.GTK
31 import qubx.model
32 import qubx.modelGTK
33 import qubx.pyenv
34 import qubx.tableGTK
35 from qubx.GTK import build_menuitem, pack_item, pack_label
36 from qubx.table import COPY_ROWS_ALL, COPY_ROWS_CHECKED, COPY_ROWS_GROUP, COPY_ROWS_CRITERIA
37 from qubx.toolspace import ColorInfo
38 from qubx.util_types import WeakEvent, Reffer, bind
39
40 COLOR_TRIALS_BG = ('trials.model.bg', (.92, .96, 1, 1))
41 ColorInfo[COLOR_TRIALS_BG[0]].label = 'Trials model background'
42
43
61 trialset = property(lambda self: self.__trialset, lambda self, x: self.set_trialset(x))
62 trialset_by_name = property(lambda self: self.__trialset and self.__trialset.trialset_name or "", lambda self, x: self.set_trialset_by_name(x))
97 if trialset == self.__trialset:
98 self.__adjust_ts_closing()
99 del self.trialsets[self.num_indep+ix]
100 del self.trialset_names[self.num_indep+ix]
101 self.OnChangeNames()
127 try:
128 ix = self.trialset_names.index(name)
129 if ix >= self.num_indep:
130 if force or self.prompt_save(self.trialsets[ix], self.__data):
131 self.__data.trials.remove_trialset(name)
132 else:
133 if (not (self.__trialset is None)) and (name == self.__trialset.trialset_name):
134 self.__adjust_ts_closing()
135 self.trialsets[ix].dispose()
136 del self.trialsets[ix]
137 del self.trialset_names[ix]
138 self.num_indep -= 1
139 self.OnChangeNames()
140 except ValueError:
141 pass
143 if len(self.trialsets) == 1:
144 self.trialset = None
145 else:
146 ix = self.trialsets.index(self.__trialset)
147 if ix == 0:
148 self.trialset = self.trialsets[1]
149 else:
150 self.trialset = self.trialsets[ix-1]
151 - def open(self, path=None):
174 - def save(self, path=None, trialset=None):
197 - def prompt_save(self, trialset, data, can_cancel=True):
222 if not (self.__table is None):
223 qubx.global_namespace.QubX.Tables.remove_table(self.__table)
224 self.__table = None
225 if not (ts is None):
226 mnuFile = gtk.Menu()
227 build_menuitem('Open Trials...', self.__ref(self.__onClickOpen), menu=mnuFile)
228 build_menuitem('Save Trials as...', self.__ref(self.__onClickSave), menu=mnuFile)
229 build_menuitem('Close', self.__ref(self.__onClickClose), menu=mnuFile)
230 btnFile = qubx.toolspace.Button_Popup(mnuFile, qubx.tableGTK.COLOR_TABLE_FILE_MENU, "File menu")
231 mnuTrials = qubx.GTK.DynamicComboBox()
232 mnuTrials.OnPopulate += self.__ref(self.__onPopulateTrials)
233 mnuTrials.OnChanged += self.__ref(self.__onChooseTrials)
234 mnuTrials.active_text = ts.trialset_name
235 self.chkInQSF = gtk.CheckButton('keep with data')
236 self.chkInQSF.set_tooltip_text('When checked, the Trials are saved in the QSF (session) file')
237 self.chkInQSF.set_active(ts.in_qsf)
238 self.chkInQSF.connect('toggled', self.__onToggleInQSF)
239 self.chkInQSF.show()
240 controls = qubx.tableGTK.TableViewCtrls(ts, None,
241 btnFile, 'Trials:', mnuTrials, self.chkInQSF,
242 ('Show in Models', bind(qubx.global_namespace.QubX.Models.set_index, 0)),
243 qubx.tableGTK.TableViewCtrls.REMOVE,
244 ('Copy row(s) to...', self.copy_rows),
245 qubx.tableGTK.TableViewCtrls.CALCULATE,
246 qubx.tableGTK.TableViewCtrls.PLOT,
247 qubx.tableGTK.TableViewCtrls.CLOSE)
248 controls.OnClickClose += self.__ref(self.__onClickClose)
249 Tables = qubx.global_namespace.QubX.Tables
250 Tables.add_table(ts, None, controls)
251 self.__table = ts
252 Tables.show_table(ts)
264 self.trialset = self.trialsets[self.trialset_names.index(ts_name)]
265 - def copy_rows(self, out_name=None, copy_rows_type=None, group=None, inverse=False, criteria=None):
266 tbn, crt, grp, inv, cta = qubx.tableGTK.prompt_copy_rows(self.trialset, self.trialset.trialset_name, self.trialset_names,
267 out_name, copy_rows_type, group, inverse, criteria)
268 if crt is None:
269 return
270 if crt == COPY_ROWS_ALL:
271 qubx.pyenv.env.OnScriptable('QubX.Trials.copy_rows(out_name=%s, copy_rows_type=COPY_ROWS_ALL)'
272 % repr(tbn))
273 elif crt == COPY_ROWS_GROUP:
274 qubx.pyenv.env.OnScriptable('QubX.Trials.copy_rows(out_name=%s, copy_rows_type=COPY_ROWS_GROUP, group=%s, inverse=%s)'
275 % (repr(tbn),
276 repr(grp), repr(inv)))
277 elif crt == COPY_ROWS_CRITERIA:
278 qubx.pyenv.env.OnScriptable('QubX.Trials.copy_rows(out_name=%s, copy_rows_type=COPY_ROWS_CRITERIA, criteria=%s)'
279 % (repr(tbn), repr(cta)))
280 elif crt == COPY_ROWS_CHECKED:
281 qubx.pyenv.env.OnScriptable('QubX.Trials.copy_rows(out_name=%s, copy_rows_type=COPY_ROWS_CHECKED)'
282 % repr(tbn))
283 from_ts = self.trialset
284 ts = self.trialset = self.get_trialset(tbn)
285 gobject.idle_add(qubx.global_namespace.QubX.Tables.show_table, ts)
286 ts.copy_rows_from(from_ts, copy_rows_type=crt, group=grp, inverse=inv, criteria=cta, on_copy=self.__onCopyRow)
287 return ts
288 - def __onCopyRow(self, from_list, from_i, to_list, to_i):
289 to_list.models[to_i] = from_list.models[from_i].clone()
290
292 - def __init__(self, models_table=None, menu_width=32):
298