1717## You should have received a copy of the GNU General Public License
1818## along with this program. If not, see http://www.gnu.org/licenses/
1919
20+ import urllib
2021import wx
2122from AuthenticationStore import AuthenticationEntry
2223from Logging import GetLogger
24+ from qrcode import QrCodeImage , QrCodeFrame
2325
2426class AuthEntryPanel ( wx .Panel ):
2527 """Authentication code entry panel."""
@@ -115,6 +117,13 @@ def __init__( self, parent, id = wx.ID_ANY, pos = wx.DefaultPosition, size = wx.
115117 self .timer_gauge .SetMinSize ( self .timer_gauge .GetSize () )
116118 sizer .Add ( self .timer_gauge , 0 , wx .RIGHT | wx .ALIGN_CENTER , 2 )
117119
120+ # Create our context menu
121+ self .context_menu = wx .Menu ()
122+ item = self .context_menu .Append ( wx .ID_ANY , "Copy provisioning URI to clipboard" )
123+ self .Bind ( wx .EVT_MENU , self .OnProvisioningUri , item )
124+ item = self .context_menu .Append ( wx .ID_ANY , "Display QR code image" )
125+ self .Bind ( wx .EVT_MENU , self .OnQrCodeImage , item )
126+
118127 self .UpdateContents ()
119128
120129 if entry != None :
@@ -125,6 +134,7 @@ def __init__( self, parent, id = wx.ID_ANY, pos = wx.DefaultPosition, size = wx.
125134 self .Bind ( wx .EVT_TIMER , self .OnTimerTick )
126135 self .Bind ( wx .EVT_ENTER_WINDOW , self .OnMouseEnter )
127136 self .Bind ( wx .EVT_LEAVE_WINDOW , self .OnMouseLeave )
137+ self .Bind ( wx .EVT_CONTEXT_MENU , self .OnContextMenu )
128138 self .MouseBind ( wx .EVT_LEFT_DCLICK , self .OnDoubleClick )
129139 self .MouseBind ( wx .EVT_LEFT_DOWN , self .OnLeftDown )
130140 self .MouseBind ( wx .EVT_LEFT_UP , self .OnLeftUp )
@@ -192,6 +202,26 @@ def OnDoubleClick( self, event ):
192202 wx .Bell ()
193203 event .Skip ()
194204
205+ def OnContextMenu ( self , event ):
206+ """Offer choice of provisioning URL or QR code image URL from right-click menu."""
207+ pos = event .GetPosition ()
208+ cl_pos = self .ScreenToClient ( pos )
209+ self .PopupMenu ( self .context_menu , cl_pos )
210+
211+ def OnProvisioningUri ( self , event ):
212+ """Copy the provisioning URI to the clipboard."""
213+ GetLogger ().info ( "%s copying provisioning URI to the clipboard." , self .GetName () )
214+ if not self .CopyProvisioningUriToClipboard ():
215+ wx .Bell ()
216+ event .Skip ()
217+
218+ def OnQrCodeImage ( self , event ):
219+ """Display the QR code image."""
220+ GetLogger ().info ( "%s displaying QR code image." , self .GetName () )
221+ if not self .DisplayQrCodeImage ():
222+ wx .Bell ()
223+ event .Skip ()
224+
195225 def OnMouseEnter ( self , event ):
196226 """Clear mouse button state when the mouse enters the panel."""
197227 self .left_down = False
@@ -366,3 +396,39 @@ def CopyCodeToClipboard( self ):
366396 GetLogger ().error ( "%s cannot open clipboard." , self .GetName () )
367397 sts = False
368398 return sts
399+
400+ def GetProvisioningUri ( self ):
401+ return self .entry .GetKeyUri ()
402+
403+ def GetQrCodeUrl ( self ):
404+ qr = QrCodeImage ( self .entry )
405+ return qr .GetUrl ()
406+
407+ def GetQrCodeImage ( self ):
408+ qr = QrCodeImage ( self .entry )
409+ return qr .GetImage ()
410+
411+ def CopyProvisioningUriToClipboard ( self ):
412+ """Copy the provisioning URI to the clipboard."""
413+ sts = True
414+ if wx .TheClipboard .Open ():
415+ if wx .TheClipboard .SetData ( wx .TextDataObject ( self .GetProvisioningUri () ) ):
416+ wx .TheClipboard .Flush ()
417+ else :
418+ GetLogger ().error ( "%s encountered an error copying the provisioning URI to the clipboard." ,
419+ self .GetName () )
420+ sts = False
421+ wx .TheClipboard .Close ()
422+ else :
423+ GetLogger ().error ( "%s cannot open clipboard." , self .GetName () )
424+ sts = False
425+ return sts
426+
427+ def DisplayQrCodeImage ( self ):
428+ """Display the QR code image."""
429+ sts = True
430+ title = self .entry .GetQualifiedAccount ()
431+ image = self .GetQrCodeImage ()
432+ fr = QrCodeFrame ( self , wx .ID_ANY , title , image = image )
433+ fr .Show ()
434+ return sts
0 commit comments