derive plugins from BasePlugin class
authorthomasv <thomasv@gitorious>
Fri, 15 Mar 2013 08:58:05 +0000 (09:58 +0100)
committerthomasv <thomasv@gitorious>
Fri, 15 Mar 2013 17:03:56 +0000 (18:03 +0100)
gui/__init__.py
gui/gui_classic.py
gui/plugins.py [new file with mode: 0644]
plugins/aliases.py
plugins/pointofsale.py
plugins/qrscanner.py

index afa8ca4..9bccd2a 100644 (file)
@@ -1 +1,2 @@
 # do not remove this file
+from plugins import BasePlugin
index 1d80132..4994438 100644 (file)
@@ -339,7 +339,7 @@ class ElectrumWindow(QMainWindow):
         self.console.showMessage(self.wallet.banner)
 
         # plugins that need to change the GUI do it here
-        self.run_hook('init')
+        self.run_hook('init_gui')
 
 
     # plugins
@@ -350,36 +350,33 @@ class ElectrumWindow(QMainWindow):
             plugin_names = [name for a, name, b in pkgutil.iter_modules([pathname])]
             plugin_names = filter( lambda name: os.path.exists(os.path.join(pathname,name+'.py')), plugin_names)
             imp.load_module('electrum_plugins', fp, pathname, description)
-            self.plugins = map(lambda name: imp.load_source('electrum_plugins.'+name, os.path.join(pathname,name+'.py')), plugin_names)
+            plugins = map(lambda name: imp.load_source('electrum_plugins.'+name, os.path.join(pathname,name+'.py')), plugin_names)
         else:
             import electrum_plugins
             plugin_names = [name for a, name, b in pkgutil.iter_modules(electrum_plugins.__path__)]
-            self.plugins = [ __import__('electrum_plugins.'+name, fromlist=['electrum_plugins']) for name in plugin_names]
+            plugins = [ __import__('electrum_plugins.'+name, fromlist=['electrum_plugins']) for name in plugin_names]
 
-        self.plugin_hooks = {}
-        for p in self.plugins:
+        self.plugins = []
+        for p in plugins:
             try:
-                p.init(self)
+                self.plugins.append( p.Plugin(self) )
             except:
                 print_msg("Error:cannot initialize plugin",p)
                 traceback.print_exc(file=sys.stdout)
 
-    def set_hook(self, name, callback):
-        h = self.plugin_hooks.get(name, [])
-        h.append(callback)
-        self.plugin_hooks[name] = h
-
-    def unset_hook(self, name, callback):
-        h = self.plugin_hooks.get(name,[])
-        if callback in h: h.remove(callback)
-        self.plugin_hooks[name] = h
 
     def run_hook(self, name, *args):
-        args = (self,) + args
-        for cb in self.plugin_hooks.get(name,[]):
-            apply(cb, args)
-
+        for p in self.plugins:
+            if not p.is_enabled():
+                continue
+            try:
+                f = eval('p.'+name)
+            except:
+                continue
+            apply(f, args)
+        return
 
+        
     def set_label(self, name, text = None):
         changed = False
         old_text = self.wallet.labels.get(name)
@@ -2002,7 +1999,7 @@ class ElectrumWindow(QMainWindow):
             grid_plugins.setColumnStretch(0,1)
             tabs.addTab(tab5, _('Plugins') )
             def mk_toggle(cb, p):
-                return lambda: cb.setChecked(p.toggle(self))
+                return lambda: cb.setChecked(p.toggle())
             for i, p in enumerate(self.plugins):
                 try:
                     name, description = p.get_info()
diff --git a/gui/plugins.py b/gui/plugins.py
new file mode 100644 (file)
index 0000000..bb00bab
--- /dev/null
@@ -0,0 +1,32 @@
+
+
+class BasePlugin:
+
+    def get_info(self):
+        return self.fullname, self.description
+
+    def __init__(self, gui, name, fullname, description):
+        self.name = name
+        self.fullname = fullname
+        self.description = description
+        self.gui = gui
+        self.config = gui.config
+
+    def toggle(self):
+        enabled = not self.is_enabled()
+        self.set_enabled(enabled)
+        self.init_gui()
+        return enabled
+    
+    def init_gui(self):
+        pass
+
+    def is_enabled(self):
+        return self.is_available() and self.config.get('use_'+self.name) is True
+
+    def is_available(self):
+        return True
+
+    def set_enabled(self, enabled):
+        self.config.set_key('use_'+self.name, enabled, True)
+
index f8a3a5b..c44df3f 100644 (file)
@@ -15,217 +15,185 @@ from electrum_gui.i18n import _
 ALIAS_REGEXP = '^(|([\w\-\.]+)@)((\w[\w\-]+\.)+[\w\-]+)$'    
 
 
-config = {}
-
-def get_info():
-    return 'Aliases', _('Retrieve aliases using http.')
-
-def init(self):
-    global config
-    config = self.config
-    self.aliases               = config.get('aliases', {})            # aliases for addresses
-    self.authorities           = config.get('authorities', {})        # trusted addresses
-    self.receipts              = config.get('receipts',{})            # signed URIs
-    do_enable(self, is_enabled())
-
-def is_enabled():
-    return config.get('use_aliases') is True
-
-def is_available():
-    return True
-
-
-def toggle(gui):
-    enabled = not is_enabled()
-    config.set_key('use_aliases', enabled, True)
-    do_enable(gui, enabled)
-    return enabled
-
-
-def do_enable(gui, enabled):
-    if enabled:
-        gui.set_hook('timer_actions', timer_actions)
-        gui.set_hook('set_url', set_url_hook)
-        gui.set_hook('update_contacts_tab', update_contacts_tab_hook)
-        gui.set_hook('update_completions', update_completions_hook)
-        gui.set_hook('create_contact_menu', create_contact_menu_hook)
-    else:
-        gui.unset_hook('timer_actions', timer_actions)
-        gui.unset_hook('set_url', set_url_hook)
-        gui.unset_hook('update_contacts_tab', update_contacts_tab_hook)
-        gui.unset_hook('update_completions', update_completions_hook)
-        gui.unset_hook('create_contact_menu', create_contact_menu_hook)
-
-
-def timer_actions(self):
-    if self.payto_e.hasFocus():
-        return
-    r = unicode( self.payto_e.text() )
-    if r != self.previous_payto_e:
-        self.previous_payto_e = r
-        r = r.strip()
-        if re.match('^(|([\w\-\.]+)@)((\w[\w\-]+\.)+[\w\-]+)$', r):
-            try:
-                to_address = get_alias(self, r, True, self.show_message, self.question)
-            except:
-                return
-            if to_address:
-                s = r + '  <' + to_address + '>'
-                self.payto_e.setText(s)
-
-
-def get_alias(self, alias, interactive = False, show_message=None, question = None):
-    try:
-        target, signing_address, auth_name = read_alias(self, alias)
-    except BaseException, e:
-        # raise exception if verify fails (verify the chain)
-        if interactive:
-            show_message("Alias error: " + str(e))
-        return
-
-    print target, signing_address, auth_name
-
-    if auth_name is None:
-        a = self.aliases.get(alias)
-        if not a:
-            msg = "Warning: the alias '%s' is self-signed.\nThe signing address is %s.\n\nDo you want to add this alias to your list of contacts?"%(alias,signing_address)
-            if interactive and question( msg ):
-                self.aliases[alias] = (signing_address, target)
-            else:
-                target = None
-        else:
-            if signing_address != a[0]:
-                msg = "Warning: the key of alias '%s' has changed since your last visit! It is possible that someone is trying to do something nasty!!!\nDo you accept to change your trusted key?"%alias
+
+from electrum_gui import BasePlugin
+class Plugin(BasePlugin):
+
+    def __init__(self, gui):
+        BasePlugin.__init__(self, gui, 'aliases', 'Aliases', _('Retrieve aliases using http.'))
+        self.aliases      = self.config.get('aliases', {})            # aliases for addresses
+        self.authorities  = self.config.get('authorities', {})        # trusted addresses
+        self.receipts     = self.config.get('receipts',{})            # signed URIs
+
+
+    def timer_actions(self):
+        if self.gui.payto_e.hasFocus():
+            return
+        r = unicode( self.gui.payto_e.text() )
+        if r != self.gui.previous_payto_e:
+            self.gui.previous_payto_e = r
+            r = r.strip()
+            if re.match('^(|([\w\-\.]+)@)((\w[\w\-]+\.)+[\w\-]+)$', r):
+                try:
+                    to_address = self.get_alias(r, True, self.gui.show_message, self.gui.question)
+                except:
+                    return
+                if to_address:
+                    s = r + '  <' + to_address + '>'
+                    self.gui.payto_e.setText(s)
+
+
+    def get_alias(self, alias, interactive = False, show_message=None, question = None):
+        try:
+            target, signing_address, auth_name = read_alias(self, alias)
+        except BaseException, e:
+            # raise exception if verify fails (verify the chain)
+            if interactive:
+                show_message("Alias error: " + str(e))
+            return
+
+        print target, signing_address, auth_name
+
+        if auth_name is None:
+            a = self.aliases.get(alias)
+            if not a:
+                msg = "Warning: the alias '%s' is self-signed.\nThe signing address is %s.\n\nDo you want to add this alias to your list of contacts?"%(alias,signing_address)
                 if interactive and question( msg ):
                     self.aliases[alias] = (signing_address, target)
                 else:
                     target = None
-    else:
-        if signing_address not in self.authorities.keys():
-            msg = "The alias: '%s' links to %s\n\nWarning: this alias was signed by an unknown key.\nSigning authority: %s\nSigning address: %s\n\nDo you want to add this key to your list of trusted keys?"%(alias,target,auth_name,signing_address)
-            if interactive and question( msg ):
-                self.authorities[signing_address] = auth_name
             else:
-                target = None
+                if signing_address != a[0]:
+                    msg = "Warning: the key of alias '%s' has changed since your last visit! It is possible that someone is trying to do something nasty!!!\nDo you accept to change your trusted key?"%alias
+                    if interactive and question( msg ):
+                        self.aliases[alias] = (signing_address, target)
+                    else:
+                        target = None
+        else:
+            if signing_address not in self.authorities.keys():
+                msg = "The alias: '%s' links to %s\n\nWarning: this alias was signed by an unknown key.\nSigning authority: %s\nSigning address: %s\n\nDo you want to add this key to your list of trusted keys?"%(alias,target,auth_name,signing_address)
+                if interactive and question( msg ):
+                    self.authorities[signing_address] = auth_name
+                else:
+                    target = None
 
-    if target:
-        self.aliases[alias] = (signing_address, target)
+        if target:
+            self.aliases[alias] = (signing_address, target)
             
-    return target
-
-
-
-def read_alias(self, alias):
-    import urllib
-
-    m1 = re.match('([\w\-\.]+)@((\w[\w\-]+\.)+[\w\-]+)', alias)
-    m2 = re.match('((\w[\w\-]+\.)+[\w\-]+)', alias)
-    if m1:
-        url = 'https://' + m1.group(2) + '/bitcoin.id/' + m1.group(1) 
-    elif m2:
-        url = 'https://' + alias + '/bitcoin.id'
-    else:
-        return ''
-    try:
-        lines = urllib.urlopen(url).readlines()
-    except:
-        return ''
-
-    # line 0
-    line = lines[0].strip().split(':')
-    if len(line) == 1:
-        auth_name = None
-        target = signing_addr = line[0]
-    else:
-        target, auth_name, signing_addr, signature = line
-        msg = "alias:%s:%s:%s"%(alias,target,auth_name)
-        print msg, signature
-        EC_KEY.verify_message(signing_addr, signature, msg)
-        
-    # other lines are signed updates
-    for line in lines[1:]:
-        line = line.strip()
-        if not line: continue
-        line = line.split(':')
-        previous = target
-        print repr(line)
-        target, signature = line
-        EC_KEY.verify_message(previous, signature, "alias:%s:%s"%(alias,target))
-
-    if not is_valid(target):
-        raise ValueError("Invalid bitcoin address")
-
-    return target, signing_addr, auth_name
-
-
-def set_url_hook(self, url, show_message, question):
-    payto, amount, label, message, signature, identity, url = util.parse_url(url)
-    if signature:
-        if re.match('^(|([\w\-\.]+)@)((\w[\w\-]+\.)+[\w\-]+)$', identity):
-            signing_address = get_alias(identity, True, show_message, question)
-        elif is_valid(identity):
-            signing_address = identity
+        return target
+
+
+
+    def read_alias(self, alias):
+        import urllib
+
+        m1 = re.match('([\w\-\.]+)@((\w[\w\-]+\.)+[\w\-]+)', alias)
+        m2 = re.match('((\w[\w\-]+\.)+[\w\-]+)', alias)
+        if m1:
+            url = 'https://' + m1.group(2) + '/bitcoin.id/' + m1.group(1) 
+        elif m2:
+            url = 'https://' + alias + '/bitcoin.id'
         else:
-            signing_address = None
-        if not signing_address:
-            return
+            return ''
         try:
-            EC_KEY.verify_message(signing_address, signature, url )
-            self.receipt = (signing_address, signature, url)
+            lines = urllib.urlopen(url).readlines()
         except:
-            show_message('Warning: the URI contains a bad signature.\nThe identity of the recipient cannot be verified.')
-            address = amount = label = identity = message = ''
+            return ''
 
-    if re.match('^(|([\w\-\.]+)@)((\w[\w\-]+\.)+[\w\-]+)$', address):
-        payto_address = get_alias(address, True, show_message, question)
-        if payto_address:
-            address = address + ' <' + payto_address + '>'
+        # line 0
+        line = lines[0].strip().split(':')
+        if len(line) == 1:
+            auth_name = None
+            target = signing_addr = line[0]
+        else:
+            target, auth_name, signing_addr, signature = line
+            msg = "alias:%s:%s:%s"%(alias,target,auth_name)
+            print msg, signature
+            EC_KEY.verify_message(signing_addr, signature, msg)
+        
+        # other lines are signed updates
+        for line in lines[1:]:
+            line = line.strip()
+            if not line: continue
+            line = line.split(':')
+            previous = target
+            print repr(line)
+            target, signature = line
+            EC_KEY.verify_message(previous, signature, "alias:%s:%s"%(alias,target))
+
+        if not is_valid(target):
+            raise ValueError("Invalid bitcoin address")
+
+        return target, signing_addr, auth_name
+
+
+    def set_url(self, url, show_message, question):
+        payto, amount, label, message, signature, identity, url = util.parse_url(url)
+        if signature:
+            if re.match('^(|([\w\-\.]+)@)((\w[\w\-]+\.)+[\w\-]+)$', identity):
+                signing_address = get_alias(identity, True, show_message, question)
+            elif is_valid(identity):
+                signing_address = identity
+            else:
+                signing_address = None
+            if not signing_address:
+                return
+            try:
+                EC_KEY.verify_message(signing_address, signature, url )
+                self.receipt = (signing_address, signature, url)
+            except:
+                show_message('Warning: the URI contains a bad signature.\nThe identity of the recipient cannot be verified.')
+                address = amount = label = identity = message = ''
 
-    return address, amount, label, message, signature, identity, url
+        if re.match('^(|([\w\-\.]+)@)((\w[\w\-]+\.)+[\w\-]+)$', address):
+            payto_address = get_alias(address, True, show_message, question)
+            if payto_address:
+                address = address + ' <' + payto_address + '>'
 
+        return address, amount, label, message, signature, identity, url
 
 
-def update_contacts_tab_hook(self, l):
-    alias_targets = []
-    for alias, v in self.aliases.items():
-        s, target = v
-        alias_targets.append(target)
-        item = QTreeWidgetItem( [ target, alias, '-'] )
-        item.setBackgroundColor(0, QColor('lightgray'))
-        l.insertTopLevelItem(0,item)
-        item.setData(0,32,False)
-        item.setData(0,33,alias + ' <' + target + '>')
 
+    def update_contacts_tab(self, l):
+        alias_targets = []
+        for alias, v in self.aliases.items():
+            s, target = v
+            alias_targets.append(target)
+            item = QTreeWidgetItem( [ target, alias, '-'] )
+            item.setBackgroundColor(0, QColor('lightgray'))
+            item.setData(0,32,False)
+            item.setData(0,33,alias + ' <' + target + '>')
+            l.insertTopLevelItem(0,item)
 
 
-def update_completions_hook(self, l):
-    l[:] = l + self.aliases.keys()
+    def update_completions(self, l):
+        l[:] = l + self.aliases.keys()
 
 
-def create_contact_menu_hook(self, menu, item):
-    label = unicode(item.text(1))
-    if label in self.aliases.keys():
-        addr = unicode(item.text(0))
+    def create_contact_menu(self, menu, item):
         label = unicode(item.text(1))
-        menu.addAction(_("View alias details"), lambda: show_contact_details(self, label))
-        menu.addAction(_("Delete alias"), lambda: delete_alias(self, label))
-
-
-def show_contact_details(self, m):
-    a = self.aliases.get(m)
-    if a:
-        if a[0] in self.authorities.keys():
-            s = self.authorities.get(a[0])
-        else:
-            s = "self-signed"
-        msg = _('Alias:')+' '+ m + '\n'+_('Target address:')+' '+ a[1] + '\n\n'+_('Signed by:')+' ' + s + '\n'+_('Signing address:')+' ' + a[0]
-        QMessageBox.information(self, 'Alias', msg, 'OK')
-
-
-def delete_alias(self, x):
-    if self.question(_("Do you want to remove")+" %s "%x +_("from your list of contacts?")):
-        if x in self.aliases:
-            self.aliases.pop(x)
-            self.update_history_tab()
-            self.update_contacts_tab()
-            self.update_completions()
+        if label in self.aliases.keys():
+            addr = unicode(item.text(0))
+            label = unicode(item.text(1))
+            menu.addAction(_("View alias details"), lambda: self.show_contact_details(label))
+            menu.addAction(_("Delete alias"), lambda: delete_alias(self, label))
+
+
+    def show_contact_details(self, m):
+        a = self.aliases.get(m)
+        if a:
+            if a[0] in self.authorities.keys():
+                s = self.authorities.get(a[0])
+            else:
+                s = "self-signed"
+            msg = _('Alias:')+' '+ m + '\n'+_('Target address:')+' '+ a[1] + '\n\n'+_('Signed by:')+' ' + s + '\n'+_('Signing address:')+' ' + a[0]
+            QMessageBox.information(self.gui, 'Alias', msg, 'OK')
+
+
+    def delete_alias(self, x):
+        if self.gui.question(_("Do you want to remove")+" %s "%x +_("from your list of contacts?")):
+            if x in self.aliases:
+                self.aliases.pop(x)
+                self.update_history_tab()
+                self.update_contacts_tab()
+                self.update_completions()
index 29dedeb..7cc8c77 100644 (file)
@@ -8,8 +8,7 @@ import PyQt4.QtCore as QtCore
 import PyQt4.QtGui as QtGui
 
 from electrum_gui.qrcodewidget import QRCodeWidget
-from electrum_gui import bmp, pyqrnative
-
+from electrum_gui import bmp, pyqrnative, BasePlugin
 from electrum_gui.i18n import _
 
 
@@ -89,98 +88,95 @@ class QR_Window(QWidget):
             
         self.qrw.set_addr( msg )
 
-            
-
 
-config = {}
 
-def get_info():
-    return 'Point of Sale', _('Show QR code window and amounts requested for each address. Add menu item to request amount.')
 
-def init(gui):
-    global config
-    config = gui.config
-    gui.requested_amounts = config.get('requested_amounts',{}) 
-    gui.merchant_name = config.get('merchant_name', 'Invoice')
-    gui.qr_window = None
-    do_enable(gui, is_enabled())
+class Plugin(BasePlugin):
 
-def is_enabled():
-    return config.get('pointofsale') is True
+    def __init__(self, gui):
+        BasePlugin.__init__(self, gui, 'pointofsale', 'Point of Sale',
+                            _('Show QR code window and amounts requested for each address. Add menu item to request amount.') )
+        self.qr_window = None
+        self.requested_amounts = self.config.get('requested_amounts',{}) 
+        self.merchant_name = self.config.get('merchant_name', 'Invoice')
 
-def is_available():
-    return True
 
+    def init_gui(self):
+        enabled = self.is_enabled()
+        if enabled:
+            self.gui.expert_mode = True
+            self.gui.receive_list.setHeaderLabels([ _('Address'), _('Label'), _('Balance'), _('Request')])
+        else:
+            self.gui.receive_list.setHeaderLabels([ _('Address'), _('Label'), _('Balance'), _('Tx')])
 
-def toggle(gui):
-    enabled = not is_enabled()
-    config.set_key('pointofsale', enabled, True)
-    do_enable(gui, enabled)
-    update_gui(gui)
-    return enabled
+        self.toggle_QR_window(enabled)
+    
 
+    def close_main_window(self):
+        if self.qr_window: 
+            self.qr_window.close()
+            self.qr_window = None
 
-def do_enable(gui, enabled):
-    if enabled:
-        gui.expert_mode = True
-        gui.set_hook('item_changed', item_changed)
-        gui.set_hook('current_item_changed', recv_changed)
-        gui.set_hook('receive_menu', receive_menu)
-        gui.set_hook('update_receive_item', update_receive_item)
-        gui.set_hook('timer_actions', timer_actions)
-        gui.set_hook('close_main_window', close_main_window)
-        gui.set_hook('init', update_gui)
-    else:
-        gui.unset_hook('item_changed', item_changed)
-        gui.unset_hook('current_item_changed', recv_changed)
-        gui.unset_hook('receive_menu', receive_menu)
-        gui.unset_hook('update_receive_item', update_receive_item)
-        gui.unset_hook('timer_actions', timer_actions)
-        gui.unset_hook('close_main_window', close_main_window)
-        gui.unset_hook('init', update_gui)
+    
+    def timer_actions(self):
+        if self.qr_window:
+            self.qr_window.qrw.update_qr()
+
+
+    def toggle_QR_window(self, show):
+        if show and not self.qr_window:
+            self.qr_window = QR_Window(self.gui.exchanger)
+            self.qr_window.setVisible(True)
+            self.qr_window_geometry = self.qr_window.geometry()
+            item = self.gui.receive_list.currentItem()
+            if item:
+                address = str(item.text(1))
+                label = self.gui.wallet.labels.get(address)
+                amount, currency = self.requested_amounts.get(address, (None, None))
+                self.qr_window.set_content( address, label, amount, currency )
 
+        elif show and self.qr_window and not self.qr_window.isVisible():
+            self.qr_window.setVisible(True)
+            self.qr_window.setGeometry(self.qr_window_geometry)
 
+        elif not show and self.qr_window and self.qr_window.isVisible():
+            self.qr_window_geometry = self.qr_window.geometry()
+            self.qr_window.setVisible(False)
 
-def update_gui(gui):
-    enabled = is_enabled()
-    if enabled:
-        gui.receive_list.setHeaderLabels([ _('Address'), _('Label'), _('Balance'), _('Request')])
-    else:
-        gui.receive_list.setHeaderLabels([ _('Address'), _('Label'), _('Balance'), _('Tx')])
 
-    toggle_QR_window(gui, enabled)
     
-
-
-def toggle_QR_window(self, show):
-    if show and not self.qr_window:
-        self.qr_window = QR_Window(self.exchanger)
-        self.qr_window.setVisible(True)
-        self.qr_window_geometry = self.qr_window.geometry()
-        item = self.receive_list.currentItem()
-        if item:
-            address = str(item.text(1))
-            label = self.wallet.labels.get(address)
+    def update_receive_item(self, address, item):
+        try:
             amount, currency = self.requested_amounts.get(address, (None, None))
-            self.qr_window.set_content( address, label, amount, currency )
-
-    elif show and self.qr_window and not self.qr_window.isVisible():
-        self.qr_window.setVisible(True)
-        self.qr_window.setGeometry(self.qr_window_geometry)
+        except:
+            print "cannot get requested amount", address, self.requested_amounts.get(address)
+            amount, currency = None, None
+            self.requested_amounts.pop(address)
 
-    elif not show and self.qr_window and self.qr_window.isVisible():
-        self.qr_window_geometry = self.qr_window.geometry()
-        self.qr_window.setVisible(False)
+        amount_str = amount + (' ' + currency if currency else '') if amount is not None  else ''
+        item.setData(column_index,0,amount_str)
 
 
+    
+    def current_item_changed(self, a):
+        if a is not None and self.qr_window and self.qr_window.isVisible():
+            address = str(a.text(0))
+            label = self.gui.wallet.labels.get(address)
+            try:
+                amount, currency = self.requested_amounts.get(address, (None, None))
+            except:
+                amount, currency = None, None
+            self.qr_window.set_content( address, label, amount, currency )
 
 
-def item_changed(self, item, column):
-    if column == column_index:
+    
+    def item_changed(self, item, column):
+        if column != column_index:
+            return
         address = str( item.text(0) )
         text = str( item.text(column) )
         try:
-            seq = self.wallet.get_address_index(address)
+            seq = self.gui.wallet.get_address_index(address)
             index = seq[-1]
         except:
             print "cannot get index"
@@ -198,9 +194,9 @@ def item_changed(self, item, column):
                 currency = currency.upper()
                     
             self.requested_amounts[address] = (amount, currency)
-            self.wallet.config.set_key('requested_amounts', self.requested_amounts, True)
+            self.gui.wallet.config.set_key('requested_amounts', self.requested_amounts, True)
 
-            label = self.wallet.labels.get(address)
+            label = self.gui.wallet.labels.get(address)
             if label is None:
                 label = self.merchant_name + ' - %04d'%(index+1)
                 self.wallet.labels[address] = label
@@ -213,50 +209,20 @@ def item_changed(self, item, column):
             if address in self.requested_amounts:
                 self.requested_amounts.pop(address)
             
-        self.update_receive_item(self.receive_list.currentItem())
-
+        self.gui.update_receive_item(self.gui.receive_list.currentItem())
 
-def recv_changed(self, a):
-    if a is not None and self.qr_window and self.qr_window.isVisible():
-        address = str(a.text(0))
-        label = self.wallet.labels.get(address)
-        try:
-            amount, currency = self.requested_amounts.get(address, (None, None))
-        except:
-            amount, currency = None, None
-        self.qr_window.set_content( address, label, amount, currency )
 
 
 
-def edit_amount(self):
-    l = self.receive_list
-    item = l.currentItem()
-    item.setFlags(Qt.ItemIsEditable|Qt.ItemIsSelectable | Qt.ItemIsUserCheckable | Qt.ItemIsEnabled | Qt.ItemIsDragEnabled)
-    l.editItem( item, column_index )
-    item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsUserCheckable | Qt.ItemIsEnabled | Qt.ItemIsDragEnabled)
+    def edit_amount(self):
+        l = self.gui.receive_list
+        item = l.currentItem()
+        item.setFlags(Qt.ItemIsEditable|Qt.ItemIsSelectable | Qt.ItemIsUserCheckable | Qt.ItemIsEnabled | Qt.ItemIsDragEnabled)
+        l.editItem( item, column_index )
+        item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsUserCheckable | Qt.ItemIsEnabled | Qt.ItemIsDragEnabled)
 
-def receive_menu(self, menu):
-    menu.addAction(_("Request amount"), lambda: edit_amount(self))
-
-
-def update_receive_item(self, address, item):
-    try:
-        amount, currency = self.requested_amounts.get(address, (None, None))
-    except:
-        print "cannot get requested amount", address, self.requested_amounts.get(address)
-        amount, currency = None, None
-        self.requested_amounts.pop(address)
-
-    amount_str = amount + (' ' + currency if currency else '') if amount is not None  else ''
-    item.setData(column_index,0,amount_str)
-
-
-def close_main_window(self):
-    if self.qr_window: 
-        self.qr_window.close()
-        self.qr_window = None
+    
+    def receive_menu(self, menu):
+        menu.addAction(_("Request amount"), self.edit_amount)
 
 
-def timer_actions(self):
-    if self.qr_window:
-        self.qr_window.qrw.update_qr()
index cc16484..f66e60b 100644 (file)
@@ -8,55 +8,62 @@ try:
 except ImportError:
     zbar = None
 
+from electrum_gui import BasePlugin
+class Plugin(BasePlugin):
 
+    def __init__(self, gui):
+        BasePlugin.__init__(self, gui, 'qrscans', 'QR scans', "QR Scans.\nInstall the zbar package to enable this plugin")
+        
+    def is_available(self):
+        if not zbar:
+            return False
+        try:
+            proc = zbar.Processor()
+            proc.init()
+        except zbar.SystemError:
+            # Cannot open video device
+            return False
+        return True
 
-def init(gui):
-    if is_enabled():
-        gui.set_hook('create_send_tab', create_send_tab)
-    else:
-        gui.unset_hook('create_send_tab', create_send_tab)
-
-def get_info():
-    return 'QR scans', "QR Scans.\nInstall the zbar package to enable this plugin"
-
-def is_enabled():
-    return is_available()
-
-def toggle(gui):
-    return is_enabled()
 
+    def create_send_tab(self, grid):
+        b = QPushButton(_("Scan QR code"))
+        b.clicked.connect(self.fill_from_qr)
+        grid.addWidget(b, 1, 5)
 
-def is_available():
-    if not zbar:
-        return False
 
-    try:
+    def scan_qr(self):
         proc = zbar.Processor()
         proc.init()
-    except zbar.SystemError:
-        # Cannot open video device
-        return False
-
-    return True
+        proc.visible = True
+
+        while True:
+            try:
+                proc.process_one()
+            except:
+                # User closed the preview window
+                return {}
+
+            for r in proc.results:
+                if str(r.type) != 'QRCODE':
+                    continue
+                return parse_uri(r.data)
+        
 
-def scan_qr():
-    proc = zbar.Processor()
-    proc.init()
-    proc.visible = True
+    def fill_from_qr(self):
+        qrcode = self.scan_qr()
+        if 'address' in qrcode:
+            self.gui.payto_e.setText(qrcode['address'])
+        if 'amount' in qrcode:
+            self.gui.amount_e.setText(str(qrcode['amount']))
+        if 'label' in qrcode:
+            self.gui.message_e.setText(qrcode['label'])
+        if 'message' in qrcode:
+            self.gui.message_e.setText("%s (%s)" % (self.gui.message_e.text(), qrcode['message']))
+                
 
-    while True:
-        try:
-            proc.process_one()
-        except:
-            # User closed the preview window
-            return {}
 
-        for r in proc.results:
-            if str(r.type) != 'QRCODE':
-                continue
 
-            return parse_uri(r.data)
-        
 def parse_uri(uri):
     if ':' not in uri:
         # It's just an address (not BIP21)
@@ -82,24 +89,6 @@ def parse_uri(uri):
 
 
 
-def fill_from_qr(self):
-    qrcode = scan_qr()
-    if 'address' in qrcode:
-        self.payto_e.setText(qrcode['address'])
-    if 'amount' in qrcode:
-        self.amount_e.setText(str(qrcode['amount']))
-    if 'label' in qrcode:
-        self.message_e.setText(qrcode['label'])
-    if 'message' in qrcode:
-        self.message_e.setText("%s (%s)" % (self.message_e.text(), qrcode['message']))
-                
-
-def create_send_tab(gui, grid):
-    if is_available():
-        b = QPushButton(_("Scan QR code"))
-        b.clicked.connect(lambda: fill_from_qr(gui))
-        grid.addWidget(b, 1, 5)
-
 
 
 if __name__ == '__main__':