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 = QtWidgets.QGroupBox(gettext("Unbind"), self) bind_box = QtWidgets.QFormLayout(gbBind) info_label = QtWidgets.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 = QtWidgets.QLabel(url_for_display(self.currbound)) bind_box.addRow(gettext("Bound to:"), curr_label) layout = QtWidgets.QVBoxLayout(self) layout.addWidget(gbBind) layout.addWidget(self.make_default_status_box()) layout.addWidget(self.buttonbox)
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: QtWidgets.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 __init__(self, anotate_window, show_action): QtWidgets.QToolBar.__init__(self, gettext("Goto Line"), anotate_window) self.anotate_window = anotate_window if 0: self.anotate_window = AnnotateWindow() self.show_action = show_action self.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon) self.setMovable(False) label = QtWidgets.QLabel(gettext("Goto Line: "), self) self.addWidget(label) self.line_edit = QtWidgets.QLineEdit(self) # QIntValidator is working in python3, so we'll use that # self.line_edit.setValidator(IntValidator(self.line_edit)) self.line_edit.setValidator(QtGui.QIntValidator()) self.addWidget(self.line_edit) label.setBuddy(self.line_edit) go = self.addAction(get_icon("go-next"), gettext("Go")) spacer = QtWidgets.QWidget() spacer.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) self.addWidget(spacer) close = QtWidgets.QAction(self) close.setIcon(self.style().standardIcon(QtWidgets.QStyle.SP_DialogCloseButton)) self.addAction(close) close.setShortcut((QtCore.Qt.Key_Escape)) close.setShortcutContext(QtCore.Qt.WidgetWithChildrenShortcut) close.setStatusTip(gettext("Close Goto Line")) close.triggered[bool].connect(self.close_triggered) go.triggered[bool].connect(self.go_triggered) self.line_edit.returnPressed.connect(self.go_triggered)
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 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: QtWidgets.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 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 = str(self.savefile_edit.text()) if not location: self.savefile_edit.setFocus() self.operation_blocked(gettext("Filename not entered.")) return False submit_branch = str(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 create_toolbar_button(text, parent=None, icon_name=None, icon_size=22, enabled=True, checkable=False, checked=False, shortcut=None, onclick=None): # RJLRJL modified to work with PyQt5 if icon_name: button = QtWidgets.QAction(get_icon(icon_name, size=icon_size), gettext(text), parent) else: button = QtWidgets.QAction(gettext(text), parent) if checkable: button.setCheckable(True) button.setChecked(checked) if not enabled: button.setEnabled(False) if shortcut: button.setShortcut(shortcut) show_shortcut_hint(button) if onclick: if checkable: button.toggled[bool].connect(onclick) else: button.triggered.connect(onclick) return button
def create_ext_diff_action(self): action = QtWidgets.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) ext_diff_menu.triggered['QString'].connect(self.ext_diff_triggered) return action
def create_find_action(self): action = QtWidgets.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 = QtWidgets.QMessageBox.warning else: func = QtWidgets.QMessageBox.question ret = func(self, gettext('Shelve'), gettext(prompt), QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Cancel) return (ret == QtWidgets.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 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 create_toggle_view_mode(self): action = QtWidgets.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); action.toggled[bool].connect(self.click_toggle_view_mode) 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 createActions(self): self.actions = {} action = QtWidgets.QAction(self.icons['view-refresh'], gettext("&Refresh"), self) action.setShortcut("Ctrl+R") action.setStatusTip(gettext("Refresh the directory tree")) action.triggered[bool].connect(self.refresh) self.actions['refresh'] = action action = QtWidgets.QAction(self.icons['image-missing'], gettext("&Commit"), self) action.setStatusTip(gettext("Commit changes into a new revision")) action.triggered[bool].connect(self.commit) self.actions['commit'] = action action = QtWidgets.QAction(self.icons['qbrz-push'], gettext("&Push"), self) action.setStatusTip( gettext("Turn this branch into a mirror of another branch")) action.triggered[bool].connect(self.push) self.actions['push'] = action action = QtWidgets.QAction(self.icons['qbrz-pull'], gettext("Pu&ll"), self) action.setStatusTip(gettext("Update a mirror of this branch")) action.triggered[bool].connect(self.pull) self.actions['pull'] = action action = QtWidgets.QAction(gettext("&Add Bookmark..."), self) action.triggered[bool].connect(self.addBookmark) self.actions['add-bookmark'] = action
def _try_to_open_branch(self, location): if location: location = str(location) try: branch = Branch.open_containing(location)[0] except errors.NotBranchError: QtWidgets.QMessageBox.critical( self, gettext('Error'), gettext('Not a branch:\n%s') % location, gettext('&Close')) return self.set_branch(branch)
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 __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 = controldir.ControlDir.open_tree_or_branch( location) # Display the branch branch_label = QtWidgets.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 = QtWidgets.QGroupBox(gettext("Move tip to"), self) self.last_radio = QtWidgets.QRadioButton( gettext("Parent of current tip revision")) self.last_radio.setChecked(QtCore.Qt.Checked) self.other_radio = QtWidgets.QRadioButton(gettext("Other revision:")) self.other_revision = QtWidgets.QLineEdit() other = QtWidgets.QHBoxLayout() other.addWidget(self.other_radio) other.addWidget(self.other_revision) vbox = QtWidgets.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 self.other_revision.textChanged['QString'].connect( self.do_other_revision_changed) # groupbox gets disabled as we are executing. self.subprocessStarted[bool].connect(groupbox.setDisabled) # Put the form together layout = QtWidgets.QVBoxLayout(self) layout.addWidget(branch_label) layout.addWidget(groupbox) layout.addWidget(self.make_default_status_box()) layout.addWidget(self.buttonbox)
def removeBookmark(self, pos): res = QtWidgets.QMessageBox.question( self, gettext("Remove Bookmark"), gettext("Do you really want to remove the selected bookmark?"), QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No) if res == QtWidgets.QMessageBox.Yes: config = get_qbrz_config() bookmarks = list(config.getBookmarks()) del bookmarks[pos] config.set_bookmarks(bookmarks) config.save() self.sideBarModel.refresh(self.sideBarModel.bookmarksItem)
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): QtWidgets.QMessageBox.critical( self, gettext("Wrong encoding"), gettext('Encoding "%s" is invalid or not supported.') % str(encoding)) self.setEncoding(self._encoding)
def create_context_menu(self): self.context_menu = QtWidgets.QMenu(self.conflicts_list) self.merge_action = QtWidgets.QAction(gettext("&Merge conflict"), self.context_menu) self.merge_action.triggered[bool].connect(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 _report_error(location, err, _critical_dialog=QtWidgets.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, 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 __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 = QtWidgets.QVBoxLayout(self.centralwidget) vbox.setContentsMargins(2, 2, 2, 2) self.throbber = ToolBarThrobberWidget(self) vbox.addWidget(self.throbber) self.tab = QtWidgets.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.tab.currentChanged[int].connect(self.current_tab_changed) shelve_view.shelfCreated[int].connect(self.shelf_created) shelvelist_view.unshelved[int, 'QString'].connect(self.unshelved) self.splitters.restore_state()
def loaded_revision_props(self, rev): props = [] if rev.timestamp is not None: props.append((gettext("Date:"), format_timestamp(rev.timestamp))) if rev.committer: props.append((gettext("Committer:"), htmlize(rev.committer))) authors = rev.properties.get('authors') if not authors: authors = rev.properties.get('author') if authors: props.append((gettext("Author:"), htmlize(authors))) branch_nick = rev.properties.get('branch-nick') if branch_nick: props.append((gettext("Branch:"), htmlize(branch_nick))) tags = self.get_tags(rev.revision_id) if tags: tags = list(map(quote_tag, tags)) props.append((gettext("Tags:"), htmlencode(", ".join(tags)))) bugs = [] for bug in rev.properties.get('bugs', '').split('\n'): if bug: try: url, status = bug.split(' ', 1) bugs.append('<a href="%(url)s">%(url)s</a> %(status)s' % (dict(url=url, status=gettext(status)))) except ValueError: bugs.append(bug) # show it "as is" if bugs: props.append((ngettext("Bug:", "Bugs:", len(bugs)), ", ".join(bugs))) foreign_attribs = None if isinstance(rev, foreign.ForeignRevision): foreign_attribs = rev.mapping.vcs.show_foreign_revid(rev.foreign_revid) elif b":" in rev.revision_id: try: foreign_revid, mapping = foreign.foreign_vcs_registry.parse_revision_id(rev.revision_id) foreign_attribs = mapping.vcs.show_foreign_revid(foreign_revid) except errors.InvalidRevisionId: pass if foreign_attribs: keys = list(foreign_attribs.keys()) keys.sort() for key in keys: props.append((key + ":", foreign_attribs[key])) return props
def showAboutDialog(self): tpl = { 'qbrz_version': qbrz.__version__, 'breezy_version': breezy.__version__, } QtWidgets.QMessageBox.about( self, gettext("About QBrz"), gettext( "<b>QBrz</b> \u2014 A graphical user interface for Breezy<br>" "<small>Version %(qbrz_version)s (breezy %(breezy_version)s)</small><br>" "<br>" "Copyright \u00A9 2006-2008 Luk\xe1\u0161 Lalinsk\xfd and others<br>" "<br>" '<a href="http://bazaar-vcs.org/QBzr">http://bazaar-vcs.org/QBzr</a>' ) % tpl)
def __init__(self, localdir=".", parent=None, ui_mode=False): super(QBzrInitWindow, self).__init__(gettext("Initialize"), name="init", ui_mode=ui_mode, dialog=True, parent=parent, hide_progress=True) self.ui = Ui_InitForm() self.ui.setupUi(self) # and add the subprocess widgets. for w in self.make_default_layout_widgets(): self.layout().addWidget(w) # One directory picker self.ui.location.setText(os.path.abspath(localdir)) hookup_directory_picker(self, self.ui.location_picker, self.ui.location, DIRECTORYPICKER_TARGET) # Combo box for repo format. cmd = get_cmd_object('init') opt = cmd.options()['format'] fill_option_combo(self.ui.combo_format, opt, 'default', self.ui.format_desc) self.ui.but_append_only.setToolTip( cmd.options()['append-revisions-only'].help) cmd = get_cmd_object('init-repo') opt = cmd.options()['no-trees'] self.ui.but_no_trees.setToolTip(opt.help)
def _create_item(self, change, shelver, trees, old_changes): """Create QTreeWidgetItem for file list from Change instance.""" ch = Change(change, shelver, trees) item = QtWidgets.QTreeWidgetItem() if ch.kind == 'directory': item.setIcon(0, get_icon("folder", 16)) else: item.setIcon(0, get_icon("file", 16)) item.change = ch item.setText(0, ch.disp_text) item.setText(1, gettext(ch.status)) if ch.status == 'modify text': item.setText(2, '0/%d' % len(ch.parsed_patch.hunks)) brush = self.brushes.get(ch.status) if brush: for i in range(3): item.setForeground(i, brush) item.setCheckState(0, QtCore.Qt.Unchecked) if old_changes: old_change = old_changes.get((ch.file_id, ch.status)) if old_change and old_change.is_same_change(ch): # Keep selection when reloading if ch.status == 'modify text': item.change = old_change self.update_item(item) else: item.setCheckState(0, QtCore.Qt.Checked) return item
def unshelve(self, id, desc, action): args = ["unshelve", str(id), '--' + action] window = SimpleSubProcessDialog(gettext("Shelve Manager"), desc=gettext(desc), args=args, dir=self.directory, immediate=True, parent=self.window()) def finished(result): if result: self.unshelved.emit(self.shelf_id, action) window.subprocessFinished[bool].connect(finished) window.exec_() self.refresh()
def load_diff(self, tree, base_tree): self.file_view.clear() for di in DiffItem.iter_items((base_tree, tree), lock_trees=False): di.load() old_path, new_path = di.paths if di.versioned == (True, False): text = old_path elif di.versioned == (False, True): text = new_path elif di.paths[0] != di.paths[1]: text = '%s => %s' % (old_path, new_path) else: text = old_path item = QtWidgets.QTreeWidgetItem() item.setText(0, text) item.setText(1, gettext(di.status)) if (di.kind[1] or di.kind[0]) == 'directory': item.setIcon(0, get_icon("folder", 16)) else: item.setIcon(0, get_icon("file", 16)) item.diffitem = di brush = self.brushes.get(di.status) if brush: item.setForeground(0, brush) item.setForeground(1, brush) self.file_view.addTopLevelItem(item)