Esempio n. 1
0
    def __init__(self, parent, main, initLabel=''):
        super(WalletBackupFrame, self).__init__(parent, main)
        # Don't have a wallet yet so assume false.
        self.hasImportedAddr = False
        self.isBackupCreated = False
        self.passphrase = None
        self.lblTitle = QRichLabel(tr("<b>Backup Options</b>"))
        lblTitleDescr = QRichLabel(
            tr("""
         Armory wallets only need to be backed up <u>one time, ever.</u>
         The backup is good no matter how many addresses you use. """))
        lblTitleDescr.setOpenExternalLinks(True)


        self.optPaperBackupTop = QRadioButtonBackupCtr(self, \
                                      tr('Printable Paper Backup'), self.OPTIONS.Paper1)
        self.optPaperBackupOne = QRadioButtonBackupCtr(self, \
                                      tr('Single-Sheet (Recommended)'), self.OPTIONS.Paper1)
        self.optPaperBackupFrag = QRadioButtonBackupCtr(self, \
                                      tr('Fragmented Backup (M-of-N)'), self.OPTIONS.PaperN)

        self.optDigitalBackupTop = QRadioButtonBackupCtr(self, \
                                      tr('Digital Backup'), self.OPTIONS.DigPlain)
        self.optDigitalBackupPlain = QRadioButtonBackupCtr(self, \
                                      tr('Unencrypted'), self.OPTIONS.DigPlain)
        self.optDigitalBackupCrypt = QRadioButtonBackupCtr(self, \
                                      tr('Encrypted'), self.OPTIONS.DigCrypt)

        self.optIndivKeyListTop = QRadioButtonBackupCtr(self, \
                                      tr('Export Key Lists'), self.OPTIONS.Export)

        self.optPaperBackupTop.setFont(GETFONT('Var', bold=True))
        self.optDigitalBackupTop.setFont(GETFONT('Var', bold=True))
        self.optIndivKeyListTop.setFont(GETFONT('Var', bold=True))

        # I need to be able to unset the sub-options when they become disabled
        self.optPaperBackupNONE = QRadioButton('')
        self.optDigitalBackupNONE = QRadioButton('')

        btngrpTop = QButtonGroup(self)
        btngrpTop.addButton(self.optPaperBackupTop)
        btngrpTop.addButton(self.optDigitalBackupTop)
        btngrpTop.addButton(self.optIndivKeyListTop)
        btngrpTop.setExclusive(True)

        btngrpPaper = QButtonGroup(self)
        btngrpPaper.addButton(self.optPaperBackupNONE)
        btngrpPaper.addButton(self.optPaperBackupOne)
        btngrpPaper.addButton(self.optPaperBackupFrag)
        btngrpPaper.setExclusive(True)

        btngrpDig = QButtonGroup(self)
        btngrpDig.addButton(self.optDigitalBackupNONE)
        btngrpDig.addButton(self.optDigitalBackupPlain)
        btngrpDig.addButton(self.optDigitalBackupCrypt)
        btngrpDig.setExclusive(True)

        self.connect(self.optPaperBackupTop, SIGNAL(CLICKED),
                     self.optionClicked)
        self.connect(self.optPaperBackupOne, SIGNAL(CLICKED),
                     self.optionClicked)
        self.connect(self.optPaperBackupFrag, SIGNAL(CLICKED),
                     self.optionClicked)
        self.connect(self.optDigitalBackupTop, SIGNAL(CLICKED),
                     self.optionClicked)
        self.connect(self.optDigitalBackupPlain, SIGNAL(CLICKED),
                     self.optionClicked)
        self.connect(self.optDigitalBackupCrypt, SIGNAL(CLICKED),
                     self.optionClicked)
        self.connect(self.optIndivKeyListTop, SIGNAL(CLICKED),
                     self.optionClicked)

        spacer = lambda: QSpacerItem(20, 1, QSizePolicy.Fixed, QSizePolicy.
                                     Expanding)
        layoutOpts = QGridLayout()
        layoutOpts.addWidget(self.optPaperBackupTop, 0, 0, 1, 2)
        layoutOpts.addItem(spacer(), 1, 0)
        layoutOpts.addItem(spacer(), 2, 0)
        layoutOpts.addWidget(self.optDigitalBackupTop, 3, 0, 1, 2)
        layoutOpts.addItem(spacer(), 4, 0)
        layoutOpts.addItem(spacer(), 5, 0)
        layoutOpts.addWidget(self.optIndivKeyListTop, 6, 0, 1, 2)

        layoutOpts.addWidget(self.optPaperBackupOne, 1, 1)
        layoutOpts.addWidget(self.optPaperBackupFrag, 2, 1)
        layoutOpts.addWidget(self.optDigitalBackupPlain, 4, 1)
        layoutOpts.addWidget(self.optDigitalBackupCrypt, 5, 1)
        layoutOpts.setColumnStretch(0, 0)
        layoutOpts.setColumnStretch(1, 1)

        frmOpts = QFrame()
        frmOpts.setLayout(layoutOpts)
        frmOpts.setFrameStyle(STYLE_SUNKEN)

        self.featuresTips = [None] * self.FEATURES.Count
        self.featuresLbls = [None] * self.FEATURES.Count
        self.featuresImgs = [None] * self.FEATURES.Count

        F = self.FEATURES
        self.featuresTips[F.ProtGen] = self.main.createToolTipWidget(
            tr("""
         Every time you click "Receive Bitcoins," a new address is generated.
         All of these addresses are generated from a single seed value, which
         is included in all backups.   Therefore, all addresses that you have
         generated so far <b>and</b> will ever be generated with this wallet, 
         are protected by this backup! """))

        self.featuresTips[F.ProtImport] = self.main.createToolTipWidget(
            tr("""
         <i>This wallet <u>does not</u> currently have any imported
         addresses, so you can safely ignore this feature!</i>
         When imported addresses are present, backups only protects those
         imported before the backup was made.  You must replace that
         backup if you import more addresses! """))

        self.featuresTips[F.LostPass] = self.main.createToolTipWidget(
            tr("""
         Lost/forgotten passphrases are, <b>by far</b>, the most common
         reason for users losing bitcoins.  It is critical you have
         at least one backup that works if you forget your wallet
         passphrase. """))

        self.featuresTips[F.Durable] = self.main.createToolTipWidget(
            tr("""
         USB drives and CD/DVD disks are not intended for long-term storage.
         They will <i>probably</i> last many years, but not guaranteed
         even for 3-5 years.   On the other hand, printed text on paper will
         last many decades, and useful even when thoroughly faded. """))

        self.featuresTips[F.Visual] = self.main.createToolTipWidget(
            tr("""
         The ability to look at a backup and determine if
         it is still usable.   If a digital backup is stored in a safe
         deposit box, you have no way to verify its integrity unless
         you take a secure computer/device with you.  A simple glance at
         a paper backup is enough to verify that it is still intact. """))

        self.featuresTips[F.Physical] = self.main.createToolTipWidget(
            tr("""
         If multiple pieces/fragments are required to restore this wallet.
         For instance, encrypted backups require the backup
         <b>and</b> the passphrase.  This feature is only needed for those
         concerned about physical security, not just online security."""))

        MkFeatLabel = lambda x: QRichLabel(tr(x), doWrap=False)
        self.featuresLbls[F.ProtGen] = MkFeatLabel(
            'Protects All Future Addresses')
        self.featuresLbls[F.ProtImport] = MkFeatLabel(
            'Protects Imported Addresses')
        self.featuresLbls[F.LostPass] = MkFeatLabel('Forgotten Passphrase')
        self.featuresLbls[F.Durable] = MkFeatLabel('Long-term Durability')
        self.featuresLbls[F.Visual] = MkFeatLabel('Visual Integrity')
        self.featuresLbls[F.Physical] = MkFeatLabel('Multi-Point Protection')

        if not self.hasImportedAddr:
            self.featuresLbls[F.ProtImport].setEnabled(False)

        self.lblSelFeat = QRichLabel('', doWrap=False, hAlign=Qt.AlignHCenter)

        layoutFeat = QGridLayout()
        layoutFeat.addWidget(self.lblSelFeat, 0, 0, 1, 3)
        layoutFeat.addWidget(HLINE(), 1, 0, 1, 3)
        for i in range(self.FEATURES.Count):
            self.featuresImgs[i] = QLabel('')
            layoutFeat.addWidget(self.featuresTips[i], i + 2, 0)
            layoutFeat.addWidget(self.featuresLbls[i], i + 2, 1)
            layoutFeat.addWidget(self.featuresImgs[i], i + 2, 2)
        layoutFeat.setColumnStretch(0, 0)
        layoutFeat.setColumnStretch(1, 1)
        layoutFeat.setColumnStretch(2, 0)

        frmFeat = QFrame()
        frmFeat.setLayout(layoutFeat)
        frmFeat.setFrameStyle(STYLE_SUNKEN)

        self.lblDescrSelected = QRichLabel('')
        frmFeatDescr = makeVertFrame([self.lblDescrSelected])
        self.lblDescrSelected.setMinimumHeight(tightSizeNChar(self, 10)[1] * 8)

        self.btnDoIt = QPushButton('Create Backup')
        self.connect(self.btnDoIt, SIGNAL(CLICKED), self.clickedDoIt)

        layout = QGridLayout()
        layout.addWidget(self.lblTitle, 0, 0, 1, 2)
        layout.addWidget(lblTitleDescr, 1, 0, 1, 2)
        layout.addWidget(frmOpts, 2, 0)
        layout.addWidget(frmFeat, 2, 1)
        layout.addWidget(frmFeatDescr, 3, 0, 1, 2)
        layout.addWidget(self.btnDoIt, 4, 0, 1, 2)
        layout.setRowStretch(0, 0)
        layout.setRowStretch(1, 0)
        layout.setRowStretch(2, 0)
        layout.setRowStretch(3, 1)
        layout.setRowStretch(4, 0)
        self.setLayout(layout)
        self.setMinimumSize(640, 350)

        self.optPaperBackupTop.setChecked(True)
        self.optPaperBackupOne.setChecked(True)
        self.setDispFrame(-1)
        self.optionClicked()
   def __init__(self, parent, main, initLabel=''):
      super(WalletBackupFrame, self).__init__(parent, main)
      # Don't have a wallet yet so assume false.
      self.hasImportedAddr = False
      self.isBackupCreated = False
      self.passphrase = None
      self.lblTitle = QRichLabel(tr("<b>Backup Options</b>"))
      lblTitleDescr = QRichLabel(tr("""
         Armory wallets only need to be backed up <u>one time, ever.</u>
         The backup is good no matter how many addresses you use. """))
      lblTitleDescr.setOpenExternalLinks(True)


      self.optPaperBackupTop = QRadioButtonBackupCtr(self, \
                                    tr('Printable Paper Backup'), self.OPTIONS.Paper1)
      self.optPaperBackupOne = QRadioButtonBackupCtr(self, \
                                    tr('Single-Sheet (Recommended)'), self.OPTIONS.Paper1)
      self.optPaperBackupFrag = QRadioButtonBackupCtr(self, \
                                    tr('Fragmented Backup (M-of-N)'), self.OPTIONS.PaperN)

      self.optDigitalBackupTop = QRadioButtonBackupCtr(self, \
                                    tr('Digital Backup'), self.OPTIONS.DigPlain)
      self.optDigitalBackupPlain = QRadioButtonBackupCtr(self, \
                                    tr('Unencrypted'), self.OPTIONS.DigPlain)
      self.optDigitalBackupCrypt = QRadioButtonBackupCtr(self, \
                                    tr('Encrypted'), self.OPTIONS.DigCrypt)

      self.optIndivKeyListTop = QRadioButtonBackupCtr(self, \
                                    tr('Export Key Lists'), self.OPTIONS.Export)


      self.optPaperBackupTop.setFont(GETFONT('Var', bold=True))
      self.optDigitalBackupTop.setFont(GETFONT('Var', bold=True))
      self.optIndivKeyListTop.setFont(GETFONT('Var', bold=True))

      # I need to be able to unset the sub-options when they become disabled
      self.optPaperBackupNONE = QRadioButton('')
      self.optDigitalBackupNONE = QRadioButton('')

      btngrpTop = QButtonGroup(self)
      btngrpTop.addButton(self.optPaperBackupTop)
      btngrpTop.addButton(self.optDigitalBackupTop)
      btngrpTop.addButton(self.optIndivKeyListTop)
      btngrpTop.setExclusive(True)

      btngrpPaper = QButtonGroup(self)
      btngrpPaper.addButton(self.optPaperBackupNONE)
      btngrpPaper.addButton(self.optPaperBackupOne)
      btngrpPaper.addButton(self.optPaperBackupFrag)
      btngrpPaper.setExclusive(True)

      btngrpDig = QButtonGroup(self)
      btngrpDig.addButton(self.optDigitalBackupNONE)
      btngrpDig.addButton(self.optDigitalBackupPlain)
      btngrpDig.addButton(self.optDigitalBackupCrypt)
      btngrpDig.setExclusive(True)

      self.connect(self.optPaperBackupTop, SIGNAL(CLICKED), self.optionClicked)
      self.connect(self.optPaperBackupOne, SIGNAL(CLICKED), self.optionClicked)
      self.connect(self.optPaperBackupFrag, SIGNAL(CLICKED), self.optionClicked)
      self.connect(self.optDigitalBackupTop, SIGNAL(CLICKED), self.optionClicked)
      self.connect(self.optDigitalBackupPlain, SIGNAL(CLICKED), self.optionClicked)
      self.connect(self.optDigitalBackupCrypt, SIGNAL(CLICKED), self.optionClicked)
      self.connect(self.optIndivKeyListTop, SIGNAL(CLICKED), self.optionClicked)


      spacer = lambda: QSpacerItem(20, 1, QSizePolicy.Fixed, QSizePolicy.Expanding)
      layoutOpts = QGridLayout()
      layoutOpts.addWidget(self.optPaperBackupTop, 0, 0, 1, 2)
      layoutOpts.addItem(spacer(), 1, 0)
      layoutOpts.addItem(spacer(), 2, 0)
      layoutOpts.addWidget(self.optDigitalBackupTop, 3, 0, 1, 2)
      layoutOpts.addItem(spacer(), 4, 0)
      layoutOpts.addItem(spacer(), 5, 0)
      layoutOpts.addWidget(self.optIndivKeyListTop, 6, 0, 1, 2)

      layoutOpts.addWidget(self.optPaperBackupOne, 1, 1)
      layoutOpts.addWidget(self.optPaperBackupFrag, 2, 1)
      layoutOpts.addWidget(self.optDigitalBackupPlain, 4, 1)
      layoutOpts.addWidget(self.optDigitalBackupCrypt, 5, 1)
      layoutOpts.setColumnStretch(0, 0)
      layoutOpts.setColumnStretch(1, 1)

      frmOpts = QFrame()
      frmOpts.setLayout(layoutOpts)
      frmOpts.setFrameStyle(STYLE_SUNKEN)


      self.featuresTips = [None] * self.FEATURES.Count
      self.featuresLbls = [None] * self.FEATURES.Count
      self.featuresImgs = [None] * self.FEATURES.Count


      F = self.FEATURES
      self.featuresTips[F.ProtGen] = self.main.createToolTipWidget(tr("""
         Every time you click "Receive Groestlcoins," a new address is generated.
         All of these addresses are generated from a single seed value, which
         is included in all backups.   Therefore, all addresses that you have
         generated so far <b>and</b> will ever be generated with this wallet, 
         are protected by this backup! """))

      self.featuresTips[F.ProtImport] = self.main.createToolTipWidget(tr("""
         <i>This wallet <u>does not</u> currently have any imported
         addresses, so you can safely ignore this feature!</i>
         When imported addresses are present, backups only protects those
         imported before the backup was made.  You must replace that
         backup if you import more addresses! """))

      self.featuresTips[F.LostPass] = self.main.createToolTipWidget(tr("""
         Lost/forgotten passphrases are, <b>by far</b>, the most common
         reason for users losing Groestlcoins.  It is critical you have
         at least one backup that works if you forget your wallet
         passphrase. """))

      self.featuresTips[F.Durable] = self.main.createToolTipWidget(tr("""
         USB drives and CD/DVD disks are not intended for long-term storage.
         They will <i>probably</i> last many years, but not guaranteed
         even for 3-5 years.   On the other hand, printed text on paper will
         last many decades, and useful even when thoroughly faded. """))

      self.featuresTips[F.Visual] = self.main.createToolTipWidget(tr("""
         The ability to look at a backup and determine if
         it is still usable.   If a digital backup is stored in a safe
         deposit box, you have no way to verify its integrity unless
         you take a secure computer/device with you.  A simple glance at
         a paper backup is enough to verify that it is still intact. """))

      self.featuresTips[F.Physical] = self.main.createToolTipWidget(tr("""
         If multiple pieces/fragments are required to restore this wallet.
         For instance, encrypted backups require the backup
         <b>and</b> the passphrase.  This feature is only needed for those
         concerned about physical security, not just online security."""))


      MkFeatLabel = lambda x: QRichLabel(tr(x), doWrap=False)
      self.featuresLbls[F.ProtGen] = MkFeatLabel('Protects All Future Addresses')
      self.featuresLbls[F.ProtImport] = MkFeatLabel('Protects Imported Addresses')
      self.featuresLbls[F.LostPass] = MkFeatLabel('Forgotten Passphrase')
      self.featuresLbls[F.Durable] = MkFeatLabel('Long-term Durability')
      self.featuresLbls[F.Visual] = MkFeatLabel('Visual Integrity')
      self.featuresLbls[F.Physical] = MkFeatLabel('Multi-Point Protection')

      if not self.hasImportedAddr:
         self.featuresLbls[F.ProtImport].setEnabled(False)

      self.lblSelFeat = QRichLabel('', doWrap=False, hAlign=Qt.AlignHCenter)

      layoutFeat = QGridLayout()
      layoutFeat.addWidget(self.lblSelFeat, 0, 0, 1, 3)
      layoutFeat.addWidget(HLINE(), 1, 0, 1, 3)
      for i in range(self.FEATURES.Count):
         self.featuresImgs[i] = QLabel('')
         layoutFeat.addWidget(self.featuresTips[i], i + 2, 0)
         layoutFeat.addWidget(self.featuresLbls[i], i + 2, 1)
         layoutFeat.addWidget(self.featuresImgs[i], i + 2, 2)
      layoutFeat.setColumnStretch(0, 0)
      layoutFeat.setColumnStretch(1, 1)
      layoutFeat.setColumnStretch(2, 0)

      frmFeat = QFrame()
      frmFeat.setLayout(layoutFeat)
      frmFeat.setFrameStyle(STYLE_SUNKEN)


      self.lblDescrSelected = QRichLabel('')
      frmFeatDescr = makeVertFrame([self.lblDescrSelected])
      self.lblDescrSelected.setMinimumHeight(tightSizeNChar(self, 10)[1] * 8)

      self.btnDoIt = QPushButton('Create Backup')
      self.connect(self.btnDoIt, SIGNAL(CLICKED), self.clickedDoIt)

      layout = QGridLayout()
      layout.addWidget(self.lblTitle, 0, 0, 1, 2)
      layout.addWidget(lblTitleDescr, 1, 0, 1, 2)
      layout.addWidget(frmOpts, 2, 0)
      layout.addWidget(frmFeat, 2, 1)
      layout.addWidget(frmFeatDescr, 3, 0, 1, 2)
      layout.addWidget(self.btnDoIt, 4, 0, 1, 2)
      layout.setRowStretch(0, 0)
      layout.setRowStretch(1, 0)
      layout.setRowStretch(2, 0)
      layout.setRowStretch(3, 1)
      layout.setRowStretch(4, 0)
      self.setLayout(layout)
      self.setMinimumSize(640, 350)

      self.optPaperBackupTop.setChecked(True)
      self.optPaperBackupOne.setChecked(True)
      self.setDispFrame(-1)
      self.optionClicked()
Esempio n. 3
0
class WalletBackupFrame(ArmoryFrame):
    # Some static enums, and a QRadioButton with mouse-enter/mouse-leave events
    FEATURES = enum('ProtGen', 'ProtImport', 'LostPass', 'Durable', \
                    'Visual', 'Physical', 'Count')
    OPTIONS = enum('Paper1', 'PaperN', 'DigPlain', 'DigCrypt', 'Export',
                   'Count')

    def __init__(self, parent, main, initLabel=''):
        super(WalletBackupFrame, self).__init__(parent, main)
        # Don't have a wallet yet so assume false.
        self.hasImportedAddr = False
        self.isBackupCreated = False
        self.passphrase = None
        self.lblTitle = QRichLabel(tr("<b>Backup Options</b>"))
        lblTitleDescr = QRichLabel(
            tr("""
         Armory wallets only need to be backed up <u>one time, ever.</u>
         The backup is good no matter how many addresses you use. """))
        lblTitleDescr.setOpenExternalLinks(True)


        self.optPaperBackupTop = QRadioButtonBackupCtr(self, \
                                      tr('Printable Paper Backup'), self.OPTIONS.Paper1)
        self.optPaperBackupOne = QRadioButtonBackupCtr(self, \
                                      tr('Single-Sheet (Recommended)'), self.OPTIONS.Paper1)
        self.optPaperBackupFrag = QRadioButtonBackupCtr(self, \
                                      tr('Fragmented Backup (M-of-N)'), self.OPTIONS.PaperN)

        self.optDigitalBackupTop = QRadioButtonBackupCtr(self, \
                                      tr('Digital Backup'), self.OPTIONS.DigPlain)
        self.optDigitalBackupPlain = QRadioButtonBackupCtr(self, \
                                      tr('Unencrypted'), self.OPTIONS.DigPlain)
        self.optDigitalBackupCrypt = QRadioButtonBackupCtr(self, \
                                      tr('Encrypted'), self.OPTIONS.DigCrypt)

        self.optIndivKeyListTop = QRadioButtonBackupCtr(self, \
                                      tr('Export Key Lists'), self.OPTIONS.Export)

        self.optPaperBackupTop.setFont(GETFONT('Var', bold=True))
        self.optDigitalBackupTop.setFont(GETFONT('Var', bold=True))
        self.optIndivKeyListTop.setFont(GETFONT('Var', bold=True))

        # I need to be able to unset the sub-options when they become disabled
        self.optPaperBackupNONE = QRadioButton('')
        self.optDigitalBackupNONE = QRadioButton('')

        btngrpTop = QButtonGroup(self)
        btngrpTop.addButton(self.optPaperBackupTop)
        btngrpTop.addButton(self.optDigitalBackupTop)
        btngrpTop.addButton(self.optIndivKeyListTop)
        btngrpTop.setExclusive(True)

        btngrpPaper = QButtonGroup(self)
        btngrpPaper.addButton(self.optPaperBackupNONE)
        btngrpPaper.addButton(self.optPaperBackupOne)
        btngrpPaper.addButton(self.optPaperBackupFrag)
        btngrpPaper.setExclusive(True)

        btngrpDig = QButtonGroup(self)
        btngrpDig.addButton(self.optDigitalBackupNONE)
        btngrpDig.addButton(self.optDigitalBackupPlain)
        btngrpDig.addButton(self.optDigitalBackupCrypt)
        btngrpDig.setExclusive(True)

        self.connect(self.optPaperBackupTop, SIGNAL(CLICKED),
                     self.optionClicked)
        self.connect(self.optPaperBackupOne, SIGNAL(CLICKED),
                     self.optionClicked)
        self.connect(self.optPaperBackupFrag, SIGNAL(CLICKED),
                     self.optionClicked)
        self.connect(self.optDigitalBackupTop, SIGNAL(CLICKED),
                     self.optionClicked)
        self.connect(self.optDigitalBackupPlain, SIGNAL(CLICKED),
                     self.optionClicked)
        self.connect(self.optDigitalBackupCrypt, SIGNAL(CLICKED),
                     self.optionClicked)
        self.connect(self.optIndivKeyListTop, SIGNAL(CLICKED),
                     self.optionClicked)

        spacer = lambda: QSpacerItem(20, 1, QSizePolicy.Fixed, QSizePolicy.
                                     Expanding)
        layoutOpts = QGridLayout()
        layoutOpts.addWidget(self.optPaperBackupTop, 0, 0, 1, 2)
        layoutOpts.addItem(spacer(), 1, 0)
        layoutOpts.addItem(spacer(), 2, 0)
        layoutOpts.addWidget(self.optDigitalBackupTop, 3, 0, 1, 2)
        layoutOpts.addItem(spacer(), 4, 0)
        layoutOpts.addItem(spacer(), 5, 0)
        layoutOpts.addWidget(self.optIndivKeyListTop, 6, 0, 1, 2)

        layoutOpts.addWidget(self.optPaperBackupOne, 1, 1)
        layoutOpts.addWidget(self.optPaperBackupFrag, 2, 1)
        layoutOpts.addWidget(self.optDigitalBackupPlain, 4, 1)
        layoutOpts.addWidget(self.optDigitalBackupCrypt, 5, 1)
        layoutOpts.setColumnStretch(0, 0)
        layoutOpts.setColumnStretch(1, 1)

        frmOpts = QFrame()
        frmOpts.setLayout(layoutOpts)
        frmOpts.setFrameStyle(STYLE_SUNKEN)

        self.featuresTips = [None] * self.FEATURES.Count
        self.featuresLbls = [None] * self.FEATURES.Count
        self.featuresImgs = [None] * self.FEATURES.Count

        F = self.FEATURES
        self.featuresTips[F.ProtGen] = self.main.createToolTipWidget(
            tr("""
         Every time you click "Receive Bitcoins," a new address is generated.
         All of these addresses are generated from a single seed value, which
         is included in all backups.   Therefore, all addresses that you have
         generated so far <b>and</b> will ever be generated with this wallet, 
         are protected by this backup! """))

        self.featuresTips[F.ProtImport] = self.main.createToolTipWidget(
            tr("""
         <i>This wallet <u>does not</u> currently have any imported
         addresses, so you can safely ignore this feature!</i>
         When imported addresses are present, backups only protects those
         imported before the backup was made.  You must replace that
         backup if you import more addresses! """))

        self.featuresTips[F.LostPass] = self.main.createToolTipWidget(
            tr("""
         Lost/forgotten passphrases are, <b>by far</b>, the most common
         reason for users losing bitcoins.  It is critical you have
         at least one backup that works if you forget your wallet
         passphrase. """))

        self.featuresTips[F.Durable] = self.main.createToolTipWidget(
            tr("""
         USB drives and CD/DVD disks are not intended for long-term storage.
         They will <i>probably</i> last many years, but not guaranteed
         even for 3-5 years.   On the other hand, printed text on paper will
         last many decades, and useful even when thoroughly faded. """))

        self.featuresTips[F.Visual] = self.main.createToolTipWidget(
            tr("""
         The ability to look at a backup and determine if
         it is still usable.   If a digital backup is stored in a safe
         deposit box, you have no way to verify its integrity unless
         you take a secure computer/device with you.  A simple glance at
         a paper backup is enough to verify that it is still intact. """))

        self.featuresTips[F.Physical] = self.main.createToolTipWidget(
            tr("""
         If multiple pieces/fragments are required to restore this wallet.
         For instance, encrypted backups require the backup
         <b>and</b> the passphrase.  This feature is only needed for those
         concerned about physical security, not just online security."""))

        MkFeatLabel = lambda x: QRichLabel(tr(x), doWrap=False)
        self.featuresLbls[F.ProtGen] = MkFeatLabel(
            'Protects All Future Addresses')
        self.featuresLbls[F.ProtImport] = MkFeatLabel(
            'Protects Imported Addresses')
        self.featuresLbls[F.LostPass] = MkFeatLabel('Forgotten Passphrase')
        self.featuresLbls[F.Durable] = MkFeatLabel('Long-term Durability')
        self.featuresLbls[F.Visual] = MkFeatLabel('Visual Integrity')
        self.featuresLbls[F.Physical] = MkFeatLabel('Multi-Point Protection')

        if not self.hasImportedAddr:
            self.featuresLbls[F.ProtImport].setEnabled(False)

        self.lblSelFeat = QRichLabel('', doWrap=False, hAlign=Qt.AlignHCenter)

        layoutFeat = QGridLayout()
        layoutFeat.addWidget(self.lblSelFeat, 0, 0, 1, 3)
        layoutFeat.addWidget(HLINE(), 1, 0, 1, 3)
        for i in range(self.FEATURES.Count):
            self.featuresImgs[i] = QLabel('')
            layoutFeat.addWidget(self.featuresTips[i], i + 2, 0)
            layoutFeat.addWidget(self.featuresLbls[i], i + 2, 1)
            layoutFeat.addWidget(self.featuresImgs[i], i + 2, 2)
        layoutFeat.setColumnStretch(0, 0)
        layoutFeat.setColumnStretch(1, 1)
        layoutFeat.setColumnStretch(2, 0)

        frmFeat = QFrame()
        frmFeat.setLayout(layoutFeat)
        frmFeat.setFrameStyle(STYLE_SUNKEN)

        self.lblDescrSelected = QRichLabel('')
        frmFeatDescr = makeVertFrame([self.lblDescrSelected])
        self.lblDescrSelected.setMinimumHeight(tightSizeNChar(self, 10)[1] * 8)

        self.btnDoIt = QPushButton('Create Backup')
        self.connect(self.btnDoIt, SIGNAL(CLICKED), self.clickedDoIt)

        layout = QGridLayout()
        layout.addWidget(self.lblTitle, 0, 0, 1, 2)
        layout.addWidget(lblTitleDescr, 1, 0, 1, 2)
        layout.addWidget(frmOpts, 2, 0)
        layout.addWidget(frmFeat, 2, 1)
        layout.addWidget(frmFeatDescr, 3, 0, 1, 2)
        layout.addWidget(self.btnDoIt, 4, 0, 1, 2)
        layout.setRowStretch(0, 0)
        layout.setRowStretch(1, 0)
        layout.setRowStretch(2, 0)
        layout.setRowStretch(3, 1)
        layout.setRowStretch(4, 0)
        self.setLayout(layout)
        self.setMinimumSize(640, 350)

        self.optPaperBackupTop.setChecked(True)
        self.optPaperBackupOne.setChecked(True)
        self.setDispFrame(-1)
        self.optionClicked()

    #############################################################################
    def setWallet(self, wlt):
        self.wlt = wlt
        wltID = wlt.uniqueIDB58
        wltName = wlt.labelName
        self.hasImportedAddr = self.wlt.hasAnyImported()
        # Highlight imported-addr feature if their wallet contains them
        pcolor = 'TextWarn' if self.hasImportedAddr else 'DisableFG'
        self.featuresLbls[self.FEATURES.ProtImport].setText(tr(\
           'Protects Imported Addresses'), color=pcolor)

        if self.hasImportedAddr:
            self.featuresTips[self.FEATURES.ProtImport].setText(
                tr("""
            When imported addresses are present, backups only protects those
            imported before the backup was made!  You must replace that
            backup if you import more addresses!
            <i>Your wallet <u>does</u> contain imported addresses<i>."""))

        self.lblTitle.setText(
            tr("""
         <b>Backup Options for Wallet "%s" (%s)</b>""" % (wltName, wltID)))

    #############################################################################
    def setDispFrame(self, index):
        if index < 0:
            self.setDispFrame(self.getIndexChecked())
        else:
            # Highlight imported-addr feature if their wallet contains them
            pcolor = 'TextWarn' if self.hasImportedAddr else 'DisableFG'
            self.featuresLbls[self.FEATURES.ProtImport].setText(tr(\
               'Protects Imported Addresses'), color=pcolor)

            txtPaper = tr("""
               Paper backups protect every address ever generated by your
               wallet. It is unencrypted, which means it needs to be stored
               in a secure place, but it will help you recover your wallet
               if you forget your encryption passphrase!
               <br><br>
               <b>You don't need a printer to make a paper backup!
               The data can be copied by hand with pen and paper.</b>
               Paper backups are preferred to digital backups, because you
               know the paper backup will work no matter how many years (or
               decades) it sits in storage.  """)
            txtDigital = tr("""
               Digital backups can be saved to an external hard-drive or
               USB removable media.  It is recommended you make a few
               copies to protect against "bit rot" (degradation). <br><br>""")
            txtDigPlain = tr("""
               <b><u>IMPORTANT:</u> Do not save an unencrypted digital
               backup to your primary hard drive!</b>
               Please save it <i>directly</i> to the backup device.
               Deleting the file does not guarantee the data is actually
               gone!  """)
            txtDigCrypt = tr("""
               <b><u>IMPORTANT:</u> It is critical that you have at least
               one unencrypted backup!</b>  Without it, your bitcoins will
               be lost forever if you forget your passphrase!  This is <b>
               by far</b> the most common reason users lose coins!  Having
               at least one paper backup is recommended.""")
            txtIndivKeys = tr("""
               View and export invidivual addresses strings,
               public keys and/or private keys contained in your wallet.
               This is useful for exporting your private keys to be imported into
               another wallet app or service.
               <br><br>
               You can view/backup imported keys, as well as unused keys in your
               keypool (pregenerated addresses protected by your backup that
               have not yet been used). """)

            chk = lambda: QPixmap(':/checkmark32.png').scaled(20, 20)
            _X_ = lambda: QPixmap(':/red_X.png').scaled(16, 16)
            if index == self.OPTIONS.Paper1:
                self.lblSelFeat.setText(tr('Single-Sheet Paper Backup'),
                                        bold=True)
                self.featuresImgs[self.FEATURES.ProtGen].setPixmap(chk())
                self.featuresImgs[self.FEATURES.ProtImport].setPixmap(chk())
                self.featuresImgs[self.FEATURES.LostPass].setPixmap(chk())
                self.featuresImgs[self.FEATURES.Durable].setPixmap(chk())
                self.featuresImgs[self.FEATURES.Visual].setPixmap(chk())
                self.featuresImgs[self.FEATURES.Physical].setPixmap(_X_())
                self.lblDescrSelected.setText(txtPaper)
            elif index == self.OPTIONS.PaperN:
                self.lblSelFeat.setText(tr('Fragmented Paper Backup'),
                                        bold=True)
                self.featuresImgs[self.FEATURES.ProtGen].setPixmap(chk())
                self.featuresImgs[self.FEATURES.ProtImport].setPixmap(_X_())
                self.featuresImgs[self.FEATURES.LostPass].setPixmap(chk())
                self.featuresImgs[self.FEATURES.Durable].setPixmap(chk())
                self.featuresImgs[self.FEATURES.Visual].setPixmap(chk())
                self.featuresImgs[self.FEATURES.Physical].setPixmap(chk())
                self.lblDescrSelected.setText(txtPaper)
            elif index == self.OPTIONS.DigPlain:
                self.lblSelFeat.setText(tr('Unencrypted Digital Backup'),
                                        bold=True)
                self.featuresImgs[self.FEATURES.ProtGen].setPixmap(chk())
                self.featuresImgs[self.FEATURES.ProtImport].setPixmap(chk())
                self.featuresImgs[self.FEATURES.LostPass].setPixmap(chk())
                self.featuresImgs[self.FEATURES.Durable].setPixmap(_X_())
                self.featuresImgs[self.FEATURES.Visual].setPixmap(_X_())
                self.featuresImgs[self.FEATURES.Physical].setPixmap(_X_())
                self.lblDescrSelected.setText(txtDigital + txtDigPlain)
            elif index == self.OPTIONS.DigCrypt:
                self.lblSelFeat.setText(tr('Encrypted Digital Backup'),
                                        bold=True)
                self.featuresImgs[self.FEATURES.ProtGen].setPixmap(chk())
                self.featuresImgs[self.FEATURES.ProtImport].setPixmap(chk())
                self.featuresImgs[self.FEATURES.LostPass].setPixmap(_X_())
                self.featuresImgs[self.FEATURES.Durable].setPixmap(_X_())
                self.featuresImgs[self.FEATURES.Visual].setPixmap(_X_())
                self.featuresImgs[self.FEATURES.Physical].setPixmap(chk())
                self.lblDescrSelected.setText(txtDigital + txtDigCrypt)
            elif index == self.OPTIONS.Export:
                self.lblSelFeat.setText(tr('Export Key Lists'), bold=True)
                self.featuresImgs[self.FEATURES.ProtGen].setPixmap(chk())
                self.featuresImgs[self.FEATURES.ProtImport].setPixmap(chk())
                self.featuresImgs[self.FEATURES.LostPass].setPixmap(chk())
                self.featuresImgs[self.FEATURES.Durable].setPixmap(_X_())
                self.featuresImgs[self.FEATURES.Visual].setPixmap(_X_())
                self.featuresImgs[self.FEATURES.Physical].setPixmap(_X_())
                self.lblDescrSelected.setText(txtIndivKeys)
            else:
                LOGERROR('What index was sent to setDispFrame? %d', index)

    #############################################################################
    def getIndexChecked(self):
        if self.optPaperBackupOne.isChecked():
            return self.OPTIONS.Paper1
        elif self.optPaperBackupFrag.isChecked():
            return self.OPTIONS.PaperN
        elif self.optPaperBackupTop.isChecked():
            return self.OPTIONS.Paper1
        elif self.optDigitalBackupPlain.isChecked():
            return self.OPTIONS.DigPlain
        elif self.optDigitalBackupCrypt.isChecked():
            return self.OPTIONS.DigCrypt
        elif self.optDigitalBackupTop.isChecked():
            return self.OPTIONS.DigPlain
        elif self.optIndivKeyListTop.isChecked():
            return self.OPTIONS.Export
        else:
            return 0

    #############################################################################
    def optionClicked(self):
        if self.optPaperBackupTop.isChecked():
            self.optPaperBackupOne.setEnabled(True)
            self.optPaperBackupFrag.setEnabled(True)
            self.optDigitalBackupPlain.setEnabled(False)
            self.optDigitalBackupCrypt.setEnabled(False)
            self.optDigitalBackupPlain.setChecked(False)
            self.optDigitalBackupCrypt.setChecked(False)
            self.optDigitalBackupNONE.setChecked(True)
            self.btnDoIt.setText(tr('Create Paper Backup'))
        elif self.optDigitalBackupTop.isChecked():
            self.optDigitalBackupPlain.setEnabled(True)
            self.optDigitalBackupCrypt.setEnabled(True)
            self.optPaperBackupOne.setEnabled(False)
            self.optPaperBackupFrag.setEnabled(False)
            self.optPaperBackupOne.setChecked(False)
            self.optPaperBackupFrag.setChecked(False)
            self.optPaperBackupNONE.setChecked(True)
            self.btnDoIt.setText(tr('Create Digital Backup'))
        elif self.optIndivKeyListTop.isChecked():
            self.optPaperBackupOne.setEnabled(False)
            self.optPaperBackupFrag.setEnabled(False)
            self.optPaperBackupOne.setChecked(False)
            self.optPaperBackupFrag.setChecked(False)
            self.optDigitalBackupPlain.setEnabled(False)
            self.optDigitalBackupCrypt.setEnabled(False)
            self.optDigitalBackupPlain.setChecked(False)
            self.optDigitalBackupCrypt.setChecked(False)
            self.optDigitalBackupNONE.setChecked(True)
            self.optPaperBackupNONE.setChecked(True)
            self.btnDoIt.setText(tr('Export Key Lists'))
        self.setDispFrame(-1)

    def setPassphrase(self, passphrase):
        self.passphrase = passphrase

    def clickedDoIt(self):
        isBackupCreated = False

        if self.passphrase:
            from qtdialogs import DlgProgress
            unlockProgress = DlgProgress(self,
                                         self.main,
                                         HBar=1,
                                         Title="Unlocking Wallet")
            unlockProgress.exec_(self.wlt.unlock,
                                 securePassphrase=SecureBinaryData( \
                                 self.passphrase),
                                 Progress=unlockProgress.UpdateHBar)

        if self.optPaperBackupOne.isChecked():
            isBackupCreated = OpenPaperBackupWindow('Single', self.parent(),
                                                    self.main, self.wlt)
        elif self.optPaperBackupFrag.isChecked():
            isBackupCreated = OpenPaperBackupWindow('Frag', self.parent(),
                                                    self.main, self.wlt)
        elif self.optDigitalBackupPlain.isChecked():
            if self.main.digitalBackupWarning():
                isBackupCreated = self.main.makeWalletCopy(
                    self, self.wlt, 'Decrypt', 'decrypt')
        elif self.optDigitalBackupCrypt.isChecked():
            isBackupCreated = self.main.makeWalletCopy(self, self.wlt,
                                                       'Encrypt', 'encrypt')
        elif self.optIndivKeyListTop.isChecked():
            if self.wlt.useEncryption and self.wlt.isLocked:
                dlg = DlgUnlockWallet(self.wlt, self, self.main,
                                      'Unlock Private Keys')
                if not dlg.exec_():
                    if self.main.usermode == USERMODE.Expert:
                        QMessageBox.warning(self, tr('Unlock Failed'), tr("""
                     Wallet was not be unlocked.  The public keys and addresses
                     will still be shown, but private keys will not be available
                     unless you reopen the dialog with the correct passphrase."""), \
                           QMessageBox.Ok)
                    else:
                        QMessageBox.warning(self, tr('Unlock Failed'), tr("""
                     'Wallet could not be unlocked to display individual keys."""), \
                           QMessageBox.Ok)
                        if self.main.usermode == USERMODE.Standard:
                            return
            DlgShowKeyList(self.wlt, self.parent(), self.main).exec_()
            isBackupCreated = True
        if isBackupCreated:
            self.isBackupCreated = True
class WalletBackupFrame(ArmoryFrame):
   # Some static enums, and a QRadioButton with mouse-enter/mouse-leave events
   FEATURES = enum('ProtGen', 'ProtImport', 'LostPass', 'Durable', \
                   'Visual', 'Physical', 'Count')
   OPTIONS = enum('Paper1', 'PaperN', 'DigPlain', 'DigCrypt', 'Export', 'Count')
   def __init__(self, parent, main, initLabel=''):
      super(WalletBackupFrame, self).__init__(parent, main)
      # Don't have a wallet yet so assume false.
      self.hasImportedAddr = False
      self.isBackupCreated = False
      self.passphrase = None
      self.lblTitle = QRichLabel(tr("<b>Backup Options</b>"))
      lblTitleDescr = QRichLabel(tr("""
         Armory wallets only need to be backed up <u>one time, ever.</u>
         The backup is good no matter how many addresses you use. """))
      lblTitleDescr.setOpenExternalLinks(True)


      self.optPaperBackupTop = QRadioButtonBackupCtr(self, \
                                    tr('Printable Paper Backup'), self.OPTIONS.Paper1)
      self.optPaperBackupOne = QRadioButtonBackupCtr(self, \
                                    tr('Single-Sheet (Recommended)'), self.OPTIONS.Paper1)
      self.optPaperBackupFrag = QRadioButtonBackupCtr(self, \
                                    tr('Fragmented Backup (M-of-N)'), self.OPTIONS.PaperN)

      self.optDigitalBackupTop = QRadioButtonBackupCtr(self, \
                                    tr('Digital Backup'), self.OPTIONS.DigPlain)
      self.optDigitalBackupPlain = QRadioButtonBackupCtr(self, \
                                    tr('Unencrypted'), self.OPTIONS.DigPlain)
      self.optDigitalBackupCrypt = QRadioButtonBackupCtr(self, \
                                    tr('Encrypted'), self.OPTIONS.DigCrypt)

      self.optIndivKeyListTop = QRadioButtonBackupCtr(self, \
                                    tr('Export Key Lists'), self.OPTIONS.Export)


      self.optPaperBackupTop.setFont(GETFONT('Var', bold=True))
      self.optDigitalBackupTop.setFont(GETFONT('Var', bold=True))
      self.optIndivKeyListTop.setFont(GETFONT('Var', bold=True))

      # I need to be able to unset the sub-options when they become disabled
      self.optPaperBackupNONE = QRadioButton('')
      self.optDigitalBackupNONE = QRadioButton('')

      btngrpTop = QButtonGroup(self)
      btngrpTop.addButton(self.optPaperBackupTop)
      btngrpTop.addButton(self.optDigitalBackupTop)
      btngrpTop.addButton(self.optIndivKeyListTop)
      btngrpTop.setExclusive(True)

      btngrpPaper = QButtonGroup(self)
      btngrpPaper.addButton(self.optPaperBackupNONE)
      btngrpPaper.addButton(self.optPaperBackupOne)
      btngrpPaper.addButton(self.optPaperBackupFrag)
      btngrpPaper.setExclusive(True)

      btngrpDig = QButtonGroup(self)
      btngrpDig.addButton(self.optDigitalBackupNONE)
      btngrpDig.addButton(self.optDigitalBackupPlain)
      btngrpDig.addButton(self.optDigitalBackupCrypt)
      btngrpDig.setExclusive(True)

      self.connect(self.optPaperBackupTop, SIGNAL(CLICKED), self.optionClicked)
      self.connect(self.optPaperBackupOne, SIGNAL(CLICKED), self.optionClicked)
      self.connect(self.optPaperBackupFrag, SIGNAL(CLICKED), self.optionClicked)
      self.connect(self.optDigitalBackupTop, SIGNAL(CLICKED), self.optionClicked)
      self.connect(self.optDigitalBackupPlain, SIGNAL(CLICKED), self.optionClicked)
      self.connect(self.optDigitalBackupCrypt, SIGNAL(CLICKED), self.optionClicked)
      self.connect(self.optIndivKeyListTop, SIGNAL(CLICKED), self.optionClicked)


      spacer = lambda: QSpacerItem(20, 1, QSizePolicy.Fixed, QSizePolicy.Expanding)
      layoutOpts = QGridLayout()
      layoutOpts.addWidget(self.optPaperBackupTop, 0, 0, 1, 2)
      layoutOpts.addItem(spacer(), 1, 0)
      layoutOpts.addItem(spacer(), 2, 0)
      layoutOpts.addWidget(self.optDigitalBackupTop, 3, 0, 1, 2)
      layoutOpts.addItem(spacer(), 4, 0)
      layoutOpts.addItem(spacer(), 5, 0)
      layoutOpts.addWidget(self.optIndivKeyListTop, 6, 0, 1, 2)

      layoutOpts.addWidget(self.optPaperBackupOne, 1, 1)
      layoutOpts.addWidget(self.optPaperBackupFrag, 2, 1)
      layoutOpts.addWidget(self.optDigitalBackupPlain, 4, 1)
      layoutOpts.addWidget(self.optDigitalBackupCrypt, 5, 1)
      layoutOpts.setColumnStretch(0, 0)
      layoutOpts.setColumnStretch(1, 1)

      frmOpts = QFrame()
      frmOpts.setLayout(layoutOpts)
      frmOpts.setFrameStyle(STYLE_SUNKEN)


      self.featuresTips = [None] * self.FEATURES.Count
      self.featuresLbls = [None] * self.FEATURES.Count
      self.featuresImgs = [None] * self.FEATURES.Count


      F = self.FEATURES
      self.featuresTips[F.ProtGen] = self.main.createToolTipWidget(tr("""
         Every time you click "Receive Groestlcoins," a new address is generated.
         All of these addresses are generated from a single seed value, which
         is included in all backups.   Therefore, all addresses that you have
         generated so far <b>and</b> will ever be generated with this wallet, 
         are protected by this backup! """))

      self.featuresTips[F.ProtImport] = self.main.createToolTipWidget(tr("""
         <i>This wallet <u>does not</u> currently have any imported
         addresses, so you can safely ignore this feature!</i>
         When imported addresses are present, backups only protects those
         imported before the backup was made.  You must replace that
         backup if you import more addresses! """))

      self.featuresTips[F.LostPass] = self.main.createToolTipWidget(tr("""
         Lost/forgotten passphrases are, <b>by far</b>, the most common
         reason for users losing Groestlcoins.  It is critical you have
         at least one backup that works if you forget your wallet
         passphrase. """))

      self.featuresTips[F.Durable] = self.main.createToolTipWidget(tr("""
         USB drives and CD/DVD disks are not intended for long-term storage.
         They will <i>probably</i> last many years, but not guaranteed
         even for 3-5 years.   On the other hand, printed text on paper will
         last many decades, and useful even when thoroughly faded. """))

      self.featuresTips[F.Visual] = self.main.createToolTipWidget(tr("""
         The ability to look at a backup and determine if
         it is still usable.   If a digital backup is stored in a safe
         deposit box, you have no way to verify its integrity unless
         you take a secure computer/device with you.  A simple glance at
         a paper backup is enough to verify that it is still intact. """))

      self.featuresTips[F.Physical] = self.main.createToolTipWidget(tr("""
         If multiple pieces/fragments are required to restore this wallet.
         For instance, encrypted backups require the backup
         <b>and</b> the passphrase.  This feature is only needed for those
         concerned about physical security, not just online security."""))


      MkFeatLabel = lambda x: QRichLabel(tr(x), doWrap=False)
      self.featuresLbls[F.ProtGen] = MkFeatLabel('Protects All Future Addresses')
      self.featuresLbls[F.ProtImport] = MkFeatLabel('Protects Imported Addresses')
      self.featuresLbls[F.LostPass] = MkFeatLabel('Forgotten Passphrase')
      self.featuresLbls[F.Durable] = MkFeatLabel('Long-term Durability')
      self.featuresLbls[F.Visual] = MkFeatLabel('Visual Integrity')
      self.featuresLbls[F.Physical] = MkFeatLabel('Multi-Point Protection')

      if not self.hasImportedAddr:
         self.featuresLbls[F.ProtImport].setEnabled(False)

      self.lblSelFeat = QRichLabel('', doWrap=False, hAlign=Qt.AlignHCenter)

      layoutFeat = QGridLayout()
      layoutFeat.addWidget(self.lblSelFeat, 0, 0, 1, 3)
      layoutFeat.addWidget(HLINE(), 1, 0, 1, 3)
      for i in range(self.FEATURES.Count):
         self.featuresImgs[i] = QLabel('')
         layoutFeat.addWidget(self.featuresTips[i], i + 2, 0)
         layoutFeat.addWidget(self.featuresLbls[i], i + 2, 1)
         layoutFeat.addWidget(self.featuresImgs[i], i + 2, 2)
      layoutFeat.setColumnStretch(0, 0)
      layoutFeat.setColumnStretch(1, 1)
      layoutFeat.setColumnStretch(2, 0)

      frmFeat = QFrame()
      frmFeat.setLayout(layoutFeat)
      frmFeat.setFrameStyle(STYLE_SUNKEN)


      self.lblDescrSelected = QRichLabel('')
      frmFeatDescr = makeVertFrame([self.lblDescrSelected])
      self.lblDescrSelected.setMinimumHeight(tightSizeNChar(self, 10)[1] * 8)

      self.btnDoIt = QPushButton('Create Backup')
      self.connect(self.btnDoIt, SIGNAL(CLICKED), self.clickedDoIt)

      layout = QGridLayout()
      layout.addWidget(self.lblTitle, 0, 0, 1, 2)
      layout.addWidget(lblTitleDescr, 1, 0, 1, 2)
      layout.addWidget(frmOpts, 2, 0)
      layout.addWidget(frmFeat, 2, 1)
      layout.addWidget(frmFeatDescr, 3, 0, 1, 2)
      layout.addWidget(self.btnDoIt, 4, 0, 1, 2)
      layout.setRowStretch(0, 0)
      layout.setRowStretch(1, 0)
      layout.setRowStretch(2, 0)
      layout.setRowStretch(3, 1)
      layout.setRowStretch(4, 0)
      self.setLayout(layout)
      self.setMinimumSize(640, 350)

      self.optPaperBackupTop.setChecked(True)
      self.optPaperBackupOne.setChecked(True)
      self.setDispFrame(-1)
      self.optionClicked()
      
   #############################################################################
   def setWallet(self, wlt):
      self.wlt = wlt
      wltID = wlt.uniqueIDB58
      wltName = wlt.labelName
      self.hasImportedAddr = self.wlt.hasAnyImported()
      # Highlight imported-addr feature if their wallet contains them
      pcolor = 'TextWarn' if self.hasImportedAddr else 'DisableFG'
      self.featuresLbls[self.FEATURES.ProtImport].setText(tr(\
         'Protects Imported Addresses'), color=pcolor)

      if self.hasImportedAddr:
         self.featuresTips[self.FEATURES.ProtImport].setText(tr("""
            When imported addresses are present, backups only protects those
            imported before the backup was made!  You must replace that
            backup if you import more addresses!
            <i>Your wallet <u>does</u> contain imported addresses<i>."""))


         
      self.lblTitle.setText(tr("""
         <b>Backup Options for Wallet "%s" (%s)</b>""" % (wltName, wltID)))

   #############################################################################
   def setDispFrame(self, index):
      if index < 0:
         self.setDispFrame(self.getIndexChecked())
      else:
         # Highlight imported-addr feature if their wallet contains them
         pcolor = 'TextWarn' if self.hasImportedAddr else 'DisableFG'
         self.featuresLbls[self.FEATURES.ProtImport].setText(tr(\
            'Protects Imported Addresses'), color=pcolor)

         txtPaper = tr("""
               Paper backups protect every address ever generated by your
               wallet. It is unencrypted, which means it needs to be stored
               in a secure place, but it will help you recover your wallet
               if you forget your encryption passphrase!
               <br><br>
               <b>You don't need a printer to make a paper backup!
               The data can be copied by hand with pen and paper.</b>
               Paper backups are preferred to digital backups, because you
               know the paper backup will work no matter how many years (or
               decades) it sits in storage.  """)
         txtDigital = tr("""
               Digital backups can be saved to an external hard-drive or
               USB removable media.  It is recommended you make a few
               copies to protect against "bit rot" (degradation). <br><br>""")
         txtDigPlain = tr("""
               <b><u>IMPORTANT:</u> Do not save an unencrypted digital
               backup to your primary hard drive!</b>
               Please save it <i>directly</i> to the backup device.
               Deleting the file does not guarantee the data is actually
               gone!  """)
         txtDigCrypt = tr("""
               <b><u>IMPORTANT:</u> It is critical that you have at least
               one unencrypted backup!</b>  Without it, your Groestlcoins will
               be lost forever if you forget your passphrase!  This is <b>
               by far</b> the most common reason users lose coins!  Having
               at least one paper backup is recommended.""")
         txtIndivKeys = tr("""
               View and export invidivual addresses strings,
               public keys and/or private keys contained in your wallet.
               This is useful for exporting your private keys to be imported into
               another wallet app or service.
               <br><br>
               You can view/backup imported keys, as well as unused keys in your
               keypool (pregenerated addresses protected by your backup that
               have not yet been used). """)


         chk = lambda: QPixmap(':/checkmark32.png').scaled(20, 20)
         _X_ = lambda: QPixmap(':/red_X.png').scaled(16, 16)
         if index == self.OPTIONS.Paper1:
            self.lblSelFeat.setText(tr('Single-Sheet Paper Backup'), bold=True)
            self.featuresImgs[self.FEATURES.ProtGen   ].setPixmap(chk())
            self.featuresImgs[self.FEATURES.ProtImport].setPixmap(chk())
            self.featuresImgs[self.FEATURES.LostPass  ].setPixmap(chk())
            self.featuresImgs[self.FEATURES.Durable   ].setPixmap(chk())
            self.featuresImgs[self.FEATURES.Visual    ].setPixmap(chk())
            self.featuresImgs[self.FEATURES.Physical  ].setPixmap(_X_())
            self.lblDescrSelected.setText(txtPaper)
         elif index == self.OPTIONS.PaperN:
            self.lblSelFeat.setText(tr('Fragmented Paper Backup'), bold=True)
            self.featuresImgs[self.FEATURES.ProtGen   ].setPixmap(chk())
            self.featuresImgs[self.FEATURES.ProtImport].setPixmap(_X_())
            self.featuresImgs[self.FEATURES.LostPass  ].setPixmap(chk())
            self.featuresImgs[self.FEATURES.Durable   ].setPixmap(chk())
            self.featuresImgs[self.FEATURES.Visual    ].setPixmap(chk())
            self.featuresImgs[self.FEATURES.Physical  ].setPixmap(chk())
            self.lblDescrSelected.setText(txtPaper)
         elif index == self.OPTIONS.DigPlain:
            self.lblSelFeat.setText(tr('Unencrypted Digital Backup'), bold=True)
            self.featuresImgs[self.FEATURES.ProtGen   ].setPixmap(chk())
            self.featuresImgs[self.FEATURES.ProtImport].setPixmap(chk())
            self.featuresImgs[self.FEATURES.LostPass  ].setPixmap(chk())
            self.featuresImgs[self.FEATURES.Durable   ].setPixmap(_X_())
            self.featuresImgs[self.FEATURES.Visual    ].setPixmap(_X_())
            self.featuresImgs[self.FEATURES.Physical  ].setPixmap(_X_())
            self.lblDescrSelected.setText(txtDigital + txtDigPlain)
         elif index == self.OPTIONS.DigCrypt:
            self.lblSelFeat.setText(tr('Encrypted Digital Backup'), bold=True)
            self.featuresImgs[self.FEATURES.ProtGen   ].setPixmap(chk())
            self.featuresImgs[self.FEATURES.ProtImport].setPixmap(chk())
            self.featuresImgs[self.FEATURES.LostPass  ].setPixmap(_X_())
            self.featuresImgs[self.FEATURES.Durable   ].setPixmap(_X_())
            self.featuresImgs[self.FEATURES.Visual    ].setPixmap(_X_())
            self.featuresImgs[self.FEATURES.Physical  ].setPixmap(chk())
            self.lblDescrSelected.setText(txtDigital + txtDigCrypt)
         elif index == self.OPTIONS.Export:
            self.lblSelFeat.setText(tr('Export Key Lists'), bold=True)
            self.featuresImgs[self.FEATURES.ProtGen   ].setPixmap(chk())
            self.featuresImgs[self.FEATURES.ProtImport].setPixmap(chk())
            self.featuresImgs[self.FEATURES.LostPass  ].setPixmap(chk())
            self.featuresImgs[self.FEATURES.Durable   ].setPixmap(_X_())
            self.featuresImgs[self.FEATURES.Visual    ].setPixmap(_X_())
            self.featuresImgs[self.FEATURES.Physical  ].setPixmap(_X_())
            self.lblDescrSelected.setText(txtIndivKeys)
         else:
            LOGERROR('What index was sent to setDispFrame? %d', index)
            
   #############################################################################
   def getIndexChecked(self):
      if self.optPaperBackupOne.isChecked():
         return self.OPTIONS.Paper1
      elif self.optPaperBackupFrag.isChecked():
         return self.OPTIONS.PaperN
      elif self.optPaperBackupTop.isChecked():
         return self.OPTIONS.Paper1
      elif self.optDigitalBackupPlain.isChecked():
         return self.OPTIONS.DigPlain
      elif self.optDigitalBackupCrypt.isChecked():
         return self.OPTIONS.DigCrypt
      elif self.optDigitalBackupTop.isChecked():
         return self.OPTIONS.DigPlain
      elif self.optIndivKeyListTop.isChecked():
         return self.OPTIONS.Export
      else:
         return 0

   #############################################################################
   def optionClicked(self):
      if self.optPaperBackupTop.isChecked():
         self.optPaperBackupOne.setEnabled(True)
         self.optPaperBackupFrag.setEnabled(True)
         self.optDigitalBackupPlain.setEnabled(False)
         self.optDigitalBackupCrypt.setEnabled(False)
         self.optDigitalBackupPlain.setChecked(False)
         self.optDigitalBackupCrypt.setChecked(False)
         self.optDigitalBackupNONE.setChecked(True)
         self.btnDoIt.setText(tr('Create Paper Backup'))
      elif self.optDigitalBackupTop.isChecked():
         self.optDigitalBackupPlain.setEnabled(True)
         self.optDigitalBackupCrypt.setEnabled(True)
         self.optPaperBackupOne.setEnabled(False)
         self.optPaperBackupFrag.setEnabled(False)
         self.optPaperBackupOne.setChecked(False)
         self.optPaperBackupFrag.setChecked(False)
         self.optPaperBackupNONE.setChecked(True)
         self.btnDoIt.setText(tr('Create Digital Backup'))
      elif self.optIndivKeyListTop.isChecked():
         self.optPaperBackupOne.setEnabled(False)
         self.optPaperBackupFrag.setEnabled(False)
         self.optPaperBackupOne.setChecked(False)
         self.optPaperBackupFrag.setChecked(False)
         self.optDigitalBackupPlain.setEnabled(False)
         self.optDigitalBackupCrypt.setEnabled(False)
         self.optDigitalBackupPlain.setChecked(False)
         self.optDigitalBackupCrypt.setChecked(False)
         self.optDigitalBackupNONE.setChecked(True)
         self.optPaperBackupNONE.setChecked(True)
         self.btnDoIt.setText(tr('Export Key Lists'))
      self.setDispFrame(-1)

   def setPassphrase(self, passphrase):
      self.passphrase = passphrase
      
   def clickedDoIt(self):
      isBackupCreated = False
      
      if self.passphrase:
         from qtdialogs import DlgProgress
         unlockProgress = DlgProgress(self, self.main, HBar=1,
                                      Title="Unlocking Wallet")
         unlockProgress.exec_(self.wlt.unlock, 
                              securePassphrase=SecureBinaryData( \
                              self.passphrase),
                              Progress=unlockProgress.UpdateHBar)
         
      if self.optPaperBackupOne.isChecked():
         isBackupCreated = OpenPaperBackupWindow('Single', self.parent(), self.main, self.wlt)
      elif self.optPaperBackupFrag.isChecked():
         isBackupCreated = OpenPaperBackupWindow('Frag', self.parent(), self.main, self.wlt)
      elif self.optDigitalBackupPlain.isChecked():
         if self.main.digitalBackupWarning():
            isBackupCreated = self.main.makeWalletCopy(self, self.wlt, 'Decrypt', 'decrypt')
      elif self.optDigitalBackupCrypt.isChecked():
         isBackupCreated = self.main.makeWalletCopy(self, self.wlt, 'Encrypt', 'encrypt')
      elif self.optIndivKeyListTop.isChecked():
         if self.wlt.useEncryption and self.wlt.isLocked:
            dlg = DlgUnlockWallet(self.wlt, self, self.main, 'Unlock Private Keys')
            if not dlg.exec_():
               if self.main.usermode == USERMODE.Expert:
                  QMessageBox.warning(self, tr('Unlock Failed'), tr("""
                     Wallet was not be unlocked.  The public keys and addresses
                     will still be shown, but private keys will not be available
                     unless you reopen the dialog with the correct passphrase."""), \
                     QMessageBox.Ok)
               else:
                  QMessageBox.warning(self, tr('Unlock Failed'), tr("""
                     'Wallet could not be unlocked to display individual keys."""), \
                     QMessageBox.Ok)
                  if self.main.usermode == USERMODE.Standard:
                     return
         DlgShowKeyList(self.wlt, self.parent(), self.main).exec_()
         isBackupCreated = True
      if isBackupCreated:
         self.isBackupCreated = True