UserDefinitionViewer.py 8.48 KB
Newer Older
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
#MDANSE : Molecular Dynamics Analysis for Neutron Scattering Experiments
#------------------------------------------------------------------------------------------
#Copyright (C)
#2015- Eric C. Pellegrini Institut Laue-Langevin
#BP 156
#6, rue Jules Horowitz
#38042 Grenoble Cedex 9
#France
#pellegrini[at]ill.fr
#goret[at]ill.fr
#aoun[at]ill.fr
#
#This library is free software; you can redistribute it and/or
#modify it under the terms of the GNU Lesser General Public
#License as published by the Free Software Foundation; either
#version 2.1 of the License, or (at your option) any later version.
#
#This library is distributed in the hope that it will be useful,
#but WITHOUT ANY WARRANTY; without even the implied warranty of
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
#Lesser General Public License for more details.
#
#You should have received a copy of the GNU Lesser General Public
#License along with this library; if not, write to the Free Software
#Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

''' 
Created on Apr 14, 2015

:author: Gael Goret and Eric C. Pellegrini
'''

import wx

35
from MDANSE import LOGGER
36
from MDANSE.Framework.UserDefinitionStore import UD_STORE
37

38
39
from MDANSE.GUI import PUBLISHER

40
class UserDefinitionViewer(wx.Dialog):
41
    
42
    def __init__(self, parent, title="User Definition Viewer", ud=None,editable=True):
43
        
44
        wx.Dialog.__init__(self, parent, wx.ID_ANY, size = (800,400), title = title, style=wx.DEFAULT_DIALOG_STYLE|wx.MINIMIZE_BOX|wx.MAXIMIZE_BOX|wx.RESIZE_BORDER)
45
46
47

        self._udTree = {}
        
48
49
        dialogSizer = wx.BoxSizer(wx.VERTICAL)
        
50
        mainPanel = wx.Panel(self, wx.ID_ANY, size=self.GetSize())
51
        
52
53
        self._tree = wx.TreeCtrl(mainPanel, wx.ID_ANY, style=wx.TR_DEFAULT_STYLE|wx.TR_HIDE_ROOT|wx.TR_EDIT_LABELS)
        
54
55
        self._root = self._tree.AddRoot("root")

56
        self.build_tree(self._root, UD_STORE.definitions)     
57
58

        self._info = wx.TextCtrl(mainPanel, wx.ID_ANY, style=wx.TE_MULTILINE|wx.TE_READONLY)
59
        
60
61
62
63
64
65
66
67
68
69
70
71
        self._save  = wx.Button(mainPanel, wx.ID_ANY, label="Save user definitions")

        mainSizer = wx.BoxSizer(wx.VERTICAL)

        infoSizer = wx.BoxSizer(wx.HORIZONTAL)
        infoSizer.Add(self._tree, 1, wx.ALL|wx.EXPAND, 5)
        infoSizer.Add(self._info, 2, wx.ALL|wx.EXPAND, 5)
                        
        mainSizer.Add(infoSizer,1,wx.ALL|wx.EXPAND,5)                      
        mainSizer.Add(self._save,0,wx.ALL|wx.EXPAND,5)                      
        mainPanel.SetSizer(mainSizer)
                
72
        self.Bind(wx.EVT_TREE_SEL_CHANGED, self.on_show_info )
73
        self.Bind(wx.EVT_TREE_KEY_DOWN, self.on_delete, self._tree)
74
75
        self.Bind(wx.EVT_TREE_END_LABEL_EDIT, self.on_rename, self._tree)
        self.Bind(wx.EVT_TREE_BEGIN_LABEL_EDIT, self.on_try_rename, self._tree)
76
77
78
79
80

        self.Bind(wx.EVT_BUTTON, self.on_save_ud, self._save)
        
        if ud is not None:
            self.expand_ud(ud)
81
82
        
        self.set_editable(editable)
83
84
85
86
        
        dialogSizer.Add(mainPanel,1,wx.EXPAND)
        
        self.SetSizer(dialogSizer)
87
88
89
90
91
92
93
            
    def set_editable(self,editable=True):
        
        self._editable = editable
        
        self._save.Show(self._editable)
                                        
94
    def get_item_level(self,item):
95
        
96
97
98
99
100
101
102
        parent = self._tree.GetItemParent(item)
        
        if parent == self._tree.GetRootItem():
            return 1
        else: 
            return 1 + self.get_item_level(parent)

103
104
    def build_tree(self, node, data):
                
105
        for k, v in sorted(data.items()):
106
            
107
108
109
110
111
112
            dataItem = wx.TreeItemData(v)
            subnode = self._tree.AppendItem(node, str(k), data=dataItem)

            self._tree.SetItemTextColour(subnode, 'blue')  
            
            if isinstance(v, dict):
113
                self.build_tree(subnode, v)
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
                
    def find_ud(self,baseitem,itemNames):

        if not itemNames:
            return baseitem
        
        name = itemNames.pop(0)

        item, cookie = self._tree.GetFirstChild(baseitem)
        
        while item.IsOk():
            if self._tree.GetItemText(item) == name:
                baseitem = item
                return self.find_ud(baseitem,itemNames)
            item, cookie = self._tree.GetNextChild(baseitem,cookie)
129
            
130
131
132
133
134
135
136
137
138
139
140
141
142
        return None

    def expand_ud(self,ud):

        item = self.find_ud(self._root, ud)
        
        if item is None:
            return

        self._tree.SelectItem(item,True)

        while item != self._root:
            item = self._tree.GetItemParent(item)
143
144
145
            # Check if item is not root (leading to crash otherwise)
            if item != self._root:
                self._tree.Expand(item)
146
        
147
    def on_show_info(self, event=None):
148
149
150
151

        currentItem = self._tree.GetSelection()

        itemData = self._tree.GetItemData(currentItem)
152
        
153
        if itemData is None:
154
155
            return
        
156
157
158
159
160
161
162
163
164
        data = itemData.GetData()
        
        level = self.get_item_level(currentItem)

        if level <= 3:
            self._info.SetValue("Contains the followings definitions: %s" % data.keys())
            return
                       
        self._info.SetValue(str(itemData.GetData()))       
165

166
167
168
169
    def on_delete(self, event):

        if not self._editable:
            return
170
171
172
173
174
175

        keycode = event.GetKeyCode()
        
        if keycode == wx.WXK_DELETE:
            
            currentItem = self._tree.GetSelection()
176
            
177
178
179
180
181
182
            level = self.get_item_level(currentItem)
            
            if level > 3:
                return
                                                                        
            d = wx.MessageDialog(None, 'Do you really want to delete this definition ?', 'Question', wx.YES_NO|wx.YES_DEFAULT|wx.ICON_QUESTION)
183
184
185
186
            if d.ShowModal() == wx.ID_NO:
                return

            currentItemName = str(self._tree.GetItemText(currentItem))
187
            
188
            if level == 1:
189
                UD_STORE.remove_definition(currentItemName)                
190
            elif level == 2:
191
                targetItem = self._tree.GetItemParent(currentItem)
192
                targetItemName = str(self._tree.GetItemText(targetItem))
193
                UD_STORE.remove_definition(targetItemName,currentItemName)
194
            elif level == 3:
195
                sectionItem = self._tree.GetItemParent(currentItem)
196
                sectionItemName = str(self._tree.GetItemText(sectionItem))
197
                targetItem = self._tree.GetItemParent(sectionItem)
198
199
200
201
202
                targetItemName = str(self._tree.GetItemText(targetItem))
                UD_STORE.remove_definition(targetItemName,sectionItemName,currentItemName)
            else:
                return
            
203
204
            self._tree.DeleteChildren(currentItem)
            self._tree.Delete(currentItem)
205
206
207
            self._udTree.clear()
            self._info.Clear()
            
208
            PUBLISHER.sendMessage("msg_set_ud",message=None)
209
210
211
212
213
214
215

    def on_save_ud(self,event):

        UD_STORE.save()

        LOGGER('User definitions successfully saved.','info',['console'])
        
216
    def on_try_rename(self, event):
217
218
219
220
        
        if not self._editable:
            event.Veto()
            return
221
222
223
224
225
226
227

        currentItem = self._tree.GetSelection()
        level = self.get_item_level(currentItem)

        if level != 3:
            event.Veto()
            return
228

229
230
    def on_rename(self, event):
        
231
232
233
        if not self._editable:
            return
        
234
        currentItem = event.GetItem()
235
236
237
        
        currentItemName = str(self._tree.GetItemText(currentItem))   
        newItemName = self._tree.GetEditControl().GetValue()
238

239
240
241
242
243
244
245
246
247
        if currentItemName == newItemName:
            return
        
        sectionItem = self._tree.GetItemParent(currentItem)
        sectionItemName = str(self._tree.GetItemText(sectionItem))
        targetItem = self._tree.GetItemParent(sectionItem)
        targetItemName = str(self._tree.GetItemText(targetItem))

        currentItemData = self._tree.GetItemData(currentItem)
248
        
249
250
        UD_STORE.set_definition(targetItemName,sectionItemName,newItemName,currentItemData.GetData())
        UD_STORE.remove_definition(targetItemName,sectionItemName,currentItemName)
251
            
252
253
if __name__ == "__main__":
    app = wx.App(False)
254
    f = UserDefinitionViewer(None,ud=['protein_in_periodic_universe.nc','atom_selection',"sfdfdfsd"],editable=True)
255
256
    f.ShowModal()
    f.Destroy()
257
    app.MainLoop()