URI: 
       tmerge dashboard back into ui - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit 9938316400ad263ab9bec40e93f7e0b10c2ed9cd
   DIR parent 1179a4cf9e11a41ada5f8dfc006a92c71da3aa8d
  HTML Author: qua-non <akshayaurora@gmail.com>
       Date:   Wed, 19 Mar 2014 10:01:15 +0530
       
       merge dashboard back into ui
       
       Diffstat:
         M gui/kivy/Makefile                   |       4 ++--
         M gui/kivy/carousel.py                |      14 +++-----------
         M gui/kivy/drawer.py                  |       2 +-
         M gui/kivy/main.kv                    |      28 ++++++++++++----------------
         M gui/kivy/main_window.py             |      30 ++++++++++++++++++------------
         M gui/kivy/screens.py                 |     998 +------------------------------
         A gui/kivy/ui_screens/mainscreen.kv   |     287 +++++++++++++++++++++++++++++++
       
       7 files changed, 327 insertions(+), 1036 deletions(-)
       ---
   DIR diff --git a/gui/kivy/Makefile b/gui/kivy/Makefile
       t@@ -7,14 +7,14 @@ theming:
                $(PYTHON) -m kivy.atlas theming/light 1024 theming/light/*.png
        apk:
                # running pre build setup
       -        @cp build/buildozer.spec ../../buildozer.spec
       +        @cp tools/buildozer.spec ../../buildozer.spec
                # get aes.py
                @cd ../..; wget -4 https://raw.github.com/devrandom/slowaes/master/python/aes.py
                # rename electrum to main.py
                @mv ../../electrum ../../main.py
                @-if [ ! -d "../../.buildozer" ];then \
                        cd ../..; buildozer android debug;\
       -                cp -f gui/kivy/build/blacklist.txt .buildozer/android/platform/python-for-android/src/blacklist.txt;\
       +                cp -f gui/kivy/tools/blacklist.txt .buildozer/android/platform/python-for-android/src/blacklist.txt;\
                        rm -rf ./.buildozer/android/platform/python-for-android/dist;\
                fi
                @-cd ../..; buildozer android debug deploy run
   DIR diff --git a/gui/kivy/carousel.py b/gui/kivy/carousel.py
       t@@ -1,7 +1,7 @@
        from kivy.uix.carousel import Carousel
        from kivy.clock import Clock
        
       -class CCarousel(Carousel):
       +class Carousel(Carousel):
        
            def on_touch_move(self, touch):
                if self._get_uid('cavoid') in touch.ud:
       t@@ -29,12 +29,4 @@ class CCarousel(Carousel):
                        diff = touch.dy
        
                    self._offset += diff * 1.27
       -        return True
       -
       -if __name__ == "__main__":
       -    from kivy.app import runTouchApp
       -    from kivy.uix.button import Button
       -    cc = CCarousel()
       -    for i in range(10):
       -        cc.add_widget(Button(text=str(i)))
       -    runTouchApp(cc)
       -\ No newline at end of file
       +        return True
       +\ No newline at end of file
   DIR diff --git a/gui/kivy/drawer.py b/gui/kivy/drawer.py
       t@@ -111,7 +111,7 @@ class Drawer(StencilView):
                ov = self._overlay_widget
                ov.x=min(self._hidden_widget.width,
                    max(ov.x + touch.dx*2, 0))
       -        #_anim = Animation(x=x, duration=1/60)
       +        #_anim = Animation(x=x, duration=1/2, t='in_out_quart')
                #_anim.cancel_all(ov)
                #_anim.start(ov)
        
   DIR diff --git a/gui/kivy/main.kv b/gui/kivy/main.kv
       t@@ -440,27 +440,23 @@ StencilView
                        Rectangle:
                            size: self.size
                            pos: self.pos
       -            canvas.after:
       -                Color
       -                    rgba: 1, 1, 1, 1
       -                BorderImage
       -                    border: 0, 32, 0, 0
       -                    source: 'atlas://gui/kivy/theming/light/shadow_right'
       -                    pos: self.pos
       -                    size: self.size
                    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
       -        ScreenManager:
       -            id: manager
       +        BoxLayout:
                    x: wallet_management.width if app.ui_mode[0] == 't' else 0
       -            size: root.size
       +            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: 2, 2, 2, 23
       -                    size: self.size
       -                    pos: self.x, self.y
       -\ No newline at end of file
       +                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
   DIR diff --git a/gui/kivy/main_window.py b/gui/kivy/main_window.py
       t@@ -7,16 +7,17 @@ from electrum.wallet import format_satoshis
        
        from kivy.app import App
        from kivy.core.window import Window
       -from kivy.metrics import inch
       +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)
        from kivy.clock import Clock
        
        #inclusions for factory so that widgets can be used in kv
       -from gui.kivy.drawer import Drawer
       -from gui.kivy.dialog import InfoBubble
       +from electrum_gui.kivy.drawer import Drawer
       +from electrum_gui.kivy.dialog import InfoBubble
        
        # delayed imports
        notification = None
       t@@ -307,7 +308,8 @@ class ElectrumWindow(App):
                self.completions = []
        
                # setup UX
       -        #self.load_dashboard
       +        self.screens = ['mainscreen']
       +        self.load_screen(index=0)
        
                self.icon = "icons/electrum.png"
        
       t@@ -352,8 +354,8 @@ class ElectrumWindow(App):
                return quote_text
        
            def set_currencies(self, quote_currencies):
       -        #TODO remove this and just directly update a observable property
                self._trigger_update_status()
       +        print quote_currencies
                self.currencies = sorted(quote_currencies.keys())
        
            def update_console(self, *dt):
       t@@ -683,19 +685,22 @@ class ElectrumWindow(App):
                Logger.debug('orientation: {} ui_mode: {}'.format(self._orientation,
                                                                  self._ui_mode))
        
       -    def load_screen(self, index=0, direction='left'):
       -        '''
       +    def load_screen(self, index=0, direction='left', manager=None):
       +        ''' Load the appropriate screen as mentioned in the parameters.
                '''
       -        screen = Builder.load_file('data/screens/' + self.screens[index])
       +        manager = manager or self.root.manager
       +        screen = Builder.load_file('gui/kivy/ui_screens/'\
       +            + self.screens[index] + '.kv')
                screen.name = self.screens[index]
       -        root.manager.switch_to(screen, direction=direction)
       +        manager.switch_to(screen, direction=direction)
        
            def load_next_screen(self):
                '''
                '''
                manager = root.manager
                try:
       -            self.load_screen(self.screens.index(manager.current_screen.name)+1)
       +            self.load_screen(self.screens.index(manager.current_screen.name)+1,
       +                             manager=manager)
                except IndexError:
                    self.load_screen()
        
       t@@ -705,9 +710,10 @@ class ElectrumWindow(App):
                manager = root.manager
                try:
                    self.load_screen(self.screens.index(manager.current_screen.name)-1,
       -                             direction='right')
       +                             direction='right',
       +                             manager=manager)
                except IndexError:
       -            self.load_screen(-1, direction='right')
       +            pass
        
            def show_error(self, error,
                           width='200dp',
   DIR diff --git a/gui/kivy/screens.py b/gui/kivy/screens.py
       t@@ -1,41 +1,7 @@
       -from functools import partial
       -import os, datetime, json, csv
       -
        from kivy.app import App
       -from kivy.animation import Animation
       -from kivy.core.clipboard import Clipboard
       +from kivy.uix.screenmanager import Screen
       +from kivy.properties import ObjectProperty
        from kivy.clock import Clock
       -from kivy.factory import Factory
       -from kivy.metrics import dp
       -from kivy.properties import (ObjectProperty, StringProperty, ListProperty,
       -                            DictProperty)
       -
       -from kivy.uix.button import Button
       -from kivy.uix.bubble import Bubble, BubbleButton
       -from kivy.uix.boxlayout import BoxLayout
       -from kivy.uix.label import Label
       -from kivy.uix.textinput import TextInput
       -from kivy.uix.screenmanager import Screen as Screen, ScreenManager
       -from kivy.uix.tabbedpanel import TabbedPanel
       -
       -
       -from electrum_gui.kivy.dialog import (NewContactDialog, TakeInputDialog,
       -        PrivateKeyDialog, SignVerifyDialog, MessageBox, MessageBoxError,
       -        SaveDialog, LoadDialog, InfoDialog, ImportPrivateKeysDialog, Dialog,
       -        EditLabelDialog, EditDescriptionDialog, ShowMasterPublicKeyDialog,
       -        RecentActivityDialog)
       -
       -from electrum_gui.i18n import _, languages
       -from electrum_gui.kivy.menus import ContextMenu
       -from electrum.interface import DEFAULT_PORTS
       -from electrum.verifier import WalletVerifier
       -from electrum.wallet import Wallet, WalletSynchronizer
       -from electrum.bitcoin import is_valid
       -
       -DEFAULT_PATH = '/tmp/'
       -
       -# Delayed imports
       -encode_uri = None
        
        
        class CScreen(Screen):
       t@@ -46,7 +12,7 @@ class CScreen(Screen):
        
            def _change_action_view(self):
                app = App.get_running_app()
       -        action_bar = app.root.main_screen.ids.action_bar
       +        action_bar = app.root.manager.current_screen.ids.action_bar
                _action_view = self.action_view
        
                if (not _action_view) or _action_view.parent:
       t@@ -61,33 +27,6 @@ class CScreen(Screen):
                Clock.schedule_once(lambda dt: self._change_action_view())
        
        
       -class RootManager(ScreenManager):
       -    '''Main Root Widget of the app'''
       -
       -    # initialize properties that will be updted in kv
       -    main_screen = ObjectProperty(None)
       -    '''Object holding the reference to main screen'''
       -
       -    screen_preferences = ObjectProperty(None)
       -    '''Object holding the reference to preferences screen'''
       -
       -    screen_seed = ObjectProperty(None)
       -    ''''''
       -
       -    screen_network = ObjectProperty(None)
       -    '''Object holding the Network screen'''
       -
       -
       -class MainScreen(Screen):
       -
       -    pass
       -
       -
       -class ScreenSend(CScreen):
       -
       -    pass
       -
       -
        class ScreenDashboard(CScreen):
        
            tab = ObjectProperty(None)
       t@@ -154,942 +93,13 @@ class ScreenPassword(Screen):
            def on_release(self, *args):
                pass
        
       -
       -class SettingsScreen(Screen):
       -
       -    def __init__(self, **kwargs):
       -        super(SettingsScreen, self).__init__(**kwargs)
       -        Clock.schedule_once(self.delayed_init)
       -        self.app = App.get_running_app()
       -
       -    def on_enter(self, *args):
       -        self.delayed_init()
       -
       -    def delayed_init(self, *dt):
       -        app = self.app
       -        try:
       -            main_gui = app.gui.main_gui
       -        except AttributeError:
       -            # wait for main gui to start
       -            Clock.schedule_once(self.delayed_init, 1)
       -            return
       -        ids = self.ids
       -
       -        ids.st_unit_combo.key = main_gui.base_unit()
       -        ids.st_fee_e.text = main_gui.format_amount(app.wallet.fee).strip()
       -        ids.st_expert_cb.active = main_gui.expert_mode
       -
       -        currencies = main_gui.exchanger.get_currencies()
       -        currencies.insert(0, "None")
       -        currencies = zip(currencies, currencies)
       -        key = app.conf.get('currency', 'None')
       -        ids.st_cur_combo.text = ids.st_cur_combo.key = key
       -        ids.st_cur_combo.items = currencies
       -
       -        ids.st_lang_combo.key = key = app.conf.get("language", '')
       -        ids.st_lang_combo.items = languages.items()
       -        x, y = zip(*ids.st_lang_combo.items)
       -        ids.st_lang_combo.text = y[x.index(key)]
       -
       -    def do_callback(self, instance):
       -        ids = self.ids
       -        app = self.app
       -        wallet = app.wallet
       -        main_gui = app.gui.main_gui
       -
       -        if instance == ids.export_labels:
       -            title = _("Select file to save your labels")
       -            path = DEFAULT_PATH
       -            filename = "electrum_labels.dat"
       -            filters = ["*.dat"]
       -
       -            def save(instance):
       -                path = dialog.file_chooser.path
       -                filename = dialog.text_input.text.strip()
       -                labels = wallet.labels
       -                try:
       -                    with open(os.path.join(path, filename), 'w+') as stream:
       -                        json.dump(labels, stream)
       -                    MessageBox(title="Labels exported",
       -                               message=_("Your labels were exported to")\
       -                                   + " '%s'" % str(filename),
       -                               size=('320dp', '320dp')).open()
       -                except (IOError, os.error), reason:
       -                    MessageBoxError(
       -                        title="Unable to export labels",
       -                        message=_("Electrum was unable to export your labels.")+
       -                            "\n" + str(reason), size=('320dp', '320dp')).open()
       -                dialog.close()
       -
       -            dialog = SaveDialog(title=title,
       -                                path=path,
       -                                filename=filename,
       -                                filters=filters)
       -            dialog.save_button.bind(on_release=save)
       -            dialog.open()
       -
       -        elif instance == ids.import_labels:
       -            title = _("Open labels file")
       -            path = DEFAULT_PATH
       -            filename = ""
       -            filters = ["*.dat"]
       -
       -            def load(instance):
       -                path = dialog.file_chooser.path
       -                filename = dialog.text_input.text.strip()
       -
       -                labels = wallet.labels
       -                try:
       -                    with open(os.path.join(path, filename), 'r') as stream:
       -                        for key, value in json.loads(stream.read()).items():
       -                            wallet.labels[key] = value
       -                        wallet.save()
       -                    MessageBox(title="Labels imported",
       -                               message=_("Your labels were imported from") + " '%s'" % str(filename),
       -                               size=('320dp', '320dp')).open()
       -                except (IOError, os.error), reason:
       -                    MessageBoxError(title="Unable to import labels",
       -                                    message=_("Electrum was unable to import your labels.") + "\n" + str(reason),
       -                                    size=('320dp', '320dp')).open()
       -
       -                dialog.close()
       -
       -            dialog = LoadDialog(title=title, path=path, filename=filename, filters=filters)
       -            dialog.load_button.bind(on_press=load)
       -            dialog.open()
       -
       -        elif instance == ids.export_history:
       -            title = _("Select file to export your wallet transactions to")
       -            path = os.path.expanduser('~')
       -            filename = "electrum-history.csv"
       -            filters = ["*.csv"]
       -
       -            def save(instance):
       -                path = dialog.file_chooser.path
       -                filename = dialog.text_input.text.strip()
       -                # extracted from gui_lite.csv_transaction
       -                wallet = wallet
       -                try:
       -                    with open(os.path.join(path, filename), "w+") as stream:
       -                        transaction = csv.writer(stream)
       -                        transaction.writerow(["transaction_hash", "label", "confirmations", "value", "fee", "balance", "timestamp"])
       -                        for item in wallet.get_tx_history():
       -                            tx_hash, confirmations, is_mine, value, fee, balance, timestamp = item
       -                            if confirmations:
       -                                if timestamp is not None:
       -                                    try:
       -                                        time_string = datetime.datetime.fromtimestamp(timestamp).isoformat(' ')[:-3]
       -                                    except [RuntimeError, TypeError, NameError] as reason:
       -                                        time_string = "unknown"
       -                                        pass
       -                                else:
       -                                    time_string = "unknown"
       -                            else:
       -                                time_string = "pending"
       -
       -                            if value is not None:
       -                                value_string = format_satoshis(value, True, wallet.num_zeros)
       -                            else:
       -                                value_string = '--'
       -
       -                            if fee is not None:
       -                                fee_string = format_satoshis(fee, True, wallet.num_zeros)
       -                            else:
       -                                fee_string = '0'
       -
       -                            if tx_hash:
       -                                label, is_default_label = wallet.get_label(tx_hash)
       -                            else:
       -                                label = ""
       -
       -                            balance_string = format_satoshis(balance, False, wallet.num_zeros)
       -                            transaction.writerow([tx_hash, label, confirmations, value_string, fee_string, balance_string, time_string])
       -                        MessageBox(title="CSV Export created",
       -                                   message="Your CSV export has been successfully created.",
       -                                   size=('320dp', '320dp')).open()
       -                except (IOError, os.error), reason:
       -                    export_error_label = _("Electrum was unable to produce a transaction export.")
       -                    MessageBoxError(title="Unable to create csv",
       -                                    message=export_error_label + "\n" + str(reason),
       -                                    size=('320dp', '320dp')).open()
       -                dialog.close()
       -
       -            dialog = SaveDialog(title=title, path=path, filename=filename, filters=filters)
       -            dialog.save_button.bind(on_press=save)
       -            dialog.open()
       -
       -        elif instance == ids.export_privkey:
       -            # NOTE: equivalent to @protected
       -            def protected_save_dialog(instance=None, password=None):
       -                def show_save_dialog(_dlg, instance):
       -                    _dlg.close()
       -                    title = _("Select file to export your private keys to")
       -                    path = DEFAULT_PATH
       -                    filename = "electrum-private-keys.csv"
       -                    filters = ["*.csv"]
       -
       -                    def save(instance):
       -                        path = dialog.file_chooser.path
       -                        filename = dialog.text_input.text.strip()
       -                        try:
       -                            with open(os.path.join(path, filename), "w+") as csvfile:
       -                                transaction = csv.writer(csvfile)
       -                                transaction.writerow(["address", "private_key"])
       -                                for addr, pk in wallet.get_private_keys(wallet.addresses(True), password).items():
       -                                    transaction.writerow(["%34s" % addr, pk])
       -                                MesageBox(message=_("Private keys exported."),
       -                                          size=('320dp', '320dp')).open()
       -                        except (IOError, os.error), reason:
       -                            export_error_label = _("Electrum was unable to produce a private key-export.")
       -                            return MessageBoxError(message="Unable to create csv", content_text=export_error_label + "\n" + str(reason),
       -                                            size=('320dp', '320dp')).open()
       -                        except BaseException, e:
       -                            return app.show_info_bubble(text=str(e))
       -
       -                        dialog.close()
       -
       -                    dialog = SaveDialog(title=title, path=path, filename=filename, filters=filters)
       -                    dialog.save_button.bind(on_press=save)
       -                    dialog.open()
       -
       -                mb = MessageBox(message="%s\n%s\n%s" % (
       -                                _("[color=ff0000ff][b]WARNING[/b][/color]: ALL your private keys are secret."),
       -                                _("Exposing a single private key can compromise your entire wallet!") + '\n\n',
       -                                _("In particular, [color=ff0000ff]DO NOT[/color] use 'redeem private key' services proposed by third parties.")),
       -                                on_release=show_save_dialog,
       -                                size = ('350dp', '320dp')).open()
       -
       -            if wallet.use_encryption:
       -                return main_gui.password_required_dialog(post_ok=protected_save_dialog)
       -            return protected_save_dialog()
       -
       -        elif instance == ids.import_privkey:
       -            # NOTE: equivalent to @protected
       -            def protected_load_dialog(_instance=None, password=None):
       -                def show_privkey_dialog(__instance=None):
       -
       -                    def on_release(_dlg, _btn):
       -                        if _btn.text == _('Cancel'):
       -                            _dlg.close()
       -                            confirm_dialog.close()
       -                            return
       -
       -                        text = _dlg.ids.ti.text.split()
       -                        badkeys = []
       -                        addrlist = []
       -                        for key in text:
       -                            try:
       -                                addr = wallet.import_key(key, password)
       -                            except BaseException as e:
       -                                badkeys.append(key)
       -                                continue
       -                            if not addr:
       -                                badkeys.append(key)
       -                            else:
       -                                addrlist.append(addr)
       -                        if addrlist:
       -                            MessageBox(title=_('Information'),
       -                                       message=_("The following addresses were added") + ':\n' + '\n'.join(addrlist),
       -                                       size=('320dp', '320dp')).open()
       -                        if badkeys:
       -                            MessageBoxError(title=_('Error'),
       -                                            message=_("The following inputs could not be imported") + ':\n' + '\n'.join(badkeys),
       -                                            size=('320dp', '320dp')).open()
       -                        main_gui.update_receive_tab()
       -                        main_gui.update_history_tab()
       -
       -                        if _instance is not None:  # called via callback
       -                            _dlg.close()
       -
       -                    ImportPrivateKeysDialog(on_release=on_release).open()
       -
       -                if not wallet.imported_keys:
       -
       -                    def on_release(_dlg, _btn):
       -                        _dlg.close
       -                        if _btn.text == _('No'):
       -                            return
       -                        show_privkey_dialog()
       -
       -                    confirm_dialog = MessageBoxError(title=_('Warning'),
       -                        message=_('Imported keys are not recoverable from seed.') + ' ' \
       -                        + _('If you ever need to restore your wallet from its seed, these keys will be lost.') + '\n\n' \
       -                        + _('Are you sure you understand what you are doing?'),
       -                        size=('320dp', '320dp'),
       -                        on_release=on_release)
       -                    confirm_dialog.buttons = [_('No'), _('Yes')]
       -                    confirm_dialog.open()
       -                else:
       -                    show_privkey_dialog()
       -
       -            if wallet.use_encryption:
       -                return main_gui.password_required_dialog(
       -                    post_ok=protected_load_dialog)
       -            return protected_load_dialog()
       -
       -        elif instance == ids.show_pubkey:
       -            # NOTE: Kivy TextInput doesn't wrap long text. So must handle it manually
       -            pub_key = wallet.get_master_public_key()
       -            pub_key = '%s\n%s\n%s\n%s' % (pub_key[0:31], pub_key[32:63], pub_key[64:95], pub_key[96:127])
       -            ShowMasterPublicKeyDialog(text=pub_key).open()
       -
       -        elif instance == ids.from_file:
       -            title = _("Select your transaction file")
       -            path = DEFAULT_PATH
       -            filename = ""
       -            filters = ["*.txn"]
       -
       -            def load(instance):
       -                path = dialog.file_chooser.path
       -                filename = dialog.text_input.text.strip()
       -
       -                if not filename:
       -                    return
       -                try:
       -                    with open(os.path.join(path, filename), "r") as f:
       -                        file_content = f.read()
       -                except (ValueError, IOError, os.error), reason:
       -                    MessageBoxError(title="Unable to read file or no transaction found",
       -                                    message=_("Electrum was unable to open your transaction file") + "\n" + str(reason),
       -                                    size=('320dp', '320dp')).open()
       -
       -                tx_dict = main_gui.tx_dict_from_text(file_content)
       -                if tx_dict:
       -                    main_gui.create_process_transaction_window(tx_dict)
       -
       -                dialog.close()
       -
       -            dialog = LoadDialog(title=title, path=path, filename=filename, filters=filters)
       -            dialog.load_button.bind(on_press=load)
       -            dialog.open()
       -
       -        elif instance == ids.from_text:
       -            def load_transaction(_dlg, _btn):
       -                if _btn.text == _('Cancel'):
       -                    _dlg.close
       -                    return
       -                text = _dlg.ids.ti.text
       -                if not text:
       -                    return
       -                tx_dict = main_gui.tx_dict_from_text(text)
       -                if tx_dict:
       -                    main_gui.create_process_transaction_window(tx_dict)
       -                _dlg.close()
       -
       -            dialog = TakeInputDialog(on_release=load_transaction)
       -            dialog.title = title=_("Input raw transaction")
       -            dialog.open()
       -
       -        # End of do_callback() #
       -
       -    def on_ok(self, instance):
       -        ##########
       -        app = self.app
       -        main_gui = app.gui.main_gui
       -
       -        fee = unicode(self.ids.st_fee_e.text)
       -        try:
       -            fee = main_gui.read_amount(fee)
       -        except:
       -            return MessageBoxError(message=_('Invalid value') + ': %s' % fee).open()
       -
       -        app.wallet.set_fee(fee)
       -
       -        ##########
       -        nz = unicode(self.ids.st_nz_e.text)
       -        try:
       -            nz = int(nz)
       -            if nz > 8: nz = 8
       -        except:
       -            return MessageBoxError(message=_('Invalid value') + ':%s' % nz).open()
       -
       -        if app.wallet.num_zeros != nz:
       -            app.wallet.num_zeros = nz
       -            app.conf.set_key('num_zeros', nz, True)
       -            main_gui.update_history_tab()
       -            main_gui.update_receive_tab()
       -
       -        usechange_result = self.ids.st_usechange_cb.active
       -        if app.wallet.use_change != usechange_result:
       -            app.wallet.use_change = usechange_result
       -            app.conf.set_key('use_change', app.wallet.use_change, True)
       -
       -        unit_result = self.ids.st_unit_combo.text
       -        if main_gui.base_unit() != unit_result:
       -            main_gui.decimal_point = 8 if unit_result == 'BTC' else 5
       -            app.conf.set_key('decimal_point', main_gui.decimal_point, True)
       -            main_gui.update_history_tab()
       -            main_gui.update_status()
       -
       -        try:
       -            n = int(self.ids.st_gap_e.text)
       -        except:
       -            return MessageBoxError(message=_('Invalid value')).open()
       -
       -        if app.wallet.gap_limit != n:
       -            if app.wallet.change_gap_limit(n):
       -                main_gui.update_receive_tab()
       -                app.conf.set_key('gap_limit', app.wallet.gap_limit, True)
       -            else:
       -                MessageBoxError(Message=_('Invalid value')).open()
       -                # TODO: no return???
       -
       -        need_restart = False
       -
       -        lang_request = str(self.ids.st_lang_combo.key)
       -        if lang_request != app.conf.get('language'):
       -            app.conf.set_key("language", lang_request, True)  # TODO: why can't save unicode
       -            need_restart = True
       -
       -        cur_request = str(self.ids.st_cur_combo.text)
       -        if cur_request != app.conf.get('currency', "None"):
       -            app.conf.set_key('currency', cur_request, True)  # TODO: why can't save unicode
       -            main_gui.update_wallet()
       -
       -        main_gui.run_hook('close_settings_dialog')
       -
       -        if need_restart:
       -            MessageBox(message=_('Please restart Electrum to activate the new GUI settings')).open()
       -
       -        # from receive_tab_set_mode()
       -        main_gui.save_column_widths()
       -        main_gui.expert_mode = self.ids.st_expert_cb.active
       -        app.conf.set_key('classic_expert_mode', main_gui.expert_mode, True)
       -        main_gui.update_receive_tab()
       -
       -        # close
       -        app.root.current = 'main_screen'
       -
       -
       -class NetworkScreen(Screen):
       -
       -    status = StringProperty(_('Uninitialized'))
       -    '''status message displayed on top of screen'''
       -
       -    server = StringProperty('')
       -
       -    #servers = ListProperty([])
       -
       -    servers_view = ObjectProperty(None)
       -
       -    server_host = ObjectProperty(None)
       -
       -    server_port = ObjectProperty(None)
       -
       -    server_protocol = ObjectProperty(None)
       -
       -    proxy_host = ObjectProperty(None)
       -
       -    proxy_port = ObjectProperty(None)
       -
       -    proxy_mode = ObjectProperty(None)
       -
       -    protocol_names = ListProperty(['TCP', 'HTTP', 'SSL', 'HTTPS'])
       -
       -    protocol_letters = StringProperty('thsg')
       -
       -    proxy_names = ListProperty(['NONE', 'SOCKS4', 'SOCKS5', 'HTTP'])
       -
       -    proxy_keys = ListProperty(['none', 'socks4', 'socks5', 'http'])
       -
       -    autocycle_cb = ObjectProperty(None)
       -
       -    interface = ObjectProperty(None)
       -
       -    def __init__(self, **kwargs):
       -        self.initialized = True
       -        super(NetworkScreen, self).__init__(**kwargs)
       -        Clock.schedule_once(self._delayed_init)
       -
       -    def _delayed_init(self, dt):
       -        self.protocol = None
       -        self.app = app = App.get_running_app()
       -        self.conf = conf = app.conf
       -        self.wallet = wallet = app.wallet
       -        self.interface = interface = wallet.interface
       -
       -        if not self.initialized:
       -            if interface.is_connected:
       -                self.status = _("Connected to") + " %s" % (interface.host) + "\n%d " % (wallet.verifier.height) + _("blocks")
       -            else:
       -                self.status = _("Not connected")
       -        else:
       -            self.status = _("Please choose a server.") + "\n" + _("Select 'Cancel' if you are offline.")
       -        self.server = server = interface.server
       -
       -        self.servers = interface.get_servers()
       -
       -        self.servers_view.content_adapter.bind(on_selection_change=self.server_changed)
       -
       -        ########################
       -        if server:
       -            host, port, protocol = server.split(':')
       -            self.set_protocol(protocol)
       -            self.change_server(host, protocol)
       -        else:
       -            self.set_protocol('s')
       -
       -        ########################
       -        # TODO: review it
       -        # if not config.is_modifiable('server'):
       -        #    for w in [self.server_host, self.server_port, self.server_protocol, self.servers_list_widget]: w.setEnabled(False)
       -
       -        self.check_for_disable(None, 'none')
       -
       -        # if not wallet.config.is_modifiable('proxy'):
       -        #    for w in [proxy_host, proxy_port, proxy_mode]: w.setEnabled(False)
       -
       -        proxy_config = interface.proxy\
       -                if interface.proxy else\
       -                { "mode":"none", "host":"localhost", "port":"8080"}
       -        self.proxy_mode.key = proxy_config.get("mode")
       -        self.proxy_host.text = proxy_config.get("host")
       -        self.proxy_port.text = proxy_config.get("port")
       -
       -        # server = unicode( server_host.text ) + ':' + unicode( server_port.text ) + ':' + (protocol_letters[server_protocol.currentIndex()])
       -        # if proxy_mode.currentText() != 'NONE':
       -        #    proxy = { u'mode':unicode(proxy_mode.currenttext).lower(), u'host':unicode(proxy_host.text), u'port':unicode(proxy_port.text) }
       -        # else:
       -        #    proxy = None
       -
       -        self.autocycle_cb.active = conf.get('auto_cycle', True)
       -        if not conf.is_modifiable('auto_cycle'):
       -            self.autocycle_cb.active = False
       -
       -    def check_for_disable(self, instance, proxy_mode_key):
       -        if proxy_mode_key != 'none':
       -            self.proxy_host.disabled = False
       -            self.proxy_port.disabled = False
       -        else:
       -            self.proxy_host.disabled = True
       -            self.proxy_port.disabled = True
       -
       -    def on_cancel(self, *args):
       -        self.manager.current = 'main_screen'
       -
       -        # TODO: RuntimeError: threads can only be started once
       -        # interface.start(wait=False)
       -        # interface.send([('server.peers.subscribe', [])])
       -
       -        # generate the first addresses, in case we are offline
       -        self.wallet.synchronize()
       -
       -        verifier = WalletVerifier(self.interface, self.conf)
       -        verifier.start()
       -        self.wallet.set_verifier(verifier)
       -        synchronizer = WalletSynchronizer(self.wallet, self.conf)
       -        synchronizer.start()
       -
       -        if not self.initialized:
       -            self.app.gui.main_gui.change_password_dialog()
       -
       -    def on_ok(self, *args):
       -        self.manager.current = 'main_screen'
       -
       -        ################
       -        server = ':'.join([str(self.server_host.text),
       -                            str(self.server_port.text),
       -                            str(self.server_protocol.key)])
       -
       -        if self.proxy_mode.key != 'none':
       -            proxy = { 'mode':str(self.proxy_mode.key),
       -                        'host':str(self.proxy_host.text),
       -                        'port':str(self.proxy_port.text) }
       -        else:
       -            proxy = None
       -
       -        app = self.app
       -        conf = self.conf
       -        wallet = self.wallet
       -        interface = self.interface
       -        conf.set_key("proxy", proxy, True)
       -        conf.set_key("server", server, True)
       -        interface.set_server(server, proxy)
       -        conf.set_key('auto_cycle', self.autocycle_cb.active, True)
       -
       -        # generate the first addresses, in case we are offline
       -        if app.gui.action == 'create':
       -            app.wallet.synchronize()
       -            app.gui.change_password_dialog()
       -
       -        verifier = WalletVerifier(interface, conf)
       -        verifier.start()
       -        wallet.set_verifier(verifier)
       -        synchronizer = WalletSynchronizer(wallet, conf)
       -        synchronizer.start()
       -
       -        if app.gui.action == 'restore':
       -            initialized = self.initialized
       -            try:
       -                def on_complete(keep_it=False):
       -                    wallet.fill_addressbook()
       -                    #if not keep_it:
       -                    #    app.stop()
       -                    #    return
       -                    if not initialized:
       -                        app.gui.change_password_dialog()
       -
       -                app.gui.restore_wallet(on_complete=on_complete)
       -            except:
       -                import traceback, sys
       -                traceback.print_exc(file=sys.stdout)
       -                app.stop()
       -        if not interface.isAlive():
       -            interface.start(wait=False)
       -        interface.send([('server.peers.subscribe', [])])
       -
       -
       -    def init_servers_list(self):
       -        data = []
       -        for _host, d in self.servers.items():
       -            if d.get(self.protocol):
       -                pruning_level = d.get('pruning', '')
       -                data.append((_host, pruning_level))
       -        self.servers_view.content_adapter.data = data
       -
       -    def set_protocol(self, protocol):
       -        if protocol != self.protocol:
       -            self.protocol = protocol
       -            self.init_servers_list()
       -
       -    def on_change_protocol(self, instance, protocol_key):
       -        p = protocol_key
       -        host = unicode(self.server_host.text)
       -        pp = self.servers.get(host)
       -        if not pp:
       -            return
       -        if p not in pp.keys():
       -            p = pp.keys()[0]
       -        port = pp[p]
       -        self.server_host.text = host
       -        self.server_port.text = port
       -        self.set_protocol(p)
       -
       -    def server_changed(self, instance):
       -        try:
       -            index = instance.selection[0].index
       -        except (AttributeError, IndexError):
       -            return
       -        item = instance.get_data_item(index)
       -        self.change_server(item[0], self.protocol)
       -
       -    def change_server(self, host, protocol):
       -        pp = self.servers.get(host, DEFAULT_PORTS)
       -        if protocol:
       -            port = pp.get(protocol)
       -            if not port: protocol = None
       -
       -        if not protocol:
       -            if 's' in pp.keys():
       -                protocol = 's'
       -                port = pp.get(protocol)
       -            else:
       -                protocol = pp.keys()[0]
       -                port = pp.get(protocol)
       -
       -        self.server_host.text = host
       -        self.server_port.text = port
       -        self.server_protocol.text = self.protocol_names[self.protocol_letters.index(protocol)]
       -
       -        if not self.servers: return
       -        # TODO: what's this?
       -        # for p in protocol_letters:
       -        #    i = protocol_letters.index(p)
       -        #    j = self.server_protocol.model().index(i,0)
       -        #    #if p not in pp.keys(): # and self.interface.is_connected:
       -        #    #    self.server_protocol.model().setData(j, QVariant(0), Qt.UserRole-1)
       -        #    #else:
       -        #    #    self.server_protocol.model().setData(j, QVariant(33), Qt.UserRole-1)
       -
       -class ScreenAddress(CScreen):
       -
       -    labels  = DictProperty({})
       -    '''
       -    '''
       -
       -    tab =  ObjectProperty(None)
       -    ''' The tab associated With this Carousel
       -    '''
       -
       -class ScreenConsole(CScreen):
       -
       +class ScreenSend(CScreen):
            pass
        
       -
        class ScreenReceive(CScreen):
       -
            pass
        
       -#TODO: move to wallet management
       -class ScreenReceive2(CScreen):
       -
       -    receive_view = ObjectProperty(None)
       -
       -    def __init__(self, **kwargs):
       -        self.context_menu = None
       -        super(ScreenReceive, self).__init__(**kwargs)
       -        self.app = App.get_running_app()
       -
       -    def on_receive_view(self, instance, value):
       -        if not value:
       -            return
       -        value.on_context_menu = self.on_context_menu
       -
       -    def on_menu_item_selected(self, instance, _menu, _btn):
       -        '''Called when any one of the bubble menu items is selected
       -        '''
       -        app = self.app
       -        main_gui = app.gui.main_gui
       -
       -        def delete_imported_key():
       -            def on_release(_dlg, _dlg_btn):
       -                if _dlg_btn.text == _('Cancel'):
       -                    _dlg.close()
       -                    return
       -                app.wallet.delete_imported_key(address)
       -                main_gui.update_receive_tab()
       -                main_gui.update_history_tab()
       -
       -            MessageBox(title=_('Delete imported key'),
       -                            message=_("Do you want to remove")
       -                                +" %s "%addr +_("from your wallet?"),
       -                            buttons=[_('Cancel'), _('OK')],
       -                            on_release=on_release).open()
       -
       -        def edit_label_dialog():
       -            # Show dialog to edit the label
       -            def save_label(_dlg, _dlg_btn):
       -                if _dlg_btn.text != _('Ok'):
       -                    return
       -                txt = _dlg.ids.ti.text
       -                if txt:
       -                    instance.parent.children[2].text = txt
       -                _dlg.close()
       -
       -            text = instance.parent.children[2].text
       -            dialog = EditLabelDialog(text=text,
       -                                     on_release=save_label).open()
       -
       -        def show_private_key_dialog():
       -            # NOTE: equivalent to @protected
       -            def protected_show_private_key(_instance=None, password=None):
       -                try:
       -                    pk = app.wallet.get_private_key(address, password)
       -                except BaseException, e:
       -                    app.show_info_bubble(text=str(e))
       -                    return
       -
       -                PrivateKeyDialog(address=address,
       -                                 private_key=pk).open()
       -
       -            if app.wallet.use_encryption:
       -                return main_gui.password_required_dialog(
       -                                            post_ok=protected_show_private_key)
       -            protected_show_private_key()
       -
       -        def show_sign_verify_dialog():
       -            def on_release(_dlg, _dlg_btn):
       -                if _dlg_btn.text != _('Ok'):
       -                    return
       -                if _dlg.ids.tabs.current_tab.text == _('Sign'):
       -                    # NOTE: equivalent to @protected
       -                    def protected_do_sign_message(instance=None, password=None):
       -                        try:
       -                            sig = app.wallet.sign_message(
       -                                    _dlg.ids.sign_address.text,
       -                                    _dlg.ids.sign_message.text,
       -                                    password)
       -                            _dlg.ids.sign_signature.text = sig
       -                        except BaseException, e:
       -                            app.show_info_bubble(text=str(e.message))
       -
       -                    if app.wallet.use_encryption:
       -                        return main_gui.password_required_dialog(
       -                                post_ok=protected_do_sign_message)
       -                    return protected_do_sign_message()
       -
       -                else:  # _('Verify')
       -                    if app.wallet.verify_message(
       -                            _dlg.ids.verify_address.text,
       -                            _dlg.ids.verify_signature.text,
       -                            _dlg.ids.verify_message.text):
       -                        app.show_info_bubble(text=_("Signature verified"))
       -                    else:
       -                        app.show_info_bubble(
       -                            text=_("Error: wrong signature"))
       -            SignVerifyDialog(on_release=on_release, address=address).open()
       -
       -        def toggle_freeze():
       -            if address in app.wallet.frozen_addresses:
       -                app.wallet.unfreeze(address)
       -            else:
       -                app.wallet.freeze(address)
       -            main_gui.update_receive_tab()
       -
       -        def toggle_priority(_dlg, _dlg_btn):
       -            if address in app.wallet.prioritized_addresses:
       -                app.wallet.unprioritize(address)
       -            else:
       -                app.wallet.prioritize(address)
       -            main_gui.update_receive_tab()
       -
       -        _menu.hide()
       -        address = instance.parent.children[3].text
       -
       -        if _btn.text == _('Copy to clipboard'):
       -            # copy data to clipboard
       -            Clipboard.put(instance.parent.children[3].text, 'UTF8_STRING')
       -        elif _btn.text == _('Edit label'):
       -            edit_label_dialog()
       -        elif _btn.text == _('Private key'):
       -            show_private_key_dialog()
       -        elif _btn.text == _('Sign message'):
       -            # sign message
       -            show_sign_verify_dialog()
       -        elif _btn.text == _('Remove_from_wallet'):
       -            delete_imported_key()
       -        elif _btn.text in (_('Freeze'), _('Unfreeze')):
       -            toggle_freeze()
       -        elif _btn.text in (_('Prioritize'), _('Unprioritize')):
       -            toggle_priority(_menu, _btn)
       -
       -
       -    def on_context_menu(self, instance):
       -        '''Called when list item is clicked.
       -        Objective: show bubble menu
       -        '''
       -        app = self.app
       -        address = instance.parent.children[3].text
       -        if not address or not is_valid(address): return
       -
       -        context_menu = ContextMenu(size_hint=(None, None),
       -                                size=('160dp', '160dp'),
       -                                orientation='vertical',
       -                                arrow_pos='left_mid',
       -                                buttons=[_('Copy to clipboard'),
       -                                        _('Edit label'),
       -                                        _('Private key'),
       -                                        _('Sign message')],
       -                                on_release=partial(self.on_menu_item_selected,
       -                                                   instance))
       -        if address in app.wallet.imported_keys:
       -            context_menu.buttons = context_menu.buttons +\
       -                                [_('Remove from wallet')]
       -            # TODO: test more this feature
       -
       -        if app.gui.main_gui.expert_mode:
       -            # TODO: show frozen, prioritized rows in different color
       -            # as original code
       -
       -            t = _("Unfreeze")\
       -                 if address in app.wallet.frozen_addresses else\
       -                 _("Freeze")
       -            context_menu.buttons = context_menu.buttons + [t]
       -            t = _("Unprioritize")\
       -                if address in app.wallet.prioritized_addresses else\
       -                _("Prioritize")
       -            context_menu.buttons = context_menu.buttons + [t]
       -        context_menu.show(pos=(instance.right, instance.top))
       -
       -
        class ScreenContacts(CScreen):
        
            def add_new_contact(self):
                NewContactDialog().open()
       -
       -
       -
       -class TabbedCarousel(TabbedPanel):
       -
       -    carousel = ObjectProperty(None)
       -
       -    def animate_tab_to_center(self, value):
       -        scrlv = self._tab_strip.parent
       -        if not scrlv:
       -            return
       -        self_center_x = scrlv.center_x
       -        vcenter_x = value.center_x
       -        diff_x = (self_center_x - vcenter_x)
       -        try:
       -            scroll_x = scrlv.scroll_x - (diff_x / scrlv.width)
       -        except ZeroDivisionError:
       -            pass
       -        mation = Animation(scroll_x=max(0, min(scroll_x, 1)), d=.25)
       -        mation.cancel_all(scrlv)
       -        mation.start(scrlv)
       -
       -    def on_current_tab(self, instance, value):
       -        if value.text == 'default_tab':
       -            return
       -        self.animate_tab_to_center(value)
       -
       -    def on_index(self, instance, value):
       -        current_slide = instance.current_slide
       -        if not hasattr(current_slide, 'tab'):
       -            return
       -        tab = current_slide.tab
       -        ct = self.current_tab
       -        try:
       -            if ct.text != tab.text:
       -                carousel = self.carousel
       -                carousel.slides[ct.slide].dispatch('on_deactivate')
       -                self.switch_to(tab)
       -                carousel.slides[tab.slide].dispatch('on_activate')
       -        except AttributeError:
       -            current_slide.dispatch('on_activate')
       -
       -    def switch_to(self, header):
       -        # we have to replace the functionality of the original switch_to
       -        if not header:
       -            return
       -        if not hasattr(header, 'slide'):
       -            header.content = self.carousel
       -            super(TabbedCarousel, self).switch_to(header)
       -            tab = self.tab_list[-1]
       -            self._current_tab = tab
       -            tab.state = 'down'
       -            return
       -
       -        carousel = self.carousel
       -        self.current_tab.state = "normal"
       -        header.state = 'down'
       -        self._current_tab = header
       -        # set the carousel to load  the appropriate slide
       -        # saved in the screen attribute of the tab head
       -        slide = carousel.slides[header.slide]
       -        if carousel.current_slide != slide:
       -            carousel.current_slide.dispatch('on_deactivate')
       -            carousel.load_slide(slide)
       -            slide.dispatch('on_activate')
       -
       -    def add_widget(self, widget, index=0):
       -        if isinstance(widget, Screen):
       -            self.carousel.add_widget(widget)
       -            return
       -        super(TabbedCarousel, self).add_widget(widget, index=index)
       -
       -
       -class TabbedScreens(TabbedPanel):
       -
       -    manager = ObjectProperty(None)
       -    '''Linked to the screen manager in kv'''
       -
       -    def switch_to(self, header):
       -        # we don't use default tab so skip
       -        if not hasattr(header, 'screen'):
       -            header.content = self.manager
       -            super(TabbedScreens, self).switch_to(header)
       -            return
       -        if not header.screen:
       -            return
       -        panel = self
       -        panel.current_tab.state = "normal"
       -        header.state = 'down'
       -        panel._current_tab = header
       -        self.manager.current = header.screen
       -
       -    def add_widget(self, widget, index=0):
       -        if isinstance(widget, Screen):
       -            self.manager.add_widget(widget)
       -            return
       -        super(TabbedScreens, self).add_widget(widget, index=index)
   DIR diff --git a/gui/kivy/ui_screens/mainscreen.kv b/gui/kivy/ui_screens/mainscreen.kv
       t@@ -0,0 +1,286 @@
       +#:import TabbedCarousel electrum_gui.kivy.tabbed_carousel.TabbedCarousel
       +#:import ScreenDashboard electrum_gui.kivy.screens.ScreenDashboard
       +#:import Factory kivy.factory.Factory
       +#:import Carousel electrum_gui.kivy.carousel.Carousel
       +
       +Screen:
       +    canvas.before:
       +        Color:
       +            rgba: 0.917, 0.917, 0.917, 1
       +        Rectangle:
       +            size: self.size
       +            pos: self.pos
       +    BoxLayout:
       +        orientation: 'vertical'
       +        ActionBar:
       +            id: action_bar
       +            size_hint: 1, None
       +            height: '40dp'
       +            border: 4, 4, 4, 4
       +            background_image: 'atlas://gui/kivy/theming/light/action_bar'
       +        ScreenManager:
       +            id: manager
       +            ScreenTabs:
       +                id: tabs
       +                name: "tabs"
       +            #ScreenPassword:
       +            #    id: password
       +            #    name: 'password'
       +
       +<TabbedCarousel>
       +    carousel: carousel
       +    do_default_tab: False
       +    Carousel:
       +        scroll_timeout: 190
       +        anim_type: 'out_quart'
       +        min_move: .05
       +        anim_move_duration: .1
       +        anim_cancel_duration: .54
       +        scroll_distance: '10dp'
       +        on_index: root.on_index(*args)
       +        id: carousel
       +
       +################################
       +##  Cards (under Dashboard)
       +################################
       +
       +<Card@GridLayout>
       +    cols: 1
       +    padding: '12dp' , '22dp', '12dp' , '12dp'
       +    spacing: '12dp'
       +    size_hint: 1, None
       +    height: max(100, self.minimum_height)
       +    canvas.before:
       +        Color:
       +            rgba: 1, 1, 1, 1
       +        BorderImage:
       +            border: 9, 9, 9, 9
       +            source: 'atlas://gui/kivy/theming/light/card'
       +            size: self.size
       +            pos: self.pos
       +
       +<CardLabel@Label>
       +    color: 0.45, 0.45, 0.45, 1
       +    size_hint: 1, None
       +    text: ''
       +    text_size: self.width, None
       +    height: self.texture_size[1]
       +    halign: 'left'
       +    valign: 'top'
       +
       +<CardButton@Button>
       +    background_normal: 'atlas://gui/kivy/theming/light/card_btn'
       +    bold: True
       +    font_size: '10sp'
       +    color: 0.699, 0.699, 0.699, 1
       +    size_hint: None, None
       +    size: self.texture_size[0] + dp(32), self.texture_size[1] + dp(7)
       +
       +<CardSeparator@Widget>
       +    size_hint: 1, None
       +    height: dp(1)
       +    color: .909, .909, .909, 1
       +    canvas:
       +        Color:
       +            rgba: root.color if root.color else (0, 0, 0, 0)
       +        Rectangle:
       +            size: self.size
       +            pos: self.pos
       +
       +<CardRecentActivity@Card>
       +    BoxLayout:
       +        size_hint: 1, None
       +        height: lbl.height
       +        CardLabel:
       +            id: lbl
       +            text: _('RECENT ACTIVITY')
       +        CardButton:
       +            id: btn_see_all
       +            text: _('SEE ALL')
       +            font_size: '12sp'
       +            on_release: app.gui.main_gui.update_history(see_all=True)
       +    GridLayout:
       +        id: content
       +        spacing: '7dp'
       +        cols: 1
       +        size_hint: 1, None
       +        height: self.minimum_height
       +        CardSeparator
       +
       +<CardPaymentRequest@Card>
       +    CardLabel:
       +        text: _('PAYMENT REQUEST')
       +    CardSeparator:
       +
       +<CardStatusInfo@Card>
       +    status: app.status
       +    base_unit: 'BTC'
       +    quote_text: '.'
       +    unconfirmed: '.'
       +    BoxLayout:
       +        size_hint: 1, None
       +        height: '72dp'
       +        IconButton:
       +            mipmap: True
       +            color: .90, .90, .90, 1
       +            source: 'atlas://gui/kivy/theming/light/qrcode'
       +            size_hint: None, 1
       +            width: self.height
       +            on_release:
       +                Factory.WalletAddressesDialog().open()
       +        GridLayout:
       +            id: grid
       +            cols: 1
       +            orientation: 'vertical'
       +            CardLabel:
       +                halign: 'right'
       +                valign: 'top'
       +                bold: True
       +                size_hint: 1, None
       +                font_size: '38sp'
       +                text:
       +                    '[color=#4E4F4F]{}[/color]'\
       +                    '[sup][color=9b948d]{}[/color][/sup]'\
       +                    .format(unicode(root.status), root.base_unit)
       +            CardLabel
       +                halign: 'right'
       +                markup: True
       +                font_size: '15dp'
       +                text: '[color=#c3c3c3]{}[/color]'.format(root.quote_text)
       +            CardLabel
       +                halign: 'right'
       +                markup: True
       +                text: '[color=#c3c3c3]{}[/color]'.format(root.unconfirmed)
       +
       +<DashboardActionView@ActionView>
       +    ActionPrevious:
       +        id: action_previous
       +        app_icon: 'atlas://gui/kivy/theming/light/wallets'
       +        with_previous: False
       +        size_hint: None, 1
       +        mipmap: True
       +        width: '77dp'
       +    ActionButton:
       +        id: action_logo
       +        important: True
       +        size_hint: 1, 1
       +        markup: True
       +        mipmap: True
       +        bold: True
       +        font_size: '22dp'
       +        icon: 'atlas://gui/kivy/theming/light/logo'
       +        minimum_width: '1dp'
       +    ActionButton:
       +        id: action_contact
       +        important: True
       +        width: '25dp'
       +        icon: 'atlas://gui/kivy/theming/light/add_contact'
       +        text: 'Add Contact'
       +        on_release: NewContactDialog().open()
       +    ActionOverflow:
       +        id: action_preferences
       +        canvas.after:
       +            Color:
       +                rgba: 1, 1, 1, 1
       +        border: 0, 0, 0, 0
       +        overflow_image: 'atlas://gui/kivy/theming/light/settings'
       +        width: '32dp'
       +        ActionButton:
       +            text: _('Seed')
       +            on_release:
       +                action_preferences._dropdown.dismiss()
       +                if app.wallet.seed: app.gui.main_gui.protected_seed_dialog(self)
       +        ActionButton:
       +            text: _('Password')
       +        ActionButton:
       +            text: _('Network')
       +            on_release:
       +                app.root.current = 'screen_network'
       +                action_preferences._dropdown.dismiss()
       +        ActionButton:
       +            text: _('Preferences')
       +            on_release:
       +                action_preferences._dropdown.dismiss()
       +                app.gui.main_gui.show_settings_dialog(self)
       +
       +<ScreenDashboard>
       +    action_view: Factory.DashboardActionView()
       +    ScrollView:
       +        do_scroll_x: False
       +        RelativeLayout:
       +            size_hint: 1, None
       +            height: grid.height
       +            GridLayout
       +                id: grid
       +                cols: 1 #if root.width < root.height else 2
       +                size_hint: 1, None
       +                height: self.minimum_height
       +                padding: '12dp'
       +                spacing: '12dp'
       +                GridLayout:
       +                    cols: 1
       +                    size_hint: 1, None
       +                    height: self.minimum_height
       +                    spacing: '12dp'
       +                    orientation: 'vertical'
       +                    CardStatusInfo:
       +                        id: status_card
       +                    CardPaymentRequest:
       +                        id: payment_card
       +                CardRecentActivity:
       +                    id: recent_activity_card
       +
       +<CleanHeader@TabbedPanelHeader>
       +    border: 0, 0, 4, 0
       +    markup: False
       +    color: (0.191, 0.558, 0.742, 1) if self.state == 'down' else (0.636, 0.636, 0.636, 1)
       +    text_size: self.size
       +    halign: 'center'
       +    valign: 'middle'
       +    bold: True
       +    font_size: '12sp'
       +    background_normal: 'atlas://gui/kivy/theming/light/tab_btn'
       +    background_disabled_normal: 'atlas://gui/kivy/theming/light/tab_btn_disabled'
       +    background_down: 'atlas://gui/kivy/theming/light/tab_btn_pressed'
       +    canvas.before:
       +        Color:
       +            rgba: 1, 1, 1, .7
       +        Rectangle:
       +            size: self.size
       +            pos: self.x + 1, self.y - 1
       +            texture: self.texture
       +
       +<ScreenTabs@Screen>
       +    TabbedCarousel:
       +        id: panel
       +        background_image: 'atlas://gui/kivy/theming/light/tab'
       +        strip_image: 'atlas://gui/kivy/theming/light/tab_strip'
       +        strip_border: 4, 0, 2, 0
       +        ScreenDashboard:
       +            id: screen_dashboard
       +            tab: tab_dashboard
       +        #ScreenSend:
       +        #    id: screen_send
       +        #    tab: tab_send
       +        #ScreenReceive:
       +        #    id: screen_receive
       +        #    tab: tab_receive
       +        #ScreenContacts:
       +        #    id: screen_contacts
       +        #    tab: tab_contacts
       +        CleanHeader:
       +            id: tab_dashboard
       +            text: _('DASHBOARD')
       +            slide: 0
       +        #CleanHeader:
       +        #    id: tab_send
       +        #    text: _('SEND')
       +        #    slide: 1
       +        #CleanHeader:
       +        #    id: tab_receive
       +        #    text: _('RECEIVE')
       +        #    slide: 2
       +        #CleanHeader:
       +        #    id: tab_contacts
       +        #    text: _('CONTACTS')
       +        #    slide: 3
       +\ No newline at end of file