1 """Simple wxpython frame for smart card application.
2
3 __author__ = "gemalto http://www.gemalto.com"
4 __date__ = "November 2006"
5 __version__ = "1.4.0"
6
7 Copyright 2001-2011 gemalto
8 Author: Jean-Daniel Aussel, mailto:jean-daniel.aussel@gemalto.com
9
10 This file is part of pyscard.
11
12 pyscard is free software; you can redistribute it and/or modify
13 it under the terms of the GNU Lesser General Public License as published by
14 the Free Software Foundation; either version 2.1 of the License, or
15 (at your option) any later version.
16
17 pyscard is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU Lesser General Public License for more details.
21
22 You should have received a copy of the GNU Lesser General Public License
23 along with pyscard; if not, write to the Free Software
24 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 """
26
27 import os.path
28 import wx
29 import smartcard.wx
30 import APDUTracerPanel
31 import CardAndReaderTreePanel
32 import ReaderToolbar
33
34 import smartcard
35 from smartcard.wx.SimpleSCardAppEventObserver import SimpleSCardAppEventObserver
36
37 [
38 wxID_SIMPLESCARDAPP_FRAME,
39 ] = map(lambda x: wx.NewId(), range(1))
40
41
42 -class BlankPanel(wx.Panel, SimpleSCardAppEventObserver):
43 '''A blank panel in case no panel is provided to SimpleSCardApp.'''
44
46 wx.Panel.__init__(self, parent, -1)
47 sizer = wx.GridSizer(1, 1)
48 self.SetSizer(sizer)
49 self.SetAutoLayout(True)
50
51
53 '''The panel that contains the Card/Reader TreeCtrl and the user provided Panel.'''
54
55 - def __init__(self, parent, apppanelclass, appstyle):
56 """
57 Constructor. Creates the panel with two panels:
58 the left-hand panel is holding the smartcard and/or reader tree
59 the right-hand panel is holding the application dialog
60
61 apppanelclass: the class of the panel to instantiate in the SimpleSCardAppFrame
62 appstyle: a combination of the following styles (bitwise or |)
63 TR_SMARTCARD: display a smartcard tree panel
64 TR_READER: display a reader tree panel
65 TB_SMARTCARD: display a smartcard toolbar
66 TB_SMARTCARD: display a reader toolbar
67 default is TR_DEFAULT = TR_SMARTCARD
68 """
69 wx.Panel.__init__(self, parent, -1)
70
71 self.parent = parent
72 self.selectedcard = None
73
74 boxsizer = wx.BoxSizer(wx.HORIZONTAL)
75
76
77
78 if None != apppanelclass:
79 self.dialogpanel = apppanelclass(self)
80 else:
81 self.dialogpanel = BlankPanel(self)
82
83
84 if appstyle & smartcard.wx.SimpleSCardApp.TR_SMARTCARD or \
85 appstyle & smartcard.wx.SimpleSCardApp.TR_READER:
86 self.readertreepanel = CardAndReaderTreePanel.CardAndReaderTreePanel(self, appstyle, self.dialogpanel)
87 boxsizer.Add(self.readertreepanel, 1, wx.EXPAND | wx.ALL, 5)
88
89 boxsizer.Add(self.dialogpanel, 2, wx.EXPAND | wx.ALL)
90
91 if appstyle & smartcard.wx.SimpleSCardApp.TR_READER:
92 self.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.OnActivateReader, self.readertreepanel.readertreectrl)
93 self.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnSelectReader, self.readertreepanel.readertreectrl)
94 self.Bind(wx.EVT_TREE_ITEM_RIGHT_CLICK, self.OnReaderRightClick, self.readertreepanel.readertreectrl)
95 self.Bind(wx.EVT_TREE_ITEM_COLLAPSED, self.OnItemCollapsed, self.readertreepanel.readertreectrl)
96
97 if appstyle & smartcard.wx.SimpleSCardApp.TR_SMARTCARD:
98 self.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.OnActivateCard, self.readertreepanel.cardtreectrl)
99 self.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnSelectCard, self.readertreepanel.cardtreectrl)
100 self.Bind(wx.EVT_TREE_ITEM_RIGHT_CLICK, self.OnCardRightClick, self.readertreepanel.cardtreectrl)
101
102 self.SetSizer(boxsizer)
103 self.SetAutoLayout(True)
104
106 """Activate a card."""
107 if not hasattr(card, 'connection'):
108 card.connection = card.createConnection()
109 if None != self.parent.apdutracerpanel:
110 card.connection.addObserver(self.parent.apdutracerpanel)
111 card.connection.connect()
112 self.dialogpanel.OnActivateCard(card)
113
115 """Deactivate a card."""
116 if hasattr(card, 'connection'):
117 card.connection.disconnect()
118 if None != self.parent.apdutracerpanel:
119 card.connection.deleteObserver(self.parent.apdutracerpanel)
120 delattr(card, 'connection')
121 self.dialogpanel.OnDeactivateCard(card)
122
124 """Called when the user activates a card in the tree."""
125 item = event.GetItem()
126 if item:
127 itemdata = self.readertreepanel.cardtreectrl.GetItemPyData(item)
128 if isinstance(itemdata, smartcard.Card.Card):
129 self.ActivateCard(itemdata)
130 else:
131 self.dialogpanel.OnDeselectCard(itemdata)
132
134 """Called when the user activates a reader in the tree."""
135 item = event.GetItem()
136 if item:
137 itemdata = self.readertreepanel.readertreectrl.GetItemPyData(item)
138 if isinstance(itemdata, smartcard.Card.Card):
139 self.ActivateCard(itemdata)
140 elif isinstance(itemdata, smartcard.reader.Reader.Reader):
141 self.dialogpanel.OnActivateReader(itemdata)
142 event.Skip()
143
145 item = event.GetItem()
146 self.readertreepanel.readertreectrl.Expand(item)
147
149 """Called when the user right-clicks a node in the card tree control."""
150 item = event.GetItem()
151 if item:
152 itemdata = self.readertreepanel.cardtreectrl.GetItemPyData(item)
153 if isinstance(itemdata, smartcard.Card.Card):
154 self.selectedcard = itemdata
155 if not hasattr(self, "connectID"):
156 self.connectID = wx.NewId()
157 self.disconnectID = wx.NewId()
158
159 self.Bind(wx.EVT_MENU, self.OnConnect, id=self.connectID)
160 self.Bind(wx.EVT_MENU, self.OnDisconnect, id=self.disconnectID)
161
162 menu = wx.Menu()
163 if not hasattr(self.selectedcard, 'connection'):
164 menu.Append(self.connectID, "Connect")
165 else:
166 menu.Append(self.disconnectID, "Disconnect")
167 self.PopupMenu(menu)
168 menu.Destroy()
169
171 """Called when the user right-clicks a node in the reader tree control."""
172 item = event.GetItem()
173 if item:
174 itemdata = self.readertreepanel.readertreectrl.GetItemPyData(item)
175 if isinstance(itemdata, smartcard.Card.Card):
176 self.selectedcard = itemdata
177 if not hasattr(self, "connectID"):
178 self.connectID = wx.NewId()
179 self.disconnectID = wx.NewId()
180
181 self.Bind(wx.EVT_MENU, self.OnConnect, id=self.connectID)
182 self.Bind(wx.EVT_MENU, self.OnDisconnect, id=self.disconnectID)
183
184 menu = wx.Menu()
185 if not hasattr(self.selectedcard, 'connection'):
186 menu.Append(self.connectID, "Connect")
187 else:
188 menu.Append(self.disconnectID, "Disconnect")
189 self.PopupMenu(menu)
190 menu.Destroy()
191
195
199
201 """Called when the user selects a card in the tree."""
202 item = event.GetItem()
203 if item:
204 itemdata = self.readertreepanel.cardtreectrl.GetItemPyData(item)
205 if isinstance(itemdata, smartcard.Card.Card):
206 self.dialogpanel.OnSelectCard(itemdata)
207 else:
208 self.dialogpanel.OnDeselectCard(itemdata)
209
211 """Called when the user selects a reader in the tree."""
212 item = event.GetItem()
213 if item:
214 itemdata = self.readertreepanel.readertreectrl.GetItemPyData(item)
215 if isinstance(itemdata, smartcard.Card.Card):
216 self.dialogpanel.OnSelectCard(itemdata)
217 elif isinstance(itemdata, smartcard.reader.Reader.Reader):
218 self.dialogpanel.OnSelectReader(itemdata)
219 else:
220 self.dialogpanel.OnDeselectCard(itemdata)
221
222
224 """The main frame of the simple smartcard application."""
225
226 - def __init__(self,
227 appname,
228 apppanelclass,
229 appstyle,
230 appicon,
231 pos=(-1, -1),
232 size=(-1, -1),
233 ):
234 """
235 Constructor. Creates the frame with two panels:
236 the left-hand panel is holding the smartcard and/or reader tree
237 the right-hand panel is holding the application dialog
238
239 appname: name of the application
240 apppanelclass: the class of the panel to instantiate in the SimpleSCardAppFrame
241 appstyle: a combination of the following styles (bitwise or |)
242 TR_SMARTCARD: display a smartcard tree panel
243 TR_READER: display a reader tree panel
244 TB_SMARTCARD: display a smartcard toolbar
245 TB_SMARTCARD: display a reader toolbar
246 PANEL_APDUTRACER: display an APDU tracer panel
247 default is TR_DEFAULT = TR_SMARTCARD
248 pos: the application position as a (x,y) tupple; default is (-1,-1)
249 size: the application window size as a (x,y) tuple; default is (-1,-1)
250 style: the frame wx.Frame style
251 """
252 wx.Frame.__init__(self,
253 None,
254 wxID_SIMPLESCARDAPP_FRAME,
255 appname,
256 pos=pos,
257 size=size,
258 style=wx.DEFAULT_FRAME_STYLE)
259
260 if appicon:
261 _icon = wx.Icon(appicon, wx.BITMAP_TYPE_ICO)
262 self.SetIcon(_icon)
263 elif os.path.exists(smartcard.wx.ICO_SMARTCARD):
264 _icon = wx.Icon(smartcard.wx.ICO_SMARTCARD, wx.BITMAP_TYPE_ICO)
265 self.SetIcon(_icon)
266
267 boxsizer = wx.BoxSizer(wx.VERTICAL)
268 self.treeuserpanel = TreeAndUserPanelPanel(self, apppanelclass, appstyle)
269 boxsizer.Add(self.treeuserpanel, 3, wx.EXPAND | wx.ALL)
270
271
272 if appstyle & smartcard.wx.SimpleSCardApp.TB_SMARTCARD:
273 self.toolbar = ReaderToolbar.ReaderToolbar(self)
274 self.SetToolBar(self.toolbar)
275 else:
276 self.toolbar = None
277
278
279 if appstyle & smartcard.wx.SimpleSCardApp.PANEL_APDUTRACER:
280 self.apdutracerpanel = APDUTracerPanel.APDUTracerPanel(self)
281 boxsizer.Add(self.apdutracerpanel, 1, wx.EXPAND | wx.ALL)
282 else:
283 self.apdutracerpanel = None
284
285 self.SetSizer(boxsizer)
286 self.SetAutoLayout(True)
287
288 self.Bind(wx.EVT_CLOSE, self.OnCloseFrame)
289 if appstyle & smartcard.wx.SimpleSCardApp.TB_SMARTCARD:
290 self.Bind(wx.EVT_COMBOBOX, self.OnReaderComboBox, self.toolbar.readercombobox)
291
293 """Called when frame is closed, i.e. on wx.EVT_CLOSE"""
294 evt.Skip()
295
297 """Called when frame application exits."""
298 self.Close(True)
299 evt.Skip()
300
307