add switch-gui button for qt
[electrum-nvc.git] / lib / gui_qt.py
index f765bdc..6c113e9 100644 (file)
@@ -19,6 +19,7 @@
 import sys, time, datetime, re
 from i18n import _
 from util import print_error
+import os.path, json, util
 
 try:
     import PyQt4
@@ -38,6 +39,7 @@ except:
 
 from wallet import format_satoshis
 import bmp, mnemonic, pyqrnative, qrscanner
+import exchange_rate
 
 from decimal import Decimal
 
@@ -137,25 +139,54 @@ class StatusBarButton(QPushButton):
 
 class QRCodeWidget(QWidget):
 
-    def __init__(self, addr):
-        super(QRCodeWidget, self).__init__()
-        self.setGeometry(300, 300, 350, 350)
-        self.set_addr(addr)
+    def __init__(self, data = None):
+        QWidget.__init__(self)
+        self.setMinimumSize(210, 210)
+        self.addr = None
+        self.qr = None
+        if data:
+            self.set_addr(data)
+            self.update_qr()
 
     def set_addr(self, addr):
-        self.addr = addr
-        self.qr = pyqrnative.QRCode(4, pyqrnative.QRErrorCorrectLevel.L)
-        self.qr.addData(addr)
-        self.qr.make()
-        
+        if self.addr != addr:
+            self.addr = addr
+            self.qr = None
+            self.update()
+
+    def update_qr(self):
+        if self.addr and not self.qr:
+            self.qr = pyqrnative.QRCode(4, pyqrnative.QRErrorCorrectLevel.L)
+            self.qr.addData(self.addr)
+            self.qr.make()
+            self.update()
+
     def paintEvent(self, e):
-        qp = QtGui.QPainter()
-        qp.begin(self)
-        boxsize = 6
-        size = self.qr.getModuleCount()*boxsize
-        k = self.qr.getModuleCount()
+
+        if not self.addr:
+            return
+
         black = QColor(0, 0, 0, 255)
         white = QColor(255, 255, 255, 255)
+
+        if not self.qr:
+            qp = QtGui.QPainter()
+            qp.begin(self)
+            qp.setBrush(white)
+            qp.setPen(white)
+            qp.drawRect(0, 0, 198, 198)
+            qp.end()
+            return
+        k = self.qr.getModuleCount()
+        qp = QtGui.QPainter()
+        qp.begin(self)
+        r = qp.viewport()
+        boxsize = min(r.width(), r.height())*0.8/k
+        size = k*boxsize
+        left = (r.width() - size)/2
+        top = (r.height() - size)/2         
+
         for r in range(k):
             for c in range(k):
                 if self.qr.isDark(r, c):
@@ -164,10 +195,70 @@ class QRCodeWidget(QWidget):
                 else:
                     qp.setBrush(white)
                     qp.setPen(white)
-                qp.drawRect(c*boxsize, r*boxsize, boxsize, boxsize)
+                qp.drawRect(left+c*boxsize, top+r*boxsize, boxsize, boxsize)
         qp.end()
         
 
+
+class QR_Window(QWidget):
+
+    def __init__(self):
+        QWidget.__init__(self)
+        self.setWindowTitle('Electrum - Invoice')
+        self.setMinimumSize(800, 250)
+        self.address = ''
+        self.labe = ''
+        self.amount = 0
+        self.setFocusPolicy(QtCore.Qt.NoFocus)
+
+        main_box = QHBoxLayout()
+        
+        self.qrw = QRCodeWidget()
+        main_box.addWidget(self.qrw, 1)
+
+        vbox = QVBoxLayout()
+        main_box.addLayout(vbox)
+
+        self.address_label = QLabel("")
+        self.address_label.setFont(QFont(MONOSPACE_FONT))
+        vbox.addWidget(self.address_label)
+
+        self.label_label = QLabel("")
+        vbox.addWidget(self.label_label)
+
+        self.amount_label = QLabel("")
+        vbox.addWidget(self.amount_label)
+
+        vbox.addStretch(1)
+        self.setLayout(main_box)
+
+
+    def set_content(self, addr, label, amount):
+        self.address = addr
+        address_text = "<span style='font-size: 18pt'>%s</span>" % addr if addr else ""
+        self.address_label.setText(address_text)
+
+        self.amount = amount
+        amount_text = "<span style='font-size: 21pt'>%s</span> <span style='font-size: 16pt'>BTC</span> " % format_satoshis(amount) if amount else ""
+        self.amount_label.setText(amount_text)
+
+        self.label = label
+        label_text = "<span style='font-size: 21pt'>%s</span>" % label if label else ""
+        self.label_label.setText(label_text)
+
+        msg = 'bitcoin:'+self.address
+        if self.amount is not None:
+            msg += '?amount=%s'%(str( Decimal(self.amount) /100000000))
+            if self.label is not None:
+                msg += '&label=%s'%(self.label)
+        elif self.label is not None:
+            msg += '?label=%s'%(self.label)
+            
+        self.qrw.set_addr( msg )
+
+            
+
+
 def waiting_dialog(f):
 
     s = Timer()
@@ -205,6 +296,7 @@ class ElectrumWindow(QMainWindow):
 
     def __init__(self, wallet, config):
         QMainWindow.__init__(self)
+        self.lite = None
         self.wallet = wallet
         self.config = config
         self.wallet.interface.register_callback('updated', self.update_callback)
@@ -212,15 +304,16 @@ class ElectrumWindow(QMainWindow):
         self.wallet.interface.register_callback('disconnected', self.update_callback)
         self.wallet.interface.register_callback('disconnecting', self.update_callback)
 
-        self.detailed_view = config.get('qt_detailed_view', False)
+        self.receive_tab_mode = config.get('qt_receive_tab_mode', 0)
+        self.merchant_name = config.get('merchant_name', 'Invoice')
 
+        self.qr_window = None
         self.funds_error = False
         self.completions = QStringListModel()
 
         self.tabs = tabs = QTabWidget(self)
         tabs.addTab(self.create_history_tab(), _('History') )
-        if self.wallet.seed:
-            tabs.addTab(self.create_send_tab(), _('Send') )
+        tabs.addTab(self.create_send_tab(), _('Send') )
         tabs.addTab(self.create_receive_tab(), _('Receive') )
         tabs.addTab(self.create_contacts_tab(), _('Contacts') )
         tabs.addTab(self.create_wall_tab(), _('Wall') )
@@ -228,6 +321,7 @@ class ElectrumWindow(QMainWindow):
         tabs.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
         self.setCentralWidget(tabs)
         self.create_status_bar()
+        self.toggle_QR_window(self.receive_tab_mode == 2)
 
         g = self.config.get("winpos-qt",[100, 100, 840, 400])
         self.setGeometry(g[0], g[1], g[2], g[3])
@@ -241,7 +335,11 @@ class ElectrumWindow(QMainWindow):
         QShortcut(QKeySequence("Ctrl+PgDown"), self, lambda: tabs.setCurrentIndex( (tabs.currentIndex() + 1 )%tabs.count() ))
         
         self.connect(self, QtCore.SIGNAL('updatesignal'), self.update_wallet)
+        #self.connect(self, SIGNAL('editamount'), self.edit_amount)
         self.history_list.setFocus(True)
+        
+        self.exchanger = exchange_rate.Exchanger(self)
+        self.connect(self, SIGNAL("refresh_balance()"), self.update_wallet)
 
         # dark magic fix by flatfly; https://bitcointalk.org/index.php?topic=73651.msg959913#msg959913
         if platform.system() == 'Windows':
@@ -249,13 +347,20 @@ class ElectrumWindow(QMainWindow):
             tabs.setCurrentIndex (n)
             tabs.setCurrentIndex (0)
 
+    def close(self):
+        QMainWindow.close(self)
+        if self.qr_window: 
+            self.qr_window.close()
+            self.qr_window = None
 
     def connect_slots(self, sender):
-        if self.wallet.seed:
-            self.connect(sender, QtCore.SIGNAL('timersignal'), self.check_recipient)
-            self.previous_payto_e=''
+        self.connect(sender, QtCore.SIGNAL('timersignal'), self.timer_actions)
+        self.previous_payto_e=''
 
-    def check_recipient(self):
+    def timer_actions(self):
+        if self.qr_window:
+            self.qr_window.qrw.update_qr()
+            
         if self.payto_e.hasFocus():
             return
         r = unicode( self.payto_e.text() )
@@ -284,25 +389,32 @@ class ElectrumWindow(QMainWindow):
                 c, u = self.wallet.get_balance()
                 text =  _( "Balance" ) + ": %s "%( format_satoshis(c,False,self.wallet.num_zeros) )
                 if u: text +=  "[%s unconfirmed]"%( format_satoshis(u,True,self.wallet.num_zeros).strip() )
+                text += self.create_quote_text(Decimal(c+u)/100000000)
                 icon = QIcon(":icons/status_connected.png")
         else:
             text = _( "Not connected" )
             icon = QIcon(":icons/status_disconnected.png")
 
-        if self.funds_error:
-            text = _( "Not enough funds" )
-
+        self.status_text = text
         self.statusBar().showMessage(text)
         self.status_button.setIcon( icon )
 
-        if self.wallet.up_to_date:
+        if self.wallet.up_to_date or not self.wallet.interface.is_connected:
             self.textbox.setText( self.wallet.banner )
             self.update_history_tab()
             self.update_receive_tab()
             self.update_contacts_tab()
             self.update_completions()
 
-
+    def create_quote_text(self, btc_balance):
+        quote_currency = self.config.get("currency", "None")
+        quote_balance = self.exchanger.exchange(btc_balance, quote_currency)
+        if quote_balance is None:
+            quote_text = ""
+        else:
+            quote_text = "  (%.2f %s)" % (quote_balance, quote_currency)
+        return quote_text
+        
     def create_history_tab(self):
         self.history_list = l = MyTreeWidget(self)
         l.setColumnCount(5)
@@ -314,15 +426,17 @@ class ElectrumWindow(QMainWindow):
         l.setHeaderLabels( [ '', _( 'Date' ), _( 'Description' ) , _('Amount'), _('Balance')] )
         self.connect(l, SIGNAL('itemDoubleClicked(QTreeWidgetItem*, int)'), self.tx_label_clicked)
         self.connect(l, SIGNAL('itemChanged(QTreeWidgetItem*, int)'), self.tx_label_changed)
+
         l.setContextMenuPolicy(Qt.CustomContextMenu)
         l.customContextMenuRequested.connect(self.create_history_menu)
         return l
 
+
     def create_history_menu(self, position):
         self.history_list.selectedIndexes() 
         item = self.history_list.currentItem()
         if not item: return
-        tx_hash = str(item.toolTip(0))
+        tx_hash = str(item.data(0, Qt.UserRole).toString())
         if not tx_hash: return
         menu = QMenu()
         menu.addAction(_("Copy ID to Clipboard"), lambda: self.app.clipboard().setText(tx_hash))
@@ -364,6 +478,7 @@ class ElectrumWindow(QMainWindow):
             item.setForeground(2, QBrush(QColor('gray')))
         self.is_edit=False
 
+
     def edit_label(self, is_recv):
         l = self.receive_list if is_recv else self.contacts_list
         c = 2 if is_recv else 1
@@ -372,8 +487,16 @@ class ElectrumWindow(QMainWindow):
         l.editItem( item, c )
         item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsUserCheckable | Qt.ItemIsEnabled | Qt.ItemIsDragEnabled)
 
+    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, 3 )
+        item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsUserCheckable | Qt.ItemIsEnabled | Qt.ItemIsDragEnabled)
+
+
     def address_label_clicked(self, item, column, l, column_addr, column_label):
-        if column==column_label and item.isSelected():
+        if column == column_label and item.isSelected():
             addr = unicode( item.text(column_addr) )
             label = unicode( item.text(column_label) )
             if label in self.wallet.aliases.keys():
@@ -382,31 +505,74 @@ class ElectrumWindow(QMainWindow):
             l.editItem( item, column )
             item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsUserCheckable | Qt.ItemIsEnabled | Qt.ItemIsDragEnabled)
 
+
     def address_label_changed(self, item, column, l, column_addr, column_label):
-        addr = unicode( item.text(column_addr) )
-        text = unicode( item.text(column_label) )
-        changed = False
-
-        if text:
-            if text not in self.wallet.aliases.keys():
-                old_addr = self.wallet.labels.get(text)
-                if old_addr != addr:
-                    self.wallet.labels[addr] = text
-                    changed = True
+
+        if column == column_label:
+            addr = unicode( item.text(column_addr) )
+            text = unicode( item.text(column_label) )
+            changed = False
+
+            if text:
+                if text not in self.wallet.aliases.keys():
+                    old_addr = self.wallet.labels.get(text)
+                    if old_addr != addr:
+                        self.wallet.labels[addr] = text
+                        changed = True
+                else:
+                    print_error("Error: This is one of your aliases")
+                    label = self.wallet.labels.get(addr,'')
+                    item.setText(column_label, QString(label))
             else:
-                print_error("Error: This is one of your aliases")
-                label = self.wallet.labels.get(addr,'')
-                item.setText(column_label, QString(label))
-        else:
-            s = self.wallet.labels.get(addr)
-            if s: 
-                self.wallet.labels.pop(addr)
-                changed = True
+                s = self.wallet.labels.get(addr)
+                if s: 
+                    self.wallet.labels.pop(addr)
+                    changed = True
 
-        if changed:
-            self.wallet.update_tx_labels()
-            self.update_history_tab()
-            self.update_completions()
+            if changed:
+                self.update_history_tab()
+                self.update_completions()
+                
+            self.recv_changed(item)
+
+        if column == 3:
+            address = unicode( item.text(column_addr) )
+            text = unicode( item.text(3) )
+            try:
+                index = self.wallet.addresses.index(address)
+            except:
+                return
+
+            try:
+                amount = int( Decimal(text) * 100000000 )
+                item.setText(3,format_satoshis(amount,False, self.wallet.num_zeros))
+            except:
+                amount = self.wallet.requested_amounts.get(address)
+                if amount: 
+                    item.setText(3,format_satoshis(amount,False, self.wallet.num_zeros))
+                else:
+                    item.setText(3,"")
+                return
+
+            self.wallet.requested_amounts[address] = amount
+
+            label = self.wallet.labels.get(address)
+            if label is None:
+                label = self.merchant_name + ' - %04d'%(index+1)
+                self.wallet.labels[address] = label
+
+            self.update_receive_item(self.receive_list.currentItem())
+            if self.qr_window:
+                self.qr_window.set_content( address, label, amount )
+
+
+    def recv_changed(self, a):
+        "current item changed"
+        if a is not None and self.qr_window and self.qr_window.isVisible():
+            address = str(a.text(1))
+            label = self.wallet.labels.get(address)
+            amount = self.wallet.requested_amounts.get(address)
+            self.qr_window.set_content( address, label, amount )
 
 
     def update_history_tab(self):
@@ -448,8 +614,11 @@ class ElectrumWindow(QMainWindow):
             item.setFont(2, QFont(MONOSPACE_FONT))
             item.setFont(3, QFont(MONOSPACE_FONT))
             item.setFont(4, QFont(MONOSPACE_FONT))
+            if value < 0:
+                item.setForeground(3, QBrush(QColor("#BC1E1E")))
             if tx_hash:
-                item.setToolTip(0, tx_hash)
+                item.setData(0, Qt.UserRole, tx_hash)
+                item.setToolTip(0, "%d %s\nTxId:%s" % (conf, _('Confirmations'), tx_hash) )
             if is_default_label:
                 item.setForeground(2, QBrush(QColor('grey')))
 
@@ -548,10 +717,14 @@ class ElectrumWindow(QMainWindow):
             if inputs:
                 palette = QPalette()
                 palette.setColor(self.amount_e.foregroundRole(), QColor('black'))
+                text = self.status_text
             else:
                 palette = QPalette()
                 palette.setColor(self.amount_e.foregroundRole(), QColor('red'))
                 self.funds_error = True
+                text = _( "Not enough funds" )
+
+            self.statusBar().showMessage(text)
             self.amount_e.setPalette(palette)
             self.fee_e.setPalette(palette)
 
@@ -615,21 +788,27 @@ class ElectrumWindow(QMainWindow):
             password = None
 
         try:
-            tx = self.wallet.mktx( to_address, amount, label, password, fee)
+            tx = self.wallet.mktx( [(to_address, amount)], label, password, fee)
         except BaseException, e:
             self.show_message(str(e))
             return
-            
-        h = self.wallet.send_tx(tx)
-        waiting_dialog(lambda: False if self.wallet.tx_event.isSet() else _("Please wait..."))
-        status, msg = self.wallet.receive_tx( h )
 
-        if status:
-            QMessageBox.information(self, '', _('Payment sent.')+'\n'+msg, _('OK'))
-            self.do_clear()
-            self.update_contacts_tab()
+        if self.wallet.seed:
+            h = self.wallet.send_tx(tx)
+            waiting_dialog(lambda: False if self.wallet.tx_event.isSet() else _("Please wait..."))
+            status, msg = self.wallet.receive_tx( h )
+            if status:
+                QMessageBox.information(self, '', _('Payment sent.')+'\n'+msg, _('OK'))
+                self.do_clear()
+                self.update_contacts_tab()
+            else:
+                QMessageBox.warning(self, _('Error'), msg, _('OK'))
         else:
-            QMessageBox.warning(self, _('Error'), msg, _('OK'))
+            filename = 'unsigned_tx'
+            f = open(filename,'w')
+            f.write(tx)
+            f.close()
+            QMessageBox.information(self, _('Unsigned transaction'), _("Unsigned transaction was saved to file:") + " " +filename, _('OK'))
 
 
     def set_url(self, url):
@@ -712,29 +891,25 @@ class ElectrumWindow(QMainWindow):
 
 
     def create_receive_tab(self):
-        l,w,hbox = self.create_list_tab([_('Flags'), _('Address'), _('Label'), _('Balance'), _('Tx')])
+        l,w,hbox = self.create_list_tab([_('Flags'), _('Address'), _('Label'), _('Requested'), _('Balance'), _('Tx')])
         l.setContextMenuPolicy(Qt.CustomContextMenu)
         l.customContextMenuRequested.connect(self.create_receive_menu)
         self.connect(l, SIGNAL('itemDoubleClicked(QTreeWidgetItem*, int)'), lambda a, b: self.address_label_clicked(a,b,l,1,2))
         self.connect(l, SIGNAL('itemChanged(QTreeWidgetItem*, int)'), lambda a,b: self.address_label_changed(a,b,l,1,2))
+        self.connect(l, SIGNAL('currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)'), lambda a,b: self.recv_changed(a))
         self.receive_list = l
         self.receive_buttons_hbox = hbox
-        self.details_button = EnterButton(self.details_button_text(), self.toggle_detailed_view)
-        hbox.addWidget(self.details_button)
         hbox.addStretch(1)
         return w
 
-    def details_button_text(self):
-        return _('Hide details') if self.detailed_view else _('Show details')
 
-    def toggle_detailed_view(self):
-        self.detailed_view = not self.detailed_view
-        self.config.set_key('qt_detailed_view', self.detailed_view, True)
 
-        self.details_button.setText(self.details_button_text())
+    def receive_tab_set_mode(self, i):
+        self.receive_tab_mode = i
+        self.config.set_key('qt_receive_tab_mode', self.receive_tab_mode, True)
         self.wallet.save()
         self.update_receive_tab()
-        self.update_contacts_tab()
+        self.toggle_QR_window(self.receive_tab_mode == 2)
 
 
     def create_contacts_tab(self):
@@ -750,6 +925,14 @@ class ElectrumWindow(QMainWindow):
         return w
 
 
+    def delete_imported_key(self, addr):
+        if self.question("Do you want to remove %s from your wallet?"%addr):
+            self.wallet.imported_keys.pop(addr)
+            self.update_receive_tab()
+            self.update_history_tab()
+            self.wallet.save()
+
+
     def create_receive_menu(self, position):
         # fixme: this function apparently has a side effect.
         # if it is not called the menu pops up several times
@@ -759,14 +942,21 @@ class ElectrumWindow(QMainWindow):
         if not item: return
         addr = unicode(item.text(1))
         menu = QMenu()
-        menu.addAction(_("Copy to Clipboard"), lambda: self.app.clipboard().setText(addr))
-        menu.addAction(_("View QR code"),lambda: self.show_address_qrcode(addr))
+        menu.addAction(_("Copy to clipboard"), lambda: self.app.clipboard().setText(addr))
+        if self.receive_tab_mode == 2:
+            menu.addAction(_("Request amount"), lambda: self.edit_amount())
+        menu.addAction(_("View QR"), lambda: ElectrumWindow.show_qrcode("Address","bitcoin:"+addr) )
         menu.addAction(_("Edit label"), lambda: self.edit_label(True))
-
-        t = _("Unfreeze") if addr in self.wallet.frozen_addresses else _("Freeze")
-        menu.addAction(t, lambda: self.toggle_freeze(addr))
-        t = _("Unprioritize") if addr in self.wallet.prioritized_addresses else _("Prioritize")
-        menu.addAction(t, lambda: self.toggle_priority(addr))
+        menu.addAction(_("Sign message"), lambda: self.sign_message(addr))
+        if addr in self.wallet.imported_keys:
+            menu.addAction(_("Remove from wallet"), lambda: self.delete_imported_key(addr))
+
+        if self.receive_tab_mode == 1:
+            t = _("Unfreeze") if addr in self.wallet.frozen_addresses else _("Freeze")
+            menu.addAction(t, lambda: self.toggle_freeze(addr))
+            t = _("Unprioritize") if addr in self.wallet.prioritized_addresses else _("Prioritize")
+            menu.addAction(t, lambda: self.toggle_priority(addr))
+            
         menu.exec_(self.receive_list.viewport().mapToGlobal(position))
 
 
@@ -809,7 +999,7 @@ class ElectrumWindow(QMainWindow):
         menu = QMenu()
         menu.addAction(_("Copy to Clipboard"), lambda: self.app.clipboard().setText(addr))
         menu.addAction(_("Pay to"), lambda: self.payto(x, is_alias))
-        menu.addAction(_("View QR code"),lambda: self.show_address_qrcode(addr))
+        menu.addAction(_("View QR code"),lambda: self.show_qrcode("Address","bitcoin:"+addr))
         if not is_alias:
             menu.addAction(_("Edit label"), lambda: self.edit_label(False))
         else:
@@ -818,26 +1008,52 @@ class ElectrumWindow(QMainWindow):
         menu.exec_(self.contacts_list.viewport().mapToGlobal(position))
 
 
+    def update_receive_item(self, item):
+        address = str( item.data(1,0).toString() )
+
+        flags = self.wallet.get_address_flags(address)
+        item.setData(0,0,flags)
+
+        label = self.wallet.labels.get(address,'')
+        item.setData(2,0,label)
+
+        amount = self.wallet.requested_amounts.get(address,None)
+        amount_str = format_satoshis( amount, False, self.wallet.num_zeros ) if amount is not None  else ""
+        item.setData(3,0,amount_str)
+        
+        c, u = self.wallet.get_addr_balance(address)
+        balance = format_satoshis( c + u, False, self.wallet.num_zeros )
+        item.setData(4,0,balance)
+
+        if self.receive_tab_mode == 1:
+            if address in self.wallet.frozen_addresses: 
+                item.setBackgroundColor(1, QColor('lightblue'))
+            elif address in self.wallet.prioritized_addresses: 
+                item.setBackgroundColor(1, QColor('lightgreen'))
+        
+
     def update_receive_tab(self):
         l = self.receive_list
+        
         l.clear()
-        l.setColumnHidden(0,not self.detailed_view)
-        l.setColumnHidden(3,not self.detailed_view)
-        l.setColumnHidden(4,not self.detailed_view)
-        l.setColumnWidth(0, 50) 
+        l.setColumnHidden(0, not self.receive_tab_mode == 1)
+        l.setColumnHidden(3, not self.receive_tab_mode == 2)
+        l.setColumnHidden(4, self.receive_tab_mode == 0)
+        l.setColumnHidden(5, not self.receive_tab_mode == 1)
+        l.setColumnWidth(0, 50)
         l.setColumnWidth(1, 310) 
-        l.setColumnWidth(2, 250)
-        l.setColumnWidth(3, 130) 
-        l.setColumnWidth(4, 10)
+        l.setColumnWidth(2, 200)
+        l.setColumnWidth(3, 130)
+        l.setColumnWidth(4, 130)
+        l.setColumnWidth(5, 10)
 
         gap = 0
         is_red = False
         for address in self.wallet.all_addresses():
 
-            if self.wallet.is_change(address) and not self.detailed_view:
+            if self.wallet.is_change(address) and self.receive_tab_mode != 1:
                 continue
 
-            label = self.wallet.labels.get(address,'')
             n = 0 
             h = self.wallet.history.get(address,[])
 
@@ -859,18 +1075,11 @@ class ElectrumWindow(QMainWindow):
                 if address in self.wallet.addresses:
                     gap = 0
 
-            c, u = self.wallet.get_addr_balance(address)
-            balance = format_satoshis( c + u, False, self.wallet.num_zeros )
-            flags = self.wallet.get_address_flags(address)
-            item = QTreeWidgetItem( [ flags, address, label, balance, num_tx] )
-
+            item = QTreeWidgetItem( [ '', address, '', '', '', num_tx] )
             item.setFont(0, QFont(MONOSPACE_FONT))
             item.setFont(1, QFont(MONOSPACE_FONT))
             item.setFont(3, QFont(MONOSPACE_FONT))
-            if address in self.wallet.frozen_addresses: 
-                item.setBackgroundColor(1, QColor('lightblue'))
-            elif address in self.wallet.prioritized_addresses: 
-                item.setBackgroundColor(1, QColor('lightgreen'))
+            self.update_receive_item(item)
             if is_red and address in self.wallet.addresses:
                 item.setBackgroundColor(1, QColor('red'))
             l.addTopLevelItem(item)
@@ -892,7 +1101,6 @@ class ElectrumWindow(QMainWindow):
 
         l = self.contacts_list
         l.clear()
-        l.setColumnHidden(2, not self.detailed_view)
         l.setColumnWidth(0, 350) 
         l.setColumnWidth(1, 330)
         l.setColumnWidth(2, 100) 
@@ -925,8 +1133,12 @@ class ElectrumWindow(QMainWindow):
         return textbox
 
     def create_status_bar(self):
+        self.status_text = ""
         sb = QStatusBar()
         sb.setFixedHeight(35)
+        qtVersion = qVersion()
+        if (int(qtVersion[0]) >= 4 and int(qtVersion[2]) >= 7):
+            sb.addPermanentWidget( StatusBarButton( QIcon(":icons/switchgui.png"), "Switch to Lite Mode", self.go_lite ) )
         if self.wallet.seed:
             sb.addPermanentWidget( StatusBarButton( QIcon(":icons/lock.png"), "Password", lambda: self.change_password_dialog(self.wallet, self) ) )
         sb.addPermanentWidget( StatusBarButton( QIcon(":icons/preferences.png"), "Preferences", self.settings_dialog ) )
@@ -935,6 +1147,15 @@ class ElectrumWindow(QMainWindow):
         self.status_button = StatusBarButton( QIcon(":icons/status_disconnected.png"), "Network", lambda: self.network_dialog(self.wallet, self) ) 
         sb.addPermanentWidget( self.status_button )
         self.setStatusBar(sb)
+        
+    def go_lite(self):
+        import gui_lite
+        self.hide()
+        if self.lite:
+            self.lite.mini.show()
+        else:
+            self.lite = gui_lite.ElectrumGui(self.wallet, self.config, self)
+            self.lite.main(None)
 
     def new_contact_dialog(self):
         text, ok = QInputDialog.getText(self, _('New Contact'), _('Address') + ':')
@@ -964,10 +1185,9 @@ class ElectrumWindow(QMainWindow):
             password = None
             
         try:
-            seed = wallet.pw_decode(wallet.seed, password)
+            seed = wallet.decode_seed(password)
         except:
-            QMessageBox.warning(parent, _('Error'),
-                                _('Incorrect Password'), _('OK'))
+            QMessageBox.warning(parent, _('Error'), _('Incorrect Password'), _('OK'))
             return
 
         dialog = QDialog(None)
@@ -996,7 +1216,7 @@ class ElectrumWindow(QMainWindow):
         copy_button = QPushButton(_("Copy to Clipboard"))
         copy_button.clicked.connect(copy_function)
 
-        show_qr_function = lambda: ElectrumWindow.show_seed_qrcode(seed)
+        show_qr_function = lambda: ElectrumWindow.show_qrcode(_("Seed"), seed)
         qr_button = QPushButton(_("View as QR Code"))
         qr_button.clicked.connect(show_qr_function)
 
@@ -1015,17 +1235,29 @@ class ElectrumWindow(QMainWindow):
         dialog.exec_()
 
     @staticmethod
-    def show_seed_qrcode(seed):
-        if not seed: return
+    def show_qrcode(title, data):
+        if not data: return
         d = QDialog(None)
         d.setModal(1)
-        d.setWindowTitle(_("Seed"))
+        d.setWindowTitle(title)
         d.setMinimumSize(270, 300)
         vbox = QVBoxLayout()
-        vbox.addWidget(QRCodeWidget(seed))
+        qrw = QRCodeWidget(data)
+        vbox.addWidget(qrw, 1)
+        vbox.addWidget(QLabel(data), 0, Qt.AlignHCenter)
         hbox = QHBoxLayout()
         hbox.addStretch(1)
-        b = QPushButton(_("OK"))
+
+        def print_qr(self):
+            filename = "qrcode.bmp"
+            bmp.save_qrcode(qrw.qr, filename)
+            QMessageBox.information(None, _('Message'), _("QR code saved to file") + " " + filename, _('OK'))
+
+        b = QPushButton(_("Print"))
+        hbox.addWidget(b)
+        b.clicked.connect(print_qr)
+
+        b = QPushButton(_("Close"))
         hbox.addWidget(b)
         b.clicked.connect(d.accept)
 
@@ -1033,57 +1265,125 @@ class ElectrumWindow(QMainWindow):
         d.setLayout(vbox)
         d.exec_()
 
-
-    def show_address_qrcode(self,address):
+    def sign_message(self,address):
         if not address: return
         d = QDialog(self)
         d.setModal(1)
-        d.setWindowTitle(address)
-        d.setMinimumSize(270, 350)
-        vbox = QVBoxLayout()
-        qrw = QRCodeWidget(address)
-        vbox.addWidget(qrw)
+        d.setWindowTitle('Sign Message')
+        d.setMinimumSize(410, 290)
 
-        hbox = QHBoxLayout()
-        amount_e = QLineEdit()
-        hbox.addWidget(QLabel(_('Amount')))
-        hbox.addWidget(amount_e)
-        vbox.addLayout(hbox)
+        tab_widget = QTabWidget()
+        tab = QWidget()
+        layout = QGridLayout(tab)
+
+        sign_address = QLineEdit()
+
+        sign_address.setText(address)
+        layout.addWidget(QLabel(_('Address')), 1, 0)
+        layout.addWidget(sign_address, 1, 1)
+
+        sign_message = QTextEdit()
+        layout.addWidget(QLabel(_('Message')), 2, 0)
+        layout.addWidget(sign_message, 2, 1)
+        layout.setRowStretch(2,3)
 
-        #hbox = QHBoxLayout()
-        #label_e = QLineEdit()
-        #hbox.addWidget(QLabel('Label'))
-        #hbox.addWidget(label_e)
-        #vbox.addLayout(hbox)
-
-        def amount_changed():
-            amount = numbify(amount_e)
-            #label = str( label_e.getText() )
-            if amount is not None:
-                qrw.set_addr('bitcoin:%s?amount=%s'%(address,str( Decimal(amount) /100000000)))
+        sign_signature = QTextEdit()
+        layout.addWidget(QLabel(_('Signature')), 3, 0)
+        layout.addWidget(sign_signature, 3, 1)
+        layout.setRowStretch(3,1)
+
+        def do_sign():
+            if self.wallet.use_encryption:
+                password = self.password_dialog()
+                if not password:
+                    return
             else:
-                qrw.set_addr( address )
-            qrw.repaint()
+                password = None
 
-        def do_save():
-            bmp.save_qrcode(qrw.qr, "qrcode.bmp")
-            self.show_message(_("QR code saved to file") + " 'qrcode.bmp'")
-            
-        amount_e.textChanged.connect( amount_changed )
+            try:
+                signature = self.wallet.sign_message(str(sign_address.text()), str(sign_message.toPlainText()), password)
+                sign_signature.setText(signature)
+            except BaseException, e:
+                self.show_message(str(e))
+                return
 
         hbox = QHBoxLayout()
-        hbox.addStretch(1)
-        b = QPushButton(_("Save"))
-        b.clicked.connect(do_save)
+        b = QPushButton(_("Sign"))
         hbox.addWidget(b)
+        b.clicked.connect(do_sign)
         b = QPushButton(_("Close"))
+        b.clicked.connect(d.accept)
         hbox.addWidget(b)
+        layout.addLayout(hbox, 4, 1)
+        tab_widget.addTab(tab, "Sign")
+
+
+        tab = QWidget()
+        layout = QGridLayout(tab)
+
+        verify_address = QLineEdit()
+        layout.addWidget(QLabel(_('Address')), 1, 0)
+        layout.addWidget(verify_address, 1, 1)
+
+        verify_message = QTextEdit()
+        layout.addWidget(QLabel(_('Message')), 2, 0)
+        layout.addWidget(verify_message, 2, 1)
+        layout.setRowStretch(2,3)
+
+        verify_signature = QTextEdit()
+        layout.addWidget(QLabel(_('Signature')), 3, 0)
+        layout.addWidget(verify_signature, 3, 1)
+        layout.setRowStretch(3,1)
+
+        def do_verify():
+            try:
+                self.wallet.verify_message(verify_address.text(), str(verify_signature.toPlainText()), str(verify_message.toPlainText()))
+                self.show_message("Signature verified")
+            except BaseException, e:
+                self.show_message(str(e))
+                return
+
+        hbox = QHBoxLayout()
+        b = QPushButton(_("Verify"))
+        b.clicked.connect(do_verify)
+        hbox.addWidget(b)
+        b = QPushButton(_("Close"))
         b.clicked.connect(d.accept)
+        hbox.addWidget(b)
+        layout.addLayout(hbox, 4, 1)
+        tab_widget.addTab(tab, "Verify")
 
-        vbox.addLayout(hbox)
+        vbox = QVBoxLayout()
+        vbox.addWidget(tab_widget)
         d.setLayout(vbox)
         d.exec_()
 
+        
+    def toggle_QR_window(self, show):
+        if show and not self.qr_window:
+            self.qr_window = QR_Window()
+            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)
+                amount = self.wallet.requested_amounts.get(address)
+                self.qr_window.set_content( address, label, amount )
+
+        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)
+
+        #self.print_button.setHidden(self.qr_window is None or not self.qr_window.isVisible())
+        self.receive_list.setColumnHidden(3, self.qr_window is None or not self.qr_window.isVisible())
+        self.receive_list.setColumnWidth(2, 200)
+
+
     def question(self, msg):
         return QMessageBox.question(self, _('Message'), msg, QMessageBox.Yes | QMessageBox.No, QMessageBox.No) == QMessageBox.Yes
 
@@ -1136,9 +1436,12 @@ class ElectrumWindow(QMainWindow):
 
         vbox = QVBoxLayout()
         if parent:
-            msg = (_('Your wallet is encrypted. Use this dialog to change your password.')+'\n'+_('To disable wallet encryption, enter an empty new password.')) if wallet.use_encryption else _('Your wallet keys are not encrypted')
+            msg = (_('Your wallet is encrypted. Use this dialog to change your password.')+'\n'\
+                   +_('To disable wallet encryption, enter an empty new password.')) \
+                   if wallet.use_encryption else _('Your wallet keys are not encrypted')
         else:
-            msg = _("Please choose a password to encrypt your wallet keys.")+'\n'+_("Leave these fields empty if you want to disable encryption.")
+            msg = _("Please choose a password to encrypt your wallet keys.")+'\n'\
+                  +_("Leave these fields empty if you want to disable encryption.")
         vbox.addWidget(QLabel(msg))
 
         grid = QGridLayout()
@@ -1165,14 +1468,14 @@ class ElectrumWindow(QMainWindow):
         new_password2 = unicode(conf_pw.text())
 
         try:
-            seed = wallet.pw_decode( wallet.seed, password)
+            seed = wallet.decode_seed(password)
         except:
             QMessageBox.warning(parent, _('Error'), _('Incorrect Password'), _('OK'))
             return
 
         if new_password != new_password2:
             QMessageBox.warning(parent, _('Error'), _('Passwords do not match'), _('OK'))
-            return
+            return ElectrumWindow.change_password_dialog(wallet, parent) # Retry
 
         wallet.update_password(seed, password, new_password)
 
@@ -1230,58 +1533,174 @@ class ElectrumWindow(QMainWindow):
         return True
 
 
+    def do_import_labels(self):
+        labelsFile = QFileDialog.getOpenFileName(QWidget(), "Open text file", util.user_dir(), self.tr("Text Files (labels.dat)"))
+        if not labelsFile: return
+        try:
+            f = open(labelsFile, 'r')
+            data = f.read()
+            f.close()
+            self.wallet.labels = json.loads(data)
+            self.wallet.save()
+            QMessageBox.information(None, "Labels imported", "Your labels where imported from '%s'" % str(labelsFile))
+        except (IOError, os.error), reason:
+            QMessageBox.critical(None, "Unable to export labels", "Electrum was unable to export your labels.\n" + str(reason))
+
+
+    def do_export_labels(self):
+        labels = self.wallet.labels
+        try:
+            labelsFile = util.user_dir() + '/labels.dat'
+            f = open(labelsFile, 'w+')
+            json.dump(labels, f)
+            f.close()
+            QMessageBox.information(None, "Labels exported", "Your labels where exported to '%s'" % str(labelsFile))
+        except (IOError, os.error), reason:
+            QMessageBox.critical(None, "Unable to export labels", "Electrum was unable to export your labels.\n" + str(reason))
+
+    def do_export_history(self):
+        from gui_lite import csv_transaction
+        csv_transaction(self.wallet)
+
+    def do_import_privkey(self):
+        if not self.wallet.imported_keys:
+            r = QMessageBox.question(None, _('Warning'), _('Warning: Imported keys are not recoverable from seed.') + ' ' \
+                                         + _('If you ever need to restore your wallet from its seed, these keys will be lost.') + '\n\n' \
+                                         + _('Are you sure you understand what you are doing?'), 3, 4)
+            if r == 4: return
+
+        text, ok = QInputDialog.getText(self, _('Import private key'), _('Private Key') + ':')
+        if not ok: return
+        sec = str(text)
+        if self.wallet.use_encryption:
+            password = self.password_dialog()
+            if not password:
+                return
+        else:
+            password = None
+        try:
+            addr = self.wallet.import_key(sec, password)
+            if not addr:
+                QMessageBox.critical(None, "Unable to import key", "error")
+            else:
+                QMessageBox.information(None, "Key imported", addr)
+                self.update_receive_tab()
+                self.update_history_tab()
+        except BaseException as e:
+            QMessageBox.critical(None, "Unable to import key", str(e))
 
     def settings_dialog(self):
         d = QDialog(self)
+        d.setWindowTitle(_('Electrum Settings'))
         d.setModal(1)
         vbox = QVBoxLayout()
-        msg = _('Here are the settings of your wallet.') + '\n'\
-              + _('For more explanations, click on the help buttons next to each field.')
 
-        label = QLabel(msg)
-        label.setFixedWidth(250)
-        label.setWordWrap(True)
-        label.setAlignment(Qt.AlignJustify)
-        vbox.addWidget(label)
+        tabs = QTabWidget(self)
+        vbox.addWidget(tabs)
 
-        grid = QGridLayout()
-        grid.setSpacing(8)
-        vbox.addLayout(grid)
+        tab1 = QWidget()
+        grid_ui = QGridLayout(tab1)
+        grid_ui.setColumnStretch(0,1)
+        tabs.addTab(tab1, _('Display') )
+
+        nz_label = QLabel(_('Display zeros'))
+        grid_ui.addWidget(nz_label, 3, 0)
+        nz_e = QLineEdit()
+        nz_e.setText("%d"% self.wallet.num_zeros)
+        grid_ui.addWidget(nz_e, 3, 1)
+        msg = _('Number of zeros displayed after the decimal point. For example, if this is set to 2, "1." will be displayed as "1.00"')
+        grid_ui.addWidget(HelpButton(msg), 3, 2)
+        nz_e.textChanged.connect(lambda: numbify(nz_e,True))
+        if not self.config.is_modifiable('num_zeros'):
+            for w in [nz_e, nz_label]: w.setEnabled(False)
+        
+        gui_label=QLabel(_('Default GUI') + ':')
+        grid_ui.addWidget(gui_label , 7, 0)
+        gui_combo = QComboBox()
+        gui_combo.addItems(['Lite', 'Classic'])
+        index = gui_combo.findText(self.config.get("gui","classic").capitalize())
+        if index==-1: index = 1
+        gui_combo.setCurrentIndex(index)
+        grid_ui.addWidget(gui_combo, 7, 1)
+        grid_ui.addWidget(HelpButton(_('Select which GUI mode to use at start up.'+'\n'+'Note: use the command line to access the "text" and "gtk" GUIs')), 7, 2)
+        if not self.config.is_modifiable('gui'):
+            for w in [gui_combo, gui_label]: w.setEnabled(False)
 
+        lang_label=QLabel(_('Language') + ':')
+        grid_ui.addWidget(lang_label , 8, 0)
+        lang_combo = QComboBox()
+        from i18n import languages
+        lang_combo.addItems(languages.values())
+        try:
+            index = languages.keys().index(self.config.get("language",''))
+        except:
+            index = 0
+        lang_combo.setCurrentIndex(index)
+        grid_ui.addWidget(lang_combo, 8, 1)
+        grid_ui.addWidget(HelpButton(_('Select which language is used in the GUI (after restart). ')), 8, 2)
+        if not self.config.is_modifiable('language'):
+            for w in [lang_combo, lang_label]: w.setEnabled(False)
+
+        currencies = self.exchanger.get_currencies()
+        currencies.insert(0, "None")
+
+        cur_label=QLabel(_('Currency') + ':')
+        grid_ui.addWidget(cur_label , 9, 0)
+        cur_combo = QComboBox()
+        cur_combo.addItems(currencies)
+        try:
+            index = currencies.index(self.config.get('currency', "None"))
+        except:
+            index = 0
+        cur_combo.setCurrentIndex(index)
+        grid_ui.addWidget(cur_combo, 9, 1)
+        grid_ui.addWidget(HelpButton(_('Select which currency is used for quotes. ')), 9, 2)
+        
+        view_label=QLabel(_('Receive Tab') + ':')
+        grid_ui.addWidget(view_label , 10, 0)
+        view_combo = QComboBox()
+        view_combo.addItems([_('Simple'), _('Advanced'), _('Point of Sale')])
+        view_combo.setCurrentIndex(self.receive_tab_mode)
+        grid_ui.addWidget(view_combo, 10, 1)
+        hh = _('This selects the interaction mode of the "Receive" tab. ') + '\n\n' \
+             + _('Simple') +   ': ' + _('Show only addresses and labels.') + '\n\n' \
+             + _('Advanced') + ': ' + _('Show address balances and add extra menu items to freeze/prioritize addresses.') + '\n\n' \
+             + _('Point of Sale') + ': ' + _('Show QR code window and amounts requested for each address. Add menu item to request amount.') + '\n\n' 
+        
+        grid_ui.addWidget(HelpButton(hh), 10, 2)
+
+        # wallet tab
+        tab2 = QWidget()
+        grid_wallet = QGridLayout(tab2)
+        grid_wallet.setColumnStretch(0,1)
+        tabs.addTab(tab2, _('Wallet') )
+        
         fee_label = QLabel(_('Transaction fee'))
-        grid.addWidget(fee_label, 2, 0)
+        grid_wallet.addWidget(fee_label, 0, 0)
         fee_e = QLineEdit()
         fee_e.setText("%s"% str( Decimal( self.wallet.fee)/100000000 ) )
-        grid.addWidget(fee_e, 2, 1)
+        grid_wallet.addWidget(fee_e, 0, 1)
         msg = _('Fee per transaction input. Transactions involving multiple inputs tend to require a higher fee.') + ' ' \
             + _('Recommended value') + ': 0.001'
-        grid.addWidget(HelpButton(msg), 2, 2)
+        grid_wallet.addWidget(HelpButton(msg), 0, 2)
         fee_e.textChanged.connect(lambda: numbify(fee_e,False))
         if not self.config.is_modifiable('fee'):
             for w in [fee_e, fee_label]: w.setEnabled(False)
 
-        nz_label = QLabel(_('Display zeros'))
-        grid.addWidget(nz_label, 3, 0)
-        nz_e = QLineEdit()
-        nz_e.setText("%d"% self.wallet.num_zeros)
-        grid.addWidget(nz_e, 3, 1)
-        msg = _('Number of zeros displayed after the decimal point. For example, if this is set to 2, "1." will be displayed as "1.00"')
-        grid.addWidget(HelpButton(msg), 3, 2)
-        nz_e.textChanged.connect(lambda: numbify(nz_e,True))
-        if not self.config.is_modifiable('num_zeros'):
-            for w in [nz_e, nz_label]: w.setEnabled(False)
-
-        usechange_cb = QCheckBox(_('Use change addresses'))
-        grid.addWidget(usechange_cb, 5, 0)
-        usechange_cb.setChecked(self.wallet.use_change)
-        grid.addWidget(HelpButton(_('Using change addresses makes it more difficult for other people to track your transactions. ')), 5, 2)
-        if not self.config.is_modifiable('use_change'): usechange_cb.setEnabled(False)
+        usechange_label = QLabel(_('Use change addresses'))
+        grid_wallet.addWidget(usechange_label, 1, 0)
+        usechange_combo = QComboBox()
+        usechange_combo.addItems(['Yes', 'No'])
+        usechange_combo.setCurrentIndex(not self.wallet.use_change)
+        grid_wallet.addWidget(usechange_combo, 1, 1)
+        grid_wallet.addWidget(HelpButton(_('Using change addresses makes it more difficult for other people to track your transactions. ')), 1, 2)
+        if not self.config.is_modifiable('use_change'): usechange_combo.setEnabled(False)
 
         gap_label = QLabel(_('Gap limit'))
-        grid.addWidget(gap_label, 6, 0)
+        grid_wallet.addWidget(gap_label, 2, 0)
         gap_e = QLineEdit()
         gap_e.setText("%d"% self.wallet.gap_limit)
-        grid.addWidget(gap_e, 6, 1)
+        grid_wallet.addWidget(gap_e, 2, 1)
         msg =  _('The gap limit is the maximal number of contiguous unused addresses in your sequence of receiving addresses.') + '\n' \
               + _('You may increase it if you need more receiving addresses.') + '\n\n' \
               + _('Your current gap limit is') + ': %d'%self.wallet.gap_limit + '\n' \
@@ -1289,23 +1708,34 @@ class ElectrumWindow(QMainWindow):
               + _('Warning') + ': ' \
               + _('The gap limit parameter must be provided in order to recover your wallet from seed.') + ' ' \
               + _('Do not modify it if you do not understand what you are doing, or if you expect to recover your wallet without knowing it!') + '\n\n' 
-        grid.addWidget(HelpButton(msg), 6, 2)
+        grid_wallet.addWidget(HelpButton(msg), 2, 2)
         gap_e.textChanged.connect(lambda: numbify(nz_e,True))
         if not self.config.is_modifiable('gap_limit'):
             for w in [gap_e, gap_label]: w.setEnabled(False)
+
+        grid_wallet.setRowStretch(3,1)
+
+
+        # wallet tab
+        tab3 = QWidget()
+        grid_io = QGridLayout(tab3)
+        grid_io.setColumnStretch(0,1)
+        tabs.addTab(tab3, _('Import/Export') )
         
-        gui_label=QLabel(_('Default GUI') + ':')
-        grid.addWidget(gui_label , 7, 0)
-        gui_combo = QComboBox()
-        gui_combo.addItems(['Lite', 'Classic', 'Gtk', 'Text'])
-        index = gui_combo.findText(self.config.get("gui","classic").capitalize())
-        if index==-1: index = 1
-        gui_combo.setCurrentIndex(index)
-        grid.addWidget(gui_combo, 7, 1)
-        grid.addWidget(HelpButton(_('Select which GUI mode to use at start up. ')), 7, 2)
-        if not self.config.is_modifiable('gui'):
-            for w in [gui_combo, gui_label]: w.setEnabled(False)
+        grid_io.addWidget(QLabel(_('Labels')), 1, 0)
+        grid_io.addWidget(EnterButton(_("Export"), self.do_export_labels), 1, 1)
+        grid_io.addWidget(EnterButton(_("Import"), self.do_import_labels), 1, 2)
+        grid_io.addWidget(HelpButton('Export your labels as json'), 1, 3)
+
+        grid_io.addWidget(QLabel(_('History')), 2, 0)
+        grid_io.addWidget(EnterButton(_("Export"), self.do_export_history), 2, 1)
+        grid_io.addWidget(HelpButton('Export your transaction history as csv'), 2, 3)
+
+        grid_io.addWidget(QLabel(_('Private key')), 3, 0)
+        grid_io.addWidget(EnterButton(_("Import"), self.do_import_privkey), 3, 2)
+        grid_io.addWidget(HelpButton('Import private key'), 3, 3)
 
+        grid_io.setRowStretch(4,1)
         vbox.addLayout(ok_cancel_buttons(d))
         d.setLayout(vbox) 
 
@@ -1337,8 +1767,9 @@ class ElectrumWindow(QMainWindow):
             self.update_history_tab()
             self.update_receive_tab()
 
-        if self.wallet.use_change != usechange_cb.isChecked():
-            self.wallet.use_change = usechange_cb.isChecked()
+        usechange_result = usechange_combo.currentIndex() == 0
+        if self.wallet.use_change != usechange_result:
+            self.wallet.use_change = usechange_result
             self.config.set_key('use_change', self.wallet.use_change, True)
         
         try:
@@ -1354,9 +1785,28 @@ class ElectrumWindow(QMainWindow):
                 self.config.set_key('gap_limit', self.wallet.gap_limit, True)
             else:
                 QMessageBox.warning(self, _('Error'), _('Invalid value'), _('OK'))
-                    
-        self.config.set_key("gui", str(gui_combo.currentText()).lower(), True)
 
+        need_restart = False
+
+        gui_request = str(gui_combo.currentText()).lower()
+        if gui_request != self.config.get('gui'):
+            self.config.set_key('gui', gui_request, True)
+            need_restart = True
+            
+        lang_request = languages.keys()[lang_combo.currentIndex()]
+        if lang_request != self.config.get('language'):
+            self.config.set_key("language", lang_request, True)
+            need_restart = True
+            
+        cur_request = str(currencies[cur_combo.currentIndex()])
+        if cur_request != self.config.get('currency', "None"):
+            self.config.set_key('currency', cur_request, True)
+            self.update_wallet()
+
+        if need_restart:
+            QMessageBox.warning(self, _('Success'), _('Please restart Electrum to activate the new GUI settings'), _('OK'))
+
+        self.receive_tab_set_mode(view_combo.currentIndex())
 
 
     @staticmethod 
@@ -1371,8 +1821,7 @@ class ElectrumWindow(QMainWindow):
         else:
             import random
             status = _("Please choose a server.") + "\n" + _("Select 'Cancel' if you are offline.")
-            server = None
-            interface.proxy = None
+            server = interface.server
 
         plist, servers_list = interface.get_servers_list()
 
@@ -1432,9 +1881,9 @@ class ElectrumWindow(QMainWindow):
         servers_list_widget = QTreeWidget(parent)
         servers_list_widget.setHeaderLabels( [ label, _('Type') ] )
         servers_list_widget.setMaximumHeight(150)
-        servers_list_widget.setColumnWidth(0, 250)
+        servers_list_widget.setColumnWidth(0, 240)
         for _host in servers_list.keys():
-            _type = 'pruning' if servers_list[_host].get('pruning') else 'full'
+            _type = 'P' if servers_list[_host].get('pruning') else 'F'
             servers_list_widget.addTopLevelItem(QTreeWidgetItem( [ _host, _type ] ))
 
         def change_server(host, protocol=None):
@@ -1475,6 +1924,12 @@ class ElectrumWindow(QMainWindow):
         if not wallet.config.is_modifiable('server'):
             for w in [server_host, server_port, server_protocol, servers_list_widget]: w.setEnabled(False)
 
+        # auto cycle
+        autocycle_cb = QCheckBox('Try random servers if disconnected')
+        autocycle_cb.setChecked(wallet.config.get('auto_cycle', False))
+        grid.addWidget(autocycle_cb, 3, 1, 3, 2)
+        if not wallet.config.is_modifiable('auto_cycle'): autocycle_cb.setEnabled(False)
+
         # proxy setting
         proxy_mode = QComboBox()
         proxy_host = QLineEdit()
@@ -1522,7 +1977,7 @@ class ElectrumWindow(QMainWindow):
         wallet.config.set_key("proxy", proxy, True)
         wallet.config.set_key("server", server, True)
         interface.set_server(server, proxy)
-                
+        wallet.config.set_key('auto_cycle', autocycle_cb.isChecked(), True)
         return True
 
     def closeEvent(self, event):
@@ -1539,9 +1994,6 @@ class ElectrumGui:
         if app is None:
             self.app = QApplication(sys.argv)
 
-    def server_list_changed(self):
-        pass
-
 
     def restore_or_create(self):
         msg = _("Wallet file not found.")+"\n"+_("Do you want to create a new wallet, or to restore an existing one?")
@@ -1555,15 +2007,13 @@ class ElectrumGui:
     def network_dialog(self):
         return ElectrumWindow.network_dialog( self.wallet, parent=None )
         
-    def create_wallet(self):
-        wallet = self.wallet
-        # generate the first addresses
-        wallet.synchronize()
-        # run a dialog indicating the seed, ask the user to remember it
-        ElectrumWindow.show_seed_dialog(wallet)
-        # ask for password
-        ElectrumWindow.change_password_dialog(wallet)
-        wallet.save()
+
+    def show_seed(self):
+        ElectrumWindow.show_seed_dialog(self.wallet)
+
+
+    def password_dialog(self):
+        ElectrumWindow.change_password_dialog(self.wallet)
 
 
     def restore_wallet(self):
@@ -1573,23 +2023,17 @@ class ElectrumGui:
             waiting = lambda: False if wallet.interface.is_connected else "connecting...\n"
             waiting_dialog(waiting)
 
-        waiting = lambda: False if wallet.up_to_date else "Please wait...\nAddresses generated: %d\nKilobytes received: %.1f"\
+        waiting = lambda: False if wallet.is_up_to_date() else "Please wait...\nAddresses generated: %d\nKilobytes received: %.1f"\
             %(len(wallet.all_addresses()), wallet.interface.bytes_received/1024.)
 
-        wallet.up_to_date_event.clear()
-        wallet.up_to_date = False
+        wallet.set_up_to_date(False)
         wallet.interface.poke('synchronizer')
         waiting_dialog(waiting)
         if wallet.is_found():
-            # history and addressbook
-            wallet.fill_addressbook()
-            print "Recovery successful"
-            wallet.save()
+            print_error( "Recovery successful" )
         else:
             QMessageBox.information(None, _('Error'), _("No transactions found for this seed"), _('OK'))
-            return False
 
-        wallet.save()
         return True
 
     def main(self,url):