def __init__(self, ui, repoagent, revs, parent=None): super(PostReviewDialog, self).__init__(parent) self.setWindowFlags(self.windowFlags() & ~Qt.WindowContextHelpButtonHint) self.ui = ui self._repoagent = repoagent self.error_message = None self.cmd = None self.qui = Ui_PostReviewDialog() self.qui.setupUi(self) self.initChangesets(revs) self.readSettings() self.review_thread = LoadReviewDataThread(self) self.review_thread.finished.connect(self.errorPrompt) self.review_thread.start() QShortcut(QKeySequence('Ctrl+Return'), self, self.accept) QShortcut(QKeySequence('Ctrl+Enter'), self, self.accept)
def __init__(self, ui, repo, revs, parent=None): super(PostReviewDialog, self).__init__(parent) self.setWindowFlags(self.windowFlags() & ~Qt.WindowContextHelpButtonHint) self.ui = ui self.repo = repo self.error_message = None self.cmd = None self.qui = Ui_PostReviewDialog() self.qui.setupUi(self) self.initChangesets(revs) self.readSettings() self.review_thread = LoadReviewDataThread(self) self.review_thread.finished.connect(self.errorPrompt) self.review_thread.start() QShortcut(QKeySequence('Ctrl+Return'), self, self.accept) QShortcut(QKeySequence('Ctrl+Enter'), self, self.accept)
class PostReviewDialog(QDialog): """Dialog for sending patches to reviewboard""" def __init__(self, ui, repo, revs, parent=None): super(PostReviewDialog, self).__init__(parent) self.setWindowFlags(self.windowFlags() & ~Qt.WindowContextHelpButtonHint) self.ui = ui self.repo = repo self.error_message = None self.cmd = None self.qui = Ui_PostReviewDialog() self.qui.setupUi(self) self.initChangesets(revs) self.readSettings() self.review_thread = LoadReviewDataThread(self) self.review_thread.finished.connect(self.errorPrompt) self.review_thread.start() QShortcut(QKeySequence('Ctrl+Return'), self, self.accept) QShortcut(QKeySequence('Ctrl+Enter'), self, self.accept) @pyqtSlot() def passwordPrompt(self): pwd, ok = QInputDialog.getText(self, _('Review Board'), _('Password:'******'Review Board'), _('Error'), self.error_message) self.close() elif self.isValid(): self.qui.post_review_button.setEnabled(True) def closeEvent(self, event): if self.cmd and self.cmd.core.running(): self.cmd.commandFinished.disconnect(self.onCompletion) self.cmd.cancel() # Dispose of the review data thread self.review_thread.terminate() self.review_thread.wait() self.writeSettings() super(PostReviewDialog, self).closeEvent(event) def readSettings(self): s = QSettings() self.restoreGeometry(s.value('reviewboard/geom').toByteArray()) self.qui.publish_immediately_check.setChecked( s.value('reviewboard/publish_immediately_check').toBool()) self.qui.outgoing_changes_check.setChecked( s.value('reviewboard/outgoing_changes_check').toBool()) self.qui.branch_check.setChecked( s.value('reviewboard/branch_check').toBool()) self.qui.update_fields.setChecked( s.value('reviewboard/update_fields').toBool()) self.qui.summary_edit.addItems( s.value('reviewboard/summary_edit_history').toStringList()) try: self.repo_id = int(self.repo.ui.config('reviewboard', 'repoid')) except Exception: self.repo_id = None if not self.repo_id: self.repo_id = s.value('reviewboard/repo_id').toInt()[0] self.server = self.repo.ui.config('reviewboard', 'server') self.user = self.repo.ui.config('reviewboard', 'user') self.password = self.repo.ui.config('reviewboard', 'password') self.browser = self.repo.ui.config('reviewboard', 'browser') def writeSettings(self): s = QSettings() s.setValue('reviewboard/geom', self.saveGeometry()) s.setValue('reviewboard/publish_immediately_check', self.qui.publish_immediately_check.isChecked()) s.setValue('reviewboard/branch_check', self.qui.branch_check.isChecked()) s.setValue('reviewboard/outgoing_changes_check', self.qui.outgoing_changes_check.isChecked()) s.setValue('reviewboard/update_fields', self.qui.update_fields.isChecked()) s.setValue('reviewboard/repo_id', self.getRepoId()) def itercombo(w): if w.currentText(): yield w.currentText() for i in xrange(w.count()): if w.itemText(i) != w.currentText(): yield w.itemText(i) s.setValue('reviewboard/summary_edit_history', list(itercombo(self.qui.summary_edit))[:10]) def initChangesets(self, revs, selected_revs=None): def purerevs(revs): return hglib.revrange(self.repo, iter(str(e) for e in revs)) if selected_revs: selectedrevs = purerevs(selected_revs) else: selectedrevs = purerevs(revs) self._changesets = _ChangesetsModel(self.repo, # TODO: [':'] is inefficient revs=purerevs(revs or [':']), selectedrevs=selectedrevs, parent=self) self.qui.changesets_view.setModel(self._changesets) @property def selectedRevs(self): """Returns list of revisions to be sent""" return self._changesets.selectedrevs @property def allRevs(self): """Returns list of revisions to be sent""" return self._changesets.revs def getRepoId(self): comboText = self.qui.repo_id_combo.currentText().split(":") return str(comboText[0]) def getReviewId(self): comboText = self.qui.review_id_combo.currentText().split(":") return str(comboText[0]) def getSummary(self): comboText = self.qui.review_id_combo.currentText().split(":") return str(comboText[1]) def postReviewOpts(self, **opts): """Generate opts for reviewboard by form values""" opts['outgoingchanges'] = self.qui.outgoing_changes_check.isChecked() opts['branch'] = self.qui.branch_check.isChecked() opts['publish'] = self.qui.publish_immediately_check.isChecked() if self.qui.tab_widget.currentIndex() == 1: opts["existing"] = self.getReviewId() opts['update'] = self.qui.update_fields.isChecked() opts['summary'] = self.getSummary() else: opts['repoid'] = self.getRepoId() opts['summary'] = hglib.fromunicode(self.qui.summary_edit.currentText()) if (len(self.selectedRevs) > 1): #Set the parent to the revision below the last one on the list #so all checked revisions are included in the request opts['parent'] = str(self.selectedRevs[0] - 1) # Always use the upstream repo to determine the parent diff base # without the diff uploaded to review board dies opts['outgoing'] = True #Set the password just in case the user has opted to not save it opts['password'] = str(self.password) #Finally we want to pass the repo path to the hg extension opts['repository'] = self.repo.root return opts def isValid(self): """Filled all required values?""" if not self.qui.repo_id_combo.currentText(): return False if self.qui.tab_widget.currentIndex() == 1: if not self.qui.review_id_combo.currentText(): return False if not self.allRevs: return False return True @pyqtSlot() def tabChanged(self): self.qui.post_review_button.setEnabled(self.isValid()) @pyqtSlot() def branchCheckToggle(self): if self.qui.branch_check.isChecked(): self.qui.outgoing_changes_check.setChecked(False) self.toggleOutgoingChangesets() @pyqtSlot() def outgoingChangesCheckToggle(self): if self.qui.outgoing_changes_check.isChecked(): self.qui.branch_check.setChecked(False) self.toggleOutgoingChangesets() def toggleOutgoingChangesets(self): branch = self.qui.branch_check.isChecked() outgoing = self.qui.outgoing_changes_check.isChecked() if branch or outgoing: self.initChangesets(self.allRevs, [self.selectedRevs.pop()]) self.qui.changesets_view.setEnabled(False) else: self.initChangesets(self.allRevs, self.allRevs) self.qui.changesets_view.setEnabled(True) def close(self): super(PostReviewDialog, self).close() def accept(self): if not self.isValid(): return if not self.password and not self.passwordPrompt(): return self.qui.progress_bar.show() self.qui.progress_label.setText("Posting Review...") self.qui.progress_label.show() def cmdargs(opts): args = [] for k, v in opts.iteritems(): if isinstance(v, bool): if v: args.append('--%s' % k.replace('_', '-')) else: for e in isinstance(v, basestring) and [v] or v: args += ['--%s' % k.replace('_', '-'), e] return args hglib.loadextension(self.ui, 'reviewboard') opts = self.postReviewOpts() revstr = str(self.selectedRevs.pop()) self.qui.post_review_button.setEnabled(False) self.qui.close_button.setEnabled(False) self.cmd = cmdui.Runner(False, self) self.cmd.setTitle(_('Review Board')) self.cmd.commandFinished.connect(self.onCompletion) self.cmd.run(['postreview'] + cmdargs(opts) + [revstr]) @pyqtSlot() def onCompletion(self): self.qui.progress_bar.hide() self.qui.progress_label.hide() output = self.cmd.core.rawoutput() saved = 'saved:' in output published = 'published:' in output if (saved or published): if saved: url = output.split('saved: ').pop().strip() msg = _('Review draft posted to %s\n' % url) else: url = output.split('published: ').pop().strip() msg = _('Review published to %s\n' % url) QDesktopServices.openUrl(QUrl(url)) qtlib.InfoMsgBox(_('Review Board'), _('Success'), msg, parent=self) else: error = output.split('abort: ').pop().strip() if error[:29] == "HTTP Error: basic auth failed": if self.passwordPrompt(): self.accept() else: self.qui.post_review_button.setEnabled(True) self.qui.close_button.setEnabled(True) return else: qtlib.ErrorMsgBox(_('Review Board'), _('Error'), error) self.writeSettings() super(PostReviewDialog, self).accept() @pyqtSlot() def onSettingsButtonClicked(self): from tortoisehg.hgqt import settings if settings.SettingsDialog(parent=self, focus='reviewboard.server').exec_(): # not use repo.configChanged because it can clobber user input # accidentally. self.repo.invalidateui() # force reloading config immediately self.readSettings()
class PostReviewDialog(QDialog): """Dialog for sending patches to reviewboard""" def __init__(self, ui, repo, revs, parent=None): super(PostReviewDialog, self).__init__(parent) self.setWindowFlags(self.windowFlags() & ~Qt.WindowContextHelpButtonHint) self.ui = ui self.repo = repo self.error_message = None self.cmd = None self.qui = Ui_PostReviewDialog() self.qui.setupUi(self) self.initChangesets(revs) self.readSettings() self.review_thread = LoadReviewDataThread(self) self.review_thread.finished.connect(self.errorPrompt) self.review_thread.start() QShortcut(QKeySequence('Ctrl+Return'), self, self.accept) QShortcut(QKeySequence('Ctrl+Enter'), self, self.accept) @pyqtSlot() def passwordPrompt(self): pwd, ok = qtlib.getTextInput(self, _('Review Board'), _('Password:'******'Review Board'), _('Error'), self.error_message) self.close() elif self.isValid(): self.qui.post_review_button.setEnabled(True) def closeEvent(self, event): if self.cmd and self.cmd.core.running(): self.cmd.commandFinished.disconnect(self.onCompletion) self.cmd.cancel() # Dispose of the review data thread self.review_thread.terminate() self.review_thread.wait() self.writeSettings() super(PostReviewDialog, self).closeEvent(event) def readSettings(self): s = QSettings() self.restoreGeometry(s.value('reviewboard/geom').toByteArray()) self.qui.publish_immediately_check.setChecked( s.value('reviewboard/publish_immediately_check').toBool()) self.qui.outgoing_changes_check.setChecked( s.value('reviewboard/outgoing_changes_check').toBool()) self.qui.branch_check.setChecked( s.value('reviewboard/branch_check').toBool()) self.qui.update_fields.setChecked( s.value('reviewboard/update_fields').toBool()) self.qui.summary_edit.addItems( s.value('reviewboard/summary_edit_history').toStringList()) try: self.repo_id = int(self.repo.ui.config('reviewboard', 'repoid')) except Exception: self.repo_id = None if not self.repo_id: self.repo_id = s.value('reviewboard/repo_id').toInt()[0] self.server = self.repo.ui.config('reviewboard', 'server') self.user = self.repo.ui.config('reviewboard', 'user') self.password = self.repo.ui.config('reviewboard', 'password') self.browser = self.repo.ui.config('reviewboard', 'browser') def writeSettings(self): s = QSettings() s.setValue('reviewboard/geom', self.saveGeometry()) s.setValue('reviewboard/publish_immediately_check', self.qui.publish_immediately_check.isChecked()) s.setValue('reviewboard/branch_check', self.qui.branch_check.isChecked()) s.setValue('reviewboard/outgoing_changes_check', self.qui.outgoing_changes_check.isChecked()) s.setValue('reviewboard/update_fields', self.qui.update_fields.isChecked()) s.setValue('reviewboard/repo_id', self.getRepoId()) def itercombo(w): if w.currentText(): yield w.currentText() for i in xrange(w.count()): if w.itemText(i) != w.currentText(): yield w.itemText(i) s.setValue('reviewboard/summary_edit_history', list(itercombo(self.qui.summary_edit))[:10]) def initChangesets(self, revs, selected_revs=None): def purerevs(revs): return scmutil.revrange(self.repo, iter(str(e) for e in revs)) if selected_revs: selectedrevs = purerevs(selected_revs) else: selectedrevs = purerevs(revs) self._changesets = _ChangesetsModel( self.repo, # TODO: [':'] is inefficient revs=purerevs(revs or [':']), selectedrevs=selectedrevs, parent=self) self.qui.changesets_view.setModel(self._changesets) @property def selectedRevs(self): """Returns list of revisions to be sent""" return self._changesets.selectedrevs @property def allRevs(self): """Returns list of revisions to be sent""" return self._changesets.revs def getRepoId(self): comboText = self.qui.repo_id_combo.currentText().split(":") return str(comboText[0]) def getReviewId(self): comboText = self.qui.review_id_combo.currentText().split(":") return str(comboText[0]) def getSummary(self): comboText = self.qui.review_id_combo.currentText().split(":") return str(comboText[1]) def postReviewOpts(self, **opts): """Generate opts for reviewboard by form values""" opts['outgoingchanges'] = self.qui.outgoing_changes_check.isChecked() opts['branch'] = self.qui.branch_check.isChecked() opts['publish'] = self.qui.publish_immediately_check.isChecked() if self.qui.tab_widget.currentIndex() == 1: opts["existing"] = self.getReviewId() opts['update'] = self.qui.update_fields.isChecked() opts['summary'] = self.getSummary() else: opts['repoid'] = self.getRepoId() opts['summary'] = hglib.fromunicode( self.qui.summary_edit.currentText()) if (len(self.selectedRevs) > 1): #Set the parent to the revision below the last one on the list #so all checked revisions are included in the request opts['parent'] = str(self.selectedRevs[0] - 1) # Always use the upstream repo to determine the parent diff base # without the diff uploaded to review board dies opts['outgoing'] = True #Set the password just in case the user has opted to not save it opts['password'] = str(self.password) #Finally we want to pass the repo path to the hg extension opts['repository'] = self.repo.root return opts def isValid(self): """Filled all required values?""" if not self.qui.repo_id_combo.currentText(): return False if self.qui.tab_widget.currentIndex() == 1: if not self.qui.review_id_combo.currentText(): return False if not self.allRevs: return False return True @pyqtSlot() def tabChanged(self): self.qui.post_review_button.setEnabled(self.isValid()) @pyqtSlot() def branchCheckToggle(self): if self.qui.branch_check.isChecked(): self.qui.outgoing_changes_check.setChecked(False) self.toggleOutgoingChangesets() @pyqtSlot() def outgoingChangesCheckToggle(self): if self.qui.outgoing_changes_check.isChecked(): self.qui.branch_check.setChecked(False) self.toggleOutgoingChangesets() def toggleOutgoingChangesets(self): branch = self.qui.branch_check.isChecked() outgoing = self.qui.outgoing_changes_check.isChecked() if branch or outgoing: self.initChangesets(self.allRevs, [self.selectedRevs.pop()]) self.qui.changesets_view.setEnabled(False) else: self.initChangesets(self.allRevs, self.allRevs) self.qui.changesets_view.setEnabled(True) def close(self): super(PostReviewDialog, self).close() def accept(self): if not self.isValid(): return if not self.password and not self.passwordPrompt(): return self.qui.progress_bar.show() self.qui.progress_label.setText("Posting Review...") self.qui.progress_label.show() def cmdargs(opts): args = [] for k, v in opts.iteritems(): if isinstance(v, bool): if v: args.append('--%s' % k.replace('_', '-')) else: for e in isinstance(v, basestring) and [v] or v: args += ['--%s' % k.replace('_', '-'), e] return args hglib.loadextension(self.ui, 'reviewboard') opts = self.postReviewOpts() revstr = str(self.selectedRevs.pop()) self.qui.post_review_button.setEnabled(False) self.qui.close_button.setEnabled(False) self.cmd = cmdui.Runner(False, self) self.cmd.setTitle(_('Review Board')) self.cmd.commandFinished.connect(self.onCompletion) self.cmd.run(['postreview'] + cmdargs(opts) + [revstr]) @pyqtSlot() def onCompletion(self): self.qui.progress_bar.hide() self.qui.progress_label.hide() output = self.cmd.core.rawoutput() saved = 'saved:' in output published = 'published:' in output if (saved or published): if saved: url = output.split('saved: ').pop().strip() msg = _('Review draft posted to %s\n') % url else: url = output.split('published: ').pop().strip() msg = _('Review published to %s\n') % url QDesktopServices.openUrl(QUrl(url)) qtlib.InfoMsgBox(_('Review Board'), _('Success'), msg, parent=self) else: error = output.split('abort: ').pop().strip() if error[:29] == "HTTP Error: basic auth failed": if self.passwordPrompt(): self.accept() else: self.qui.post_review_button.setEnabled(True) self.qui.close_button.setEnabled(True) return else: qtlib.ErrorMsgBox(_('Review Board'), _('Error'), error) self.writeSettings() super(PostReviewDialog, self).accept() @pyqtSlot() def onSettingsButtonClicked(self): from tortoisehg.hgqt import settings if settings.SettingsDialog(parent=self, focus='reviewboard.server').exec_(): # not use repo.configChanged because it can clobber user input # accidentally. self.repo.invalidateui() # force reloading config immediately self.readSettings()