scipion-pyworkflow 3.10.6__py3-none-any.whl → 3.11.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. pyworkflow/config.py +131 -67
  2. pyworkflow/constants.py +2 -1
  3. pyworkflow/plugin.py +93 -44
  4. pyworkflow/resources/showj/arrowDown.png +0 -0
  5. pyworkflow/resources/showj/arrowUp.png +0 -0
  6. pyworkflow/resources/showj/background_section.png +0 -0
  7. pyworkflow/resources/showj/colRowModeOff.png +0 -0
  8. pyworkflow/resources/showj/colRowModeOn.png +0 -0
  9. pyworkflow/resources/showj/delete.png +0 -0
  10. pyworkflow/resources/showj/doc_icon.png +0 -0
  11. pyworkflow/resources/showj/download_icon.png +0 -0
  12. pyworkflow/resources/showj/enabled_gallery.png +0 -0
  13. pyworkflow/resources/showj/galleryViewOff.png +0 -0
  14. pyworkflow/resources/showj/galleryViewOn.png +0 -0
  15. pyworkflow/resources/showj/goto.png +0 -0
  16. pyworkflow/resources/showj/menu.png +0 -0
  17. pyworkflow/resources/showj/separator.png +0 -0
  18. pyworkflow/resources/showj/tableViewOff.png +0 -0
  19. pyworkflow/resources/showj/tableViewOn.png +0 -0
  20. pyworkflow/resources/showj/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  21. pyworkflow/resources/showj/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  22. pyworkflow/resources/showj/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  23. pyworkflow/resources/showj/volumeOff.png +0 -0
  24. pyworkflow/resources/showj/volumeOn.png +0 -0
  25. pyworkflow/viewer.py +23 -1
  26. pyworkflowtests/protocols.py +1 -3
  27. {scipion_pyworkflow-3.10.6.dist-info → scipion_pyworkflow-3.11.0.dist-info}/METADATA +13 -27
  28. scipion_pyworkflow-3.11.0.dist-info/RECORD +71 -0
  29. {scipion_pyworkflow-3.10.6.dist-info → scipion_pyworkflow-3.11.0.dist-info}/WHEEL +1 -1
  30. pyworkflow/apps/__init__.py +0 -29
  31. pyworkflow/apps/pw_manager.py +0 -37
  32. pyworkflow/apps/pw_plot.py +0 -51
  33. pyworkflow/apps/pw_project.py +0 -113
  34. pyworkflow/apps/pw_protocol_list.py +0 -143
  35. pyworkflow/apps/pw_protocol_run.py +0 -51
  36. pyworkflow/apps/pw_run_tests.py +0 -267
  37. pyworkflow/apps/pw_schedule_run.py +0 -322
  38. pyworkflow/apps/pw_sleep.py +0 -37
  39. pyworkflow/apps/pw_sync_data.py +0 -439
  40. pyworkflow/apps/pw_viewer.py +0 -78
  41. pyworkflow/gui/__init__.py +0 -36
  42. pyworkflow/gui/browser.py +0 -726
  43. pyworkflow/gui/canvas.py +0 -1190
  44. pyworkflow/gui/dialog.py +0 -977
  45. pyworkflow/gui/form.py +0 -2637
  46. pyworkflow/gui/graph.py +0 -247
  47. pyworkflow/gui/graph_layout.py +0 -271
  48. pyworkflow/gui/gui.py +0 -566
  49. pyworkflow/gui/matplotlib_image.py +0 -233
  50. pyworkflow/gui/plotter.py +0 -247
  51. pyworkflow/gui/project/__init__.py +0 -25
  52. pyworkflow/gui/project/base.py +0 -192
  53. pyworkflow/gui/project/constants.py +0 -139
  54. pyworkflow/gui/project/labels.py +0 -205
  55. pyworkflow/gui/project/project.py +0 -492
  56. pyworkflow/gui/project/searchprotocol.py +0 -154
  57. pyworkflow/gui/project/searchrun.py +0 -181
  58. pyworkflow/gui/project/steps.py +0 -171
  59. pyworkflow/gui/project/utils.py +0 -332
  60. pyworkflow/gui/project/variables.py +0 -179
  61. pyworkflow/gui/project/viewdata.py +0 -472
  62. pyworkflow/gui/project/viewprojects.py +0 -510
  63. pyworkflow/gui/project/viewprotocols.py +0 -2093
  64. pyworkflow/gui/project/viewprotocols_extra.py +0 -559
  65. pyworkflow/gui/text.py +0 -771
  66. pyworkflow/gui/tooltip.py +0 -185
  67. pyworkflow/gui/tree.py +0 -684
  68. pyworkflow/gui/widgets.py +0 -307
  69. pyworkflow/mapper/__init__.py +0 -26
  70. pyworkflow/mapper/mapper.py +0 -222
  71. pyworkflow/mapper/sqlite.py +0 -1581
  72. pyworkflow/mapper/sqlite_db.py +0 -145
  73. pyworkflow/project/__init__.py +0 -31
  74. pyworkflow/project/config.py +0 -454
  75. pyworkflow/project/manager.py +0 -180
  76. pyworkflow/project/project.py +0 -2007
  77. pyworkflow/protocol/__init__.py +0 -38
  78. pyworkflow/protocol/bibtex.py +0 -48
  79. pyworkflow/protocol/constants.py +0 -87
  80. pyworkflow/protocol/executor.py +0 -471
  81. pyworkflow/protocol/hosts.py +0 -314
  82. pyworkflow/protocol/launch.py +0 -270
  83. pyworkflow/protocol/package.py +0 -42
  84. pyworkflow/protocol/params.py +0 -741
  85. pyworkflow/protocol/protocol.py +0 -2641
  86. pyworkflow/tests/__init__.py +0 -29
  87. pyworkflow/tests/test_utils.py +0 -25
  88. pyworkflow/tests/tests.py +0 -341
  89. pyworkflow/utils/__init__.py +0 -38
  90. pyworkflow/utils/dataset.py +0 -414
  91. pyworkflow/utils/echo.py +0 -104
  92. pyworkflow/utils/graph.py +0 -169
  93. pyworkflow/utils/log.py +0 -284
  94. pyworkflow/utils/path.py +0 -528
  95. pyworkflow/utils/process.py +0 -153
  96. pyworkflow/utils/profiler.py +0 -92
  97. pyworkflow/utils/progressbar.py +0 -154
  98. pyworkflow/utils/properties.py +0 -631
  99. pyworkflow/utils/reflection.py +0 -129
  100. pyworkflow/utils/utils.py +0 -879
  101. pyworkflow/utils/which.py +0 -229
  102. pyworkflow/webservices/__init__.py +0 -8
  103. pyworkflow/webservices/config.py +0 -11
  104. pyworkflow/webservices/notifier.py +0 -162
  105. pyworkflow/webservices/repository.py +0 -59
  106. pyworkflow/webservices/workflowhub.py +0 -74
  107. pyworkflowtests/tests/__init__.py +0 -0
  108. pyworkflowtests/tests/test_canvas.py +0 -72
  109. pyworkflowtests/tests/test_domain.py +0 -45
  110. pyworkflowtests/tests/test_logs.py +0 -74
  111. pyworkflowtests/tests/test_mappers.py +0 -392
  112. pyworkflowtests/tests/test_object.py +0 -507
  113. pyworkflowtests/tests/test_project.py +0 -42
  114. pyworkflowtests/tests/test_protocol_execution.py +0 -142
  115. pyworkflowtests/tests/test_protocol_export.py +0 -78
  116. pyworkflowtests/tests/test_protocol_output.py +0 -158
  117. pyworkflowtests/tests/test_streaming.py +0 -47
  118. pyworkflowtests/tests/test_utils.py +0 -210
  119. scipion_pyworkflow-3.10.6.dist-info/RECORD +0 -140
  120. scipion_pyworkflow-3.10.6.dist-info/dependency_links.txt +0 -1
  121. {scipion_pyworkflow-3.10.6.dist-info → scipion_pyworkflow-3.11.0.dist-info}/entry_points.txt +0 -0
  122. {scipion_pyworkflow-3.10.6.dist-info → scipion_pyworkflow-3.11.0.dist-info}/licenses/LICENSE.txt +0 -0
  123. {scipion_pyworkflow-3.10.6.dist-info → scipion_pyworkflow-3.11.0.dist-info}/top_level.txt +0 -0
pyworkflow/gui/tree.py DELETED
@@ -1,684 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- # **************************************************************************
3
- # *
4
- # * Authors: J.M. De la Rosa Trevin (jmdelarosa@cnb.csic.es)
5
- # *
6
- # * Unidad de Bioinformatica of Centro Nacional de Biotecnologia , CSIC
7
- # *
8
- # * This program is free software; you can redistribute it and/or modify
9
- # * it under the terms of the GNU General Public License as published by
10
- # * the Free Software Foundation; either version 3 of the License, or
11
- # * (at your option) any later version.
12
- # *
13
- # * This program is distributed in the hope that it will be useful,
14
- # * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
- # * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
- # * GNU General Public License for more details.
17
- # *
18
- # * You should have received a copy of the GNU General Public License
19
- # * along with this program; if not, write to the Free Software
20
- # * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21
- # * 02111-1307 USA
22
- # *
23
- # * All comments concerning this program package may be sent to the
24
- # * e-mail address 'scipion@cnb.csic.es'
25
- # *
26
- # **************************************************************************
27
-
28
-
29
- import os
30
- import tkinter as tk
31
- import tkinter.ttk as ttk
32
-
33
- from pyworkflow.mapper import SqliteMapper
34
- from pyworkflow.utils import prettyDelta
35
- from . import gui
36
- from .widgets import Scrollable
37
-
38
- FIRST_TREE_COLUMN = '#0'
39
-
40
-
41
- class Tree(ttk.Treeview, Scrollable):
42
- """ This widget acts as a wrapper around the ttk.Treeview"""
43
- _images = {}
44
-
45
- def __init__(self, master, frame=True, **opts):
46
- """Create a new Tree, if frame=True, a container
47
- frame will be created and an scrollbar will be added"""
48
- Scrollable.__init__(self, master, ttk.Treeview, frame, **opts)
49
-
50
- def getImage(self, img):
51
- return gui.getImage(img)
52
-
53
- def getFirst(self):
54
- """ Return first selected item or None if selection empty"""
55
- selection = self.selection()
56
- if len(selection):
57
- return selection[0]
58
- return None
59
-
60
- def _moveSelection(self, moveFunc):
61
- item = self.selection_first()
62
- if item:
63
- item = moveFunc(item)
64
- if item != '':
65
- self.selection_set(item)
66
-
67
- def moveSelectionUp(self, e=None):
68
- """ change selection to previous item """
69
- self._moveSelection(self.prev)
70
-
71
- def moveSelectionDown(self, e=None):
72
- """ change selection to to next item """
73
- self._moveSelection(self.next)
74
-
75
- def moveItemUp(self, e=None):
76
- """if selected item is not the first move up one position"""
77
- item = self.selection_first()
78
- if item:
79
- index = self.index(item)
80
- if index > 0:
81
- self.move(item, '', index - 1)
82
-
83
- def moveItemDown(self, e=None):
84
- """if selected item is not the first move up one position"""
85
- item = self.selection_first()
86
- if item:
87
- index = self.index(item)
88
- if self.next(item) != '':
89
- self.move(item, '', index + 1)
90
-
91
- def clear(self):
92
- """ remove all items """
93
- childs = self.get_children('')
94
- for c in childs:
95
- self.delete(c)
96
-
97
- def selectChildByIndex(self, index):
98
- """ Select the item at the position index """
99
- child = self.get_children('')[index]
100
- self.selection_set(child)
101
-
102
- def selectChild(self, child):
103
- self.selection_set(child)
104
-
105
- def search(self, initial, fromSelected=True):
106
- """ Search the first item starting with "start"
107
- Implemented for Flat tree like FileBrowser...TODO: consider
108
- a proper tree with branches and leaves..
109
-
110
- Parameters
111
- ----------
112
- initial: String - text to look for in the items. Usually the first initial letter
113
- fromSelected : Boolean, start looking from the selected item"""
114
-
115
- # Validate search string, do not allow empty chars
116
- if len(initial) == 0:
117
- return False
118
-
119
- # Get all
120
- children = self.get_children('')
121
-
122
- # Get the selected item
123
- searchAfter = self.getFirst() if fromSelected else None
124
-
125
- # Loop ...
126
- for child in children:
127
-
128
- text = self.item(child, 'text')
129
-
130
- if searchAfter is not None and searchAfter == text:
131
- searchAfter = None
132
- continue
133
-
134
- if searchAfter is None:
135
-
136
- # Do a lower case search
137
- text = text.lower()
138
-
139
- if text.startswith(initial.lower()):
140
-
141
- # Enclose text in "" due to bug
142
- # https://stackoverflow.com/questions/10691257/ttk-treeview-selection-set-cant-accept-spaces
143
- searchText = '"' + child + '"'
144
- self.focus(child)
145
- self.selection_set(searchText)
146
- return True
147
- else:
148
- continue
149
-
150
- # If we started from a selected item...start again without selection
151
- if fromSelected:
152
- return self.search(initial, False)
153
-
154
- # From: https://stackoverflow.com/questions/1966929/tk-treeview-column-sort
155
- def sortByColumn(self, col, reverse, casting=str):
156
- """
157
- Function to sort a treeview
158
- :param self: treview
159
- :param col: column to apply the sorting on
160
- :param reverse: sorting direction
161
- :param casting: optional - casting operation to apply on the column value: str is default. int, float are other options
162
- :return:
163
- """
164
- l = [(casting(self.set(k, col)), k) for k in self.get_children('')]
165
- l.sort(reverse=reverse)
166
-
167
- # rearrange items in sorted positions
168
- for index, (val, k) in enumerate(l):
169
- self.move(k, '', index)
170
-
171
- # reverse sort next time
172
- self.heading(col, command=lambda: self.sortByColumn(col, not reverse, casting))
173
-
174
-
175
- class TreeProvider:
176
- """ Class class will serve to separate the logic of feed data
177
- from the graphical Tree build. Subclasses should implement
178
- the abstract methods """
179
-
180
- def __init__(self, sortingColumnName=None, sortingAscending=True):
181
- self._sortingColumnName = sortingColumnName
182
- self._sortingAscending = sortingAscending
183
- self._sortEnabled = (sortingColumnName is not None)
184
-
185
- def getColumns(self):
186
- """Return a list of tuples (c, w) where:
187
- c: is the column name and index
188
- w: is the column width
189
- """
190
- pass
191
-
192
- def getObjects(self):
193
- """Return the objects that will be inserted in the Tree"""
194
- pass
195
-
196
- def getObjectInfo(self, obj):
197
- """ This function will be called by the Tree with each
198
- object that will be inserted. A dictionary should be
199
- returned with the possible following entries:
200
- 'key': the key value to insert in the Tree
201
- 'text': text of the object to be displayed
202
- (if not passed the 'key' will be used)
203
- 'image': image path to be displayed as icon (optional)
204
- 'parent': the object's parent in which insert this object (optional)
205
- 'tags': list of tags names (optional)
206
- """
207
- pass
208
-
209
- def getObjectPreview(self, obj):
210
- """ Should return a tuple (img, desc),
211
- where img is the preview image and
212
- desc the description string.
213
- """
214
- return None, None
215
-
216
- def getObjectActions(self, obj):
217
- """ Return a list of tuples (key, action)
218
- were keys are the string
219
- options that will be display in the context menu
220
- and the actions are the functions to call when
221
- the specific action is selected.
222
- The first action in the list will be taken
223
- as the default one when the element is double-clicked.
224
- """
225
- return []
226
-
227
- def configureTags(self, tree):
228
- """
229
- Configure the available tags in the tree that
230
- will be setup later for each item in the tree.
231
- Returns
232
- -------
233
- Nothing
234
-
235
- Adds tags to the tree for customizing
236
- """
237
- pass
238
-
239
- def setSortingParams(self, columnName, ascending):
240
- """
241
- Column name to sort by it and sorting direction
242
- Parameters
243
- ----------
244
- columnName: Name of the column
245
- ascending: If true sorting will be ascending.
246
-
247
- Returns
248
- -------
249
- Nothing
250
- """
251
- self._sortingColumnName = columnName
252
- self._sortingAscending = ascending
253
-
254
- def getSortingColumnName(self):
255
- return self._sortingColumnName
256
-
257
- def isSortingAscending(self):
258
- return self._sortingAscending
259
-
260
- def sortEnabled(self):
261
- # return self._sortingColumnName is not None
262
- return self._sortEnabled
263
-
264
-
265
- class BoundTree(Tree):
266
- """ This class is base on Tree but fetch the
267
- items from a TreeProvider, which provides columns
268
- values for each item and items info to insert into the Tree """
269
-
270
- def __init__(self, master, provider, frame=True, **opts):
271
- """Create a new Tree, if frame=True, a container
272
- frame will be created and a scrollbar will be added"""
273
- # Get columns to display and width
274
- cols = provider.getColumns()
275
- colsTuple = tuple([c[0] for c in cols[1:]])
276
- Tree.__init__(self, master, frame, columns=colsTuple, **opts)
277
- # Set the special case of first tree column
278
- self.heading(FIRST_TREE_COLUMN, text=cols[0][0],
279
- command=lambda: self.sortTree(FIRST_TREE_COLUMN, cols[0][0]))
280
- self.column(FIRST_TREE_COLUMN, width=cols[0][1])
281
- # Set other columns
282
- for c, w in cols[1:]:
283
- self.column(c, width=w)
284
- self.heading(c, text=c, command=lambda _c=c: self.sortTree(_c, _c))
285
-
286
- self.grid(row=0, column=0, sticky='news')
287
-
288
- self.menu = tk.Menu(self, tearoff=0)
289
-
290
- self.setProvider(provider)
291
-
292
- self.bind("<Button-3>", self._onRightClick)
293
- # Hide the right-click menu
294
- self.bind('<FocusOut>', self._unpostMenu)
295
- self.bind("<Key>", self._onKeyPress)
296
- self.bind('<Button-1>', self._onClick)
297
- self.bind('<Double-1>', self._onDoubleClick)
298
- self.bind('<<TreeviewSelect>>', self._onSelect)
299
-
300
- def setProvider(self, provider):
301
- """ Set new provider and updated items. """
302
- self.provider = provider
303
- self.update()
304
-
305
- def _onClick(self, e=None):
306
- self._unpostMenu()
307
- if hasattr(self, 'itemOnClick'):
308
- self.itemOnClick(e)
309
-
310
- def _onKeyPress(self, e=None):
311
- self._unpostMenu()
312
-
313
- if hasattr(self, 'itemKeyPressed'):
314
- selected = self.getFirst()
315
- if selected:
316
- obj = self._objDict[selected]
317
- self.itemKeyPressed(obj, e)
318
-
319
- def _unpostMenu(self, e=None):
320
-
321
- self.menu.unpost()
322
-
323
- def _onSelect(self, e=None):
324
- if hasattr(self, 'itemClick'):
325
- selected = self.getFirst()
326
- if selected:
327
- obj = self._objDict[selected]
328
- self.itemClick(obj)
329
-
330
- def _onDoubleClick(self, e=None):
331
- selected = self.getFirst()
332
- if selected:
333
- obj = self._objDict[selected]
334
- if hasattr(self, 'itemDoubleClick'):
335
- self.itemDoubleClick(obj)
336
- else: # If not callback, use default action
337
- actions = self.provider.getObjectActions(obj)
338
- if len(actions):
339
- # actions[0] = first Action, [1] = the action callback
340
- actions[0][1]()
341
-
342
- def _onRightClick(self, e=None):
343
- item = self.identify('item', e.x, e.y)
344
- unpost = True
345
- if len(item):
346
- self.selection_set(item)
347
- obj = self._objDict[item]
348
- actions = self.provider.getObjectActions(obj)
349
- if len(actions):
350
- self.menu.delete(0, tk.END)
351
- for a in actions:
352
- if a is None:
353
- self.menu.add_separator()
354
- else:
355
- img = ''
356
- if len(a) > 2: # image for the action
357
- img = self.getImage(a[2])
358
- self.menu.add_command(label=a[0], command=a[1],
359
- image=img, compound=tk.LEFT)
360
- self.menu.post(e.x_root, e.y_root)
361
- unpost = False
362
- if unpost:
363
- self._unpostMenu()
364
-
365
- def update(self):
366
- self.clear()
367
- self.provider.configureTags(self)
368
- self._objDict = {} # Store the mapping between Tree ids and objects
369
- self._objects = self.provider.getObjects()
370
-
371
- for obj in self._objects:
372
- # If the object is a pointer that has a null value do not show
373
- # if ((not obj.isPointer()) or (obj.isPointer() and obj.get() is not None)):
374
- objDict = self.provider.getObjectInfo(obj)
375
- if objDict is not None:
376
- key = objDict.get('key')
377
- text = objDict.get('text', key)
378
- parent = objDict.get('parent', None)
379
-
380
- if parent is None:
381
- parentId = ''
382
- else:
383
- if hasattr(parent, '_treeId'): # This should happens always
384
- parentId = parent._treeId # Previously set
385
- else:
386
- parentId = ''
387
- text += '---> Error: parent not Inserted'
388
- image = objDict.get('image', '')
389
- if len(image):
390
- image = self.getImage(image)
391
- if image is None:
392
- image = ''
393
- values = objDict.get('values', ())
394
-
395
- tags = objDict.get('tags', ())
396
-
397
- try:
398
- obj._treeId = self.insert(parentId, 'end', key,
399
- text=text, image=image, values=values, tags=tags)
400
- self._objDict[obj._treeId] = obj
401
-
402
- if objDict.get('open', False):
403
- self.itemConfig(obj, open=True)
404
-
405
- if objDict.get('selected', False):
406
- self.selectChild(obj._treeId)
407
-
408
- except Exception as ex:
409
- print("error: ", ex)
410
- if hasattr(obj, "getObjId") and obj.getObjId():
411
- print("error object with id=%d (%s) is duplicated!!!"
412
- % (obj.getObjId(), str(obj)))
413
- else:
414
- print("error, object %s does not have an id. This could"
415
- " be due to the load of old project that does not"
416
- " have recently added attributes "
417
- "(e.g.:datastreaming)" % str(obj))
418
-
419
- def sortTree(self, heading, column):
420
-
421
- if not self.provider.sortEnabled():
422
- return
423
-
424
- # Calculate the sorting direction. default to true
425
- ascending = True
426
-
427
- # Current sorted column
428
- currentSortedColumn = self.provider.getSortingColumnName()
429
-
430
- # If its the same column
431
- if column == currentSortedColumn:
432
- ascending = not self.provider.isSortingAscending()
433
- else:
434
- # Remove previous arrow
435
- previousHeading = self.getColumnKeyByColumnName(currentSortedColumn)
436
- self.heading(previousHeading, text=currentSortedColumn)
437
-
438
- # Visualize column sorted in the header
439
- if ascending:
440
- self.heading(heading, text=column + ' ▲')
441
- else:
442
- self.heading(heading, text=column + ' ▼')
443
-
444
- self.provider.setSortingParams(column, ascending)
445
-
446
- self.update()
447
-
448
- def getColumnKeyByColumnName(self, columnName):
449
- try:
450
- self.column(columnName)
451
- return columnName
452
- except Exception as e:
453
- return FIRST_TREE_COLUMN
454
-
455
- def itemConfig(self, obj, **args):
456
- """ Configure inserted items. """
457
- self.item(obj._treeId, **args)
458
-
459
- def iterSelectedObjects(self):
460
- for treeId in self.selection():
461
- yield self.getObjectFromId(treeId)
462
-
463
- def getSelectedObjects(self):
464
- return [obj for obj in self.iterSelectedObjects()]
465
-
466
- def getObjectFromId(self, treeId):
467
- """ Return the corresponding object from a given Tree item id. """
468
- return self._objDict[treeId]
469
-
470
-
471
- class ObjectTreeProvider(TreeProvider):
472
- """ Populate Tree from Objects. """
473
-
474
- def __init__(self, objList=None):
475
- TreeProvider.__init__(self)
476
- self.objList = objList
477
- self.getColumns = lambda: [('Object', 300), ('Id', 70), ('Class', 150)]
478
- self._parentDict = {}
479
-
480
- def getObjectInfo(self, obj):
481
- # if obj.isPointer() and not obj.hasValue():
482
- # return None
483
- cls = obj.getClassName()
484
- if obj.getName() is None:
485
- t = cls
486
- else:
487
- t = obj.getName().split('.')[-1]
488
- if t.startswith('__item__'):
489
- t = "%s [%s]" % (cls, t.replace('__item__', ''))
490
-
491
- value = obj.get()
492
- if value is None:
493
- if obj.isPointer():
494
- t += " = %s" % str(obj.getObjValue())
495
- else:
496
- t += " = None"
497
- else:
498
- t += " = %s" % str(obj)
499
-
500
- info = {'key': obj.getObjId(),
501
- 'parent': self._parentDict.get(obj.getObjId(), None),
502
- 'text': t, 'values': (obj.strId(), cls)}
503
- # This image step.gif is missing, I guess we are not showing Scalars
504
- # if issubclass(obj.__class__, Scalar):
505
- # info['image'] = 'step.gif'
506
-
507
- return info
508
-
509
- def getObjectPreview(self, obj):
510
- return None, None
511
-
512
- def getObjectActions(self, obj):
513
- return []
514
-
515
- def _getObjectList(self):
516
- """Retrieve the object list"""
517
- return self.objList
518
-
519
- def getObjects(self):
520
- objList = self._getObjectList()
521
- self._parentDict = {}
522
- childs = []
523
- for obj in objList:
524
- childs += self._getChilds(obj)
525
- objList += childs
526
- return objList
527
-
528
- def _getChilds(self, obj):
529
- childs = []
530
- grandchilds = []
531
-
532
- for a, v in obj.getAttributesToStore():
533
- childs.append(v)
534
- self._parentDict[v.getObjId()] = obj
535
- grandchilds += self._getChilds(v)
536
- childs += grandchilds
537
- return childs
538
-
539
-
540
- class DbTreeProvider(ObjectTreeProvider):
541
- """Retrieve the elements from the database"""
542
-
543
- def __init__(self, dbName, classesDict):
544
- ObjectTreeProvider.__init__(self)
545
- self.mapper = SqliteMapper(dbName, classesDict)
546
-
547
- def _getObjectList(self):
548
- return self.mapper.selectAll()
549
-
550
-
551
- class ProjectRunsTreeProvider(TreeProvider):
552
- """ Provide run list from a project
553
- to populate a tree.
554
- """
555
- ID_COLUMN = 'Id'
556
- RUN_COLUMN = 'Run'
557
- STATE_COLUMN = 'State'
558
- TIME_COLUMN = 'Time'
559
-
560
- def __init__(self, project, **kwargs):
561
- TreeProvider.__init__(self, sortingColumnName=ProjectRunsTreeProvider.ID_COLUMN)
562
- self.project = project
563
- self._objDict = {}
564
- self._refresh = True
565
- self._checkPids = False
566
-
567
- def setRefresh(self, value):
568
- self._refresh = value
569
-
570
- def getObjects(self):
571
- runs = self.project.getRuns(refresh=self._refresh,
572
- checkPids=self._checkPids)
573
-
574
- # Sort objects
575
- runs.sort(key=self.runsKey, reverse=not self.isSortingAscending())
576
-
577
- return runs
578
-
579
- def runsKey(self, run):
580
- sortDict = {ProjectRunsTreeProvider.ID_COLUMN: 'getObjId',
581
- ProjectRunsTreeProvider.TIME_COLUMN: 'getElapsedTime',
582
- ProjectRunsTreeProvider.RUN_COLUMN: 'getRunName',
583
- ProjectRunsTreeProvider.STATE_COLUMN: 'getStatusMessage'}
584
- return getattr(run, sortDict.get(self._sortingColumnName))()
585
-
586
- def getColumns(self):
587
- return [(ProjectRunsTreeProvider.ID_COLUMN, 5),
588
- (ProjectRunsTreeProvider.RUN_COLUMN, 300),
589
- (ProjectRunsTreeProvider.STATE_COLUMN, 50),
590
- (ProjectRunsTreeProvider.TIME_COLUMN, 50)]
591
-
592
- def getObjectInfo(self, obj):
593
- objId = obj.getObjId()
594
- self._objDict[objId] = obj
595
- info = {'key': objId, 'text': objId,
596
- 'values': (obj.getRunName(), obj.getStatusMessage(),
597
- prettyDelta(obj.getElapsedTime()))
598
- }
599
- objPid = obj.getObjParentId()
600
- if objPid in self._objDict:
601
- info['parent'] = self._objDict[objPid]
602
-
603
- return info
604
-
605
- def getObjectFromId(self, objId):
606
- return self._objDict[objId]
607
-
608
-
609
- class ListTreeProvider(TreeProvider):
610
- """ Simple list tree provider. """
611
-
612
- def __init__(self, objList=None):
613
- TreeProvider.__init__(self)
614
- self.objList = objList
615
- self.getColumns = lambda: [('Object', 150)]
616
- self.getObjects = lambda: self.objList
617
-
618
- def getObjectInfo(self, obj):
619
- info = {'key': obj.getObjId(), 'text': self.getText(obj), 'values': ()}
620
- return info
621
-
622
- def getText(self, obj):
623
- """ Get the text to display for an object. """
624
- index, fn = obj.getLocation()
625
- name = os.path.basename(fn)
626
- if index:
627
- name = "%03d@%s" % (index, name)
628
- return name
629
-
630
- def getObjs(self):
631
- """ Get the objects. """
632
- return self.objList
633
-
634
-
635
- class ListTreeProviderString(ListTreeProvider):
636
- def getText(self, obj):
637
- return obj.get()
638
-
639
-
640
- class ListTreeProviderTemplate(ListTreeProviderString):
641
- def __init__(self, objList=None):
642
- TreeProvider.__init__(self)
643
- self.objList = objList
644
- self.getColumns = lambda: [('Template', 250),
645
- ('Description', 800)]
646
- self.getObjects = lambda: self.objList
647
-
648
- def getObjectInfo(self, obj):
649
- info = {'key': obj.getObjId(), 'text': self.getText(obj), 'values': self.getValues(obj)}
650
- return info
651
-
652
- def getText(self, obj):
653
- return obj.source + '-' + obj.name
654
-
655
- def getValues(self, obj):
656
- return (obj.description,)
657
-
658
- class AttributesTreeProvider(ListTreeProviderString):
659
- def __init__(self, item):
660
- TreeProvider.__init__(self)
661
- self.objList = self._attributesToObjectList(item)
662
- self.getColumns = lambda: [('attribute', 250),
663
- ('value', 125)]
664
- self.getObjects = lambda: self.objList
665
-
666
- def _attributesToObjectList(self, item):
667
- """ Returns a list of all available attributes ready as a list of objects for the tree"""
668
- objList = []
669
-
670
- for key, attr in item.getAttributesToStore():
671
- clone = attr.clone()
672
- clone.attrName = key
673
- objList.append(clone)
674
- return objList
675
-
676
- def getObjectInfo(self, obj):
677
- info = {'key': obj.attrName, 'text': self.getText(obj), 'values': self.getValues(obj)}
678
- return info
679
-
680
- def getText(self, obj):
681
- return obj.attrName
682
-
683
- def getValues(self, obj):
684
- return (obj.get(),)