def load_diff(self): self.view_refresh.setEnabled(False) self.processEvents() try: no_changes = True # if there is no changes found we need to inform the user for di in DiffItem.iter_items(self.trees, specific_files=self.specific_files, filter=self.filter_options.check, lock_trees=True): lines = di.lines self.processEvents() groups = di.groups(self.complete, self.ignore_whitespace) self.processEvents() ulines = di.get_unicode_lines( (self.encoding_selector_left.encoding, self.encoding_selector_right.encoding)) data = [''.join(l) for l in ulines] for view in self.views: view.append_diff(list(di.paths), di.file_id, di.kind, di.status, di.dates, di.versioned, di.binary, ulines, groups, data, di.properties_changed) self.processEvents() no_changes = False except PathsNotVersionedError, e: QtGui.QMessageBox.critical( self, gettext('Diff'), gettext(u'File %s is not versioned.\n' 'Operation aborted.') % e.paths_as_string, gettext('&Close')) self.close()
def retranslateUi(self, InitForm): InitForm.setWindowTitle(gettext("Initialize")) self.groupBox_3.setTitle(gettext("Local Directory")) self.location_picker.setText(gettext("Browse...")) self.groupBox.setTitle(gettext("Repository")) self.but_init.setText(gettext("Create a new standalone tree")) self.but_append_only.setText( gettext("Ensure all revisions are appended to the log")) self.radioButton_2.setText(gettext("Create a new shared repository")) self.but_no_trees.setText( gettext("Skip the creation of working trees in this repository")) self.link_help.setText( QtGui.QApplication.translate( "InitForm", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n" "<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n" "p, li { white-space: pre-wrap; }\n" "</style></head><body style=\" font-family:\'MS Shell Dlg 2\'; font-size:8.25pt; font-weight:400; font-style:normal;\">\n" "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\">Tell me more about <a href=\"bzrtopic:standalone-trees\"><span style=\" text-decoration: underline; color:#0000ff;\">standalone trees</span></a>, <a href=\"bzrtopic:repositories\"><span style=\" text-decoration: underline; color:#0000ff;\">repositories</span></a> and <a href=\"bzrtopic:branches\"><span style=\" text-decoration: underline; color:#0000ff;\">branches</span></a>.</p></body></html>", None, QtGui.QApplication.UnicodeUTF8)) self.label.setText(gettext("Repository Format:")) self.format_desc.setText(gettext("Description of format")) self.link_help_formats.setText( QtGui.QApplication.translate( "InitForm", "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\" \"http://www.w3.org/TR/REC-html40/strict.dtd\">\n" "<html><head><meta name=\"qrichtext\" content=\"1\" /><style type=\"text/css\">\n" "p, li { white-space: pre-wrap; }\n" "</style></head><body style=\" font-family:\'MS Shell Dlg 2\'; font-size:8.25pt; font-weight:400; font-style:normal;\">\n" "<p style=\" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;\"><a href=\"bzrtopic:formats\"><span style=\" text-decoration: underline; color:#0000ff;\">More information about repository formats.</span></a></p></body></html>", None, QtGui.QApplication.UnicodeUTF8))
def validate(self): if self.submit_email_radio.isChecked(): location = str(self.mailto_edit.text()) if not location: self.mailto_edit.setFocus() self.operation_blocked(gettext("Email address not entered.")) return False if re.match( "^.+\\@(\\[?)[a-zA-Z0-9\\-\\.]+\\.([a-zA-Z]{2,3}|[0-9]{1,3})(\\]?)$", location) is None: self.mailto_edit.setFocus() self.operation_blocked(gettext("Email address is not valid.")) return False else: location = unicode(self.savefile_edit.text()) if not location: self.savefile_edit.setFocus() self.operation_blocked(gettext("Filename not entered.")) return False submit_branch = unicode(self.submit_branch_combo.currentText()) if not submit_branch: self.submit_branch_combo.setFocus() self.operation_blocked(gettext("No submit branch entered.")) return False return True
def is_extmerge_definition_valid(self, showErrorDialog): bzr_config = GlobalConfig() extmerge_tool = bzr_config.get_user_option("external_merge") # Check if the definition format is correct flags = "%r" try: extmerge_tool.rindex('%r') flags = "%b" extmerge_tool.rindex('%b') flags = "%t" extmerge_tool.rindex('%t') flags = "%o" extmerge_tool.rindex('%o') except ValueError: if showErrorDialog: QtGui.QMessageBox.critical( self, gettext("Error"), gettext( "The extmerge definition: '%(tool)s' is invalid.\n" "Missing the flag: %(flags)s. " "This must be fixed in qconfig under the Merge tab.") % { 'tool': extmerge_tool, 'flags': flags, }) return gettext( "Missing the flag: %s. Configure in qconfig under the merge tab." ) % flags return ""
def __init__(self, branch, ui_mode=None, immediate=False): super(QBzrUnbindDialog, self).__init__( gettext("Unbind branch"), name = "unbind", default_size = (200, 200), ui_mode = ui_mode, dialog = True, parent = None, hide_progress=False, immediate = immediate ) self.branch = branch gbBind = QtGui.QGroupBox(gettext("Unbind"), self) bind_box = QtGui.QFormLayout(gbBind) info_label = QtGui.QLabel(url_for_display(branch.base)) bind_box.addRow(gettext("Branch:"), info_label) self.currbound = branch.get_bound_location() if self.currbound != None: curr_label = QtGui.QLabel(url_for_display(self.currbound)) bind_box.addRow(gettext("Bound to:"), curr_label) layout = QtGui.QVBoxLayout(self) layout.addWidget(gbBind) layout.addWidget(self.make_default_status_box()) layout.addWidget(self.buttonbox)
def validate(self): if not self._get_from_location(): self.operation_blocked(gettext("You should specify branch source")) return False to_location = self._get_to_location() if not to_location: self.operation_blocked( gettext("You should select destination directory")) return False # This is a check if the user really wants to checkout to a non-empty directory. # Because this may create conflicts, we want to make sure this is intended. if os.path.exists(to_location) and os.listdir(to_location): if self._is_checkout_action(): quiz = gettext( "Do you really want to checkout into a non-empty folder?") else: quiz = gettext( "Do you really want to branch into a non-empty folder?") reason = gettext( "The destination folder is not empty.\n" "Populating new working tree there may create conflicts.") if not self.ask_confirmation(reason + '\n\n' + quiz, type='warning'): return False return True
def _build_options_group_box(self): """Build and return the options group box.""" # Build the revision selection fields revisions_box = QtGui.QGridLayout() revisions_label = QtGui.QLabel(gettext("Revision:")) revisions_tip = QtGui.QRadioButton("Branch tip") revisions_tip.setChecked(True) self.revisions_tip = revisions_tip revisions_box.addWidget(revisions_label, 0, 0) revisions_box.addWidget(revisions_tip, 0, 1) revisions_other = QtGui.QRadioButton("Other") self.revisions_other = revisions_other revisions_edit = QtGui.QLineEdit() self.revisions_edit = revisions_edit revisions_box.addWidget(revisions_other, 1, 1) revisions_box.addWidget(revisions_edit, 1, 2) # Build the content filtering field format_box = QtGui.QGridLayout() format_canonical = QtGui.QCheckBox("Apply content filters to files") self.format_canonical = format_canonical format_box.addWidget(format_canonical, 0, 0) # Build the group box and return it gbExportOptions = QtGui.QGroupBox(gettext("Options"), self) vbxExportOptions = QtGui.QVBoxLayout(gbExportOptions) vbxExportOptions.addLayout(revisions_box) vbxExportOptions.addLayout(format_box) return gbExportOptions
def use_editor(self): cleanup = [] items = self.file_view.selectedItems() if len(items) != 1 or items[0].change.status != 'modify text': return else: change = items[0].change try: target_tree, work_tree = self.trees cleanup.append(work_tree.lock_read().unlock) cleanup.append(target_tree.lock_read().unlock) config = work_tree.branch.get_config() change_editor = config.get_change_editor(target_tree, work_tree) if change_editor is None: QtGui.QMessageBox.information( self, gettext('Shelve'), gettext('Change editor is not defined.'), gettext('&OK')) self.editor_available = False self.editor_button.setEnabled(False) return cleanup.append(change_editor.finish) lines = split_lines(change_editor.edit_file(change.file_id)) change_count = Shelver._count_changed_regions( change.work_lines, lines) if change_count > 0: change.edited_lines = lines self.update_item(items[0]) self.selected_file_changed() finally: while cleanup: cleanup.pop()()
def show_diff_for_checked(self, ext_diff=None, dialog_action='revert'): """Diff button clicked: show the diff for checked entries. @param ext_diff: selected external diff tool (if any) @param dialog_action: purpose of parent window (main action) """ # XXX make this function universal for both qcommit and qrevert (?) checked = [ref.path for ref in self.filelist.tree_model.iter_checked()] if checked: arg_provider = InternalWTDiffArgProvider( self.tree.basis_tree().get_revision_id(), self.tree, self.tree.branch, self.tree.branch, specific_files=checked) show_diff(arg_provider, ext_diff=ext_diff, parent_window=self, context=self.filelist.diff_context) else: msg = "No changes selected to " + dialog_action QtGui.QMessageBox.warning(self, "QBzr - " + gettext("Diff"), gettext(msg), QtGui.QMessageBox.Ok)
def create_find_action(self): action = QtGui.QAction(get_icon("edit-find"), gettext("&Find"), self) action.setShortcut(QtGui.QKeySequence.Find) action.setToolTip(gettext("Find on active panel")) show_shortcut_hint(action) action.setCheckable(True) return action
def prompt_bool(self, prompt, warning=False): if warning: func = QtGui.QMessageBox.warning else: func = QtGui.QMessageBox.question ret = func(self, gettext('Shelve'), gettext(prompt), QtGui.QMessageBox.Ok | QtGui.QMessageBox.Cancel) return (ret == QtGui.QMessageBox.Ok)
def current_tab_changed(self, index): view = self.tab.currentWidget() if not view.loaded: view.refresh() if hasattr(view, "files_str") and view.files_str: self.setWindowTitle( gettext("Shelve Manager") + " - %s" % view.files_str) else: self.setWindowTitle(gettext("Shelve Manager"))
def create_ext_diff_action(self): action = QtGui.QAction(get_icon("system-run"), gettext("&External Diff"), self) action.setToolTip(gettext("Launch an external diff application")) ext_diff_menu = ExtDiffMenu(parent=self, include_builtin=False) action.setMenu(ext_diff_menu) self.connect(ext_diff_menu, QtCore.SIGNAL("triggered(QString)"), self.ext_diff_triggered) return action
def show_trace_back(self): """toggle the text box containing the full exception details""" self.trace_back_label.setVisible(not self.trace_back_label.isVisible()) if self.trace_back_label.isVisible(): self.show_trace_back_button.setText( gettext("<<< Hide Error Details")) else: self.show_trace_back_button.setText( gettext("Show Error Details >>>")) self.resize(self.sizeHint())
def to_str(self): s = [] if self.deleted: s.append(gettext('deleted files')) if self.added: s.append(gettext('added files')) if self.renamed: s.append(gettext('renamed files')) if self.modified: s.append(gettext('modified files')) return ', '.join(s)
def reportProcessError(self, error, message=None): self.aborting = False self.setProgress(1000000, [gettext("Failed!")]) if message is None: if error == QtCore.QProcess.FailedToStart: message = gettext("Failed to start bzr.") else: message = gettext("Error while running bzr. (error code: %d)" % error) self.logMessage(message, True) self.emit(QtCore.SIGNAL("failed(QString)"), self.error_class)
def retranslateUi(self, RunDialog): RunDialog.setWindowTitle(gettext("Run bzr command")) self.run_container.setTitle(gettext("Options")) self.wd_label.setText(gettext("&Working directory:")) self.browse_button.setText(gettext("&Browse...")) self.cat_label.setText(gettext("C&ategory:")) self.cmd_label.setText(gettext("&Command:")) self.hidden_checkbox.setText(gettext("&Show hidden commands")) self.opt_arg_label.setText( gettext("&Options and arguments for command:")) self.directory_button.setText(gettext("Insert &directory...")) self.filenames_button.setText(gettext("Insert &filenames..."))
def _encodingChanged(self, encoding): try: encoding = str(encoding) # may raise UnicodeError codecs.lookup(encoding) # may raise LookupError self._encoding = encoding self.onChanged(encoding) except (UnicodeError, LookupError): QtGui.QMessageBox.critical( self, gettext("Wrong encoding"), gettext('Encoding "%s" is invalid or not supported.') % unicode(encoding)) self.setEncoding(self._encoding)
def create_toggle_view_mode(self): action = QtGui.QAction(get_icon("view-split-left-right"), gettext("Unidiff"), self) action.setToolTip( gettext("Toggle between Side by side and Unidiff view modes")) action.setShortcut("Ctrl+U") show_shortcut_hint(action) action.setCheckable(True) action.setChecked(False) self.connect(action, QtCore.SIGNAL("toggled (bool)"), self.click_toggle_view_mode) return action
def __init__(self, arg_provider, parent=None, complete=False, encoding=None, filter_options=None, ui_mode=True, allow_refresh=True): title = [gettext("Diff"), gettext("Loading...")] QBzrWindow.__init__(self, title, parent, ui_mode=ui_mode) self.restoreSize("diff", (780, 580)) self.trees = None self.encoding = encoding self.arg_provider = arg_provider self.filter_options = filter_options if filter_options is None: self.filter_options = FilterOptions(all_enable=True) self.complete = complete self.ignore_whitespace = False self.delayed_signal_connections = [] self.diffview = SidebySideDiffView(self) self.sdiffview = SimpleDiffView(self) self.views = (self.diffview, self.sdiffview) for view in self.views: view.set_complete(complete) self.stack = QtGui.QStackedWidget(self.centralwidget) self.stack.addWidget(self.diffview) self.stack.addWidget(self.sdiffview) vbox = QtGui.QVBoxLayout(self.centralwidget) vbox.addWidget(self.stack) # Don't use a custom tab width by default # Indices are left side, right side and unidiff # respectively self.custom_tab_widths = [-1, -1, -1] for browser in self.diffview.browsers: browser.installEventFilter(self) self.create_main_toolbar(allow_refresh) self.addToolBarBreak() self.find_toolbar = FindToolbar(self, self.diffview.browsers, self.show_find) self.find_toolbar.hide() self.addToolBar(self.find_toolbar) setup_guidebar_for_find(self.sdiffview, self.find_toolbar, 1) for gb in self.diffview.guidebar_panels: setup_guidebar_for_find(gb, self.find_toolbar, 1) self.diff_context = ExtDiffContext(self)
def __init__(self, initial_tab=0, directory=None, file_list=None, complete=False, ignore_whitespace=False, encoding=None, parent=None, ui_mode=True, select_all=False, message=None): QBzrWindow.__init__(self, [gettext("Shelve Manager")], parent, ui_mode=ui_mode) self.restoreSize("shelve", (780, 680)) vbox = QtGui.QVBoxLayout(self.centralwidget) vbox.setMargin(2) self.throbber = ToolBarThrobberWidget(self) vbox.addWidget(self.throbber) self.tab = QtGui.QTabWidget(self) vbox.addWidget(self.tab) self.splitters = Splitters("shelve") self.directory = directory or '.' shelve_view = ShelveWidget(file_list=file_list, directory=self.directory, complete=complete, encoding=encoding, splitters=self.splitters, parent=self, select_all=select_all, init_msg=message) shelvelist_view = ShelveListWidget(directory=self.directory, complete=complete, ignore_whitespace=ignore_whitespace, encoding=encoding, splitters=self.splitters, parent=self) self.tab.addTab(shelve_view, gettext('Shelve')) self.tab.addTab(shelvelist_view, gettext('View shelved changes')) self.tab.setCurrentIndex(initial_tab) self.connect(self.tab, QtCore.SIGNAL("currentChanged(int)"), self.current_tab_changed) self.connect(shelve_view, QtCore.SIGNAL("shelfCreated(int)"), self.shelf_created) self.connect(shelvelist_view, QtCore.SIGNAL("unshelved(int, QString*)"), self.unshelved) self.splitters.restore_state()
def set_annotate_title(self): # and update the title to show we are done. if isinstance(self.annotate_tree, RevisionTree): revno = self.get_revno(self.annotate_tree.get_revision_id()) if revno: self.set_title_and_icon([ gettext("Annotate"), self.path, gettext("Revision %s") % revno ]) return self.set_title_and_icon([gettext("Annotate"), self.path])
def __init__(self, tree, ui_mode=True, immediate=False, parent=None): self.tree = tree super(QBzrUpdateWindow, self).__init__( title=gettext("Update working tree"), desc=gettext("Update tree %s") % tree.basedir, name="update", args=["update"], dir=self.tree.basedir, default_size=(256, 256), ui_mode=ui_mode, parent=parent, immediate=immediate, )
def _report_error(location, err, _critical_dialog=QtGui.QMessageBox.critical): """Report error in GUI dialog. @param location: valid location for which error is reported. @param err: error object (NotBranchError or NoWorkingTree). @param _critical_dialog: callable to show error dialog. """ if isinstance(err, errors.NotBranchError): text = gettext('Not a branch "%s"') % location elif isinstance(err, errors.NoWorkingTree): text = gettext('No working tree exists for "%s"') % location _critical_dialog(None, gettext("Error"), text, gettext('&Close'))
def __init__(self, location, dialog=True, ui_mode=True, parent=None, local=None, message=None): super(QBzrUncommitWindow, self).__init__( gettext("Uncommit"), name="uncommit", default_size=(400, 400), ui_mode=ui_mode, dialog=dialog, parent=parent, hide_progress=True, ) self.tree, self.branch = bzrdir.BzrDir.open_tree_or_branch(location) # Display the branch branch_label = QtGui.QLabel(gettext("Branch: %s") % url_for_display(self.branch.base)) # Display the revision selection section. We nearly always # want to just uncommit the last revision (to tweak the # commit message say) so we make that the default. groupbox = QtGui.QGroupBox(gettext("Move tip to"), self) self.last_radio = QtGui.QRadioButton( gettext("Parent of current tip revision")) self.last_radio.setChecked(QtCore.Qt.Checked) self.other_radio = QtGui.QRadioButton(gettext("Other revision:")) self.other_revision = QtGui.QLineEdit() other = QtGui.QHBoxLayout() other.addWidget(self.other_radio) other.addWidget(self.other_revision) vbox = QtGui.QVBoxLayout(groupbox) vbox.addWidget(self.last_radio) vbox.addLayout(other) # If the user starts entering a value in the 'other revision' field, # set the matching radio button implicitly QtCore.QObject.connect(self.other_revision, QtCore.SIGNAL("textChanged(QString)"), self.do_other_revision_changed) # groupbox gets disabled as we are executing. QtCore.QObject.connect(self, QtCore.SIGNAL("subprocessStarted(bool)"), groupbox, QtCore.SLOT("setDisabled(bool)")) # Put the form together layout = QtGui.QVBoxLayout(self) layout.addWidget(branch_label) layout.addWidget(groupbox) layout.addWidget(self.make_default_status_box()) layout.addWidget(self.buttonbox)
def retranslateUi(self, BranchForm): BranchForm.setWindowTitle(gettext("Branch")) self.groupBox.setTitle(gettext("Locations")) self.from_label.setText(gettext("&From:")) self.from_picker.setText(gettext("Browse...")) self.to_label.setText(gettext("&To:")) self.to_picker.setText(gettext("Browse...")) self.groupBox_2.setTitle(gettext("Options")) self.bind.setText(gettext("Bind new branch to parent location")) self.revision_label.setText(gettext("&Revision:"))
def create_context_menu(self): self.context_menu = QtGui.QMenu(self.conflicts_list) self.merge_action = QtGui.QAction(gettext("&Merge conflict"), self.context_menu) self.connect(self.merge_action, QtCore.SIGNAL("triggered(bool)"), self.launch_merge_tool) self.context_menu.addAction(self.merge_action) self.context_menu.setDefaultAction(self.merge_action) self.context_menu.addAction(gettext('Take "&THIS" version'), self.take_this) self.context_menu.addAction(gettext('Take "&OTHER" version'), self.take_other) self.context_menu.addAction(gettext("Mark as &resolved"), self.mark_item_as_resolved)
def auto_resolve(self): while self.wt is None: QtGui.QApplication.processEvents() un_resolved, resolved = self.wt.auto_resolve() if len(un_resolved) > 0: n = len(resolved) QtGui.QMessageBox.information( self, gettext('Conflicts'), ngettext('%d conflict auto-resolved.', '%d conflicts auto-resolved.', n) % n, gettext('&OK')) QtCore.QTimer.singleShot(1, self.load) else: QtGui.QMessageBox.information(self, gettext('Conflicts'), gettext('All conflicts resolved.'), gettext('&OK')) self.close()
def readStdout(self): # ensure we read from subprocess plain string data = str(self.process.readAllStandardOutput()) # we need unicode for all strings except bencoded streams for line in data.splitlines(): if line.startswith(SUB_PROGRESS): try: progress, transport_activity, task_info = bencode.bdecode( line[len(SUB_PROGRESS):]) messages = [b.decode("utf-8") for b in task_info] except ValueError, e: # we got malformed data from qsubprocess (bencode failed to decode) # so just show it in the status console self.logMessageEx("qsubprocess error: " + str(e), "error", self.stderr) self.logMessageEx(line.decode(self.encoding), "error", self.stderr) else: self.setProgress(progress, messages, transport_activity) elif line.startswith(SUB_GETPASS): prompt = bdecode_prompt(line[len(SUB_GETPASS):]) passwd, ok = QtGui.QInputDialog.getText( self, gettext("Enter Password"), prompt, QtGui.QLineEdit.Password) data = unicode(passwd).encode('utf-8'), int(ok) self.process.write(SUB_GETPASS + bencode.bencode(data) + "\n") if not ok: self.abort_futher_processes()
def __init__(self, parent=None): """Create help window. @param parent: If None, a normal top-level window will be opened. If not None, a 'tool' style window will be opened, be 'always on top' of the parent and have no taskbar entry. """ if parent is None: # a normal window. window_id = "help" default_size = (780, 580) else: # a smallish tooltop window. window_id = "help-popup" default_size = (500, 400) QBzrWindow.__init__(self, [gettext("Help")], parent, centralwidget=QtGui.QTextBrowser()) self.restoreSize(window_id, default_size) if parent is not None: # make it a tool window for the parent. self.setWindowFlags(QtCore.Qt.Tool) # Without this, the window object remains alive even after its closed. # There's no good reason for that... self.setAttribute(QtCore.Qt.WA_DeleteOnClose)