-
Notifications
You must be signed in to change notification settings - Fork 93
/
pseudos.py
349 lines (304 loc) · 12.1 KB
/
pseudos.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
#!/usr/bin/env python
from __future__ import print_function, division, unicode_literals, absolute_import
import os
import wx
import abipy.gui.awx as awx
import wx.lib.mixins.listctrl as listmix
import wx.lib.dialogs as wxdg
from monty.string import is_string
from abipy.flowtk import PseudoParser
class MyListCtrl(wx.ListCtrl, listmix.ListCtrlAutoWidthMixin):
""" Mixin class to resize the last column appropriately."""
def __init__(self, parent, **kwargs):
wx.ListCtrl.__init__(self, parent, id=-1, style=wx.LC_REPORT | wx.BORDER_SUNKEN, **kwargs)
listmix.ListCtrlAutoWidthMixin.__init__(self)
class PseudosViewerFrame(awx.Frame):
def __init__(self, parent, pseudos, **kwargs):
super(PseudosViewerFrame, self).__init__(parent, -1, **kwargs)
main_sizer = wx.BoxSizer(wx.VERTICAL)
panel = PseudoListPanel(self, pseudos)
main_sizer.Add(panel, 1, wx.EXPAND, 5)
#hsizer = wx.BoxSizer(wx.HORIZONTAL)
#filter_label = wx.StaticText(self, -1, "Filter:", wx.DefaultPosition, wx.DefaultSize, 0)
#filter_label.Wrap(-1)
#hsizer.Add(filter_label, 0, wx.ALIGN_CENTER_VERTICAL | wx.TOP | wx.BOTTOM | wx.LEFT, 5)
## Combobox to enter shell patterns.
#wildcard_choices = ["*", "*.nc", "*.abo", "*.log"]
#self.filter_combobox = wx.ComboBox(self, id=-1, value="*", style=wx.TE_PROCESS_ENTER, choices=wildcard_choices)
#self.filter_combobox.SetToolTipString("Shell patterns separated by |")
#self.filter_combobox.Bind(wx.EVT_COMBOBOX, self.OnFilterComboBox)
#self.filter_combobox.Bind(wx.EVT_TEXT_ENTER, self.OnFilterComboBox)
#hsizer.Add(self.filter_combobox, 0, wx.ALL, 5)
#main_sizer.Add(hsizer, 0, wx.ALIGN_CENTER_HORIZONTAL, 5)
#panel.SetSizerAndFit(main_sizer)
self.SetSizer(main_sizer)
self.Layout()
class PseudoListPanel(awx.Panel, listmix.ColumnSorterMixin):
"""
This panel shows a list of files (strings), supports column sorting
and provides specific popup menus for the different type of files
(file type detection is based on file extensions).
"""
def __init__(self, parent, pseudos, **kwargs):
"""
Args:
parent:
parent window
pseudos:
List of pseudopotentials.
"""
super(PseudoListPanel, self).__init__(parent, -1, **kwargs)
self.pseudos = pseudos
self.BuildUi()
def BuildUi(self):
self.pseudo_list = pseudo_list = MyListCtrl(self)
pseudo_list.Bind(wx.EVT_LIST_ITEM_RIGHT_CLICK, self.OnRightClick)
pseudo_list.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnItemActivated)
self.id2pseudo = {}
columns = self.columns = ["basename", "symbol", "Z_val", "l_max", "rcore", "type"]
# Used to store the Max width in pixels for the data in the column.
column_widths = [awx.get_width_height(self, s)[0] for s in columns]
for (index, colname) in enumerate(columns):
pseudo_list.InsertColumn(index, colname)
for pseudo in self.pseudos:
entry = self.AppendPseudo(pseudo)
w = [awx.get_width_height(self, s)[0] for s in entry]
column_widths = map(max, zip(w, column_widths))
for (index, colname) in enumerate(columns):
pseudo_list.SetColumnWidth(index, column_widths[index])
# Now that the list exists we can init the other base class, see wx/lib/mixins/listctrl.py
self.itemDataMap = {pid: [getattr(pseudo, attr) for attr in self.columns] for pid, pseudo in self.id2pseudo.items()}
listmix.ColumnSorterMixin.__init__(self, len(columns))
self.Bind(wx.EVT_LIST_COL_CLICK, self.OnColClick, self.pseudo_list)
# Pack
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(pseudo_list, 1, wx.ALL | wx.EXPAND, 5)
self.SetSizerAndFit(sizer)
def GetListCtrl(self):
"""Used by the ColumnSorterMixin, see wx/lib/mixins/listctrl.py"""
return self.pseudo_list
def AppendPseudo(self, pseudo):
"""Add a pseudo to the panel."""
next = len(self.id2pseudo)
# We use next as entry id because we want to be able
# to sort the columns with the mixin ColumnSorterMixin.
entry_id = next
entry = map(str, [getattr(pseudo, attr) for attr in self.columns])
self.pseudo_list.Append(entry)
self.pseudo_list.SetItemData(next, entry_id)
self.id2pseudo[entry_id] = pseudo
return entry
def OnColClick(self, event):
event.Skip()
def OnItemActivated(self, event):
currentItem = event.m_itemIndex
pseudo = self.id2pseudo[self.pseudo_list.GetItemData(currentItem)]
print(pseudo)
wxdg.ScrolledMessageDialog(self, str(pseudo), caption=pseudo.filepath, style=wx.MAXIMIZE_BOX).Show()
#def OnOpenPseudoFile(self, event):
# """Open the pseudopotential file in another frame."""
# currentItem = event.m_itemIndex
# pseudo = self.id2pseudo[self.pseudo_list.GetItemData(currentItem)]
# print(pseudo)
# filepath = pseudo.filepath
# wxdg.ScrolledMessageDialog(self, str(pseudo), caption=pseudo.filepath, style=wx.MAXIMIZE_BOX).Show()
#def OnPlotPseudo(self, event):
# """Open the pseudopotential file in another frame."""
# currentItem = event.m_itemIndex
# pseudo = self.id2pseudo[self.pseudo_list.GetItemData(currentItem)]
# print(pseudo)
def OnRightClick(self, event):
currentItem = event.m_itemIndex
if currentItem == -1:
return
#pseudo = self.id2pseudo[self.pseudo_list.GetItemData(currentItem)]
#print(pseudo)
## Open the popup menu then destroy it to avoid mem leak.
#menu = popupmenu_for_pseudo(self, pseudo)
#if menu is not None:
# self.PopupMenu(menu, event.GetPoint())
# menu.Destroy()
#class PopupMenu(wx.Menu):
# """
# Base class for popup menus. `A PopupMenu` has a list of callback functions
# indexed by the menu title. The signature of the callback function is func(parent, filename) where
# filename is the name of the file selected in the Widget and parent is the wx
# Window that will become the parent of the new frame created by the callback.
# """
# MENU_TITLES = OrderedDict([
# ])
#
# HANDLED_FILES = []
#
# def __init__(self):
# super(PopupMenu, self).__init__()
# self._make_menu()
#
# @staticmethod
# def from_filename(filename):
# """
# Static factory function that instanciates the appropriate subclass of `NcFilePopupMenu`
# Returns None if the extesion of filename is not supported.
# """
# # Find the AbinitNcFile subclass associated to files.
# try:
# file_class = abifile_subclass_from_filename(filename)
# except KeyError:
# return None
#
# # Check whether a subclass handles this file..
# # Fallback to a simple PopupMenu if no match.
# def allsubclasses(cls):
# """Returns the set of subclasses of cls."""
# children = [cls]
# for sc in cls.__subclasses__():
# if sc.__subclasses__():
# for k in sc.__subclasses__():
# children.extend(allsubclasses(k))
# else:
# children.append(sc)
# return set(children)
#
# for cls in allsubclasses(PopupMenu):
# if cls.handle_file_class(file_class):
# return cls()
# else:
# return PopupMenu()
#
# @classmethod
# def handle_file_class(cls, file_class):
# """True if the popupmenu is associated to file_class."""
# return file_class in cls.HANDLED_FILES
#
# def _make_menu(self):
# """Build the menu taking into account the options of the superclasses."""
# base_classes = list(self.__class__.__bases__) + [self.__class__]
# base_classes.reverse()
#
# assert not hasattr(self, "menu_title_by_id")
# assert not hasattr(self, "menu_titles")
# self.menu_title_by_id, self.menu_titles = OrderedDict(), OrderedDict()
#
# for cls in base_classes:
# try:
# menus = cls.MENU_TITLES
# except AttributeError as exc:
# awx.WARNING("exc ",exc," for cls", cls)
# continue
#
# self.menu_titles.update(menus)
#
# for title in menus:
# self.menu_title_by_id[wx.NewId()] = title
#
# # Add sentinel for Menu separator.
# self.menu_title_by_id["separator_" + str(len(self.menu_titles))] = None
#
# for (id, title) in self.menu_title_by_id.items():
# if title is None:
# sepid = int(id.split("_")[-1])
# if sepid != len(self.menu_titles):
# self.AppendSeparator()
# else:
# # Register menu handlers with EVT_MENU, on the menu.
# self.Append(id, title)
# wx.EVT_MENU(self, id, self.OnMenuSelection)
#
# def set_parent(self, parent):
# """Set the parent window."""
# self._parent = parent
#
# @property
# def parent(self):
# """Returns the parent window."""
# try:
# return self._parent
# except AttributeError:
# awx.WARNING("Popup menu doesn't have parent")
# return None
#
# def set_target(self, target):
# """Set the target of the callback."""
# self._target = target
#
# @property
# def target(self):
# """The target of the callback."""
# try:
# return self._target
# except AttributeError:
# return None
#
# def _get_callback(self, title):
# return self.menu_titles[title]
#
# def OnMenuSelection(self, event):
# title = self.menu_title_by_id[event.GetId()]
# callback = self._get_callback(title)
# #print("Calling callback %s on target %s" % (callback, self.target))
# try:
# callback(parent=self.parent, filepath=self.target)
# except:
# awx.showErrorMessage(parent=self.parent)
#
#
#class AbinitTextFilePopupMenu(PopupMenu):
# """
# """
# MENU_TITLES = OrderedDict([
# ("events", showAbinitEventsFrame),
# ("properties", showFileStat),
# ("timer", showAbinitTimerFrame),
# ])
#
# HANDLED_FILES = [AbinitLogFile, AbinitOutputFile]
#
#
#class NcFilePopupMenu(PopupMenu):
# """
# Base class for popup menus. `A PopupMenu` has a list of callback functions
# indexed by the menu title and a list of `AbinitNcFile` associated to it.
# The signature of the callback function is func(filename, parent) where
# filename is the name of the file selected in the Widget and parent is the wx
# Window that will become the parent of the new frame created by the callback.
#
# How to subclass PopupMenu:
#
# 1. Define a new class that inherits from NcFilePopupMenu.
#
# 2. Define the callbacks in the class variable MENU_TITLES.
# Use OrderedDict to have a fixed ordering of the labels.
#
# 3. Define the class variable HANDLED_FILES with the list of
# `AbinitNcFile` subclasses associated to the popupmenu.
#
# 4. Done (most of the work is indeed done in the base class and in
# the factory function popupmenu_for_filename.
# """
# MENU_TITLES = OrderedDict([
# ("structure", showStructure),
# ("ncdump", showNcdumpMessage),
# ("properties", showFileStat),
# ])
#
# HANDLED_FILES = []
#
#
#class EbandsPopupMenu(NcFilePopupMenu):
# """Popup menu for Netcdf files that contain the electron band structure."""
# MENU_TITLES = OrderedDict([
# ("ePlot", ewx.showElectronBandsPlot),
# ("eDos", ewx.showElectronDosFrame),
# ("eJdos", ewx.showElectronJdosFrame),
# ])
#
# HANDLED_FILES = [WFK_File, GSR_File]
def wxapp_pseudos(dirpath):
"""Standalone application."""
parser = PseudoParser()
pseudos = parser.scan_directory(dirpath)
app = wx.App()
frame = PseudosViewerFrame(None, pseudos)
app.SetTopWindow(frame)
frame.Show()
return app