diff options
| -rw-r--r-- | src/leap/gui/firstrun/providerselect.py | 107 | ||||
| -rw-r--r-- | src/leap/gui/progress.py | 169 | 
2 files changed, 187 insertions, 89 deletions
diff --git a/src/leap/gui/firstrun/providerselect.py b/src/leap/gui/firstrun/providerselect.py index 8d1aa869..fc030cf3 100644 --- a/src/leap/gui/firstrun/providerselect.py +++ b/src/leap/gui/firstrun/providerselect.py @@ -11,12 +11,13 @@ from PyQt4 import QtGui  #from leap.eip import exceptions as eipexceptions  from leap.gui.constants import APP_LOGO +from leap.gui.progress import InlineValidationPage  from leap.gui.styles import ErrorLabelStyleSheet  logger = logging.getLogger(__name__) -class SelectProviderPage(QtGui.QWizardPage): +class SelectProviderPage(InlineValidationPage):      def __init__(self, parent=None, providers=None):          super(SelectProviderPage, self).__init__(parent) @@ -32,6 +33,18 @@ class SelectProviderPage(QtGui.QWizardPage):          self.did_cert_check = False          self.current_page = 'providerselection' +        self.is_done = False + +        self.setupSteps() +        self.setupUI() + +        self.stepChanged.connect( +            self.onStepStatusChanged) + +    def setupUI(self): +        """ +        initializes the UI +        """          providerNameLabel = QtGui.QLabel("h&ttps://")          # note that we expect the bare domain name          # we will add the scheme later @@ -61,6 +74,8 @@ class SelectProviderPage(QtGui.QWizardPage):          validationMsg = QtGui.QLabel("")          validationMsg.setStyleSheet(ErrorLabelStyleSheet)          self.validationMsg = validationMsg +        providerCheckButton = QtGui.QPushButton("check") +        self.providerCheckButton = providerCheckButton          # cert info @@ -81,25 +96,66 @@ class SelectProviderPage(QtGui.QWizardPage):              self.onTrustCheckChanged)          self.providerNameEdit.textChanged.connect(              self.onProviderChanged) +        self.providerCheckButton.clicked.connect( +            self.onCheckButtonClicked)          layout = QtGui.QGridLayout()          layout.addWidget(validationMsg, 0, 2)          layout.addWidget(providerNameLabel, 1, 1)          layout.addWidget(providerNameEdit, 1, 2) +        layout.addWidget(providerCheckButton, 1, 3) + +        # add certinfo group +        # XXX not shown now. should move to validation box. +        #layout.addWidget(certinfoGroup, 4, 1, 4, 2) +        #self.certinfoGroup = certinfoGroup +        #self.certinfoGroup.hide() + +        # add validation frame +        self.setupValidationFrame() +        layout.addWidget(self.valFrame, 4, 1, 4, 2) +        self.valFrame.hide() + +        self.setLayout(layout) -        # XXX get a groupbox or something.... +    # certinfo + +    def setupCertInfoGroup(self): +        # XXX not used now.          certinfoGroup = QtGui.QGroupBox("Certificate validation")          certinfoLayout = QtGui.QVBoxLayout()          certinfoLayout.addWidget(self.certInfo)          certinfoLayout.addWidget(self.certWarning)          certinfoLayout.addWidget(self.trustProviderCertCheckBox)          certinfoGroup.setLayout(certinfoLayout) +        self.certinfoGroup = self.certinfoGroup + +    # progress frame + +    def setupValidationFrame(self): +        qframe = QtGui.QFrame +        valFrame = qframe() +        valFrame.setFrameStyle(qframe.StyledPanel)  # | qframe.Sunken) +        valframeLayout = QtGui.QVBoxLayout() + +        #dummylabel = QtGui.QLabel('test foo') +        #valframeLayout.addWidget(dummylabel) +        valframeLayout.addWidget(self.stepsTableWidget) +        valFrame.setLayout(valframeLayout) +        self.valFrame = valFrame + +    # check domain + +    def onCheckButtonClicked(self): +        import time +        time.sleep(1) +        self.is_done = True +        self.providerCheckButton.setDisabled(True) +        self.stepChanged.emit('foo check', 0) +        self.valFrame.show() +        self.completeChanged.emit() -        layout.addWidget(certinfoGroup, 4, 1, 4, 2) -        self.certinfoGroup = certinfoGroup -        self.certinfoGroup.hide() - -        self.setLayout(layout) +    # cert trust verification      def is_insecure_cert_trusted(self):          return self.trustProviderCertCheckBox.isChecked() @@ -117,7 +173,20 @@ class SelectProviderPage(QtGui.QWizardPage):          # trigger signal to redraw next button          self.completeChanged.emit() +    def add_cert_info(self, certinfo): +        self.certWarning.setText( +            "Do you want to <b>trust this provider certificate?</b>") +        self.certInfo.setText( +            'SHA-256 fingerprint: <i>%s</i><br>' % certinfo) +        self.certInfo.setWordWrap(True) +        self.certinfoGroup.show() +      def onProviderChanged(self, text): +        provider = self.providerNameEdit.text() +        if provider: +            self.providerCheckButton.setDisabled(False) +        else: +            self.providerCheckButton.setDisabled(True)          self.completeChanged.emit()      def reset_validation_status(self): @@ -126,29 +195,23 @@ class SelectProviderPage(QtGui.QWizardPage):          """          self.validationMsg.setText('') -    #def set_validation_status(selF, STATUS): -        #self.validationMsg.setText(status) - -    def add_cert_info(self, certinfo): -        self.certWarning.setText( -            "Do you want to <b>trust this provider certificate?</b>") -        self.certInfo.setText( -            'SHA-256 fingerprint: <i>%s</i><br>' % certinfo) -        self.certInfo.setWordWrap(True) -        self.certinfoGroup.show() -      # pagewizard methods      def isComplete(self):          provider = self.providerNameEdit.text() +        if not self.is_done: +            return False +          if not provider:              return False          else:              if self.is_insecure_cert_trusted():                  return True              if not self.did_cert_check: -                return True +                if self.is_done: +                    # XXX sure? +                    return True              return False      def populateErrors(self): @@ -195,7 +258,11 @@ class SelectProviderPage(QtGui.QWizardPage):      def initializePage(self):          self.validationMsg.setText('') -        self.certinfoGroup.hide() +        if hasattr(self, 'certinfoGroup'): +            # XXX remove ? +            self.certinfoGroup.hide() +        self.is_done = False +        self.providerCheckButton.setDisabled(True)      def validatePage(self):          # some cleanup before we leave the page diff --git a/src/leap/gui/progress.py b/src/leap/gui/progress.py index 687356aa..3ade28b3 100644 --- a/src/leap/gui/progress.py +++ b/src/leap/gui/progress.py @@ -144,67 +144,28 @@ class StepsTableWidget(QtGui.QTableWidget):          # some failing tests if they are not critical. -class ValidationPage(QtGui.QWizardPage): -    """ -    class to be used as an intermediate -    between two pages in a wizard. -    shows feedback to the user and goes back if errors, -    goes forward if ok. -    initializePage triggers a one shot timer -    that calls do_checks. -    Derived classes should implement -    _do_checks and -    _do_validation -    """ +class WithStepsMixIn(object): -    # signals - -    stepChanged = QtCore.pyqtSignal([str, int]) +    def connect_step_status(self): +        print 'connect method called' +        self.stepChanged.connect( +            self.onStepStatusChanged) -    def __init__(self, parent=None): -        super(ValidationPage, self).__init__(parent) +    # slot +    #@QtCore.pyqtSlot(QtCore.QString, int) +    def onStepStatusChanged(self, status, progress=None): +        import pdb4qt; pdb4qt.set_trace() +        if status not in ("head_sentinel", "end_sentinel"): +            self.add_status_line(status) +        if progress and hasattr(self, 'progress'): +            self.progress.setValue(progress) +            self.progress.update() +    def setupSteps(self):          self.steps = ProgressStepContainer() -        self.progress = QtGui.QProgressBar(self) -          # steps table widget          self.stepsTableWidget = StepsTableWidget(self) - -        layout = QtGui.QVBoxLayout() -        layout.addWidget(self.progress) -        layout.addWidget(self.stepsTableWidget) - -        self.setLayout(layout) -        self.layout = layout - -        self.timer = QtCore.QTimer() - -        # connect the new step status -        # signal to status handler -        self.stepChanged.connect( -            self.onStepStatusChanged) -          self.errors = OrderedDict() -        self.done = False - -    # Sets/unsets done flag -    # for isComplete checks - -    def set_done(self): -        self.done = True -        self.completeChanged.emit() - -    def set_undone(self): -        self.done = False -        self.completeChanged.emit() - -    def is_done(self): -        return self.done - -    def isComplete(self): -        return self.is_done() - -    ########################      def set_error(self, name, error):          self.errors[name] = error @@ -255,13 +216,6 @@ class ValidationPage(QtGui.QWizardPage):          logger.debug('populate table. width=%s' % width)          table.horizontalHeader().resizeSection(0, width * FIRST_COLUMN_PERCENT) -    def onStepStatusChanged(self, status, progress=None): -        if status not in ("head_sentinel", "end_sentinel"): -            self.add_status_line(status) -        if progress: -            self.progress.setValue(progress) -            self.progress.update() -      def add_status_line(self, message):          index = len(self.steps)          step = ProgressStep(message, False, index=index) @@ -279,20 +233,86 @@ class ValidationPage(QtGui.QWizardPage):              ImgWidget(img=CHECKMARK_IMG))          table.update() + +""" +Resist the temptation to refactor the declaration of the signal +to the mixin. +PyQt and multiple inheritance do not mix well together. +You can only have one QObject base. +Therefore, we will use one base class for the intermediate pages +and another one for the in-page validations, both sharing the creation +of the tablewidgets. +""" + + +class InlineValidationPage(QtGui.QWizardPage, WithStepsMixIn): + +    # signals +    stepChanged = QtCore.pyqtSignal([str, int]) + +    def __init__(self, parent=None): +        super(InlineValidationPage, self).__init__(parent) +        self.connect_step_status() + + +class ValidationPage(QtGui.QWizardPage, WithStepsMixIn): +    """ +    class to be used as an intermediate +    between two pages in a wizard. +    shows feedback to the user and goes back if errors, +    goes forward if ok. +    initializePage triggers a one shot timer +    that calls do_checks. +    Derived classes should implement +    _do_checks and +    _do_validation +    """ + +    # signals +    stepChanged = QtCore.pyqtSignal([str, int]) + +    def __init__(self, parent=None): +        super(ValidationPage, self).__init__(parent) +        self.setupSteps() +        self.connect_step_status() + +        layout = QtGui.QVBoxLayout() +        self.progress = QtGui.QProgressBar(self) +        layout.addWidget(self.progress) +        layout.addWidget(self.stepsTableWidget) + +        self.setLayout(layout) +        self.layout = layout + +        self.timer = QtCore.QTimer() + +        self.done = False + +    # Sets/unsets done flag +    # for isComplete checks + +    def set_done(self): +        self.done = True +        self.completeChanged.emit() + +    def set_undone(self): +        self.done = False +        self.completeChanged.emit() + +    def is_done(self): +        return self.done + +    def isComplete(self): +        return self.is_done() + +    ######################## +      def go_back(self):          self.wizard().back()      def go_next(self):          self.wizard().next() -    def initializePage(self): -        self.clean_errors() -        self.clean_wizard_errors() -        self.steps.removeAllSteps() -        self.clearTable() -        self.resizeTable() -        self.timer.singleShot(0, self.do_checks) -      def do_checks(self):          """          launches a thread to do the checks @@ -313,3 +333,14 @@ class ValidationPage(QtGui.QWizardPage):      def hide_progress(self):          self.progress.hide()          self.stepsTableWidget.hide() + +    # pagewizard methods. +    # if overriden, child classes should call super. + +    def initializePage(self): +        self.clean_errors() +        self.clean_wizard_errors() +        self.steps.removeAllSteps() +        self.clearTable() +        self.resizeTable() +        self.timer.singleShot(0, self.do_checks)  | 
