From 4153bee65d2541b99d4e41aaaf2fd6b2b71b2cc3 Mon Sep 17 00:00:00 2001 From: kali Date: Mon, 19 Nov 2012 23:15:36 +0900 Subject: disable "next" button during validation and wait for user to click it. Closes #973 --- src/leap/gui/progress.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'src/leap/gui/progress.py') diff --git a/src/leap/gui/progress.py b/src/leap/gui/progress.py index 6e8abc1f..687356aa 100644 --- a/src/leap/gui/progress.py +++ b/src/leap/gui/progress.py @@ -185,6 +185,26 @@ class ValidationPage(QtGui.QWizardPage): 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 @@ -285,3 +305,11 @@ class ValidationPage(QtGui.QWizardPage): #logger.debug('check thread started!') #logger.debug('waiting for it to terminate...') self.checks.wait() + + def show_progress(self): + self.progress.show() + self.stepsTableWidget.show() + + def hide_progress(self): + self.progress.hide() + self.stepsTableWidget.hide() -- cgit v1.2.3 From d225d5a4eb0a8e63eb11a0311c732bda88e8385b Mon Sep 17 00:00:00 2001 From: kali Date: Tue, 20 Nov 2012 04:11:01 +0900 Subject: TableWidget refactor so we can use it also in the inline validation widgets. --- src/leap/gui/progress.py | 169 ++++++++++++++++++++++++++++------------------- 1 file changed, 100 insertions(+), 69 deletions(-) (limited to 'src/leap/gui/progress.py') 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) -- cgit v1.2.3 From 4e1d0ed099a82843cbb91d5f417c552e9f1674e2 Mon Sep 17 00:00:00 2001 From: kali Date: Tue, 20 Nov 2012 19:09:11 +0900 Subject: added inline panel within zero-margin frame --- src/leap/gui/progress.py | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'src/leap/gui/progress.py') diff --git a/src/leap/gui/progress.py b/src/leap/gui/progress.py index 3ade28b3..cbfa6194 100644 --- a/src/leap/gui/progress.py +++ b/src/leap/gui/progress.py @@ -152,11 +152,12 @@ class WithStepsMixIn(object): self.onStepStatusChanged) # slot - #@QtCore.pyqtSlot(QtCore.QString, int) + #@QtCore.pyqtSlot(str, 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 status in ("end_sentinel"): + self.check_last_item() if progress and hasattr(self, 'progress'): self.progress.setValue(progress) self.progress.update() @@ -165,6 +166,8 @@ class WithStepsMixIn(object): self.steps = ProgressStepContainer() # steps table widget self.stepsTableWidget = StepsTableWidget(self) + zeros = (0, 0, 0, 0) + self.stepsTableWidget.setContentsMargins(*zeros) self.errors = OrderedDict() def set_error(self, name, error): @@ -216,6 +219,19 @@ class WithStepsMixIn(object): logger.debug('populate table. width=%s' % width) table.horizontalHeader().resizeSection(0, width * FIRST_COLUMN_PERCENT) + def check_last_item(self): + """ + mark the last item + as done + """ + index = len(self.steps) + table = self.stepsTableWidget + table.setCellWidget( + index - 1, + ProgressStep.DONE, + ImgWidget(img=CHECKMARK_IMG)) + table.update() + def add_status_line(self, message): index = len(self.steps) step = ProgressStep(message, False, index=index) -- cgit v1.2.3 From 7dceb11bcd4cf552938ccfa02daaf6f902ef385b Mon Sep 17 00:00:00 2001 From: kali Date: Wed, 21 Nov 2012 05:15:06 +0900 Subject: tango icons for checking/checked/failed check status --- src/leap/gui/progress.py | 63 +++++++++++++++++++++++++++++++++++------------- 1 file changed, 46 insertions(+), 17 deletions(-) (limited to 'src/leap/gui/progress.py') diff --git a/src/leap/gui/progress.py b/src/leap/gui/progress.py index cbfa6194..10d19207 100644 --- a/src/leap/gui/progress.py +++ b/src/leap/gui/progress.py @@ -17,7 +17,9 @@ from leap.gui.threads import FunThread from leap.gui import mainwindow_rc -CHECKMARK_IMG = ":/images/checked.png" +ICON_CHECKMARK = ":/images/Dialog-accept.png" +ICON_FAILED = ":/images/Dialog-error.png" +ICON_WAITING = ":/images/Emblem-question.png" logger = logging.getLogger(__name__) @@ -147,17 +149,21 @@ class StepsTableWidget(QtGui.QTableWidget): class WithStepsMixIn(object): def connect_step_status(self): - print 'connect method called' self.stepChanged.connect( self.onStepStatusChanged) + def connect_failstep_status(self): + self.stepFailed.connect( + self.set_failed_icon) + # slot #@QtCore.pyqtSlot(str, int) def onStepStatusChanged(self, status, progress=None): if status not in ("head_sentinel", "end_sentinel"): self.add_status_line(status) if status in ("end_sentinel"): - self.check_last_item() + self.checks_finished = True + self.set_checked_icon() if progress and hasattr(self, 'progress'): self.progress.setValue(progress) self.progress.update() @@ -219,35 +225,44 @@ class WithStepsMixIn(object): logger.debug('populate table. width=%s' % width) table.horizontalHeader().resizeSection(0, width * FIRST_COLUMN_PERCENT) - def check_last_item(self): + def set_item_icon(self, img=ICON_CHECKMARK, current=True): """ mark the last item as done """ + # setting cell widget. + # see note on StepsTableWidget about plans to + # change this for a better solution. index = len(self.steps) table = self.stepsTableWidget + _index = index - 1 if current else index - 2 table.setCellWidget( - index - 1, + _index, ProgressStep.DONE, - ImgWidget(img=CHECKMARK_IMG)) + ImgWidget(img=img)) table.update() + def set_failed_icon(self): + self.set_item_icon(img=ICON_FAILED, current=True) + + def set_checking_icon(self): + self.set_item_icon(img=ICON_WAITING, current=True) + + def set_checked_icon(self, current=True): + self.set_item_icon(current=current) + def add_status_line(self, message): + """ + adds a new status line + and mark the next-to-last item + as done + """ index = len(self.steps) step = ProgressStep(message, False, index=index) self.steps.addStep(step) self.populateStepsTable() - table = self.stepsTableWidget - - # setting cell widget. - # see note on StepsTableWidget about plans to - # change this for a better solution. - - table.setCellWidget( - index - 1, - ProgressStep.DONE, - ImgWidget(img=CHECKMARK_IMG)) - table.update() + self.set_checking_icon() + self.set_checked_icon(current=False) """ @@ -265,10 +280,24 @@ class InlineValidationPage(QtGui.QWizardPage, WithStepsMixIn): # signals stepChanged = QtCore.pyqtSignal([str, int]) + stepFailed = QtCore.pyqtSignal() def __init__(self, parent=None): super(InlineValidationPage, self).__init__(parent) self.connect_step_status() + self.connect_failstep_status() + + def do_checks(self): + """ + launches a thread to do the checks + """ + beupdate = self.stepChanged + befailed = self.stepFailed + self.checks = FunThread( + self._do_checks(update_signal=beupdate, failed_signal=befailed)) + self.checks.finished.connect(self._inline_validation_ready) + self.checks.begin() + #self.checks.wait() class ValidationPage(QtGui.QWizardPage, WithStepsMixIn): -- cgit v1.2.3 From 53c6c92e26970de7de0bddca0034e72af7d0ce48 Mon Sep 17 00:00:00 2001 From: kali Date: Wed, 21 Nov 2012 06:15:41 +0900 Subject: add red border to failed field --- src/leap/gui/progress.py | 1 + 1 file changed, 1 insertion(+) (limited to 'src/leap/gui/progress.py') diff --git a/src/leap/gui/progress.py b/src/leap/gui/progress.py index 10d19207..33b0cb8c 100644 --- a/src/leap/gui/progress.py +++ b/src/leap/gui/progress.py @@ -369,6 +369,7 @@ class ValidationPage(QtGui.QWizardPage, WithStepsMixIn): self.checks.begin() #logger.debug('check thread started!') #logger.debug('waiting for it to terminate...') + # XXX needed for it to join? self.checks.wait() def show_progress(self): -- cgit v1.2.3 From 7bf4c0aa6db8cbaa1befdb2841f722554a3a0731 Mon Sep 17 00:00:00 2001 From: kali Date: Wed, 21 Nov 2012 23:01:06 +0900 Subject: fixed ui freeze using queue for passing status between worker and parent --- src/leap/gui/progress.py | 97 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 76 insertions(+), 21 deletions(-) (limited to 'src/leap/gui/progress.py') diff --git a/src/leap/gui/progress.py b/src/leap/gui/progress.py index 33b0cb8c..9a5b352c 100644 --- a/src/leap/gui/progress.py +++ b/src/leap/gui/progress.py @@ -24,6 +24,24 @@ ICON_WAITING = ":/images/Emblem-question.png" logger = logging.getLogger(__name__) +# XXX import this from threads +def delay(obj, method_str=None, call_args=None): + """ + this is a hack to get responsiveness in the ui + """ + if callable(obj) and not method_str: + QtCore.QTimer().singleShot( + 50, + lambda: obj()) + return + + if method_str: + QtCore.QTimer().singleShot( + 50, + lambda: QtCore.QMetaObject.invokeMethod( + obj, method_str)) + + class ImgWidget(QtGui.QWidget): # XXX move to widgets @@ -168,6 +186,22 @@ class WithStepsMixIn(object): self.progress.setValue(progress) self.progress.update() + def processStepsQueue(self): + """ + consume steps queue + and pass messages + to the ui updater functions + """ + while self.queue.qsize(): + try: + status = self.queue.get(0) + if status == "failed": + self.set_failed_icon() + else: + self.onStepStatusChanged(*status) + except Queue.Empty: + pass + def setupSteps(self): self.steps = ProgressStepContainer() # steps table widget @@ -266,38 +300,59 @@ class WithStepsMixIn(object): """ -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 +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. +The logic of this split comes from where I was trying to solve +the ui update using signals, but now that it's working well with +queues I could join them again. """ +import Queue +from functools import partial -class InlineValidationPage(QtGui.QWizardPage, WithStepsMixIn): - # signals - stepChanged = QtCore.pyqtSignal([str, int]) - stepFailed = QtCore.pyqtSignal() +class InlineValidationPage(QtGui.QWizardPage, WithStepsMixIn): def __init__(self, parent=None): super(InlineValidationPage, self).__init__(parent) - self.connect_step_status() - self.connect_failstep_status() + + self.queue = Queue.Queue() + self.timer = QtCore.QTimer() + self.timer.timeout.connect(self.processStepsQueue) + self.timer.start(100) + self.threads = [] def do_checks(self): - """ - launches a thread to do the checks - """ - beupdate = self.stepChanged - befailed = self.stepFailed - self.checks = FunThread( - self._do_checks(update_signal=beupdate, failed_signal=befailed)) - self.checks.finished.connect(self._inline_validation_ready) - self.checks.begin() - #self.checks.wait() + + # yo dawg, I heard you like checks + # so I put a __do_checks in your do_checks + # for calling others' _do_checks + + def __do_checks(fun=None, queue=None): + + for checkcase in fun(): + checkmsg, checkfun = checkcase + + queue.put(checkmsg) + if checkfun() is False: + queue.put("failed") + break + + t = FunThread(fun=partial( + __do_checks, + fun=self._do_checks, + queue=self.queue)) + t.finished.connect(self._inline_validation_ready) + t.begin() + self.threads.append(t) + + # slot + + @QtCore.pyqtSlot() + def showStepsFrame(self): + self.valFrame.show() + self.update() class ValidationPage(QtGui.QWizardPage, WithStepsMixIn): -- cgit v1.2.3 From 60ae69dd79fc4a17e54e9f898b04c7130d8b9f6e Mon Sep 17 00:00:00 2001 From: kali Date: Thu, 22 Nov 2012 06:26:02 +0900 Subject: fix widgets focus on providerselect page it works with enter, enter, enter :) dedicated to DJ Focus... --- src/leap/gui/progress.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/leap/gui/progress.py') diff --git a/src/leap/gui/progress.py b/src/leap/gui/progress.py index 9a5b352c..331db6b2 100644 --- a/src/leap/gui/progress.py +++ b/src/leap/gui/progress.py @@ -145,6 +145,8 @@ class StepsTableWidget(QtGui.QTableWidget): # this disables the table grid. # we should add alignment to the ImgWidget (it's top-left now) self.setShowGrid(False) + self.setFocusPolicy(QtCore.Qt.NoFocus) + #self.setStyleSheet("QTableView{outline: 0;}") # XXX change image for done to rc @@ -254,7 +256,7 @@ class WithStepsMixIn(object): def resizeTable(self): # resize first column to ~80% table = self.stepsTableWidget - FIRST_COLUMN_PERCENT = 0.75 + FIRST_COLUMN_PERCENT = 0.70 width = table.width() logger.debug('populate table. width=%s' % width) table.horizontalHeader().resizeSection(0, width * FIRST_COLUMN_PERCENT) -- cgit v1.2.3 From 7a263b8ee74cc92ba39796cd9ad48395adfa7450 Mon Sep 17 00:00:00 2001 From: kali Date: Fri, 23 Nov 2012 05:13:36 +0900 Subject: refactor validation mixin; progress until register page --- src/leap/gui/progress.py | 149 ++++++++++++++++++++++++----------------------- 1 file changed, 76 insertions(+), 73 deletions(-) (limited to 'src/leap/gui/progress.py') diff --git a/src/leap/gui/progress.py b/src/leap/gui/progress.py index 331db6b2..4f3a7d81 100644 --- a/src/leap/gui/progress.py +++ b/src/leap/gui/progress.py @@ -168,13 +168,43 @@ class StepsTableWidget(QtGui.QTableWidget): class WithStepsMixIn(object): - def connect_step_status(self): - self.stepChanged.connect( - self.onStepStatusChanged) + # worker threads for checks + + def setupStepsProcessingQueue(self): + self.steps_queue = Queue.Queue() + self.stepscheck_timer = QtCore.QTimer() + self.stepscheck_timer.timeout.connect(self.processStepsQueue) + self.stepscheck_timer.start(100) + # we need to keep a reference to child threads + self.threads = [] - def connect_failstep_status(self): - self.stepFailed.connect( - self.set_failed_icon) + def do_checks(self): + + # yo dawg, I heard you like checks + # so I put a __do_checks in your do_checks + # for calling others' _do_checks + + def __do_checks(fun=None, queue=None): + + for checkcase in fun(): + checkmsg, checkfun = checkcase + + queue.put(checkmsg) + if checkfun() is False: + queue.put("failed") + break + + t = FunThread(fun=partial( + __do_checks, + fun=self._do_checks, + queue=self.steps_queue)) + t.finished.connect(self.on_checks_validation_ready) + t.begin() + self.threads.append(t) + + @QtCore.pyqtSlot() + def launch_checks(self): + self.do_checks() # slot #@QtCore.pyqtSlot(str, int) @@ -194,9 +224,9 @@ class WithStepsMixIn(object): and pass messages to the ui updater functions """ - while self.queue.qsize(): + while self.steps_queue.qsize(): try: - status = self.queue.get(0) + status = self.steps_queue.get(0) if status == "failed": self.set_failed_icon() else: @@ -300,6 +330,26 @@ class WithStepsMixIn(object): self.set_checking_icon() self.set_checked_icon(current=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 go_back(self): + self.wizard().back() + + def go_next(self): + self.wizard().next() + """ We will use one base class for the intermediate pages @@ -318,36 +368,8 @@ class InlineValidationPage(QtGui.QWizardPage, WithStepsMixIn): def __init__(self, parent=None): super(InlineValidationPage, self).__init__(parent) - - self.queue = Queue.Queue() - self.timer = QtCore.QTimer() - self.timer.timeout.connect(self.processStepsQueue) - self.timer.start(100) - self.threads = [] - - def do_checks(self): - - # yo dawg, I heard you like checks - # so I put a __do_checks in your do_checks - # for calling others' _do_checks - - def __do_checks(fun=None, queue=None): - - for checkcase in fun(): - checkmsg, checkfun = checkcase - - queue.put(checkmsg) - if checkfun() is False: - queue.put("failed") - break - - t = FunThread(fun=partial( - __do_checks, - fun=self._do_checks, - queue=self.queue)) - t.finished.connect(self._inline_validation_ready) - t.begin() - self.threads.append(t) + self.setupStepsProcessingQueue() + self.done = False # slot @@ -356,6 +378,20 @@ class InlineValidationPage(QtGui.QWizardPage, WithStepsMixIn): self.valFrame.show() self.update() + # progress frame + + def setupValidationFrame(self): + qframe = QtGui.QFrame + valFrame = qframe() + valFrame.setFrameStyle(qframe.NoFrame) + valframeLayout = QtGui.QVBoxLayout() + zeros = (0, 0, 0, 0) + valframeLayout.setContentsMargins(*zeros) + + valframeLayout.addWidget(self.stepsTableWidget) + valFrame.setLayout(valframeLayout) + self.valFrame = valFrame + class ValidationPage(QtGui.QWizardPage, WithStepsMixIn): """ @@ -376,7 +412,7 @@ class ValidationPage(QtGui.QWizardPage, WithStepsMixIn): def __init__(self, parent=None): super(ValidationPage, self).__init__(parent) self.setupSteps() - self.connect_step_status() + #self.connect_step_status() layout = QtGui.QVBoxLayout() self.progress = QtGui.QProgressBar(self) @@ -387,48 +423,15 @@ class ValidationPage(QtGui.QWizardPage, WithStepsMixIn): 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 + self.setupStepsProcessingQueue() def isComplete(self): return self.is_done() ######################## - def go_back(self): - self.wizard().back() - - def go_next(self): - self.wizard().next() - - def do_checks(self): - """ - launches a thread to do the checks - """ - signal = self.stepChanged - self.checks = FunThread( - self._do_checks(update_signal=signal)) - self.checks.finished.connect(self._do_validation) - self.checks.begin() - #logger.debug('check thread started!') - #logger.debug('waiting for it to terminate...') - # XXX needed for it to join? - self.checks.wait() - def show_progress(self): self.progress.show() self.stepsTableWidget.show() -- cgit v1.2.3 From d5136a5f3b2aa8b16e8341f2eb99d05993028acf Mon Sep 17 00:00:00 2001 From: kali Date: Tue, 27 Nov 2012 00:12:22 +0900 Subject: inline validation at register page. inline widget and focus and red marks and whistles. --- src/leap/gui/progress.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'src/leap/gui/progress.py') diff --git a/src/leap/gui/progress.py b/src/leap/gui/progress.py index 4f3a7d81..6f13a1ac 100644 --- a/src/leap/gui/progress.py +++ b/src/leap/gui/progress.py @@ -202,6 +202,20 @@ class WithStepsMixIn(object): t.begin() self.threads.append(t) + def fail(self, err=None): + """ + return failed state + and send error notification as + a nice side effect + """ + wizard = self.wizard() + senderr = lambda err: wizard.set_validation_error( + self.current_page, err) + self.set_undone() + if err: + senderr(err) + return False + @QtCore.pyqtSlot() def launch_checks(self): self.do_checks() -- cgit v1.2.3