URI: 
       treorganize files and bring code inline with current master - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit c121c1aa4e2d20825d4eafc201144e84df3129dd
   DIR parent 9938316400ad263ab9bec40e93f7e0b10c2ed9cd
  HTML Author: akshayaurora <akshayaurora@gmail.com>
       Date:   Thu,  5 Jun 2014 06:12:29 +0530
       
       reorganize files and bring code inline with current master
       
       Conflicts:
               lib/simple_config.py
       
       Diffstat:
         M data/fonts/Roboto-Bold.ttf          |       0 
         A data/fonts/Roboto-Condensed.ttf     |       0 
         A data/fonts/Roboto-Medium.ttf        |       0 
         M gui/kivy/Makefile                   |       2 +-
         M gui/kivy/__init__.py                |      54 +++++++++++++++++++++++++++----
         D gui/kivy/carousel.py                |      33 -------------------------------
         D gui/kivy/dialog.py                  |     686 -------------------------------
         D gui/kivy/drawer.py                  |     188 -------------------------------
         D gui/kivy/gridview.py                |     203 -------------------------------
         D gui/kivy/installwizard.py           |     328 -------------------------------
         M gui/kivy/main.kv                    |     439 ++++---------------------------
         M gui/kivy/main_window.py             |    1023 ++++++++++++++++++++++---------
         M gui/kivy/plugins/exchange_rate.py   |      97 +++++++++++++++++++++----------
         M gui/kivy/qr_scanner/__init__.py     |      54 +++----------------------------
         M gui/kivy/qr_scanner/scanner_androi… |       9 +++++++--
         D gui/kivy/qrcodewidget.py            |     179 -------------------------------
         D gui/kivy/screens.py                 |     105 -------------------------------
         D gui/kivy/statusbar.py               |       7 -------
         D gui/kivy/textinput.py               |      14 --------------
         M gui/kivy/theming/light-0.png        |       0 
         M gui/kivy/theming/light.atlas        |       4 ++--
         M gui/kivy/theming/light/action_bar.… |       0 
         A gui/kivy/theming/light/action_butt… |       0 
         A gui/kivy/theming/light/action_grou… |       0 
         A gui/kivy/theming/light/bit_logo.png |       0 
         M gui/kivy/theming/light/card.png     |       0 
         M gui/kivy/theming/light/card_top.png |       0 
         M gui/kivy/theming/light/contact.png  |       0 
         A gui/kivy/theming/light/contact_ava… |       0 
         A gui/kivy/theming/light/contact_ove… |       0 
         A gui/kivy/theming/light/dropdown_ba… |       0 
         M gui/kivy/theming/light/gear.png     |       0 
         M gui/kivy/theming/light/logo.png     |       0 
         M gui/kivy/theming/light/manualentry… |       0 
         M gui/kivy/theming/light/nfc_phone.p… |       0 
         A gui/kivy/theming/light/overflow_ba… |       0 
         A gui/kivy/theming/light/overflow_bt… |       0 
         M gui/kivy/theming/light/qrcode.png   |       0 
         M gui/kivy/theming/light/settings.png |       0 
         M gui/kivy/theming/light/tab_btn_pre… |       0 
         M gui/kivy/theming/light/tab_strip.p… |       0 
         M gui/kivy/theming/light/wallets.png  |       0 
         A gui/kivy/tools/blacklist.txt        |      99 +++++++++++++++++++++++++++++++
         A gui/kivy/tools/buildozer.spec       |     172 ++++++++++++++++++++++++++++++
         D gui/kivy/ui_screens/mainscreen.kv   |     287 -------------------------------
         A gui/kivy/ui_screens/screenreceive.… |     130 +++++++++++++++++++++++++++++++
         A gui/kivy/ui_screens/screensend.kv   |     187 +++++++++++++++++++++++++++++++
         A gui/kivy/uix/__init__.py            |       1 +
         R gui/kivy/combobox.py -> gui/kivy/u… |       0 
         R gui/kivy/console.py -> gui/kivy/ui… |       0 
         A gui/kivy/uix/dialogs/__init__.py    |     190 ++++++++++++++++++++++++++++++
         A gui/kivy/uix/dialogs/carousel_dial… |     239 +++++++++++++++++++++++++++++++
         A gui/kivy/uix/dialogs/create_restor… |     488 +++++++++++++++++++++++++++++++
         A gui/kivy/uix/dialogs/installwizard… |     478 +++++++++++++++++++++++++++++++
         A gui/kivy/uix/dialogs/new_contact.py |      26 ++++++++++++++++++++++++++
         A gui/kivy/uix/dialogs/nfc_transacti… |      33 +++++++++++++++++++++++++++++++
         A gui/kivy/uix/dialogs/qr_scanner.py  |      42 +++++++++++++++++++++++++++++++
         A gui/kivy/uix/drawer.py              |     258 +++++++++++++++++++++++++++++++
         A gui/kivy/uix/gridview.py            |     205 ++++++++++++++++++++++++++++++
         R gui/kivy/menus.py -> gui/kivy/uix/… |       0 
         A gui/kivy/uix/qrcodewidget.py        |     180 +++++++++++++++++++++++++++++++
         A gui/kivy/uix/screens.py             |     300 +++++++++++++++++++++++++++++++
         A gui/kivy/uix/ui_screens/mainscreen… |    1406 +++++++++++++++++++++++++++++++
         A gui/kivy/uix/ui_screens/screenrece… |     139 ++++++++++++++++++++++++++++++
         A gui/kivy/uix/ui_screens/screensend… |     232 ++++++++++++++++++++++++++++++
         D gui/kivy/utils.py                   |       2 --
         A lib/android/libiconv.so             |       0 
         A lib/android/libzbarjni.so           |       0 
         A lib/android/zbar.jar                |       0 
       
       69 files changed, 5738 insertions(+), 2781 deletions(-)
       ---
   DIR diff --git a/data/fonts/Roboto-Bold.ttf b/data/fonts/Roboto-Bold.ttf
       Binary files differ.
   DIR diff --git a/data/fonts/Roboto-Condensed.ttf b/data/fonts/Roboto-Condensed.ttf
       Binary files differ.
   DIR diff --git a/data/fonts/Roboto-Medium.ttf b/data/fonts/Roboto-Medium.ttf
       Binary files differ.
   DIR diff --git a/gui/kivy/Makefile b/gui/kivy/Makefile
       t@@ -9,7 +9,7 @@ apk:
                # running pre build setup
                @cp tools/buildozer.spec ../../buildozer.spec
                # get aes.py
       -        @cd ../..; wget -4 https://raw.github.com/devrandom/slowaes/master/python/aes.py
       +        @cd ../..; curl -O https://raw.github.com/devrandom/slowaes/master/python/aes.py
                # rename electrum to main.py
                @mv ../../electrum ../../main.py
                @-if [ ! -d "../../.buildozer" ];then \
   DIR diff --git a/gui/kivy/__init__.py b/gui/kivy/__init__.py
       t@@ -21,7 +21,7 @@
        import sys
        #, time, datetime, re, threading
        #from electrum.i18n import _, set_language
       -#from electrum.util import print_error, print_msg, parse_url
       +from electrum.util import print_error, print_msg, parse_url
        
        #:TODO: replace this with kivy's own plugin managment
        #from electrum.plugins import run_hook
       t@@ -42,9 +42,8 @@ from kivy.logger import Logger
        
        from electrum.bitcoin import MIN_RELAY_TX_FEE
        
       -#:TODO main window
        from main_window import ElectrumWindow
       -from electrum.plugins import init_plugins
       +#from electrum.plugins import init_plugins
        
        #:TODO find a equivalent method to register to `bitcoin:` uri
        #: ref: http://stackoverflow.com/questions/30931/register-file-extensions-mime-types-in-linux
       t@@ -60,7 +59,6 @@ from electrum.plugins import init_plugins
        #                return True
        #        return False
        
       -
        class ElectrumGui:
        
            def __init__(self, config, network, app=None):
       t@@ -74,6 +72,47 @@ class ElectrumGui:
                # base
                #init_plugins(self)
        
       +    def set_url(self, url):
       +        from electrum import util
       +        from decimal import Decimal
       +
       +        try:
       +            address, amount, label, message,\
       +                request_url, url = util.parse_url(url)
       +        except Exception:
       +            self.main_window.show_error(_('Invalid bitcoin URL'))
       +            return
       +
       +        if amount:
       +            try:
       +                if main_window.base_unit == 'mBTC':
       +                    amount = str( 1000* Decimal(amount))
       +                else:
       +                    amount = str(Decimal(amount))
       +            except Exception:
       +                amount = "0.0"
       +                self.main_window.show_error(_('Invalid Amount'))
       +
       +        if request_url:
       +            try:
       +                from electrum import paymentrequest
       +            except:
       +                self.main_window.show_error("cannot import payment request")
       +                request_url = None
       +
       +        if not request_url:
       +            self.main_window.set_send(address, amount, label, message)
       +            return
       +
       +        def payment_request():
       +            self.payment_request = paymentrequest.PaymentRequest(request_url)
       +            if self.payment_request.verify():
       +                Clock.schedule_once(self.main_window.payment_request_ok)
       +            else:
       +                Clock.schedule_once(self.main_window.payment_request_error)
       +
       +        threading.Thread(target=payment_request).start()
       +        self.main_window.prepare_for_payment_request()
        
            def main(self, url):
                ''' The main entry point of the kivy ux
       t@@ -83,5 +122,7 @@ class ElectrumGui:
                '''
        
                self.main_window = w = ElectrumWindow(config=self.config,
       -                                              network=self.network)
       -        w.run()
       +                                              network=self.network,
       +                                              url=url,
       +                                              gui_object=self)
       +        w.run()
       +\ No newline at end of file
   DIR diff --git a/gui/kivy/carousel.py b/gui/kivy/carousel.py
       t@@ -1,32 +0,0 @@
       -from kivy.uix.carousel import Carousel
       -from kivy.clock import Clock
       -
       -class Carousel(Carousel):
       -
       -    def on_touch_move(self, touch):
       -        if self._get_uid('cavoid') in touch.ud:
       -            return
       -        if self._touch is not touch:
       -            super(Carousel, self).on_touch_move(touch)
       -            return self._get_uid() in touch.ud
       -        if touch.grab_current is not self:
       -            return True
       -        ud = touch.ud[self._get_uid()]
       -        direction = self.direction
       -        if ud['mode'] == 'unknown':
       -            if direction[0] in ('r', 'l'):
       -                distance = abs(touch.ox - touch.x)
       -            else:
       -                distance = abs(touch.oy - touch.y)
       -            if distance > self.scroll_distance:
       -                Clock.unschedule(self._change_touch_mode)
       -                ud['mode'] = 'scroll'
       -        else:
       -            diff = 0
       -            if direction[0] in ('r', 'l'):
       -                diff = touch.dx
       -            if direction[0] in ('t', 'b'):
       -                diff = touch.dy
       -
       -            self._offset += diff * 1.27
       -        return True
       -\ No newline at end of file
   DIR diff --git a/gui/kivy/dialog.py b/gui/kivy/dialog.py
       t@@ -1,686 +0,0 @@
       -from functools import partial
       -
       -from kivy.app import App
       -from kivy.factory import Factory
       -from kivy.uix.button import Button
       -from kivy.uix.bubble import Bubble
       -from kivy.uix.popup import Popup
       -from kivy.uix.widget import Widget
       -from kivy.uix.carousel import Carousel
       -from kivy.uix.tabbedpanel import TabbedPanelHeader
       -from kivy.properties import (NumericProperty, StringProperty, ListProperty,
       -                             ObjectProperty, AliasProperty, OptionProperty,
       -                             BooleanProperty)
       -
       -from kivy.animation import Animation
       -from kivy.core.window import Window
       -from kivy.clock import Clock
       -from kivy.lang import Builder
       -from kivy.metrics import dp, inch
       -
       -#from electrum.bitcoin import is_valid
       -from electrum.i18n import _
       -
       -# Delayed inits
       -QRScanner = None
       -NFCSCanner = None
       -ScreenAddress = None
       -decode_uri = None
       -
       -DEFAULT_PATH = '/tmp/'
       -app = App.get_running_app()
       -
       -class CarouselHeader(TabbedPanelHeader):
       -
       -    slide = NumericProperty(0)
       -    ''' indicates the link to carousels slide'''
       -
       -class AnimatedPopup(Popup):
       -
       -    def open(self):
       -        self.opacity = 0
       -        super(AnimatedPopup, self).open()
       -        anim = Animation(opacity=1, d=.5).start(self)
       -
       -    def dismiss(self):
       -        def on_complete(*l):
       -            super(AnimatedPopup, self).dismiss()
       -        anim = Animation(opacity=0, d=.5)
       -        anim.bind(on_complete=on_complete)
       -        anim.start(self)
       -
       -
       -class CarouselDialog(AnimatedPopup):
       -    ''' A Popup dialog with a CarouselIndicator used as the content.
       -    '''
       -
       -    carousel_content = ObjectProperty(None)
       -
       -    def open(self):
       -        self.opacity = 0
       -        super(CarouselDialog, self).open()
       -        anim = Animation(opacity=1, d=.5).start(self)
       -
       -    def dismiss(self):
       -        def on_complete(*l):
       -            super(CarouselDialog, self).dismiss()
       -        anim = Animation(opacity=0, d=.5)
       -        anim.bind(on_complete=on_complete)
       -        anim.start(self)
       -
       -    def add_widget(self, widget, index=0):
       -        if isinstance(widget, Carousel):
       -            super(CarouselDialog, self).add_widget(widget, index)
       -            return
       -        if 'carousel_content' not in self.ids.keys():
       -            super(CarouselDialog, self).add_widget(widget)
       -            return
       -        self.carousel_content.add_widget(widget, index)
       -
       -
       -
       -class NFCTransactionDialog(AnimatedPopup):
       -
       -    mode = OptionProperty('send', options=('send','receive'))
       -
       -    scanner = ObjectProperty(None)
       -
       -    def __init__(self, **kwargs):
       -        # Delayed Init
       -        global NFCSCanner
       -        if NFCSCanner is None:
       -            from electrum_gui.kivy.nfc_scanner import NFCScanner
       -        self.scanner = NFCSCanner
       -
       -        super(NFCTransactionDialog, self).__init__(**kwargs)
       -        self.scanner.nfc_init()
       -        self.scanner.bind()
       -
       -    def on_parent(self, instance, value):
       -        sctr = self.ids.sctr
       -        if value:
       -            def _cmp(*l):
       -                anim = Animation(rotation=2, scale=1, opacity=1)
       -                anim.start(sctr)
       -                anim.bind(on_complete=_start)
       -
       -            def _start(*l):
       -                anim = Animation(rotation=350, scale=2, opacity=0)
       -                anim.start(sctr)
       -                anim.bind(on_complete=_cmp)
       -            _start()
       -            return
       -        Animation.cancel_all(sctr)
       -
       -
       -class InfoBubble(Bubble):
       -    '''Bubble to be used to display short Help Information'''
       -
       -    message = StringProperty(_('Nothing set !'))
       -    '''Message to be displayed; defaults to "nothing set"'''
       -
       -    icon = StringProperty('')
       -    ''' Icon to be displayed along with the message defaults to ''
       -
       -    :attr:`icon` is a  `StringProperty` defaults to `''`
       -    '''
       -
       -    fs = BooleanProperty(False)
       -    ''' Show Bubble in half screen mode
       -
       -    :attr:`fs` is a `BooleanProperty` defaults to `False`
       -    '''
       -
       -    modal = BooleanProperty(False)
       -    ''' Allow bubble to be hidden on touch.
       -
       -    :attr:`modal` is a `BooleanProperty` defauult to `False`.
       -    '''
       -
       -    exit = BooleanProperty(False)
       -    '''Indicates whether to exit app after bubble is closed.
       -
       -    :attr:`exit` is a `BooleanProperty` defaults to False.
       -    '''
       -
       -    dim_background = BooleanProperty(False)
       -    ''' Indicates Whether to draw a background on the windows behind the bubble.
       -
       -    :attr:`dim` is a `BooleanProperty` defaults to `False`.
       -    '''
       -
       -    def on_touch_down(self, touch):
       -        if self.modal:
       -            return True
       -        self.hide()
       -        if self.collide_point(*touch.pos):
       -            return True
       -
       -    def show(self, pos, duration, width=None, modal=False, exit=False):
       -        '''Animate the bubble into position'''
       -        self.modal, self.exit = modal, exit
       -        if width:
       -            self.width = width
       -        if self.modal:
       -            from kivy.uix.modalview import ModalView
       -            self._modal_view = m = ModalView()
       -            Window.add_widget(m)
       -            m.add_widget(self)
       -        else:
       -            Window.add_widget(self)
       -        # wait for the bubble to adjust it's size according to text then animate
       -        Clock.schedule_once(lambda dt: self._show(pos, duration))
       -
       -    def _show(self, pos, duration):
       -
       -        def on_stop(*l):
       -            if duration:
       -                Clock.schedule_once(self.hide, duration + .5)
       -
       -        self.opacity = 0
       -        arrow_pos = self.arrow_pos
       -        if arrow_pos[0] in ('l', 'r'):
       -            pos = pos[0], pos[1] - (self.height/2)
       -        else:
       -            pos = pos[0] - (self.width/2), pos[1]
       -
       -        self.limit_to = Window
       -
       -        anim = Animation(opacity=1, pos=pos, d=.32)
       -        anim.bind(on_complete=on_stop)
       -        anim.cancel_all(self)
       -        anim.start(self)
       -
       -
       -    def hide(self, now=False):
       -        ''' Auto fade out the Bubble
       -        '''
       -        def on_stop(*l):
       -            if self.modal:
       -                m = self._modal_view
       -                m.remove_widget(self)
       -                Window.remove_widget(m)
       -            Window.remove_widget(self)
       -            if self.exit:
       -                App.get_running_app().stop()
       -                import sys
       -                sys.exit()
       -        if now:
       -            return on_stop()
       -
       -        anim = Animation(opacity=0, d=.25)
       -        anim.bind(on_complete=on_stop)
       -        anim.cancel_all(self)
       -        anim.start(self)
       -
       -
       -class InfoContent(Widget):
       -    '''Abstract class to be used to add to content to InfoDialog'''
       -    pass
       -
       -
       -class InfoButton(Button):
       -    '''Button that is auto added to the dialog when setting `buttons:`
       -    property.
       -    '''
       -    pass
       -
       -
       -class EventsDialog(AnimatedPopup):
       -    ''' Abstract Popup that provides the following events
       -    .. events::
       -        `on_release`
       -        `on_press`
       -    '''
       -
       -    __events__ = ('on_release', 'on_press')
       -
       -    def __init__(self, **kwargs):
       -        super(EventsDialog, self).__init__(**kwargs)
       -        self._on_release = kwargs.get('on_release')
       -        Window.bind(size=self.on_size,
       -                    rotation=self.on_size)
       -        self.on_size(Window, Window.size)
       -
       -    def on_size(self, instance, value):
       -        if app.ui_mode[0] == 'p':
       -            self.size = Window.size
       -        else:
       -            #tablet
       -            if app.orientation[0] == 'p':
       -                #portrait
       -                self.size = Window.size[0]/1.67, Window.size[1]/1.4
       -            else:
       -                self.size = Window.size[0]/2.5, Window.size[1]
       -
       -    def on_release(self, instance):
       -        pass
       -
       -    def on_press(self, instance):
       -        pass
       -
       -    def close(self):
       -        self._on_release = None
       -        self.dismiss()
       -
       -
       -class InfoDialog(EventsDialog):
       -    ''' A dialog box meant to display info along with buttons at the bottom
       -
       -    '''
       -
       -    buttons = ListProperty([_('ok'), _('cancel')])
       -    '''List of Buttons to be displayed at the bottom'''
       -
       -    def __init__(self, **kwargs):
       -        self._old_buttons = self.buttons
       -        super(InfoDialog, self).__init__(**kwargs)
       -        self.on_buttons(self, self.buttons)
       -
       -    def on_buttons(self, instance, value):
       -        if 'buttons_layout' not in self.ids.keys():
       -            return
       -        if value == self._old_buttons:
       -            return
       -        blayout = self.ids.buttons_layout
       -        blayout.clear_widgets()
       -        for btn in value:
       -            ib = InfoButton(text=btn)
       -            ib.bind(on_press=partial(self.dispatch, 'on_press'))
       -            ib.bind(on_release=partial(self.dispatch, 'on_release'))
       -            blayout.add_widget(ib)
       -        self._old_buttons = value
       -        pass
       -
       -    def add_widget(self, widget, index=0):
       -        if isinstance(widget, InfoContent):
       -            self.ids.info_content.add_widget(widget, index=index)
       -        else:
       -            super(InfoDialog, self).add_widget(widget)
       -
       -
       -class TakeInputDialog(InfoDialog):
       -    ''' A simple Dialog for displaying a message and taking a input
       -    using a Textinput
       -    '''
       -
       -    text = StringProperty('Nothing set yet')
       -
       -    readonly = BooleanProperty(False)
       -
       -
       -class EditLabelDialog(TakeInputDialog):
       -    pass
       -
       -
       -
       -class ImportPrivateKeysDialog(TakeInputDialog):
       -    pass
       -
       -
       -
       -class ShowMasterPublicKeyDialog(TakeInputDialog):
       -    pass
       -
       -
       -class EditDescriptionDialog(TakeInputDialog):
       -
       -    pass
       -
       -
       -class PrivateKeyDialog(InfoDialog):
       -
       -    private_key = StringProperty('')
       -    ''' private key to be displayed in the TextInput
       -    '''
       -
       -    address = StringProperty('')
       -    ''' address to be displayed in the dialog
       -    '''
       -
       -
       -class SignVerifyDialog(InfoDialog):
       -
       -    address = StringProperty('')
       -    '''current address being verified'''
       -
       -
       -
       -class MessageBox(InfoDialog):
       -
       -    image = StringProperty('atlas://gui/kivy/theming/light/info')
       -    '''path to image to be displayed on the left'''
       -
       -    message = StringProperty('Empty Message')
       -    '''Message to be displayed on the dialog'''
       -
       -    def __init__(self, **kwargs):
       -        super(MessageBox, self).__init__(**kwargs)
       -        self.title = kwargs.get('title', _('Message'))
       -
       -
       -class MessageBoxExit(MessageBox):
       -
       -    def __init__(self, **kwargs):
       -        super(MessageBox, self).__init__(**kwargs)
       -        self.title = kwargs.get('title', _('Exiting'))
       -
       -class MessageBoxError(MessageBox):
       -
       -    def __init__(self, **kwargs):
       -        super(MessageBox, self).__init__(**kwargs)
       -        self.title = kwargs.get('title', _('Error'))
       -
       -
       -class WalletAddressesDialog(CarouselDialog):
       -
       -    def __init__(self, **kwargs):
       -        super(WalletAddressesDialog, self).__init__(**kwargs)
       -        CarouselHeader = Factory.CarouselHeader
       -        ch = CarouselHeader()
       -        ch.slide = 0 # idx
       -
       -        # delayed init
       -        global ScreenAddress
       -        if not ScreenAddress:
       -            from electrum_gui.kivy.screens import ScreenAddress
       -        slide = ScreenAddress()
       -
       -        slide.tab=ch
       -
       -        labels = app.wallet.labels
       -        addresses = app.wallet.addresses()
       -        _labels = {}
       -        for address in addresses:
       -            _labels[labels.get(address, address)] = address
       -
       -        slide.labels = _labels
       -
       -        self.add_widget(slide)
       -        self.add_widget(ch)
       -        Clock.schedule_once(lambda dt: self.delayed_init(slide))
       -
       -    def delayed_init(self, slide):
       -        # add a tab for each wallet
       -        # for wallet in wallets
       -        slide.ids.btn_address.values = values = slide.labels.keys()
       -        slide.ids.btn_address.text = values[0]
       -
       -
       -
       -class RecentActivityDialog(CarouselDialog):
       -
       -    def send_payment(self, address):
       -        tabs = app.root.main_screen.ids.tabs
       -        screen_send = tabs.ids.screen_send
       -        # remove self
       -        self.dismiss()
       -        # switch_to the send screen
       -        tabs.ids.panel.switch_to(tabs.ids.tab_send)
       -        # populate
       -        screen_send.ids.payto_e.text = address
       -
       -    def populate_inputs_outputs(self, app, tx_hash):
       -        if tx_hash:
       -            tx = app.wallet.transactions.get(tx_hash)
       -            self.ids.list_outputs.content_adapter.data = \
       -                [(address, app.gui.main_gui.format_amount(value))\
       -                for address, value in tx.outputs]
       -            self.ids.list_inputs.content_adapter.data = \
       -                [(input['address'], input['prevout_hash'])\
       -                for input in tx.inputs]
       -
       -
       -class CreateAccountDialog(EventsDialog):
       -    ''' Abstract dialog to be used as the base for all Create Account Dialogs
       -    '''
       -    crcontent = ObjectProperty(None)
       -
       -    def add_widget(self, widget, index=0):
       -        if not self.crcontent:
       -            super(CreateAccountDialog, self).add_widget(widget)
       -        else:
       -            self.crcontent.add_widget(widget, index=index)
       -
       -
       -class CreateRestoreDialog(CreateAccountDialog):
       -    ''' Initial Dialog for creating or restoring seed'''
       -
       -    def on_parent(self, instance, value):
       -        if value:
       -            self.ids.but_close.disabled = True
       -            self.ids.but_close.opacity = 0
       -            self._back = _back = partial(app.dispatch, 'on_back')
       -            app.navigation_higherarchy.append(_back)
       -
       -    def close(self):
       -        if self._back in app.navigation_higherarchy:
       -            app.navigation_higherarchy.pop()
       -            self._back = None
       -        super(CreateRestoreDialog, self).close()
       -
       -
       -class InitSeedDialog(CreateAccountDialog):
       -
       -    seed_msg = StringProperty('')
       -    '''Text to be displayed in the TextInput'''
       -
       -    message = StringProperty('')
       -    '''Message to be displayed under seed'''
       -
       -    seed = ObjectProperty(None)
       -
       -    def on_parent(self, instance, value):
       -        if value:
       -            stepper = self.ids.stepper
       -            stepper.opacity = 1
       -            stepper.source = 'atlas://gui/kivy/theming/light/stepper_full'
       -            self._back = _back = partial(self.ids.back.dispatch, 'on_release')
       -            app.navigation_higherarchy.append(_back)
       -
       -    def close(self):
       -        if self._back in app.navigation_higherarchy:
       -            app.navigation_higherarchy.pop()
       -            self._back = None
       -        super(InitSeedDialog, self).close()
       -
       -class VerifySeedDialog(CreateAccountDialog):
       -
       -    pass
       -
       -class RestoreSeedDialog(CreateAccountDialog):
       -
       -    def on_parent(self, instance, value):
       -        if value:
       -            tis = self.ids.text_input_seed
       -            tis.focus = True
       -            tis._keyboard.bind(on_key_down=self.on_key_down)
       -            stepper = self.ids.stepper
       -            stepper.opacity = 1
       -            stepper.source = ('atlas://gui/kivy/theming'
       -                              '/light/stepper_restore_seed')
       -            self._back = _back = partial(self.ids.back.dispatch, 'on_release')
       -            app.navigation_higherarchy.append(_back)
       -
       -    def on_key_down(self, keyboard, keycode, key, modifiers):
       -        if keycode[0] in (13, 271):
       -            self.on_enter()
       -            return True
       -        #super
       -
       -    def on_enter(self):
       -        #self._remove_keyboard()
       -        # press next
       -        self.ids.next.dispatch('on_release')
       -
       -    def _remove_keyboard(self):
       -        tis = self.ids.text_input_seed
       -        if tis._keyboard:
       -            tis._keyboard.unbind(on_key_down=self.on_key_down)
       -            tis.focus = False
       -
       -    def close(self):
       -        self._remove_keyboard()
       -        if self._back in app.navigation_higherarchy:
       -            app.navigation_higherarchy.pop()
       -            self._back = None
       -        super(RestoreSeedDialog, self).close()
       -
       -class NewContactDialog(Popup):
       -
       -    qrscr = ObjectProperty(None)
       -    _decoder = None
       -
       -    def load_qr_scanner(self):
       -        global QRScanner
       -        if not QRScanner:
       -            from electrum_gui.kivy.qr_scanner import QRScanner
       -        qrscr = self.qrscr
       -        if not qrscr:
       -            self.qrscr = qrscr = QRScanner(opacity=0)
       -            #pos=self.pos, size=self.size)
       -            #self.bind(pos=qrscr.setter('pos'),
       -            #      size=qrscr.setter('size')
       -            qrscr.bind(symbols=self.on_symbols)
       -        bl = self.ids.bl
       -        bl.clear_widgets()
       -        bl.add_widget(qrscr)
       -        qrscr.opacity = 1
       -        Animation(height=dp(280)).start(self)
       -        Animation(opacity=1).start(self)
       -        qrscr.start()
       -
       -    def on_symbols(self, instance, value):
       -        instance.stop()
       -        self.remove_widget(instance)
       -        self.ids.but_contact.dispatch('on_release')
       -        global decode_uri
       -        if not decode_uri:
       -            from electrum_gui.kivy.qr_scanner import decode_uri
       -        uri = decode_uri(value[0].data)
       -        self.ids.ti.text = uri.get('address', 'empty')
       -        self.ids.ti_lbl.text = uri.get('label', 'empty')
       -        self.ids.ti_lbl.focus = True
       -
       -
       -class PasswordRequiredDialog(InfoDialog):
       -
       -    pass
       -
       -
       -class ChangePasswordDialog(CreateAccountDialog):
       -
       -    message = StringProperty(_('Empty Message'))
       -    '''Message to be displayed.'''
       -
       -    mode = OptionProperty('new',
       -                          options=('new', 'confirm', 'create', 'restore'))
       -    ''' Defines the mode of the password dialog.'''
       -
       -    def validate_new_password(self):
       -        self.ids.next.dispatch('on_release')
       -
       -    def on_parent(self, instance, value):
       -        if value:
       -            stepper = self.ids.stepper
       -            stepper.opacity = 1
       -            t_wallet_name = self.ids.ti_wallet_name
       -            if self.mode in ('create', 'restore'):
       -                t_wallet_name.text = 'Default Wallet'
       -                t_wallet_name.readonly = True
       -                self.ids.ti_new_password.focus = True
       -            else:
       -                t_wallet_name.text = ''
       -                t_wallet_name.readonly = False
       -                t_wallet_name.focus = True
       -            stepper.source = 'atlas://gui/kivy/theming/light/stepper_left'
       -            self._back = _back = partial(self.ids.back.dispatch, 'on_release')
       -            app.navigation_higherarchy.append(_back)
       -
       -    def close(self):
       -        ids = self.ids
       -        ids.ti_wallet_name.text = ""
       -        ids.ti_wallet_name.focus = False
       -        ids.ti_password.text = ""
       -        ids.ti_password.focus = False
       -        ids.ti_new_password.text = ""
       -        ids.ti_new_password.focus = False
       -        ids.ti_confirm_password.text = ""
       -        ids.ti_confirm_password.focus = False
       -        if self._back in app.navigation_higherarchy:
       -            app.navigation_higherarchy.pop()
       -            self._back = None
       -        super(ChangePasswordDialog, self).close()
       -
       -
       -
       -class Dialog(Popup):
       -
       -    content_padding = NumericProperty('2dp')
       -    '''Padding for the content area of the dialog defaults to 2dp
       -    '''
       -
       -    buttons_padding = NumericProperty('2dp')
       -    '''Padding for the bottns area of the dialog defaults to 2dp
       -    '''
       -
       -    buttons_height = NumericProperty('40dp')
       -    '''Height to be used for the Buttons at the bottom
       -    '''
       -
       -    def close(self):
       -        self.dismiss()
       -
       -    def add_content(self, widget, index=0):
       -        self.ids.layout_content.add_widget(widget, index)
       -
       -    def add_button(self, widget, index=0):
       -        self.ids.layout_buttons.add_widget(widget, index)
       -
       -
       -class SaveDialog(Popup):
       -
       -    filename = StringProperty('')
       -    '''The default file name provided
       -    '''
       -
       -    filters = ListProperty([])
       -    ''' list of files to be filtered and displayed defaults to  allow all
       -    '''
       -
       -    path = StringProperty(DEFAULT_PATH)
       -    '''path to be loaded by default in this dialog
       -    '''
       -
       -    file_chooser = ObjectProperty(None)
       -    '''link to the file chooser object inside the dialog
       -    '''
       -
       -    text_input = ObjectProperty(None)
       -    '''
       -    '''
       -
       -    cancel_button = ObjectProperty(None)
       -    '''
       -    '''
       -
       -    save_button = ObjectProperty(None)
       -    '''
       -    '''
       -
       -    def close(self):
       -        self.dismiss()
       -
       -
       -class LoadDialog(SaveDialog):
       -
       -    def _get_load_btn(self):
       -        return self.save_button
       -
       -    load_button = AliasProperty(_get_load_btn, None, bind=('save_button', ))
       -    '''Alias to the Save Button to be used as LoadButton
       -    '''
       -
       -    def __init__(self, **kwargs):
       -        super(LoadDialog, self).__init__(**kwargs)
       -        self.load_button.text=_("Load")
   DIR diff --git a/gui/kivy/drawer.py b/gui/kivy/drawer.py
       t@@ -1,187 +0,0 @@
       -
       -from kivy.uix.stencilview import StencilView
       -from kivy.uix.boxlayout import BoxLayout
       -from kivy.uix.image import Image
       -
       -from kivy.animation import Animation
       -from kivy.clock import Clock
       -from kivy.properties import OptionProperty, NumericProperty, ObjectProperty
       -
       -# delayed import
       -app = None
       -
       -
       -class Drawer(StencilView):
       -
       -    state = OptionProperty('closed',
       -                            options=('closed', 'open', 'opening', 'closing'))
       -    '''This indicates the current state the drawer is in.
       -
       -    :attr:`state` is a `OptionProperty` defaults to `closed`. Can be one of
       -    `closed`, `open`, `opening`, `closing`.
       -    '''
       -
       -    scroll_timeout = NumericProperty(200)
       -    '''Timeout allowed to trigger the :data:`scroll_distance`,
       -    in milliseconds. If the user has not moved :data:`scroll_distance`
       -    within the timeout, the scrolling will be disabled and the touch event
       -    will go to the children.
       -
       -    :data:`scroll_timeout` is a :class:`~kivy.properties.NumericProperty`
       -    and defaults to 200 (milliseconds)
       -    '''
       -
       -    scroll_distance = NumericProperty('9dp')
       -    '''Distance to move before scrolling the :class:`Drawer` in pixels.
       -    As soon as the distance has been traveled, the :class:`Drawer` will
       -    start to scroll, and no touch event will go to children.
       -    It is advisable that you base this value on the dpi of your target
       -    device's screen.
       -
       -    :data:`scroll_distance` is a :class:`~kivy.properties.NumericProperty`
       -    and defaults to 20dp.
       -    '''
       -
       -    drag_area = NumericProperty(.1)
       -    '''The percentage of area on the left edge that triggers the opening of
       -    the drawer. from 0-1
       -
       -    :attr:`drag_area` is a `NumericProperty` defaults to 2
       -    '''
       -
       -    _hidden_widget = ObjectProperty(None)
       -    _overlay_widget = ObjectProperty(None)
       -
       -    def __init__(self, **kwargs):
       -        super(Drawer, self).__init__(**kwargs)
       -        self.bind(pos=self._do_layout,
       -                    size=self._do_layout,
       -                    children=self._do_layout)
       -
       -    def _do_layout(self, instance, value):
       -        if not self._hidden_widget or not self._overlay_widget:
       -            return
       -        self._overlay_widget.height = self._hidden_widget.height =\
       -            self.height
       -
       -    def on_touch_down(self, touch):
       -        if self.disabled:
       -            return
       -
       -        if not self.collide_point(*touch.pos):
       -            return
       -
       -        touch.grab(self)
       -
       -        global app
       -        if not app:
       -            from kivy.app import App
       -            app = App.get_running_app()
       -
       -        # skip on tablet mode
       -        if app.ui_mode[0] == 't':
       -            return super(Drawer, self).on_touch_down(touch)
       -
       -        state = self.state
       -        touch.ud['send_touch_down'] = False
       -        start = 0 if state[0] == 'c' else self._hidden_widget.right
       -        drag_area = ((self.width * self.drag_area)
       -                    if self.state[0] == 'c' else
       -                    self.width)
       -        if touch.x not in range(int(start), int(drag_area)):
       -            return super(Drawer, self).on_touch_down(touch)
       -        self._touch = touch
       -        Clock.schedule_once(self._change_touch_mode,
       -                            self.scroll_timeout/1000.)
       -        touch.ud['in_drag_area'] = True
       -        touch.ud['send_touch_down'] = True
       -        return
       -
       -    def on_touch_move(self, touch):
       -        if not touch.grab_current:
       -            return
       -
       -        # skip on tablet mode
       -        if app.ui_mode[0] == 't':
       -            return super(Drawer, self).on_touch_move(touch)
       -
       -        if not touch.ud.get('in_drag_area', None):
       -            return super(Drawer, self).on_touch_move(touch)
       -
       -        ov = self._overlay_widget
       -        ov.x=min(self._hidden_widget.width,
       -            max(ov.x + touch.dx*2, 0))
       -        #_anim = Animation(x=x, duration=1/2, t='in_out_quart')
       -        #_anim.cancel_all(ov)
       -        #_anim.start(ov)
       -
       -        if abs(touch.x - touch.ox) < self.scroll_distance:
       -            return
       -        touch.ud['send_touch_down'] = False
       -        Clock.unschedule(self._change_touch_mode)
       -        self._touch = None
       -        self.state = 'opening' if touch.dx > 0 else 'closing'
       -        touch.ox = touch.x
       -        return
       -
       -    def _change_touch_mode(self, *args):
       -        if not self._touch:
       -            return
       -        touch = self._touch
       -        touch.ud['in_drag_area'] = False
       -        touch.ud['send_touch_down'] = False
       -        self._touch = None
       -        super(Drawer, self).on_touch_down(touch)
       -        return
       -
       -    def on_touch_up(self, touch):
       -        if not touch.grab_current:
       -            return
       -
       -        # skip on tablet mode
       -        if app.ui_mode[0] == 't':
       -            return super(Drawer, self).on_touch_down(touch)
       -
       -        if touch.ud.get('send_touch_down', None):
       -            Clock.unschedule(self._change_touch_mode)
       -            Clock.schedule_once(
       -                lambda dt: super(Drawer, self).on_touch_down(touch), -1)
       -        if touch.ud.get('in_drag_area', None):
       -            touch.ud['in_drag_area'] = False
       -        Animation.cancel_all(self._overlay_widget)
       -        anim = Animation(x=self._hidden_widget.width
       -                            if self.state[0] == 'o' else 0,
       -                            d=.1, t='linear')
       -        anim.bind(on_complete = self._complete_drawer_animation)
       -        anim.start(self._overlay_widget)
       -        Clock.schedule_once(
       -            lambda dt: super(Drawer, self).on_touch_up(touch), 0)
       -
       -    def _complete_drawer_animation(self, *args):
       -        self.state = 'open' if self.state[0] == 'o' else 'closed'
       -
       -    def add_widget(self, widget, index=1):
       -        if not widget:
       -            return
       -        children = self.children
       -        len_children = len(children)
       -        if len_children == 2:
       -            Logger.debug('Drawer: No more than two widgets allowed')
       -            return
       -
       -        super(Drawer, self).add_widget(widget)
       -        if len_children == 0:
       -            # first widget add it to the hidden/drawer section
       -            self._hidden_widget = widget
       -            return
       -        # Second Widget
       -        self._overlay_widget = widget
       -
       -    def remove_widget(self, widget):
       -        super(Drawer, self).remove_widget(self)
       -        if widget == self._hidden_widget:
       -            self._hidden_widget = None
       -            return
       -        if widget == self._overlay_widget:
       -            self._overlay_widget = None
       -            return
       -\ No newline at end of file
   DIR diff --git a/gui/kivy/gridview.py b/gui/kivy/gridview.py
       t@@ -1,203 +0,0 @@
       -from kivy.uix.boxlayout import BoxLayout
       -from kivy.adapters.dictadapter import DictAdapter
       -from kivy.adapters.listadapter import ListAdapter
       -from kivy.properties import ObjectProperty, ListProperty, AliasProperty
       -from kivy.uix.listview import (ListItemButton, ListItemLabel, CompositeListItem,
       -                               ListView)
       -from kivy.lang import Builder
       -from kivy.metrics import dp, sp
       -
       -Builder.load_string('''
       -<GridView>
       -    header_view: header_view
       -    content_view: content_view
       -    BoxLayout:
       -        orientation: 'vertical'
       -        padding: '0dp', '2dp'
       -        BoxLayout:
       -            id: header_box
       -            orientation: 'vertical'
       -            size_hint: 1, None
       -            height: '30dp'
       -            ListView:
       -                id: header_view
       -        BoxLayout:
       -            id: content_box
       -            orientation: 'vertical'
       -            ListView:
       -                id: content_view
       -
       -<-HorizVertGrid>
       -    header_view: header_view
       -    content_view: content_view
       -    ScrollView:
       -        id: scrl
       -        do_scroll_y: False
       -        RelativeLayout:
       -            size_hint_x: None
       -            width: max(scrl.width, dp(sum(root.widths)))
       -            BoxLayout:
       -                orientation: 'vertical'
       -                padding: '0dp', '2dp'
       -                BoxLayout:
       -                    id: header_box
       -                    orientation: 'vertical'
       -                    size_hint: 1, None
       -                    height: '30dp'
       -                    ListView:
       -                        id: header_view
       -                BoxLayout:
       -                    id: content_box
       -                    orientation: 'vertical'
       -                    ListView:
       -                        id: content_view
       -
       -''')
       -
       -class GridView(BoxLayout):
       -    """Workaround solution for grid view by using 2 list view.
       -    Sometimes the height of lines is shown properly."""
       -
       -    def _get_hd_adpt(self):
       -        return self.ids.header_view.adapter
       -
       -    header_adapter = AliasProperty(_get_hd_adpt, None)
       -    '''
       -    '''
       -
       -    def _get_cnt_adpt(self):
       -        return self.ids.content_view.adapter
       -
       -    content_adapter = AliasProperty(_get_cnt_adpt, None)
       -    '''
       -    '''
       -
       -    headers = ListProperty([])
       -    '''
       -    '''
       -
       -    widths = ListProperty([])
       -    '''
       -    '''
       -
       -    data = ListProperty([])
       -    '''
       -    '''
       -
       -    getter = ObjectProperty(lambda item, i: item[i])
       -    '''
       -    '''
       -    on_context_menu = ObjectProperty(None)
       -
       -    def __init__(self, **kwargs):
       -        super(GridView, self).__init__(**kwargs)
       -        self._from_widths = False
       -        #self.on_headers(self, self.headers)
       -
       -    def on_widths(self, instance, value):
       -        self._from_widths = True
       -        self.on_headers(instance, self.headers)
       -        self._from_widths = False
       -
       -    def on_headers(self, instance, value):
       -        if not self._from_widths:
       -            return
       -        if not (value and self.canvas and self.headers):
       -            return
       -        widths = self.widths
       -        if len(self.widths) != len(value):
       -            return
       -        #if widths is not None:
       -        #    widths = ['%sdp' % i for i in widths]
       -
       -        def generic_args_converter(row_index,
       -                                   item,
       -                                   is_header=True,
       -                                   getter=self.getter):
       -            cls_dicts = []
       -            _widths = self.widths
       -            getter = self.getter
       -            on_context_menu = self.on_context_menu
       -
       -            for i, header in enumerate(self.headers):
       -                kwargs = {
       -                    'padding': ('2dp','2dp'),
       -                    'halign': 'center',
       -                    'valign': 'middle',
       -                    'size_hint_y': None,
       -                    'shorten': True,
       -                    'height': '30dp',
       -                    'text_size': (_widths[i], dp(30)),
       -                    'text': getter(item, i),
       -                }
       -
       -                kwargs['font_size'] = '9sp'
       -                if is_header:
       -                    kwargs['deselected_color'] = kwargs['selected_color']  =\
       -                        [0, 1, 1, 1]
       -                else:  # this is content
       -                    kwargs['deselected_color'] = 1, 1, 1, 1
       -                    if on_context_menu is not None:
       -                        kwargs['on_press'] = on_context_menu
       -
       -                if widths is not None:  # set width manually
       -                    kwargs['size_hint_x'] = None
       -                    kwargs['width'] = widths[i]
       -
       -                cls_dicts.append({
       -                    'cls': ListItemButton,
       -                    'kwargs': kwargs,
       -                })
       -
       -            return {
       -                'id': item[-1],
       -                'size_hint_y': None,
       -                'height': '30dp',
       -                'cls_dicts': cls_dicts,
       -            }
       -
       -        def header_args_converter(row_index, item):
       -            return generic_args_converter(row_index, item)
       -
       -        def content_args_converter(row_index, item):
       -            return generic_args_converter(row_index, item, is_header=False)
       -
       -
       -        self.ids.header_view.adapter = ListAdapter(data=[self.headers],
       -                                   args_converter=header_args_converter,
       -                                   selection_mode='single',
       -                                   allow_empty_selection=False,
       -                                   cls=CompositeListItem)
       -
       -        self.ids.content_view.adapter = ListAdapter(data=self.data,
       -                                   args_converter=content_args_converter,
       -                                   selection_mode='single',
       -                                   allow_empty_selection=False,
       -                                   cls=CompositeListItem)
       -        self.content_adapter.bind_triggers_to_view(self.ids.content_view._trigger_reset_populate)
       -
       -class HorizVertGrid(GridView):
       -    pass
       -
       -
       -if __name__ == "__main__":
       -    from kivy.app import App
       -    class MainApp(App):
       -
       -        def build(self):
       -            data = []
       -            for i in range(90):
       -                data.append((str(i), str(i)))
       -            self.data = data
       -            return Builder.load_string('''
       -BoxLayout:
       -    orientation: 'vertical'
       -    HorizVertGrid:
       -        on_parent: if args[1]: self.content_adapter.data = app.data
       -        headers:['Address', 'Previous output']
       -        widths: [400, 500]
       -
       -<Label>
       -    font_size: '16sp'
       -''')
       -    MainApp().run()
   DIR diff --git a/gui/kivy/installwizard.py b/gui/kivy/installwizard.py
       t@@ -1,328 +0,0 @@
       -from electrum import Wallet
       -from electrum.i18n import _
       -
       -from kivy.app import App
       -from kivy.uix.widget import Widget
       -from kivy.core.window import Window
       -from kivy.clock import Clock
       -
       -from electrum_gui.kivy.dialog import CreateRestoreDialog
       -#from network_dialog import NetworkDialog
       -#from util import *
       -#from amountedit import AmountEdit
       -
       -import sys
       -import threading
       -from functools import partial
       -
       -# global Variables
       -app = App.get_running_app()
       -
       -
       -class InstallWizard(Widget):
       -    '''Installation Wizard. Responsible for instantiating the
       -    creation/restoration of wallets.
       -
       -    events::
       -        `on_wizard_complete` Fired when the wizard is done creating/ restoring
       -        wallet/s.
       -    '''
       -
       -    __events__ = ('on_wizard_complete', )
       -
       -    def __init__(self, config, network, storage):
       -        super(InstallWizard, self).__init__()
       -        self.config  = config
       -        self.network = network
       -        self.storage = storage
       -
       -    def waiting_dialog(self, task,
       -                       msg= _("Electrum is generating your addresses,"
       -                              " please wait."),
       -                       on_complete=None):
       -        '''Perform a blocking task in the background by running the passed
       -        method in a thread.
       -        '''
       -
       -        def target():
       -
       -            # run your threaded function
       -            try:
       -                task()
       -            except Exception as err:
       -                Clock.schedule_once(lambda dt: app.show_error(str(err)))
       -
       -            # on  completion hide message
       -            Clock.schedule_once(lambda dt: app.info_bubble.hide(now=True), -1)
       -
       -            # call completion routine
       -            if on_complete:
       -                Clock.schedule_once(lambda dt: on_complete())
       -
       -        app.show_info_bubble(
       -            text=msg, icon='atlas://gui/kivy/theming/light/important',
       -            pos=Window.center, width='200sp', arrow_pos=None, modal=True)
       -        t = threading.Thread(target = target)
       -        t.start()
       -
       -    def run(self):
       -        '''Entry point of our Installation wizard
       -        '''
       -        CreateRestoreDialog(on_release=self.on_creatrestore_complete).open()
       -
       -    def on_creatrestore_complete(self, dialog, button):
       -        if not button:
       -            return self.dispatch('on_wizard_complete', None)
       -
       -        #gap = self.config.get('gap_limit', 5)
       -        #if gap !=5:
       -        #    wallet.gap_limit = gap_limit
       -        #    wallet.storage.put('gap_limit', gap, True)
       -
       -        dialog.close()
       -        if button == dialog.ids.create:
       -            # create
       -            wallet = Wallet(self.storage)
       -            self.change_password_dialog(wallet=wallet)
       -        elif button == dialog.ids.restore:
       -            # restore
       -            wallet = None
       -            self.restore_seed_dialog(wallet)
       -        #if button == dialog.ids.watching:
       -        #TODO: not available in the new design
       -        #    self.action = 'watching'
       -        else:
       -            self.dispatch('on_wizard_complete', None)
       -
       -    def restore_seed_dialog(self, wallet):
       -        from electrum_gui.kivy.dialog import RestoreSeedDialog
       -        RestoreSeedDialog(
       -            on_release=partial(self.on_verify_restore_ok, wallet)).open()
       -
       -    def on_verify_restore_ok(self, wallet, _dlg, btn, restore=False):
       -
       -        if _dlg.ids.back == btn:
       -            _dlg.close()
       -            CreateRestoreDialog(
       -                on_release=self.on_creatrestore_complete).open()
       -            return
       -
       -        seed = unicode(_dlg.ids.text_input_seed.text)
       -        if not seed:
       -            app.show_error(_("No seed!"), duration=.5)
       -            return
       -
       -        try:
       -            wallet = Wallet.from_seed(seed, self.storage)
       -        except Exception as err:
       -            _dlg.close()
       -            return app.show_error(str(err) + '\n App will now exit',
       -                           exit=True, modal=True, duration=.5)
       -        _dlg.close()
       -        return self.change_password_dialog(wallet=wallet, mode='restore')
       -
       -
       -    def init_seed_dialog(self, wallet=None, instance=None, password=None,
       -                         wallet_name=None, mode='create'):
       -        # renamed from show_seed()
       -        '''Can be called directly (password is None)
       -        or from a password-protected callback (password is not None)'''
       -
       -        if not wallet or not wallet.seed:
       -            if instance == None:
       -                wallet.init_seed(None)
       -            else:
       -                return app.show_error(_('No seed'))
       -
       -        if password is None or not instance:
       -            seed = wallet.get_mnemonic(None)
       -        else:
       -            try:
       -                seed = self.wallet.get_seed(password)
       -            except Exception:
       -                return app.show_error(_('Incorrect Password'))
       -
       -        brainwallet = seed
       -
       -        msg2 = _("[color=#414141]"+\
       -                "[b]PLEASE WRITE DOWN YOUR SEED PASS[/b][/color]"+\
       -                "[size=9]\n\n[/size]" +\
       -                "[color=#929292]If you ever forget your pincode, your seed" +\
       -                " phrase will be the [color=#EB984E]"+\
       -                "[b]only way to recover[/b][/color] your wallet. Your " +\
       -                " [color=#EB984E][b]Bitcoins[/b][/color] will otherwise be" +\
       -                " [color=#EB984E][b]lost forever![/b][/color]")
       -
       -        if wallet.imported_keys:
       -            msg2 += "[b][color=#ff0000ff]" + _("WARNING") + "[/color]:[/b] " +\
       -                    _("Your wallet contains imported keys. These keys cannot" +\
       -                    " be recovered from seed.")
       -
       -        def on_ok_press(_dlg, _btn):
       -            _dlg.close()
       -            if _btn != _dlg.ids.confirm:
       -                if not instance:
       -                    self.change_password_dialog(wallet)
       -                return
       -            # confirm
       -            if instance is None:
       -                # in initial phase
       -                def create(password):
       -                    try:
       -                        password = None if not password else password
       -                        wallet.save_seed(password)
       -                    except Exception as err:
       -                        Logger.Info('Wallet: {}'.format(err))
       -                        Clock.schedule_once(lambda dt:
       -                            app.show_error(err))
       -                    wallet.synchronize()  # generate first addresses offline
       -                self.waiting_dialog(
       -                    partial(create, password),
       -                    on_complete=partial(self.load_network, wallet, mode=mode))
       -
       -        from electrum_gui.kivy.dialog import InitSeedDialog
       -        InitSeedDialog(message=msg2,
       -            seed_msg=brainwallet, seed=seed, on_release=on_ok_press).open()
       -
       -    def change_password_dialog(self, wallet=None, instance=None, mode='create'):
       -        """Can be called directly (instance is None)
       -        or from a callback (instance is not None)"""
       -
       -        if instance and not wallet.seed:
       -            return ShowError(_('No seed !!'), exit=True, modal=True)
       -
       -        if instance is not None:
       -            if wallet.use_encryption:
       -                msg = (
       -                    _('Your wallet is encrypted. Use this dialog to change" + \
       -                    " your password.') + '\n' + _('To disable wallet" + \
       -                    " encryption, enter an empty new password.'))
       -                mode = 'confirm'
       -            else:
       -                msg = _('Your wallet keys are not encrypted')
       -                mode = 'new'
       -        else:
       -            msg = _("Please choose a password to encrypt your wallet keys.") +\
       -                '\n' + _("Leave these fields empty if you want to disable" + \
       -                " encryption.")
       -
       -        def on_release(_dlg, _btn):
       -            ti_password = _dlg.ids.ti_password
       -            ti_new_password = _dlg.ids.ti_new_password
       -            ti_confirm_password = _dlg.ids.ti_confirm_password
       -            if _btn != _dlg.ids.next:
       -                if mode == 'restore':
       -                    # back is disabled cause seed is already set
       -                    return
       -                _dlg.close()
       -                if not instance:
       -                    # back on create
       -                    CreateRestoreDialog(
       -                        on_release=self.on_creatrestore_complete).open()
       -                return
       -
       -            # Confirm
       -            wallet_name = _dlg.ids.ti_wallet_name.text
       -            password = (unicode(ti_password.text)
       -                        if wallet.use_encryption else
       -                        None)
       -            new_password = unicode(ti_new_password.text)
       -            new_password2 = unicode(ti_confirm_password.text)
       -
       -            if new_password != new_password2:
       -                ti_password.text = ""
       -                ti_new_password.text = ""
       -                ti_confirm_password.text = ""
       -                if ti_password.disabled:
       -                    ti_new_password.focus = True
       -                else:
       -                    ti_password.focus = True
       -                return app.show_error(_('Passwords do not match'), duration=.5)
       -
       -            if mode == 'restore':
       -                def on_complete(*l):
       -                    _dlg.close()
       -                    self.load_network(wallet, mode='restore')
       -
       -                self.waiting_dialog(lambda: wallet.save_seed(new_password),
       -                                    msg=_("saving seed"),
       -                                    on_complete=on_complete)
       -                return
       -            if not instance:
       -                # create
       -                _dlg.close()
       -                #self.load_network(wallet, mode='create')
       -                return self.init_seed_dialog(password=new_password,
       -                    wallet=wallet, wallet_name=wallet_name, mode=mode)
       -
       -            try:
       -                seed = wallet.decode_seed(password)
       -            except BaseException:
       -                return app.show_error(_('Incorrect Password'), duration=.5)
       -
       -            # test carefully
       -            try:
       -                wallet.update_password(seed, password, new_password)
       -            except BaseException:
       -                return app.show_error(_('Failed to update password'), exit=True)
       -            else:
       -                app.show_info_bubble(
       -                    text=_('Password successfully updated'), duration=1,
       -                    pos=_btn.pos)
       -            _dlg.close()
       -
       -
       -            if instance is None:  # in initial phase
       -                self.load_wallet()
       -            self.app.update_wallet()
       -
       -        from electrum_gui.kivy.dialog import ChangePasswordDialog
       -        cpd = ChangePasswordDialog(
       -                             message=msg,
       -                             mode=mode,
       -                             on_release=on_release).open()
       -
       -    def load_network(self, wallet, mode='create'):
       -        #if not self.config.get('server'):
       -        if self.network:
       -            if self.network.interfaces:
       -                if mode not in ('restore', 'create'):
       -                    self.network_dialog()
       -            else:
       -                app.show_error(_('You are offline'))
       -                self.network.stop()
       -                self.network = None
       -
       -        if mode in ('restore', 'create'):
       -            # auto cycle
       -            self.config.set_key('auto_cycle', True, True)
       -
       -        # start wallet threads
       -        wallet.start_threads(self.network)
       -
       -        if not mode == 'restore':
       -            return self.dispatch('on_wizard_complete', wallet)
       -
       -        def get_text(text):
       -            def set_text(*l): app.info_bubble.ids.lbl.text=text
       -            Clock.schedule_once(set_text)
       -
       -        def on_complete(*l):
       -            if not self.network:
       -                app.show_info(
       -                    _("This wallet was restored offline. It may contain more"
       -                      " addresses than displayed."), duration=.5)
       -                return self.dispatch('on_wizard_complete', wallet)
       -
       -            if wallet.is_found():
       -                app.show_info(_("Recovery successful"), duration=.5)
       -            else:
       -                app.show_info(_("No transactions found for this seed"),
       -                              duration=.5)
       -            return self.dispatch('on_wizard_complete', wallet)
       -
       -        self.waiting_dialog(lambda: wallet.restore(get_text),
       -                            on_complete=on_complete)
       -
       -    def on_wizard_complete(self, wallet):
       -        pass
   DIR diff --git a/gui/kivy/main.kv b/gui/kivy/main.kv
       t@@ -1,7 +1,4 @@
        #:import Window kivy.core.window.Window
       -#:import _ electrum.i18n._
       -#:import partial functools.partial
       -
        
        # Custom Global Widgets
        
       t@@ -22,37 +19,36 @@
                        if root.state == 'normal' else 'icon_border')
                    size: root.size
                    pos: root.pos
       -###########################
       -##    Gloabal Defaults
       -###########################
       -
       -<Label>
       -    markup: True
       -    font_name: 'Roboto'
       -    font_size: '16sp'
        
       -<ListItemButton>
       -    font_size: '12sp'
       -
       -#########################
       -#       Dialogs
       -#########################
       -
       -################################################
       -##      Create Dialogs
       -################################################
       +<Butt_star@ActionToggleButton>:
       +    important: True
       +    size_hint_x: None
       +    width: '32dp'
       +    mipmap: True
       +    state: 'down' if app.expert_mode else 'normal'
       +    background_down: self.background_normal
       +    foreground_color: (.466, .466, .466, 1)
       +    color_active: (0.235, .588, .89, 1)
       +    on_release: app.expert_mode = True if self.state == 'down' else False
       +    Image:
       +        source: 'atlas://gui/kivy/theming/light/star_big_inactive'
       +        center: root.center
       +        size: root.width/1.5, self.width
       +        color:
       +            root.foreground_color if root.state == 'normal' else root.color_active
       +        canvas.after:
       +            Color:
       +                rgba: 1, 1, 1, 1
       +        source: 
       +        allow_stretch: True
       +
       +<ELTextInput>
       +    padding: '10dp', '4dp'
       +    background_color: (0.238, 0.589, .996, 1) if self.focus else self.foreground_color
       +    foreground_color: 0.531, 0.531, 0.531, 1
       +    background_active: 'atlas://gui/kivy/theming/light/textinput_active'
       +    background_normal: 'atlas://gui/kivy/theming/light/textinput_active'
        
       -<CreateAccountTextInput@TextInput>
       -    border: 4, 4, 4, 4
       -    font_size: '15sp'
       -    padding: '15dp', '15dp'
       -    background_color: (1, 1, 1, 1) if self.focus else (0.454, 0.698, 0.909, 1)
       -    foreground_color: (0.31, 0.31, 0.31, 1) if self.focus else (0.835, 0.909, 0.972, 1)
       -    hint_text_color: self.foreground_color
       -    background_active: 'atlas://gui/kivy/theming/light/create_act_text_active'
       -    background_normal: 'atlas://gui/kivy/theming/light/create_act_text_active'
       -    size_hint_y: None
       -    height: '48sp'
        
        <CreateAccountButtonBlue@Button>
            canvas.after:
       t@@ -75,26 +71,40 @@
            text_size: self.size
            halign: 'center'
            valign: 'middle'
       +    root: None
            background_normal: 'atlas://gui/kivy/theming/light/btn_create_account'
            background_down: 'atlas://gui/kivy/theming/light/btn_create_account'
            background_disabled_normal: 'atlas://gui/kivy/theming/light/btn_create_act_disabled'
       -    on_release: self.root.dispatch('on_press', self)
       -    on_release: self.root.dispatch('on_release', self)
       +    on_press: if self.root: self.root.dispatch('on_press', self)
       +    on_release: if self.root: self.root.dispatch('on_release', self)
       +
        
        <CreateAccountButtonGreen@CreateAccountButtonBlue>
            background_color: (1, 1, 1, 1) if self.disabled else (.415, .717, 0, 1 if self.state == 'normal' else .75)
       +###########################
       +##    Gloabal Defaults
       +###########################
       +<TextInput>
       +    on_focus: app._focused_widget = root
       +
       +<Label>
       +    markup: True
       +    font_name: 'Roboto'
       +    font_size: '16sp'
       +
       +<ListItemButton>
       +    font_size: '12sp'
       +
       +#########################
       +#       Dialogs
       +#########################
        
        <InfoBubble>
       -    canvas.before:
       -        Color:
       -            rgba: 0, 0, 0, .7 if root.dim_background else 0
       -        Rectangle:
       -            size: Window.size
            size_hint: None, None
            width: '270dp' if root.fs else min(self.width, dp(270))
            height: self.width if self.fs else (lbl.texture_size[1] + dp(27))
            BoxLayout:
       -        padding: '5dp'
       +        padding: '5dp' if root.fs else 0
                Widget:
                    size_hint: None, 1
                    width: '4dp' if root.fs else '2dp'
       t@@ -117,346 +127,11 @@
                    size_hint: 1, 1
                    width: 0 if root.fs else (root.width - img.width)
        
       -<-CreateAccountDialog>
       -    text_color: .854, .925, .984, 1
       -    auto_dismiss: False
       -    size_hint: None, None
       -    canvas.before:
       -        Color:
       -            rgba: 0, 0, 0, .9
       -        Rectangle:
       -            size: Window.size
       -        Color:
       -            rgba: .239, .588, .882, 1
       -        Rectangle:
       -            size: Window.size
       -
       -    crcontent: crcontent
       -    # add electrum icon
       -    FloatLayout:
       -        size_hint: None, None
       -        size: 0, 0
       -        IconButton:
       -            id: but_close
       -            size_hint: None, None
       -            size: '27dp', '27dp'
       -            top: Window.height - dp(10)
       -            right: Window.width - dp(10)
       -            source: 'atlas://gui/kivy/theming/light/closebutton'
       -            on_release: root.dispatch('on_press', self)
       -            on_release: root.dispatch('on_release', self)
       -    BoxLayout:
       -        orientation: 'vertical' if self.width < self.height else 'horizontal'
       -        padding:
       -            min(dp(42), self.width/8), min(dp(60), self.height/9.7),\
       -            min(dp(42), self.width/8), min(dp(72), self.height/8)
       -        spacing: '27dp'
       -        GridLayout:
       -            id: grid_logo
       -            cols: 1
       -            pos_hint: {'center_y': .5}
       -            size_hint: 1, .62
       -            #height: self.minimum_height
       -            Image:
       -                id: logo_img
       -                mipmap: True
       -                allow_stretch: True
       -                size_hint: 1, None
       -                height: '110dp'
       -                source: 'atlas://gui/kivy/theming/light/electrum_icon640'
       -            Widget:
       -                size_hint: 1, None
       -                height: 0 if stepper.opacity else dp(15)
       -            Label:
       -                color: root.text_color
       -                opacity: 0 if stepper.opacity else 1
       -                text: 'ELECTRUM'
       -                size_hint: 1, None
       -                height: self.texture_size[1] if self.opacity else 0
       -                font_size: '33sp'
       -                font_name: 'data/fonts/tron/Tr2n.ttf'
       -            Image:
       -                id: stepper
       -                allow_stretch: True
       -                opacity: 0
       -                source: 'atlas://gui/kivy/theming/light/stepper_left'
       -                size_hint: 1, None
       -                height: grid_logo.height/2.5 if self.opacity else 0
       -        Widget:
       -            size_hint: None, None
       -            size: '5dp', '5dp'
       -        GridLayout:
       -            cols: 1
       -            id: crcontent
       -            spacing: '13dp'
       -
       -<CreateRestoreDialog>
       -    Label:
       -        color: root.text_color
       -        size_hint: 1, None
       -        text_size: self.width, None
       -        height: self.texture_size[1]
       -        text:
       -            _("Wallet file not found!!")+\
       -            "\n\n" + _("Do you want to create a new wallet ")+\
       -            _("or restore an existing one?")
       -    Widget
       -        size_hint: 1, None
       -        height: dp(15)
       -    GridLayout:
       -        id: grid
       -        orientation: 'vertical'
       -        cols: 1
       -        spacing: '14dp'
       -        size_hint: 1, None
       -        height: self.minimum_height
       -        CreateAccountButtonGreen:
       -            id: create
       -            text: _('Create a Wallet')
       -            root: root
       -        CreateAccountButtonBlue:
       -            id: restore
       -            text: _('I already have a wallet')
       -            root: root
       -        #CreateAccountButtonBlue:
       -        #    id: watching
       -        #    text: _('Create a Watching only wallet')
       -        #    root: root
       -
       -<RestoreSeedDialog>
       -    GridLayout
       -        # leave room for future selection of gap through a widget
       -        # removed for mobile
       -        id: text_input_gap
       -        text: '5'
       -
       -        cols: 1
       -        padding: 0, '12dp'
       -        orientation: 'vertical'
       -        spacing: '12dp'
       -        size_hint: 1, None
       -        height: self.minimum_height
       -        CreateAccountTextInput:
       -            id: text_input_seed
       -            size_hint: 1, None
       -            height: '110dp'
       -            hint_text:
       -                _('Enter your seedphrase')
       -        Label:
       -            font_size: '12sp'
       -            text_size: self.width, None
       -            size_hint: 1, None
       -            height: self.texture_size[1]
       -            halign: 'justify'
       -            valign: 'middle'
       -            text:
       -                _('If you need additional information, please check '
       -                '[color=#0000ff][ref=1]'
       -                'https://electrum.org/faq.html#seed[/ref][/color]')
       -            on_ref_press:
       -                import webbrowser
       -                webbrowser.open('https://electrum.org/faq.html#seed')
       -    GridLayout:
       -        rows: 1
       -        spacing: '12dp'
       -        size_hint: 1, None
       -        height: self.minimum_height
       -        CreateAccountButtonBlue:
       -            id: back
       -            text: _('Back')
       -            root: root
       -        CreateAccountButtonGreen:
       -            id: next
       -            text: _('Next')
       -            root: root
       -
       -<InitSeedDialog>
       -    spacing: '12dp'
       -    GridLayout:
       -        id: grid
       -        cols: 1
       -        pos_hint: {'center_y': .5}
       -        size_hint_y: None
       -        height: dp(180)
       -        orientation: 'vertical'
       -        Button:
       -            border: 4, 4, 4, 4
       -            halign: 'justify'
       -            valign: 'middle'
       -            font_size: self.width/21
       -            text_size: self.width - dp(24), self.height - dp(12)
       -            #size_hint: 1, None
       -            #height: self.texture_size[1] + dp(24)
       -            background_normal: 'atlas://gui/kivy/theming/light/white_bg_round_top'
       -            background_down: self.background_normal
       -            text: root.message
       -        GridLayout:
       -            rows: 1
       -            size_hint: 1, .7
       -            #size_hint_y: None
       -            #height: but_seed.texture_size[1] + dp(24)
       -            Button:
       -                id: but_seed
       -                border: 4, 4, 4, 4
       -                halign: 'justify'
       -                valign: 'middle'
       -                font_size: self.width/15
       -                text: root.seed_msg
       -                text_size: self.width - dp(24), self.height - dp(12)
       -                background_normal: 'atlas://gui/kivy/theming/light/lightblue_bg_round_lb'
       -                background_down: self.background_normal
       -            Button:
       -                id: bt
       -                size_hint_x: .25
       -                background_normal: 'atlas://gui/kivy/theming/light/blue_bg_round_rb'
       -                background_down: self.background_normal
       -                Image:
       -                    mipmap: True
       -                    source: 'atlas://gui/kivy/theming/light/qrcode'
       -                    size: bt.size
       -                    center: bt.center
       -                 #on_release:
       -    GridLayout:
       -        rows: 1
       -        spacing: '12dp'
       -        size_hint: 1, None
       -        height: self.minimum_height
       -        CreateAccountButtonBlue:
       -            id: back
       -            text: _('Back')
       -            root: root
       -        CreateAccountButtonGreen:
       -            id: confirm
       -            text: _('Confirm')
       -            root: root
       -
       -<ChangePasswordDialog>
       -    padding: '7dp'
       -    GridLayout:
       -        size_hint_y: None
       -        height: self.minimum_height
       -        cols: 1
       -        CreateAccountTextInput:
       -            id: ti_wallet_name
       -            hint_text: 'Your Wallet Name'
       -            multiline: False
       -            on_text_validate:
       -                next = ti_new_password if ti_password.disabled else ti_password
       -                next.focus = True
       -        Widget:
       -            size_hint_y: None
       -            height: '13dp'
       -        CreateAccountTextInput:
       -            id: ti_password
       -            hint_text: 'Enter old pincode'
       -            size_hint_y: None
       -            height: 0 if self.disabled else '38sp'
       -            password: True
       -            disabled: True if root.mode in ('new', 'create', 'restore') else False
       -            opacity: 0 if self.disabled else 1
       -            multiline: False
       -            on_text_validate:
       -                #root.validate_old_password()
       -                ti_new_password.focus = True
       -        Widget:
       -            size_hint_y: None
       -            height: 0 if ti_password.disabled else '13dp'
       -        CreateAccountTextInput:
       -            id: ti_new_password
       -            hint_text: 'Enter new pincode'
       -            multiline: False
       -            password: True
       -            on_text_validate: ti_confirm_password.focus = True
       -        Widget:
       -            size_hint_y: None
       -            height: '13dp'
       -        CreateAccountTextInput:
       -            id: ti_confirm_password
       -            hint_text: 'Confirm pincode'
       -            password: True
       -            multiline: False
       -            on_text_validate: root.validate_new_password()
       -    Widget
       -    GridLayout:
       -        rows: 1
       -        spacing: '12dp'
       -        size_hint: 1, None
       -        height: self.minimum_height
       -        CreateAccountButtonBlue:
       -            id: back
       -            text: _('Back')
       -            root: root
       -            disabled: True if root.mode[0] == 'r' else self.disabled
       -        CreateAccountButtonGreen:
       -            id: next
       -            text: _('Confirm') if root.mode[0] == 'r' else _('Next')
       -            root: root
       -
       -###############################################
       -##              Wallet Management
       -###############################################
       -
       -<WalletManagement@ScrollView>
       +StencilView:
       +    manager: None
            canvas.before:
                Color:
       -            rgba: .145, .145, .145, 1
       -        Rectangle:
       -            size: root.size
       -            pos: root.pos
       -    VGridLayout:
       -        Wallets:
       -            id: wallets_section
       -        Plugins:
       -            id: plugins_section
       -        Commands:
       -            id: commands_section
       -
       -<WalletManagementItem@BoxLayout>
       -
       -<Header@WalletManagementItem>
       -
       -<Wallets@VGridLayout>
       -    Header
       -
       -<Plugins@VGridLayout>
       -    Header
       -
       -<Commands@VGridLayout>
       -    Header
       -
       -################################################
       -##      This is our Root Widget of the app
       -################################################
       -StencilView
       -    manager: manager
       -    Drawer
       -        id: drawer
       -        size: root.size
       -        WalletManagement
       -            id: wallet_management
       -            canvas.before:
       -                Color:
       -                    rgba: .176, .176, .176, 1
       -                Rectangle:
       -                    size: self.size
       -                    pos: self.pos
       -            width:
       -                (root.width * .877) if app.ui_mode[0] == 'p'\
       -                else root.width * .35 if app.orientation[0] == 'l'\
       -                else root.width * .10
       -            height: root.height
       -        BoxLayout:
       -            x: wallet_management.width if app.ui_mode[0] == 't' else 0
       -            width: (root.width - self.x) if app.ui_mode[0] == 't' else root.width
       -            size_hint: None, None
       -            height: root.height
       -            canvas.before:
       -                Color
       -                    rgba: 1, 1, 1, 1
       -                BorderImage
       -                    border: 0, 32, 0, 0
       -                    source: 'atlas://gui/kivy/theming/light/shadow_right'
       -                    pos: root.pos
       -                    size: self.x, self.height
       -            ScreenManager:
       -                id: manager
       -\ No newline at end of file
       +            rgba: 1, 1, 1, 1
       +        Rectangle
       +            size: self.size
       +            pos: self.pos
       +\ No newline at end of file
   DIR diff --git a/gui/kivy/main_window.py b/gui/kivy/main_window.py
       t@@ -1,35 +1,88 @@
        import  sys
       -from decimal import Decimal
       +import datetime
        
        from electrum import WalletStorage, Wallet
        from electrum.i18n import _, set_language
       -from electrum.wallet import format_satoshis
        
        from kivy.app import App
        from kivy.core.window import Window
       -from kivy.lang import Builder
        from kivy.logger import Logger
       -from kivy.metrics import inch
        from kivy.utils import platform
        from kivy.properties import (OptionProperty, AliasProperty, ObjectProperty,
       -                             StringProperty, ListProperty)
       +                             StringProperty, ListProperty, BooleanProperty)
       +from kivy.cache import Cache
        from kivy.clock import Clock
       +from kivy.factory import Factory
        
       -#inclusions for factory so that widgets can be used in kv
       -from electrum_gui.kivy.drawer import Drawer
       -from electrum_gui.kivy.dialog import InfoBubble
       +from electrum_gui.kivy.uix.drawer import Drawer
        
       -# delayed imports
       -notification = None
       +# lazy imports for factory so that widgets can be used in kv
       +Factory.register('InstallWizard',
       +                 module='electrum_gui.kivy.uix.dialogs.installwizard')
       +Factory.register('InfoBubble', module='electrum_gui.kivy.uix.dialogs')
       +Factory.register('ELTextInput', module='electrum_gui.kivy.uix.screens')
       +
       +# delayed imports: for startup speed on android
       +notification = app = Decimal = ref = format_satoshis = is_valid = Builder = None
       +inch = None
       +util = False
       +re = None
       +
       +# register widget cache for keeping memory down timeout to 4 minutes to cache
       +# the data
       +Cache.register('electrum_widgets', timeout=240)
        
        class ElectrumWindow(App):
        
       -    title = _('Electrum App')
       +    def _get_bu(self):
       +        assert self.decimal_point in (5,8)
       +        return "BTC" if self.decimal_point == 8 else "mBTC"
        
       -    wallet = ObjectProperty(None)
       -    '''Holds the electrum wallet
       +    def _set_bu(self, value):
       +        try:
       +            self.electrum_config.set_key('base_unit', value, True)
       +        except AttributeError:
       +            Logger.error('Electrum: Config not set '
       +                         'While trying to save value to config')
        
       -    :attr:`wallet` is a `ObjectProperty` defaults to None.
       +    base_unit = AliasProperty(_get_bu, _set_bu, bind=('decimal_point',))
       +    '''BTC or UBTC or mBTC...
       +
       +    :attr:`base_unit` is a `AliasProperty` defaults to the unit set in
       +    electrum config.
       +    '''
       +
       +    currencies = ListProperty(['EUR', 'GBP', 'USD'])
       +    '''List of currencies supported by the current exchanger plugin.
       +
       +    :attr:`currencies` is a `ListProperty` default to ['Eur', 'GBP'. 'USD'].
       +    '''
       +
       +    expert_mode = BooleanProperty(False)
       +    '''This defines whether expert mode options are available in the ui.
       +
       +    :attr:`expert_mode` is a `BooleanProperty` defaults to `False`.
       +    '''
       +
       +    def _get_decimal(self):
       +        try:
       +            return self.electrum_config.get('decimal_point', 8)
       +        except AttributeError:
       +            return 8
       +
       +    def _set_decimal(self, value):
       +        try:
       +            self.electrum_config.set_key('decimal_point', value, True)
       +        except AttributeError:
       +            Logger.error('Electrum: Config not set '
       +                         'While trying to save value to config')
       +
       +    decimal_point = AliasProperty(_get_decimal, _set_decimal)
       +    '''This defines the decimal point to be used determining the
       +    :attr:`decimal_point`.
       +
       +    :attr:`decimal_point` is a `AliasProperty` defaults to the value gotten
       +    from electrum config.
            '''
        
            electrum_config = ObjectProperty(None)
       t@@ -61,43 +114,26 @@ class ElectrumWindow(App):
            '''Number of zeros used while representing the value in base_unit.
            '''
        
       -    def _get_decimal(self):
       -        try:
       -            return self.electrum_config.get('decimal_point', 8)
       -        except AttributeError:
       -            return 8
       -
       -    def _set_decimal(self, value):
       -        try:
       -            self.electrum_config.set_key('decimal_point', value, True)
       -        except AttributeError:
       -            Logger.error('Electrum: Config not set '
       -                         'While trying to save value to config')
       -
       -    decimal_point = AliasProperty(_get_decimal, _set_decimal)
       -    '''This defines the decimal point to be used determining the
       -    :attr:`base_unit`.
       +    navigation_higherarchy = ListProperty([])
       +    '''This is a list of the current navigation higherarchy of the app used to
       +    navigate using back button.
        
       -    :attr:`decimal_point` is a `AliasProperty` defaults to the value gotten
       -    from electrum config.
       +    :attr:`navigation_higherarchy` is s `ListProperty` defaults to []
            '''
        
       -    def _get_bu(self):
       -        assert self.decimal_point in (5,8)
       -        return "BTC" if self.decimal_point == 8 else "mBTC"
       +    _orientation = OptionProperty('landscape',
       +                                 options=('landscape', 'portrait'))
        
       -    def _set_bu(self, value):
       -        try:
       -            self.electrum_config.set_key('base_unit', value, True)
       -        except AttributeError:
       -            Logger.error('Electrum: Config not set '
       -                         'While trying to save value to config')
       +    def _get_orientation(self):
       +        return self._orientation
        
       -    base_unit = AliasProperty(_get_bu, _set_bu, bind=('decimal_point',))
       -    '''BTC or UBTC or mBTC...
       +    orientation = AliasProperty(_get_orientation,
       +                                None,
       +                                bind=('_orientation',))
       +    '''Tries to ascertain the kind of device the app is running on.
       +    Cane be one of `tablet` or `phone`.
        
       -    :attr:`base_unit` is a `AliasProperty` defaults to the unit set in
       -    electrum config.
       +    :data:`orientation` is a read only `AliasProperty` Defaults to 'landscape'
            '''
        
            _ui_mode = OptionProperty('phone', options=('tablet', 'phone'))
       t@@ -114,51 +150,58 @@ class ElectrumWindow(App):
            :data:`ui_mode` is a read only `AliasProperty` Defaults to 'phone'
            '''
        
       -    _orientation = OptionProperty('landscape',
       -                                 options=('landscape', 'portrait'))
       -
       -    def _get_orientation(self):
       -        return self._orientation
       -
       -    orientation = AliasProperty(_get_orientation,
       -                                None,
       -                                bind=('_orientation',))
       -    '''Tries to ascertain the kind of device the app is running on.
       -    Cane be one of `tablet` or `phone`.
       -
       -    :data:`orientation` is a read only `AliasProperty` Defaults to 'landscape'
       +    url = StringProperty('', allownone=True)
       +    '''
            '''
        
       -    navigation_higherarchy = ListProperty([])
       -    '''This is a list of the current navigation higherarchy of the app used to
       -    navigate using back button.
       +    wallet = ObjectProperty(None)
       +    '''Holds the electrum wallet
        
       -    :attr:`navigation_higherarchy` is s `ListProperty` defaults to []
       +    :attr:`wallet` is a `ObjectProperty` defaults to None.
            '''
        
            __events__ = ('on_back', )
        
            def __init__(self, **kwargs):
                # initialize variables
       -        self.info_bubble = None
       +        self._clipboard = None
                self.console = None
                self.exchanger = None
       +        self.info_bubble = None
       +        self.qrscanner = None
       +        self.nfcscanner = None
       +        self.tabs = None
        
                super(ElectrumWindow, self).__init__(**kwargs)
        
       -        self.network = network = kwargs.get('network')
       -        self.electrum_config = config = kwargs.get('config')
       +        title = _('Electrum App')
       +        self.network = network = kwargs.get('network', None)
       +        self.electrum_config = config = kwargs.get('config', None)
       +        self.gui_object = kwargs.get('gui_object', None)
       +
       +        self.bind(url=self.set_url)
       +        # were we sent a url?
       +        url = kwargs.get('url', None)
       +        if url:
       +            self.gui_object.set_url(url)
        
                # create triggers so as to minimize updation a max of 2 times a sec
       +        self._trigger_update_wallet =\
       +            Clock.create_trigger(self.update_wallet, .5)
                self._trigger_update_status =\
                    Clock.create_trigger(self.update_status, .5)
                self._trigger_update_console =\
                    Clock.create_trigger(self.update_console, .5)
                self._trigger_notify_transactions = \
       -            Clock.create_trigger(self.notify_transactions, .5)
       +            Clock.create_trigger(self.notify_transactions, 5)
       +
       +    def set_url(self, instance, url):
       +        self.gui_object.set_url(url)
        
            def build(self):
       -        from kivy.lang import Builder
       +        global Builder
       +        if not Builder:
       +            from kivy.lang import Builder
                return Builder.load_file('gui/kivy/main.kv')
        
            def _pause(self):
       t@@ -172,11 +215,13 @@ class ElectrumWindow(App):
            def on_start(self):
                ''' This is the start point of the kivy ui
                '''
       -        Window.bind(size=self.on_size,
       +        win = Window
       +        win.bind(size=self.on_size,
                            on_keyboard=self.on_keyboard)
       -        Window.bind(on_key_down=self.on_key_down)
       +        win.bind(on_key_down=self.on_key_down)
        
       -        # register fonts
       +        # Register fonts without this you won't be able to use bold/italic...
       +        # inside markup.
                from kivy.core.text import Label
                Label.register('Roboto',
                           'data/fonts/Roboto.ttf',
       t@@ -185,23 +230,29 @@ class ElectrumWindow(App):
                           'data/fonts/Roboto-Bold.ttf')
        
                if platform == 'android':
       -            #
       -            Window.bind(keyboard_height=self.on_keyboard_height)
       -        self.on_size(Window, Window.size)
       +            # bind to keyboard height so we can get the window contents to
       +            # behave the way we want when the keyboard appears.
       +            win.bind(keyboard_height=self.on_keyboard_height)
       +
       +        self.on_size(win, win.size)
                config = self.electrum_config
                storage = WalletStorage(config)
        
                Logger.info('Electrum: Check for existing wallet')
       -        if not storage.file_exists:
       +
       +        if storage.file_exists:
       +            wallet = Wallet(storage)
       +            action = wallet.get_action()
       +        else:
       +            action = 'new'
       +
       +        if action is not None:
                    # start installation wizard
                    Logger.debug('Electrum: Wallet not found. Launching install wizard')
       -            import installwizard
       -            wizard = installwizard.InstallWizard(config, self.network,
       -                                                 storage)
       +            wizard = Factory.InstallWizard(config, self.network, storage)
                    wizard.bind(on_wizard_complete=self.on_wizard_complete)
       -            wizard.run()
       +            wizard.run(action)
                else:
       -            wallet = Wallet(storage)
                    wallet.start_threads(self.network)
                    self.on_wizard_complete(None, wallet)
        
       t@@ -220,15 +271,22 @@ class ElectrumWindow(App):
                    # capture back button and pause app.
                    self._pause()
        
       -    def on_keyboard_height(self, *l):
       -        from kivy.animation import Animation
       -        from kivy.uix.popup import Popup
       -        active_widg = Window.children[0]
       -        active_widg = active_widg\
       -            if (active_widg == self.root or\
       -            issubclass(active_widg.__class__, Popup)) else\
       -            Window.children[1]
       -        Animation(y=Window.keyboard_height, d=.1).start(active_widg)
       +    def on_keyboard_height(self, window, height):
       +        win = window
       +        active_widg = win.children[0]
       +        if not issubclass(active_widg.__class__, Factory.Popup):
       +            try:
       +                active_widg = self.root.children[0]
       +            except IndexError:
       +                return
       +
       +        try:
       +            fw = self._focused_widget
       +        except AttributeError:
       +            return
       +        if height > 0 and fw.to_window(*fw.pos)[1] > height:
       +            return
       +        Factory.Animation(y=win.keyboard_height, d=.1).start(active_widg)
        
            def on_key_down(self, instance, key, keycode, codepoint, modifiers):
                if 'ctrl' in modifiers:
       t@@ -261,6 +319,7 @@ class ElectrumWindow(App):
            def on_wizard_complete(self, instance, wallet):
                if not wallet:
                    Logger.debug('Electrum: No Wallet set/found. Exiting...')
       +            app = App.get_running_app()
                    app.show_error('Electrum: No Wallet set/found. Exiting...',
                                   exit=True)
        
       t@@ -271,21 +330,6 @@ class ElectrumWindow(App):
        
                self.load_wallet(wallet)
        
       -        #TODO: URI handling
       -        #self.windows.append(w)
       -        #if url: w.set_url(url)
       -
       -        # TODO:remove properties are used instead
       -        #Clock.schedule_interval(self.timer_actions, .5)
       -
       -
       -    #TODO: remove not needed properties allow on_property events
       -    #def timer_actions(self):
       -    #    if self.need_update.is_set():
       -    #        self.update_wallet()
       -    #        self.need_update.clear()
       -    #    run_hook('timer_actions')
       -
            def init_ui(self):
                ''' Initialize The Ux part of electrum. This function performs the basic
                tasks of setting up the ui.
       t@@ -297,49 +341,70 @@ class ElectrumWindow(App):
                #self._tray_icon = 'icons/" + (electrum_dark_icon.png'\
                #    if platform == 'mac' else 'electrum_light_icon.png')
        
       -        #setup tray
       +        #setup tray TODO: use the systray branch
                #self.tray = SystemTrayIcon(self.icon, self)
                #self.tray.setToolTip('Electrum')
                #self.tray.activated.connect(self.tray_activated)
        
       +        global ref
       +        if not ref:
       +            from weakref import ref
       +
                set_language(self.electrum_config.get('language'))
        
                self.funds_error = False
                self.completions = []
        
                # setup UX
       -        self.screens = ['mainscreen']
       -        self.load_screen(index=0)
       -
       -        self.icon = "icons/electrum.png"
       +        self.screens = ['mainscreen',]
       +
       +        #setup lazy imports for mainscreen
       +        Factory.register('AnimatedPopup',
       +                         module='electrum_gui.kivy.uix.dialogs')
       +        Factory.register('TabbedCarousel',
       +                         module='electrum_gui.kivy.uix.screens')
       +        Factory.register('ScreenDashboard',
       +                         module='electrum_gui.kivy.uix.screens')
       +        Factory.register('EffectWidget',
       +                         module='electrum_gui.kivy.uix.effectwidget')
        
                # load and focus the ui
       +        #Load mainscreen
       +
       +        Factory.register('QRCodeWidget',
       +                         module='electrum_gui.kivy.uix.qrcodewidget')
       +        Factory.register('MainScreen',
       +                         module='electrum_gui.kivy.uix.screens')
       +        Factory.register('CSpinner',
       +                         module='electrum_gui.kivy.uix.screens')
       +
       +        dr = Builder.load_file('gui/kivy/uix/ui_screens/mainscreen.kv')
       +        self.root.add_widget(dr)
       +        self.root.manager = manager = dr.ids.manager
       +        self.root.main_screen = m = manager.screens[0]
       +        self.tabs = m.ids.tabs
       +
       +        #TODO
       +        # load left_menu
       +
       +        self.icon = "icons/electrum.png"
        
                # connect callbacks
                if self.network:
       -            self.network.register_callback(
       -                'updated', self._trigger_update_status)
       -            self.network.register_callback(
       -                'banner', self._trigger_update_console)
       -            self.network.register_callback(
       -                'disconnected', self._trigger_update_status)
       -            self.network.register_callback(
       -                'disconnecting', self._trigger_update_status)
       -            self.network.register_callback('new_transaction',
       -                self._trigger_notify_transactions)
       +            self.network.register_callback('updated', self._trigger_update_wallet)
       +            #self.network.register_callback('banner', self.console.show_message(self.network.banner))
       +            self.network.register_callback('disconnected', self._trigger_update_status)
       +            self.network.register_callback('disconnecting', self._trigger_update_status)
       +            self.network.register_callback('new_transaction', self._trigger_notify_transactions)
        
                    # set initial message
       -            self.update_console()
       +            #self.console.show_message(self.network.banner)
        
                self.wallet = None
        
            def create_quote_text(self, btc_balance, mode='normal'):
                '''
                '''
       -        if not self.exchanger:
       -            from electrum_gui.kivy.plugins.exchange_rate import Exchanger
       -            self.exchanger = Exchanger(self)
       -            self.exchanger.start()
                quote_currency = self.exchanger.currency
                quote_balance = self.exchanger.exchange(btc_balance, quote_currency)
        
       t@@ -348,19 +413,60 @@ class ElectrumWindow(App):
                                                                quote_currency)
        
                if quote_balance is None:
       -            quote_text = ""
       +            quote_text = u"..."
                else:
       -            quote_text = "  (%.2f %s)" % (quote_balance, quote_currency)
       +            quote_text = u"%s%.2f" % (quote_currency,
       +                                     quote_balance)
                return quote_text
        
            def set_currencies(self, quote_currencies):
       -        self._trigger_update_status()
       -        print quote_currencies
                self.currencies = sorted(quote_currencies.keys())
       +        self._trigger_update_status()
       +
       +    def get_history_rate(self, item, btc_balance, mintime):
       +        '''Historical rates: currently only using coindesk by default.
       +        '''
       +        maxtime = datetime.datetime.now().strftime('%Y-%m-%d')
       +        rate = self.exchanger.get_history_rate(item, btc_balance, mintime,
       +                                                maxtime)
       +
       +        return self.set_history_rate(item, rate)
       +
       +    def set_history_rate(self, item, rate):
       +        '''
       +        '''
       +        #TODO: fix me allow other currencies to be used for history rates
       +        quote_currency = self.exchanger.symbols.get('USD', 'USD')
       +
       +        if rate is None:
       +            quote_text = "..."
       +        else:
       +            quote_text = "{0}{1:.3}".format(quote_currency, rate)
       +
       +        item = item()
       +        if item:
       +            item.quote_text = quote_text
       +        return quote_text
        
            def update_console(self, *dt):
       -        if self.console:
       -            self.console.showMessage(self.network.banner)
       +        console = self.console
       +        if console:
       +            console = self.console
       +            console.history = self.config.get("console-history",[])
       +            console.history_index = len(console.history)
       +
       +            console.updateNamespace({'wallet' : self.wallet, 'network' : self.network, 'gui':self})
       +            console.updateNamespace({'util' : util, 'bitcoin':bitcoin})
       +
       +            c = commands.Commands(self.wallet, self.network, lambda: self.console.set_json(True))
       +            methods = {}
       +            def mkfunc(f, method):
       +                return lambda *args: apply( f, (method, args, self.password_dialog ))
       +            for m in dir(c):
       +                if m[0]=='_' or m in ['network','wallet']: continue
       +                methods[m] = mkfunc(c._run, m)
       +
       +            console.updateNamespace(methods)
        
            def load_wallet(self, wallet):
                self.wallet = wallet
       t@@ -375,25 +481,28 @@ class ElectrumWindow(App):
                self.update_wallet()
                # Once GUI has been initialized check if we want to announce something
                # since the callback has been called before the GUI was initialized
       +        self.update_history_tab()
                self.notify_transactions()
                self.update_account_selector()
       -        #TODO
       -        #self.new_account.setEnabled(self.wallet.seed_version>4)
       -        #self.update_lock_icon()
       -        #self.update_buttons_on_seed()
        
                #run_hook('load_wallet', wallet)
        
            def update_status(self, *dt):
                if not self.wallet:
                    return
       +
       +        global Decimal
       +        if not Decimal:
       +            from decimal import Decimal
       +
       +        unconfirmed = ''
       +        quote_text = ''
       +
                if self.network is None or not self.network.is_running():
                    text = _("Offline")
                    #icon = QIcon(":icons/status_disconnected.png")
        
                elif self.network.is_connected():
       -            unconfirmed = ''
       -            quote_text = '.'
                    if not self.wallet.up_to_date:
                        text = _("Synchronizing...")
                        #icon = QIcon(":icons/status_waiting.png")
       t@@ -406,7 +515,8 @@ class ElectrumWindow(App):
                        if u:
                            unconfirmed =  " [%s unconfirmed]"\
                                %( self.format_amount(u, True).strip())
       -                quote_text = self.create_quote_text(Decimal(c+u)/100000000) or '.'
       +                quote_text = self.create_quote_text(Decimal(c+u)/100000000,
       +                                                    mode='symbol') or ''
        
                        #r = {}
                        #run_hook('set_quote_text', c+u, r)
       t@@ -420,29 +530,42 @@ class ElectrumWindow(App):
                    text = _("Not connected")
                    #icon = QIcon(":icons/status_disconnected.png")
        
       -        #TODO
       -        #status_card = self.root.main_screen.ids.tabs.ids.\
       -        #                screen_dashboard.ids.status_card
       +        try:
       +            status_card = self.root.main_screen.ids.tabs.ids.\
       +                        screen_dashboard.ids.status_card
       +        except AttributeError:
       +            return
                self.status = text.strip()
       -        #status_card.quote_text = quote_text.strip()
       -        #status_card.uncomfirmed = unconfirmed.strip()
       -        ##app.base_unit = self.base_unit().strip()
       +        status_card.quote_text = quote_text.strip()
       +        status_card.uncomfirmed = unconfirmed.strip()
        
            def format_amount(self, x, is_diff=False, whitespaces=False):
                '''
                '''
       -        return format_satoshis(x, is_diff, self.num_zeros, self.decimal_point, whitespaces)
       -
       -    def update_wallet(self):
       +        global format_satoshis
       +        if not format_satoshis:
       +            from electrum.wallet import format_satoshis
       +        return format_satoshis(x, is_diff, self.num_zeros,
       +                               self.decimal_point, whitespaces)
       +
       +    def read_amount(self, x):
       +        if x in['.', '']:
       +            return None
       +        p = pow(10, self.decimal_point)
       +        return int( p * Decimal(x) )
       +
       +    def update_wallet(self, *dt):
                '''
                '''
       -        self.update_status()
       -        if (self.wallet.up_to_date or
       -            not self.network or not self.network.is_connected()):
       -            #TODO
       -            #self.update_history_tab()
       -            #self.update_receive_tab()
       -            #self.update_contacts_tab()
       +        if not self.exchanger:
       +            from electrum_gui.kivy.plugins.exchange_rate import Exchanger
       +            self.exchanger = Exchanger(self)
       +            self.exchanger.start()
       +            return
       +        self._trigger_update_status()
       +        if (self.wallet.up_to_date or  not self.network or not self.network.is_connected()):
       +            self.update_history_tab()
       +            self.update_contacts_tab()
                    self.update_completions()
        
            def update_account_selector(self):
       t@@ -458,54 +581,54 @@ class ElectrumWindow(App):
                else:
                    self.account_selector.hide()
        
       -    def update_history_tab(self, see_all=False):
       -        def parse_histories(items):
       -            results = []
       -            for item in items:
       -                tx_hash, conf, is_mine, value, fee, balance, timestamp = item
       -                if conf > 0:
       -                    try:
       -                        time_str = datetime.datetime.fromtimestamp(
       -                                        timestamp).isoformat(' ')[:-3]
       -                    except:
       -                        time_str = _("unknown")
       -
       -                if conf == -1:
       -                    time_str = _('unverified')
       -                    icon = "atlas://gui/kivy/theming/light/close"
       -                elif conf == 0:
       -                    time_str = _('pending')
       -                    icon = "atlas://gui/kivy/theming/light/unconfirmed"
       -                elif conf < 6:
       -                    time_str = ''  # add new to fix error when conf < 0
       -                    conf = max(1, conf)
       -                    icon = "atlas://gui/kivy/theming/light/clock{}".format(conf)
       -                else:
       -                    icon = "atlas://gui/kivy/theming/light/confirmed"
       +    def parse_histories(self, items):
       +        for item in items:
       +            tx_hash, conf, is_mine, value, fee, balance, timestamp = item
       +            time_str = _("unknown")
       +            if conf > 0:
       +                try:
       +                    time_str = datetime.datetime.fromtimestamp(
       +                                    timestamp).isoformat(' ')[:-3]
       +                except Exception:
       +                    time_str = _("error")
       +
       +            if conf == -1:
       +                time_str = _('unverified')
       +                icon = "atlas://gui/kivy/theming/light/close"
       +            elif conf == 0:
       +                time_str = _('pending')
       +                icon = "atlas://gui/kivy/theming/light/unconfirmed"
       +            elif conf < 6:
       +                time_str = ''  # add new to fix error when conf < 0
       +                conf = max(1, conf)
       +                icon = "atlas://gui/kivy/theming/light/clock{}".format(conf)
       +            else:
       +                icon = "atlas://gui/kivy/theming/light/confirmed"
        
       -                if value is not None:
       -                    v_str = self.format_amount(value, True, whitespaces=True)
       -                else:
       -                    v_str = '--'
       +            if value is not None:
       +                v_str = self.format_amount(value, True, whitespaces=True)
       +            else:
       +                v_str = '--'
        
       -                balance_str = self.format_amount(balance, whitespaces=True)
       +            balance_str = self.format_amount(balance, whitespaces=True)
        
       -                if tx_hash:
       -                    label, is_default_label = self.wallet.get_label(tx_hash)
       -                else:
       -                    label = _('Pruned transaction outputs')
       -                    is_default_label = False
       +            if tx_hash:
       +                label, is_default_label = self.wallet.get_label(tx_hash)
       +            else:
       +                label = _('Pruned transaction outputs')
       +                is_default_label = False
        
       -                results.append((
       -                        conf, icon, time_str, label, v_str, balance_str, tx_hash))
       +            yield (conf, icon, time_str, label, v_str, balance_str, tx_hash)
        
       -            return results
       +    def update_history_tab(self, see_all=False):
        
       -        history_card = self.root.main_screen.ids.tabs.ids.\
       +        try:
       +            history_card = self.root.main_screen.ids.tabs.ids.\
                                screen_dashboard.ids.recent_activity_card
       -        histories = parse_histories(reversed(
       +        except AttributeError:
       +            return
       +        histories = self.parse_histories(reversed(
                                self.wallet.get_tx_history(self.current_account)))
       -        #history_view.content_adapter.data = histories
        
                # repopulate History Card
                last_widget = history_card.ids.content.children[-1]
       t@@ -513,26 +636,34 @@ class ElectrumWindow(App):
                history_add = history_card.ids.content.add_widget
                history_add(last_widget)
                RecentActivityItem = Factory.RecentActivityItem
       -
       -        history_card.ids.btn_see_all.opacity = (0 if see_all or
       -                                                len(histories) < 8 else 1)
       -        if not see_all:
       -            histories = histories[:8]
       -
       -        create_quote_text = self.create_quote_text
       +        global Decimal, ref
       +        if not ref:
       +            from weakref import ref
       +        if not Decimal:
       +            from decimal import Decimal
       +
       +        get_history_rate = self.get_history_rate
       +        count = 0
                for items in histories:
       +            count += 1
                    conf, icon, date_time, address, amount, balance, tx = items
                    ri = RecentActivityItem()
                    ri.icon = icon
                    ri.date = date_time
       +            mintimestr = date_time.split()[0]
                    ri.address = address
       -            ri.amount = amount
       -            ri.quote_text = create_quote_text(
       -                                Decimal(amount)/100000000, mode='symbol')
       +            ri.amount = amount.strip()
       +            ri.quote_text = get_history_rate(ref(ri),
       +                                             Decimal(amount),
       +                                             mintimestr)
                    ri.balance = balance
                    ri.confirmations = conf
                    ri.tx_hash = tx
                    history_add(ri)
       +            if count == 8 and not see_all:
       +                break
       +
       +        history_card.ids.btn_see_all.opacity = (0 if count < 8 else 1)
        
            def update_receive_tab(self):
                #TODO move to address managment
       t@@ -590,24 +721,45 @@ class ElectrumWindow(App):
                receive_list.content_adapter.data = data
        
            def update_contacts_tab(self):
       -        data = []
       +        contact_list = self.root.main_screen.ids.tabs.ids.\
       +            screen_contacts.ids.contact_container
       +        #contact_list.clear_widgets()
       +
       +        child = -1
       +        children = contact_list.children
                for address in self.wallet.addressbook:
                    label = self.wallet.labels.get(address, '')
       -            item = (address, label, "%d" % self.wallet.get_num_tx(address))
       -            data.append(item)
       -            # item.setFont(0, QFont(MONOSPACE_FONT))
       -            # # 32 = label can be edited (bool)
       -            # item.setData(0,32, True)
       -            # # 33 = payto string
       -            # item.setData(0,33, address)
       +            child += 1
       +            try:
       +                if children[child].label == label:
       +                    continue
       +            except IndexError:
       +                pass
       +            tx = self.wallet.get_num_tx(address)
       +            ci = Factory.ContactItem()
       +            ci.address = address
       +            ci.label = label
       +            ci.tx_amount = tx
       +            contact_list.add_widget(ci)
       +
       +        #self.run_hook('update_contacts_tab')
       +
       +    def set_pay_from(self, l):
       +        #TODO
       +        return
       +        self.pay_from = l
       +        self.from_list.clear()
       +        self.from_label.setHidden(len(self.pay_from) == 0)
       +        self.from_list.setHidden(len(self.pay_from) == 0)
       +        for addr in self.pay_from:
       +            c, u = self.wallet.get_addr_balance(addr)
       +            balance = self.format_amount(c + u)
       +            self.from_list.addTopLevelItem(QTreeWidgetItem( [addr, balance] ))
        
       -        self.run_hook('update_contacts_tab')
        
       -        contact_list = app.root.main_screen.ids.tabs.ids.\
       -            screen_contacts.ids.contacts_list
       -        contact_list.content_adapter.data = data
        
            def update_completions(self):
       +        #TODO: check and remove if not used
                l = []
                for addr, label in self.wallet.labels.items():
                    if addr in self.wallet.addressbook:
       t@@ -616,19 +768,134 @@ class ElectrumWindow(App):
                #self.run_hook('update_completions', l)
                self.completions = l
        
       +    def protected(func):
       +        return lambda s, *args, **kwargs: s.do_protect(func, args, **kwargs)
       +
       +    def do_protect(self, func, **kwargs):
       +        print kwargs
       +        instance = kwargs.get('instance', None)
       +        password = kwargs.get('password', None)
       +        message = kwargs.get('message', '')
       +
       +        def run_func(instance=None, password=None):
       +            args = (self, instance, password)
       +            apply(func, args)
       +
       +        if self.wallet.use_encryption:
       +            return self.password_required_dialog(post_ok=run_func, message=message)
       +
       +        return run_func()
       +
       +    def do_send(self):
       +        app = App.get_running_app()
       +        screen_send = app.root.main_screen.ids.tabs.ids.screen_send
       +        scrn = screen_send.content.ids
       +        label = unicode(scrn.message_e.text)
       +        # TODO
       +        #if self.gui_object.payment_request:
       +        #    outputs = self.gui_object.payment_request.outputs
       +        #    amount = self.gui_object.payment_request.get_amount()
       +        #else:
       +
       +        r = unicode(scrn.payto_e.text).strip()
       +
       +        # label or alias, with address in brackets
       +        global re
       +        if not re:
       +            import re
       +        m = re.match('(.*?)\s*\<([1-9A-HJ-NP-Za-km-z]{26,})\>', r)
       +        to_address = m.group(2) if m else r
       +
       +        global is_valid
       +        if not is_valid:
       +            from electrum.bitcoin import is_valid
       +
       +        if not is_valid(to_address):
       +            app.show_error(_('Invalid Bitcoin Address') +
       +                                            ':\n' + to_address)
       +            return
       +
       +        try:
       +            amount = self.read_amount(unicode(scrn.amount_e.text))
       +        except Exception:
       +            app.show_error(_('Invalid Amount'))
       +            return
       +        try:
       +            fee = self.read_amount(unicode(scrn.fee_e.amt))
       +        except Exception as err:
       +            print err
       +            app.show_error(_('Invalid Fee'))
       +            return
       +
       +        from pudb import set_trace; set_trace()
       +        message = 'sending {} {} to {}'.format(\
       +            app.base_unit, scrn.amount_e.text, r)
       +
       +        confirm_fee = self.config.get('confirm_fee', 100000)
       +        if fee >= confirm_fee:
       +            if not self.question(_("The fee for this transaction seems unusually high.\nAre you really sure you want to pay %(fee)s in fees?")%{ 'fee' : self.format_amount(fee) + ' '+ self.base_unit()}):
       +                return
       +
       +        self.send_tx(to_address, amount, fee, label)
       +
       +    @protected
       +    def send_tx(self, outputs, fee, label, password):
       +
       +        # first, create an unsigned tx 
       +        domain = self.get_payment_sources()
       +        try:
       +            tx = self.wallet.make_unsigned_transaction(outputs, fee, None, domain)
       +            tx.error = None
       +        except Exception as e:
       +            traceback.print_exc(file=sys.stdout)
       +            self.show_info(str(e))
       +            return
       +
       +        # call hook to see if plugin needs gui interaction
       +        #run_hook('send_tx', tx)
       +
       +        # sign the tx
       +        def sign_thread():
       +            time.sleep(0.1)
       +            keypairs = {}
       +            self.wallet.add_keypairs_from_wallet(tx, keypairs, password)
       +            self.wallet.sign_transaction(tx, keypairs, password)
       +            return tx, fee, label
       +
       +        def sign_done(tx, fee, label):
       +            if tx.error:
       +                self.show_info(tx.error)
       +                return
       +            if tx.requires_fee(self.wallet.verifier) and fee < MIN_RELAY_TX_FEE:
       +                self.show_error(_("This transaction requires a higher fee, or "
       +                                  "it will not be propagated by the network."))
       +                return
       +            if label:
       +                self.wallet.set_label(tx.hash(), label)
       +
       +            if not self.gui_object.payment_request:
       +                if not tx.is_complete() or self.config.get('show_before_broadcast'):
       +                    self.show_transaction(tx)
       +                    return
       +
       +            self.broadcast_transaction(tx)
       +
       +        WaitingDialog(self, 'Signing..').start(sign_thread, sign_done)
       +
            def notify_transactions(self, *dt):
                '''
                '''
                if not self.network or not self.network.is_connected():
                    return
        
       -        iface = self.network.interface
       -        if len(iface.pending_transactions_for_notifications) > 0:
       +        iface = self.network
       +        ptfn = iface.pending_transactions_for_notifications
       +        if len(ptfn) > 0:
                    # Combine the transactions if there are more then three
       -            tx_amount = len(iface.pending_transactions_for_notifications)
       +            tx_amount = len(ptfn)
                    if(tx_amount >= 3):
                        total_amount = 0
       -                for tx in iface.pending_transactions_for_notifications:
       +                for tx in ptfn:
                            is_relevant, is_mine, v, fee = self.wallet.get_tx_value(tx)
                            if(v > 0):
                                total_amount += v
       t@@ -645,11 +912,18 @@ class ElectrumWindow(App):
                              iface.pending_transactions_for_notifications.remove(tx)
                              is_relevant, is_mine, v, fee = self.wallet.get_tx_value(tx)
                              if(v > 0):
       -                          from pudb import set_trace; set_trace()
                                  self.notify(
       -                              _("New transaction received. {amount}s {unit}s").
       +                              _("{} new transaction received. {amount}s {unit}s").
                                      format( amount=self.format_amount(v),
       -                                     unit=self.base_unit()))
       +                                     unit=self.base_unit))
       +
       +    def copy(self, text):
       +        ''' Copy provided text to clipboard
       +        '''
       +        if not self._clipboard:
       +            from kivy.core.clipboard import Clipboard
       +            self._clipboard = Clipboard
       +        self._clipboard.put(text, 'text/plain')
        
            def notify(self, message):
                try:
       t@@ -668,31 +942,42 @@ class ElectrumWindow(App):
                '''
                '''
                # pause nfc
       -        # pause qrscanner(Camera) if active
       +        if self.qrscanner:
       +            self.qrscanner.stop()
       +        if self.nfcscanner:
       +            self.nfcscanner.nfc_disable()
                return True
        
            def on_resume(self):
                '''
                '''
       -        # resume nfc
       -        # resume camera if active
       -        pass
       +        if self.qrscanner and qrscanner.get_parent_window():
       +            self.qrscanner.start()
       +        if self.nfcscanner:
       +            self.nfcscanner.nfc_enable()
        
            def on_size(self, instance, value):
                width, height = value
                self._orientation = 'landscape' if width > height else 'portrait'
       +
       +        global inch
       +        if not inch:
       +            from kivy.metrics import inch
       +
                self._ui_mode = 'tablet' if min(width, height) > inch(3.51) else 'phone'
                Logger.debug('orientation: {} ui_mode: {}'.format(self._orientation,
                                                                  self._ui_mode))
        
       -    def load_screen(self, index=0, direction='left', manager=None):
       +    def load_screen(self, index=0, direction='left', manager=None, switch=True):
                ''' Load the appropriate screen as mentioned in the parameters.
                '''
                manager = manager or self.root.manager
       -        screen = Builder.load_file('gui/kivy/ui_screens/'\
       +        screen = Builder.load_file('gui/kivy/uix/ui_screens/'\
                    + self.screens[index] + '.kv')
                screen.name = self.screens[index]
       -        manager.switch_to(screen, direction=direction)
       +        if switch:
       +            manager.switch_to(screen, direction=direction)
       +        return screen
        
            def load_next_screen(self):
                '''
       t@@ -705,7 +990,7 @@ class ElectrumWindow(App):
                    self.load_screen()
        
            def load_previous_screen(self):
       -        '''
       +        ''' Load the previous screen from disk.
                '''
                manager = root.manager
                try:
       t@@ -715,51 +1000,239 @@ class ElectrumWindow(App):
                except IndexError:
                    pass
        
       -    def show_error(self, error,
       -                   width='200dp',
       -                   pos=None,
       -                   arrow_pos=None,
       -                   exit=False,
       -                   icon='atlas://gui/kivy/theming/light/error',
       -                   duration=0,
       -                   modal=False):
       +    def save_new_contact(self, address, label):
       +        address = unicode(address)
       +        label = unicode(label)
       +        global is_valid
       +        if not is_valid:
       +            from electrum.bitcoin import is_valid
       +
       +
       +        if is_valid(address):
       +            if label:
       +                self.set_label(address, text=label)
       +            self.wallet.add_contact(address)
       +            self.update_contacts_tab()
       +            self.update_history_tab()
       +            self.update_completions()
       +        else:
       +            self.show_error(_('Invalid Address'))
       +
       +    def send_payment(self, address, amount=0, label='', message=''):
       +        tabs = self.tabs
       +        screen_send = tabs.ids.screen_send
       +
       +        if label and self.wallet.labels.get(address) != label:
       +            #if self.question('Give label "%s" to address %s ?'%(label,address)):
       +            if address not in self.wallet.addressbook and not self.wallet.  is_mine(address):
       +                self.wallet.addressbook.append(address)
       +            self.wallet.set_label(address, label)
       +
       +        # switch_to the send screen
       +        tabs.ids.panel.switch_to(tabs.ids.tab_send)
       +
       +        label = self.wallet.labels.get(address)
       +        m_addr = label + '  <'+ address +'>' if label else address
       +
       +        # populate
       +        def set_address(*l):
       +            content = screen_send.content.ids
       +            content.payto_e.text = m_addr
       +            content.message_e.text = message
       +            if amount:
       +                content.amount_e.text = amount
       +
       +        # wait for screen to load
       +        Clock.schedule_once(set_address, .5)
       +
       +    def set_send(self, address, amount, label, message):
       +        self.send_payment(address, amount=amount, label=label, message=message)
       +
       +    def prepare_for_payment_request(self):
       +        tabs = self.tabs
       +        screen_send = tabs.ids.screen_send
       +
       +        # switch_to the send screen
       +        tabs.ids.panel.switch_to(tabs.ids.tab_send)
       +
       +        content = screen_send.content.ids
       +        if content:
       +            self.set_frozen(content, False)
       +        screen_send.screen_label.text = _("please wait...")
       +        return True
       +
       +    def payment_request_ok(self):
       +        tabs = self.tabs
       +        screen_send = tabs.ids.screen_send
       +
       +        # switch_to the send screen
       +        tabs.ids.panel.switch_to(tabs.ids.tab_send)
       +
       +        content = screen_send.content
       +        self.set_frozen(content, True)
       +
       +        content.ids.payto_e.text = self.gui_object.payment_request.domain
       +        content.ids.amount_e.text = self.format_amount(self.gui_object.payment_request.get_amount())
       +        content.ids.message_e.text = self.gui_object.payment_request.memo
       +
       +        # wait for screen to load
       +        Clock.schedule_once(set_address, .5)
       +
       +    def do_clear(self):
       +        tabs = self.tabs
       +        screen_send = tabs.ids.screen_send
       +        content = screen_send.ids.content
       +        cts = content.ids
       +        cts.payto_e.text = cts.message_e.text = cts.amount_e.text = \
       +            cts.fee_e.text = ''
       +
       +        self.set_frozen(content, False)
       +
       +        self.set_pay_from([])
       +        self.update_status()
       +
       +    def set_frozen(self, entry, frozen):
       +        if frozen:
       +            entry.disabled = True
       +            Factory.Animation(opacity=0).start(content)
       +        else:
       +            entry.disabled = False
       +            Factory.Animation(opacity=1).start(content)
       +
       +    def set_addrs_frozen(self,addrs,freeze):
       +        for addr in addrs:
       +            if not addr: continue
       +            if addr in self.wallet.frozen_addresses and not freeze:
       +                self.wallet.unfreeze(addr)
       +            elif addr not in self.wallet.frozen_addresses and freeze:
       +                self.wallet.freeze(addr)
       +        self.update_receive_tab()
       +
       +    def payment_request_error(self):
       +        tabs = self.tabs
       +        screen_send = tabs.ids.screen_send
       +
       +        # switch_to the send screen
       +        tabs.ids.panel.switch_to(tabs.ids.tab_send)
       +
       +        self.do_clear()
       +        self.show_info(self.gui_object.payment_request.error)
       +
       +    def encode_uri(self, addr, amount=0, label='',
       +                   message='', size='', currency='btc'):
       +        ''' Convert to BIP0021 compatible URI
       +        '''
       +        uri = 'bitcoin:{}'.format(addr)
       +        first = True
       +        if amount:
       +            uri += '{}amount={}'.format('?' if first else '&', amount)
       +            first = False
       +        if label:
       +            uri += '{}label={}'.format('?' if first else '&', label)
       +            first = False
       +        if message:
       +            uri += '{}?message={}'.format('?' if first else '&', message)
       +            first = False
       +        if size:
       +            uri += '{}size={}'.format('?' if not first else '&', size)
       +        return uri
       +
       +    def decode_uri(self, uri):
       +        if ':' not in uri:
       +            # It's just an address (not BIP21)
       +            return {'address': uri}
       +
       +        if '//' not in uri:
       +            # Workaround for urlparse, it don't handle bitcoin: URI properly
       +            uri = uri.replace(':', '://')
       +
       +        try:
       +            uri = urlparse(uri)
       +        except NameError:
       +            # delayed import
       +            from urlparse import urlparse, parse_qs
       +            uri = urlparse(uri)
       +
       +        result = {'address': uri.netloc}
       +
       +        if uri.path.startswith('?'):
       +            params = parse_qs(uri.path[1:])
       +        else:
       +            params = parse_qs(uri.path)
       +
       +        for k,v in params.items():
       +            if k in ('amount', 'label', 'message', 'size'):
       +                result[k] = v[0]
       +
       +        return result
       +
       +    def delete_imported_key(self, addr):
       +        self.wallet.delete_imported_key(addr)
       +        self.update_receive_tab()
       +        self.update_history_tab()
       +
       +    def delete_pending_account(self, k):
       +        self.wallet.delete_pending_account(k)
       +        self.update_receive_tab()
       +
       +    def get_sendable_balance(self):
       +        return sum(sum(self.wallet.get_addr_balance(a))
       +                   for a in self.get_payment_sources())
       +
       +
       +    def get_payment_sources(self):
       +        if self.pay_from:
       +            return self.pay_from
       +        else:
       +            return self.wallet.get_account_addresses(self.current_account)
       +
       +
       +    def send_from_addresses(self, addrs):
       +        self.set_pay_from( addrs )
       +        tabs = self.tabs
       +        screen_send = tabs.ids.screen_send
       +        self.tabs.setCurrentIndex(1)
       +
       +
       +    def payto(self, addr):
       +        if not addr:
       +            return
       +        label = self.wallet.labels.get(addr)
       +        m_addr = label + '  <' + addr + '>' if label else addr
       +        self.tabs.setCurrentIndex(1)
       +        self.payto_e.setText(m_addr)
       +        self.amount_e.setFocus()
       +
       +
       +    def delete_contact(self, x):
       +        if self.question(_("Do you want to remove") +
       +                         " %s "%x +
       +                         _("from your list of contacts?")):
       +            self.wallet.delete_contact(x)
       +            self.wallet.set_label(x, None)
       +            self.update_history_tab()
       +            self.update_contacts_tab()
       +            self.update_completions()
       +
       +    def show_error(self, error, width='200dp', pos=None, arrow_pos=None,
       +        exit=False, icon='atlas://gui/kivy/theming/light/error', duration=0,
       +        modal=False):
                ''' Show a error Message Bubble.
                '''
       -        self.show_info_bubble(
       -                    text=error,
       -                    icon=icon,
       -                    width=width,
       -                    pos=pos or Window.center,
       -                    arrow_pos=arrow_pos,
       -                    exit=exit,
       -                    duration=duration,
       -                    modal=modal)
       -
       -    def show_info(self, error,
       -                   width='200dp',
       -                   pos=None,
       -                   arrow_pos=None,
       -                   exit=False,
       -                   duration=0,
       -                   modal=False):
       +        self.show_info_bubble( text=error, icon=icon, width=width,
       +            pos=pos or Window.center, arrow_pos=arrow_pos, exit=exit,
       +            duration=duration, modal=modal)
       +
       +    def show_info(self, error, width='200dp', pos=None, arrow_pos=None,
       +        exit=False, duration=0, modal=False):
                ''' Show a Info Message Bubble.
                '''
                self.show_error(error, icon='atlas://gui/kivy/theming/light/error',
       -                        duration=duration,
       -                        modal=modal,
       -                        exit=exit,
       -                        pos=pos,
       -                        arrow_pos=arrow_pos)
       -
       -    def show_info_bubble(self,
       -                    text=_('Hello World'),
       -                    pos=(0, 0),
       -                    duration=0,
       -                    arrow_pos='bottom_mid',
       -                    width=None,
       -                    icon='',
       -                    modal=False,
       -                    exit=False):
       +            duration=duration, modal=modal, exit=exit, pos=pos,
       +            arrow_pos=arrow_pos)
       +
       +    def show_info_bubble(self, text=_('Hello World'), pos=None, duration=0,
       +        arrow_pos='bottom_mid', width=None, icon='', modal=False, exit=False):
                '''Method to show a Information Bubble
        
                .. parameters::
       t@@ -769,13 +1242,13 @@ class ElectrumWindow(App):
                    width: width of the Bubble
                    arrow_pos: arrow position for the bubble
                '''
       -
                info_bubble = self.info_bubble
                if not info_bubble:
       -            info_bubble = self.info_bubble = InfoBubble()
       +            info_bubble = self.info_bubble = Factory.InfoBubble()
        
       +        win = Window
                if info_bubble.parent:
       -            Window.remove_widget(info_bubble
       +            win.remove_widget(info_bubble
                                         if not info_bubble.modal else
                                         info_bubble._modal_view)
        
       t@@ -794,7 +1267,6 @@ class ElectrumWindow(App):
                    info_bubble.show_arrow = False
                    img.allow_stretch = True
                    info_bubble.dim_background = True
       -            pos = (Window.center[0], Window.center[1] - info_bubble.center[1])
                    info_bubble.background_image = 'atlas://gui/kivy/theming/light/card'
                else:
                    info_bubble.fs = False
       t@@ -805,4 +1277,6 @@ class ElectrumWindow(App):
                    info_bubble.dim_background = False
                    info_bubble.background_image = 'atlas://data/images/defaulttheme/bubble'
                info_bubble.message = text
       -        info_bubble.show(pos, duration, width, modal=modal, exit=exit)
       +        if not pos:
       +                pos = (win.center[0], win.center[1] - (info_bubble.height/2))
       +        info_bubble.show(pos, duration, width, modal=modal, exit=exit)
       +\ No newline at end of file
   DIR diff --git a/gui/kivy/plugins/exchange_rate.py b/gui/kivy/plugins/exchange_rate.py
       t@@ -6,13 +6,18 @@ This module is responsible for getting the conversion rates from different
        bitcoin exchanges.
        '''
        
       +import decimal
       +import json
       +
        from kivy.network.urlrequest import UrlRequest
        from kivy.event import EventDispatcher
        from kivy.properties import (OptionProperty, StringProperty, AliasProperty,
            ListProperty)
        from kivy.clock import Clock
       -import decimal
       -import json
       +from kivy.cache import Cache
       +
       +# Register local cache
       +Cache.register('history_rate', timeout=220)
        
        EXCHANGES = ["BitcoinAverage",
                     "BitcoinVenezuela",
       t@@ -25,27 +30,32 @@ EXCHANGES = ["BitcoinAverage",
                     "LocalBitcoins",
                     "Winkdex"]
        
       +HISTORY_EXCHNAGES = ['Coindesk',
       +                     'Winkdex',
       +                     'BitcoinVenezuela']
       +
        
        class Exchanger(EventDispatcher):
            ''' Provide exchanges rate between crypto and different national
            currencies. See Module Documentation for details.
            '''
        
       -    symbols = {'ALL': 'Lek', 'AED': 'د.إ', 'AFN':'؋', 'ARS': '$', 'AMD': '֏',
       -        'AWG': 'ƒ', 'ANG': 'ƒ', 'AOA': 'Kz', 'BDT': '৳', 'BHD': 'BD',
       -        'BIF': 'FBu', 'BTC': 'BTC', 'BTN': 'Nu', 'CDF': 'FC', 'CHF': 'CHF',
       -        'CLF': 'UF', 'CLP':'$', 'CVE': '$', 'DJF':'Fdj', 'DZD': 'دج',
       -        'AUD': '$', 'AZN': 'ман', 'BSD': '$', 'BBD': '$', 'BYR': 'p', 'CRC': '₡',
       -        'BZD': 'BZ$', 'BMD': '$', 'BOB': '$b', 'BAM': 'KM', 'BWP': 'P',
       -        'BGN': 'лв', 'BRL': 'R$', 'BND': '$', 'KHR': '៛', 'CAD': '$',
       -        'ERN': 'Nfk', 'ETB': 'Br', 'KYD': '$', 'USD': '$', 'CLP': '$',
       -        'HRK': 'kn', 'CUP':'₱', 'CZK': 'Kč', 'DKK': 'kr', 'DOP': 'RD$',
       -        'XCD': '$', 'EGP': '£', 'SVC': '$' , 'EEK': 'kr', 'EUR': '€',
       -        'FKP': '£', 'FJD': '$', 'GHC': '¢', 'GIP': '£', 'GTQ': 'Q', 'GBP': '£',
       -        'GYD': '$', 'HNL': 'L', 'HKD': '$', 'HUF': 'Ft', 'ISK': 'kr',
       -        'INR': '₹', 'IDR': 'Rp', 'IRR': '﷼', 'IMP': '£', 'ILS': '₪', 'COP': '$',
       -        'JMD': 'J$', 'JPY': '¥', 'JEP': '£', 'KZT': 'лв', 'KPW': '₩',
       -        'KRW': '₩', 'KGS': 'лв', 'LAK': '₭', 'LVL': 'Ls', 'CNY': '¥'}
       +    symbols = {'ALL': u'Lek', 'AED': u'د.إ', 'AFN':u'؋', 'ARS': u'$',
       +        'AMD': u'֏', 'AWG': u'ƒ', 'ANG': u'ƒ', 'AOA': u'Kz', 'BDT': u'৳',
       +        'BHD': u'BD', 'BIF': u'FBu', 'BTC': u'BTC', 'BTN': u'Nu', 'CDF': u'FC',
       +        'CHF': u'CHF', 'CLF': u'UF', 'CLP':u'$', 'CVE': u'$', 'DJF':u'Fdj',
       +        'DZD': u'دج', 'AUD': u'$', 'AZN': u'ман', 'BSD': u'$', 'BBD': u'$',
       +        'BYR': u'p', 'CRC': u'₡', 'BZD': u'BZ$', 'BMD': u'$', 'BOB': u'$b',
       +        'BAM': u'KM', 'BWP': u'P', 'BGN': 'uлв', 'BRL': u'R$', 'BND': u'$',
       +        'KHR': u'៛', 'CAD': u'$', 'ERN': u'Nfk', 'ETB': u'Br', 'KYD': u'$',
       +        'USD': u'$', 'CLP': u'$', 'HRK': u'kn', 'CUP': u'₱', 'CZK': u'Kč',
       +        'DKK': u'kr', 'DOP': u'RD$', 'XCD': u'$', 'EGP': u'£', 'SVC': u'$' ,
       +        'EEK': u'kr', 'EUR': u'€', u'FKP': u'£', 'FJD': u'$', 'GHC': u'¢',
       +        'GIP': u'£', 'GTQ': u'Q', 'GBP': u'£', 'GYD': u'$', 'HNL': u'L',
       +        'HKD': u'$', 'HUF': u'Ft', 'ISK': u'kr', 'INR': u'₹', 'IDR': u'Rp',
       +        'IRR': u'﷼', 'IMP': '£', 'ILS': '₪', 'COP': '$', 'JMD': u'J$',
       +        'JPY': u'¥', 'JEP': u'£', 'KZT': u'лв', 'KPW': u'₩', 'KRW': u'₩',
       +        'KGS': u'лв', 'LAK': u'₭', 'LVL': u'Ls', 'CNY': u'¥'}
        
            _use_exchange = OptionProperty('Blockchain', options=EXCHANGES)
            '''This is the exchange to be used for getting the currency exchange rates
       t@@ -56,23 +66,16 @@ class Exchanger(EventDispatcher):
            '''
        
            def _set_currency(self, value):
       -        exchanger = self.exchanger
       +        value = str(value)
                if self.use_exchange == 'CoinDesk':
                    self._update_cd_currency(self.currency)
                    return
       -        try:
       -            self._currency = value
       -            self.electrum_cinfig.set_key('currency', value, True)
       -        except AttributeError:
       -            self._currency = 'EUR'
       +        self._currency = value
       +        self.parent.electrum_config.set_key('currency', value, True)
        
            def _get_currency(self):
       -        try:
       -            self._currency = self.electrum_config.get('currency', 'EUR')
       -        except AttributeError:
       -            pass
       -        finally:
       -            return self._currency
       +        self._currency = self.parent.electrum_config.get('currency', 'EUR')
       +        return self._currency
        
            currency = AliasProperty(_get_currency, _set_currency, bind=('_currency',))
        
       t@@ -104,6 +107,7 @@ class Exchanger(EventDispatcher):
                self.parent = parent
                self.quote_currencies = None
                self.exchanges = EXCHANGES
       +        self.history_exchanges = HISTORY_EXCHNAGES
        
            def exchange(self, btc_amount, quote_currency):
                if self.quote_currencies is None:
       t@@ -115,10 +119,40 @@ class Exchanger(EventDispatcher):
        
                return btc_amount * decimal.Decimal(quote_currencies[quote_currency])
        
       +    def get_history_rate(self, item, btc_amt, mintime, maxtime):
       +        def on_success(request, response):
       +            response = json.loads(response)
       +
       +            try:
       +                hrate = response['bpi'][mintime]
       +                hrate = abs(btc_amt) * decimal.Decimal(hrate)
       +                Cache.append('history_rate', uid, hrate)
       +            except KeyError:
       +                hrate = 'not found'
       +
       +            self.parent.set_history_rate(item, hrate)
       +
       +        # Check local cache before getting data from remote
       +        exchange = 'coindesk'
       +        uid = '{}:{}'.format(exchange, mintime)
       +        hrate = Cache.get('history_rate', uid)
       +
       +        if hrate:
       +            return hrate
       +
       +        req = UrlRequest(url='https://api.coindesk.com/v1/bpi/historical'
       +                         '/close.json?start={}&end={}'
       +                         .format(mintime, maxtime)
       +            ,on_success=on_success, timeout=15)
       +        return None
       +
            def update_rate(self, dt):
                ''' This is called from :method:`start` every X seconds; to update the
                rates for currencies for the currently selected exchange.
                '''
       +        if not self.parent.network or not self.parent.network.is_connected():
       +            return
       +
                update_rates = {
                    "BitcoinAverage": self.update_ba,
                    "BitcoinVenezuela": self.update_bv,
       t@@ -268,7 +302,7 @@ class Exchanger(EventDispatcher):
                        for r in response:
                            quote_currencies[r] = _lookup_rate(response, r)
                        self.quote_currencies = quote_currencies
       -            except KeyError:
       +            except KeyError, TypeError:
                        pass
                    self.parent.set_currencies(quote_currencies)
        
       t@@ -329,9 +363,8 @@ class Exchanger(EventDispatcher):
                                timeout=5)
        
            def start(self):
       -        # check rates every few seconds
                self.update_rate(0)
       -        # check every few seconds
       +        # check every 20 seconds
                Clock.unschedule(self.update_rate)
                Clock.schedule_interval(self.update_rate, 20)
        
   DIR diff --git a/gui/kivy/qr_scanner/__init__.py b/gui/kivy/qr_scanner/__init__.py
       t@@ -7,69 +7,23 @@ from collections import namedtuple
        
        from kivy.uix.anchorlayout import AnchorLayout
        from kivy.core import core_select_lib
       +from kivy.metrics import dp
        from kivy.properties import ListProperty, BooleanProperty
        from kivy.factory import Factory
        
        
       -def encode_uri(addr, amount=0, label='', message='', size='',
       -            currency='btc'):
       -    ''' Convert to BIP0021 compatible URI
       -    '''
       -    uri = 'bitcoin:{}'.format(addr)
       -    first = True
       -    if amount:
       -        uri += '{}amount={}'.format('?' if first else '&', amount)
       -        first = False
       -    if label:
       -        uri += '{}label={}'.format('?' if first else '&', label)
       -        first = False
       -    if message:
       -        uri += '{}?message={}'.format('?' if first else '&', message)
       -        first = False
       -    if size:
       -        uri += '{}size={}'.format('?' if not first else '&', size)
       -    return uri
       -
       -def decode_uri(uri):
       -    if ':' not in uri:
       -        # It's just an address (not BIP21)
       -        return {'address': uri}
       -
       -    if '//' not in uri:
       -        # Workaround for urlparse, it don't handle bitcoin: URI properly
       -        uri = uri.replace(':', '://')
       -
       -    try:
       -        uri = urlparse(uri)
       -    except NameError:
       -        # delayed import
       -        from urlparse import urlparse, parse_qs
       -        uri = urlparse(uri)
       -
       -    result = {'address': uri.netloc} 
       -
       -    if uri.path.startswith('?'):
       -        params = parse_qs(uri.path[1:])
       -    else:
       -        params = parse_qs(uri.path)
       -
       -    for k,v in params.items():
       -        if k in ('amount', 'label', 'message', 'size'):
       -            result[k] = v[0]
       -
       -    return result
       -
       -
        class ScannerBase(AnchorLayout):
            ''' Base implementation for camera based scanner
            '''
       -    camera_size = ListProperty([320, 240])
       +    camera_size = ListProperty([320, 240] if dp(1) < 2 else [640, 480])
        
            symbols = ListProperty([])
        
            # XXX can't work now, due to overlay.
            show_bounds = BooleanProperty(False)
        
       +    running = BooleanProperty(False)
       +
            Qrcode = namedtuple('Qrcode',
                    ['type', 'data', 'bounds', 'quality', 'count'])
        
   DIR diff --git a/gui/kivy/qr_scanner/scanner_android.py b/gui/kivy/qr_scanner/scanner_android.py
       t@@ -88,7 +88,7 @@ class SurfaceHolderCallback(PythonJavaClass):
            def __init__(self, callback):
                super(SurfaceHolderCallback, self).__init__()
                self.callback = callback
       - 
       +
            @java_method('(Landroid/view/SurfaceHolder;III)V')
            def surfaceChanged(self, surface, fmt, width, height):
                self.callback(fmt, width, height)
       t@@ -96,7 +96,7 @@ class SurfaceHolderCallback(PythonJavaClass):
            @java_method('(Landroid/view/SurfaceHolder;)V')
            def surfaceCreated(self, surface):
                pass
       - 
       +
            @java_method('(Landroid/view/SurfaceHolder;)V')
            def surfaceDestroyed(self, surface):
                pass
       t@@ -170,6 +170,7 @@ class AndroidCamera(Widget):
        
            @run_on_ui_thread
            def stop(self):
       +        self.running = False
                if self._android_camera is None:
                    return
                self._android_camera.setPreviewCallback(None)
       t@@ -179,6 +180,7 @@ class AndroidCamera(Widget):
        
            @run_on_ui_thread
            def start(self):
       +        self.running = True
                if self._android_camera is not None:
                    return
        
       t@@ -196,6 +198,9 @@ class AndroidCamera(Widget):
                # attach the android surfaceview to our android widget holder
                self._holder.view = self._android_surface
        
       +        # set orientation
       +        self._android_camera.setDisplayOrientation(90)
       +
            def _on_surface_changed(self, fmt, width, height):
                # internal, called when the android SurfaceView is ready
                # FIXME if the size is not handled by the camera, it will failed.
   DIR diff --git a/gui/kivy/qrcodewidget.py b/gui/kivy/qrcodewidget.py
       t@@ -1,179 +0,0 @@
       -''' Kivy Widget that accepts data and displas qrcode
       -'''
       -
       -from threading import Thread
       -from functools import partial
       -
       -from kivy.uix.floatlayout import FloatLayout
       -
       -from kivy.graphics.texture import Texture
       -from kivy.properties import StringProperty
       -from kivy.properties import ObjectProperty, StringProperty, ListProperty,\
       -    BooleanProperty
       -from kivy.lang import Builder
       -from kivy.clock import Clock
       -
       -try:
       -    import qrcode
       -except ImportError:
       -    sys.exit("Error: qrcode does not seem to be installed. Try 'sudo pip install qrcode'")
       -
       -
       -
       -Builder.load_string('''
       -<QRCodeWidget>
       -    on_parent: if args[1]: qrimage.source = self.loading_image
       -    canvas.before:
       -        # Draw white Rectangle
       -        Color:
       -            rgba: root.background_color
       -        Rectangle:
       -            size: self.size
       -            pos: self.pos
       -    canvas.after:
       -        Color:
       -            rgba: .5, .5, .5, 1 if root.show_border else 0
       -        Line:
       -            width: dp(1.333)
       -            points:
       -                dp(2), dp(2),\
       -                self.width - dp(2), dp(2),\
       -                self.width - dp(2), self.height - dp(2),\
       -                dp(2), self.height - dp(2),\
       -                dp(2), dp(2)
       -    Image
       -        id: qrimage
       -        pos_hint: {'center_x': .5, 'center_y': .5}
       -        allow_stretch: True
       -        size_hint: None, None
       -        size: root.width * .9, root.height * .9
       -''')
       -
       -class QRCodeWidget(FloatLayout):
       -
       -    show_border = BooleanProperty(True)
       -    '''Whether to show border around the widget.
       -
       -    :data:`show_border` is a :class:`~kivy.properties.BooleanProperty`,
       -    defaulting to `True`.
       -    '''
       -
       -    data = StringProperty(None, allow_none=True)
       -    ''' Data using which the qrcode is generated.
       -
       -    :data:`data` is a :class:`~kivy.properties.StringProperty`, defaulting to
       -    `None`.
       -    '''
       -
       -    background_color = ListProperty((1, 1, 1, 1))
       -    ''' Background color of the background of the widget.
       -
       -    :data:`background_color` is a :class:`~kivy.properties.ListProperty`,
       -    defaulting to `(1, 1, 1, 1)`.
       -    '''
       -
       -    loading_image = StringProperty('gui/kivy/theming/loading.gif')
       -
       -    def __init__(self, **kwargs):
       -        super(QRCodeWidget, self).__init__(**kwargs)
       -        self.addr = None
       -        self.qr = None
       -        self._qrtexture = None
       -
       -    def on_data(self, instance, value):
       -        if not (self.canvas or value):
       -            return
       -        img = self.ids.get('qrimage', None)
       -
       -        if not img:
       -            # if texture hasn't yet been created delay the texture updation
       -            Clock.schedule_once(lambda dt: self.on_data(instance, value))
       -            return
       -        img.anim_delay = .25
       -        img.source = self.loading_image
       -        Thread(target=partial(self.generate_qr, value)).start()
       -
       -    def generate_qr(self, value):
       -        self.set_addr(value)
       -        self.update_qr()
       -
       -    def set_addr(self, addr):
       -        if self.addr == addr:
       -            return
       -        MinSize = 210 if len(addr) < 128 else 500
       -        self.setMinimumSize((MinSize, MinSize))
       -        self.addr = addr
       -        self.qr = None
       -
       -    def update_qr(self):
       -        if not self.addr and self.qr:
       -            return
       -        QRCode = qrcode.QRCode
       -        L = qrcode.constants.ERROR_CORRECT_L
       -        addr = self.addr
       -        try:
       -            self.qr = qr = QRCode(
       -                version=None,
       -                error_correction=L,
       -                box_size=10,
       -                border=0,
       -                )
       -            qr.add_data(addr)
       -            qr.make(fit=True)
       -        except Exception as e:
       -            print e
       -            self.qr=None
       -        self.update_texture()
       -
       -    def setMinimumSize(self, size):
       -        # currently unused, do we need this?
       -        self._texture_size = size
       -
       -    def _create_texture(self, k, dt):
       -        self._qrtexture = texture = Texture.create(size=(k,k), colorfmt='rgb')
       -        # don't interpolate texture
       -        texture.min_filter = 'nearest'
       -        texture.mag_filter = 'nearest'
       -
       -    def update_texture(self):
       -        if not self.addr:
       -            return
       -
       -        matrix = self.qr.get_matrix()
       -        k = len(matrix)
       -        # create the texture in main UI thread otherwise
       -        # this will lead to memory corruption
       -        Clock.schedule_once(partial(self._create_texture, k), -1)
       -        buff = []
       -        bext = buff.extend
       -        cr, cg, cb, ca = self.background_color[:]
       -        cr, cg, cb = cr*255, cg*255, cb*255
       -
       -        for r in range(k):
       -            for c in range(k):
       -                bext([0, 0, 0] if matrix[r][c] else [cr, cg, cb])
       -
       -        # then blit the buffer
       -        buff = ''.join(map(chr, buff))
       -        # update texture in UI thread.
       -        Clock.schedule_once(lambda dt: self._upd_texture(buff))
       -
       -    def _upd_texture(self, buff):
       -        texture = self._qrtexture
       -        if not texture:
       -            # if texture hasn't yet been created delay the texture updation
       -            Clock.schedule_once(lambda dt: self._upd_texture(buff))
       -            return
       -        texture.blit_buffer(buff, colorfmt='rgb', bufferfmt='ubyte')
       -        img =self.ids.qrimage
       -        img.anim_delay = -1
       -        img.texture = texture
       -        img.canvas.ask_update()
       -
       -if __name__ == '__main__':
       -    from kivy.app import runTouchApp
       -    import sys
       -    data = str(sys.argv[1:])
       -    runTouchApp(QRCodeWidget(data=data))
       -
       -
   DIR diff --git a/gui/kivy/screens.py b/gui/kivy/screens.py
       t@@ -1,105 +0,0 @@
       -from kivy.app import App
       -from kivy.uix.screenmanager import Screen
       -from kivy.properties import ObjectProperty
       -from kivy.clock import Clock
       -
       -
       -class CScreen(Screen):
       -
       -    __events__ = ('on_activate', 'on_deactivate')
       -
       -    action_view = ObjectProperty(None)
       -
       -    def _change_action_view(self):
       -        app = App.get_running_app()
       -        action_bar = app.root.manager.current_screen.ids.action_bar
       -        _action_view = self.action_view
       -
       -        if (not _action_view) or _action_view.parent:
       -            return
       -        action_bar.clear_widgets()
       -        action_bar.add_widget(_action_view)
       -
       -    def on_activate(self):
       -        Clock.schedule_once(lambda dt: self._change_action_view())
       -
       -    def on_deactivate(self):
       -        Clock.schedule_once(lambda dt: self._change_action_view())
       -
       -
       -class ScreenDashboard(CScreen):
       -
       -    tab = ObjectProperty(None)
       -
       -    def show_tx_details(
       -        self, date, address, amount, amount_color, balance,
       -        tx_hash, conf, quote_text):
       -
       -        ra_dialog = RecentActivityDialog()
       -
       -        ra_dialog.address = address
       -        ra_dialog.amount = amount
       -        ra_dialog.amount_color = amount_color
       -        ra_dialog.confirmations = conf
       -        ra_dialog.quote_text = quote_text
       -        date_time = date.split()
       -        if len(date_time) == 2:
       -            ra_dialog.date = date_time[0]
       -            ra_dialog.time = date_time[1]
       -            ra_dialog.status = 'Validated'
       -        else:
       -            ra_dialog.date = date_time
       -            ra_dialog.status = 'Pending'
       -        ra_dialog.tx_hash = tx_hash
       -
       -        app = App.get_running_app()
       -        main_gui = app.gui.main_gui
       -        tx_hash = tx_hash
       -        tx = app.wallet.transactions.get(tx_hash)
       -
       -        if tx_hash in app.wallet.transactions.keys():
       -            is_relevant, is_mine, v, fee = app.wallet.get_tx_value(tx)
       -            conf, timestamp = app.wallet.verifier.get_confirmations(tx_hash)
       -            #if timestamp:
       -            #    time_str = datetime.datetime.fromtimestamp(timestamp).isoformat(' ')[:-3]
       -            #else:
       -            #    time_str = 'pending'
       -        else:
       -            is_mine = False
       -
       -        ra_dialog.is_mine = is_mine
       -
       -        if is_mine:
       -            if fee is not None: 
       -                ra_dialog.fee = main_gui.format_amount(fee)
       -            else:
       -                ra_dialog.fee = 'unknown'
       -
       -        ra_dialog.open()
       -
       -
       -class ScreenPassword(Screen):
       -
       -    __events__ = ('on_release', 'on_deactivate', 'on_activate')
       -
       -    def on_activate(self):
       -        app = App.get_running_app()
       -        action_bar = app.root.main_screen.ids.action_bar
       -        action_bar.add_widget(self._action_view)
       -
       -    def on_deactivate(self):
       -        self.ids.password.text = ''
       -
       -    def on_release(self, *args):
       -        pass
       -
       -class ScreenSend(CScreen):
       -    pass
       -
       -class ScreenReceive(CScreen):
       -    pass
       -
       -class ScreenContacts(CScreen):
       -
       -    def add_new_contact(self):
       -        NewContactDialog().open()
   DIR diff --git a/gui/kivy/statusbar.py b/gui/kivy/statusbar.py
       t@@ -1,7 +0,0 @@
       -from kivy.uix.boxlayout import BoxLayout
       -from kivy.properties import StringProperty
       -
       -
       -class StatusBar(BoxLayout):
       -
       -    text = StringProperty('')
   DIR diff --git a/gui/kivy/textinput.py b/gui/kivy/textinput.py
       t@@ -1,14 +0,0 @@
       -from kivy.uix.textinput import TextInput
       -from kivy.properties import OptionProperty
       -
       -class ELTextInput(TextInput):
       -
       -    def insert_text(self, substring, from_undo=False):
       -        if not from_undo:
       -            if self.input_type == 'numbers':
       -                numeric_list = map(str, range(10))
       -                if '.' not in self.text:
       -                    numeric_list.append('.')
       -                if substring not in numeric_list:
       -                    return
       -        super(ELTextInput, self).insert_text(substring, from_undo=from_undo)
   DIR diff --git a/gui/kivy/theming/light-0.png b/gui/kivy/theming/light-0.png
       Binary files differ.
   DIR diff --git a/gui/kivy/theming/light.atlas b/gui/kivy/theming/light.atlas
       t@@ -1 +1 @@
parazyd.org:70 /git/electrum/commit/c121c1aa4e2d20825d4eafc201144e84df3129dd.gph:4082: line too long