def update_combo_boxes(self, left=False): """Update listwidgets from the combobox selection Update either the left or right listwidgets to reflect the available items. """ if left: which = ustr(self.left_combo.currentText()) widget = self.left_list else: which = ustr(self.right_combo.currentText()) widget = self.right_list if not which: return # If we're looking at "local" stuff then provide the # sandbox as a valid choice. If we're looking at # "remote" stuff then also include the branch point. if which == self.LOCAL: new_list = ([self.SANDBOX]+ self.local_branches) else: new_list = ([self.BRANCH_POINT] + self.remote_branches) widget.clear() widget.addItems(new_list) if new_list: item = widget.item(0) widget.setCurrentItem(item) widget.setItemSelected(item, True)
def action_callback(self): action = self.action if action == FETCH: model_action = self.model.fetch elif action == PUSH: model_action = self.push_to_all else: # if action == PULL: model_action = self.model.pull remote_name = ustr(self.remote_name.text()) if not remote_name: errmsg = N_("No repository selected.") Interaction.log(errmsg) return remote, kwargs = self.common_args() self.selected_remotes = qtutils.selected_items(self.remotes, self.model.remotes) # Check if we're about to create a new branch and warn. remote_branch = ustr(self.remote_branch.text()) local_branch = ustr(self.local_branch.text()) if action == PUSH and not remote_branch: branch = local_branch candidate = "%s/%s" % (remote, branch) if candidate not in self.model.remote_branches: title = N_("Push") args = dict(branch=branch, remote=remote) msg = ( N_('Branch "%(branch)s" does not exist in "%(remote)s".\n' "A new remote branch will be published.") % args ) info_txt = N_("Create a new remote branch?") ok_text = N_("Create Remote Branch") if not qtutils.confirm(title, msg, info_txt, ok_text, icon=icons.cola()): return if not self.ffwd_only_checkbox.isChecked(): if action == FETCH: title = N_("Force Fetch?") msg = N_("Non-fast-forward fetch overwrites local history!") info_txt = N_("Force fetching from %s?") % remote ok_text = N_("Force Fetch") elif action == PUSH: title = N_("Force Push?") msg = N_("Non-fast-forward push overwrites published " "history!\n(Did you pull first?)") info_txt = N_("Force push to %s?") % remote ok_text = N_("Force Push") else: # pull: shouldn't happen since the controls are hidden msg = "You probably don't want to do this.\n\tContinue?" return if not qtutils.confirm(title, msg, info_txt, ok_text, default=False, icon=icons.discard()): return # Disable the GUI by default self.buttons.setEnabled(False) # Use a thread to update in the background task = ActionTask(self.task_runner, model_action, remote, kwargs) self.task_runner.start(task, progress=self.progress, finish=self.action_completed)
def network_finished(self, reply): email = self.email header = QtCore.QByteArray('Location') raw_header = reply.rawHeader(header) if raw_header: location = ustr(QtCore.QString(raw_header)).strip() request_location = ustr( Gravatar.url_for_email(self.email, self.imgsize)) relocated = location != request_location else: relocated = False if reply.error() == QtNetwork.QNetworkReply.NoError: if relocated: # We could do get_url(urllib.unquote(location)) to # download the default image. # Save bandwidth by using a pixmap. self.response = self.default_pixmap_as_bytes() else: self.response = reply.readAll() self.timeout = 0 else: self.response = self.default_pixmap_as_bytes() self.timeout = int(time.time()) pixmap = self.set_pixmap_from_response() # If the email has not changed (e.g. no other requests) # then we know that this pixmap corresponds to this specific # email address. We can't blindly trust self.email else # we may add cache entries for thee wrong email address. url = Gravatar.url_for_email(email, self.imgsize) if url == ustr(reply.url().toString()): self.pixmaps[email] = pixmap
def commitData(self, session_mgr): """Save session data""" if self.view is None: return sid = ustr(session_mgr.sessionId()) skey = ustr(session_mgr.sessionKey()) session_id = '%s_%s' % (sid, skey) session = Session(session_id, repo=core.getcwd()) self.view.save_state(settings=session)
def selection(self): left_item = self.left_list.currentItem() if left_item and left_item.isSelected(): left_item = ustr(left_item.text()) else: left_item = None right_item = self.right_list.currentItem() if right_item and right_item.isSelected(): right_item = ustr(right_item.text()) else: right_item = None return (left_item, right_item)
def confirm_config_action(name, opts): dlg = ActionDialog(qtutils.active_window(), name, opts) dlg.show() if dlg.exec_() != QtGui.QDialog.Accepted: return False rev = ustr(dlg.revision()) if rev: opts['revision'] = rev args = ustr(dlg.args()) if args: opts['args'] = args return True
def export_state(self): """Exports data for save/restore""" state = WidgetMixin.export_state(self) windowstate = self.saveState(self.widget_version) state['lock_layout'] = self.lock_layout state['windowstate'] = ustr(windowstate.toBase64().data()) return state
def do(self): if not self.filenames: return filename = self.filenames[0] if not core.exists(filename): return editor = prefs.editor() opts = [] if self.line_number is None: opts = self.filenames else: # Single-file w/ line-numbers (likely from grep) editor_opts = { '*vim*': ['+'+self.line_number, filename], '*emacs*': ['+'+self.line_number, filename], '*textpad*': ['%s(%s,0)' % (filename, self.line_number)], '*notepad++*': ['-n'+self.line_number, filename], } opts = self.filenames for pattern, opt in editor_opts.items(): if fnmatch(editor, pattern): opts = opt break try: core.fork(utils.shell_split(editor) + opts) except Exception as e: message = (N_('Cannot exec "%s": please configure your editor') % editor) Interaction.critical(N_('Error Editing File'), message, ustr(e))
def apply_patches(self): items = self.tree.items() if not items: return patches = [ustr(i.data(0, Qt.UserRole).toPyObject()) for i in items] cmds.do(cmds.ApplyPatches, patches) self.accept()
def highlightBlock(self, qstr): if not self.enabled: return ascii = ustr(qstr) if not ascii: return formats = self.formats(ascii) if not formats: return for match, fmts in formats: start = match.start() groups = match.groups() # No groups in the regex, assume this is a single rule # that spans the entire line if not groups: self.setFormat(0, len(ascii), fmts) continue # Groups exist, rule is a tuple corresponding to group for grpidx, group in enumerate(groups): # allow empty matches if not group: continue # allow None as a no-op format length = len(group) if fmts[grpidx]: self.setFormat(start, start + length, fmts[grpidx]) start += length
def getopts(self): self.opts.revision = self.revision.value() self.opts.branch = ustr(self.branch_name.text()) self.opts.checkout = self.checkout_checkbox.isChecked() self.opts.reset = self.reset_radio.isChecked() self.opts.fetch = self.fetch_checkbox.isChecked() self.opts.track = self.remote_radio.isChecked()
def prompt(msg, title=None, text=''): """Presents the user with an input widget and returns the input.""" if title is None: title = msg result = QtGui.QInputDialog.getText(active_window(), msg, title, QtGui.QLineEdit.Normal, text) return (ustr(result[0]), result[1])
def diff(self): items = self._tree.selectedItems() if not items: return paths = [i.data(0, QtCore.Qt.UserRole).toPyObject() for i in items] for path in paths: launch(self.diff_arg + ['--', ustr(path)])
def open_bookmark(self, index): if index.row() == 0: self.open_repo() else: self.repodir = ustr(self.bookmarks_model.data(index).toString()) if self.repodir: self.accept()
def update_text(self, width): self._display = self._text if not self._elide: return text = self._metrics.elidedText(self._template, Qt.ElideRight, width - 2) if ustr(text) != self._template: self._display = text
def remote_renamed(self, item): idx = self.remotes.row(item) if idx < 0: return if idx >= len(self.remote_list): return old_name = self.remote_list[idx] new_name = ustr(item.text()) if new_name == old_name: return if not new_name: item.setText(old_name) return title = N_('Rename Remote') question = N_('Rename remote?') info = (N_('Rename remote "%(current)s" to "%(new)s"?') % dict(current=old_name, new=new_name)) ok_btn = N_('Rename') if qtutils.confirm(title, question, info, ok_btn): status, out, err = git.remote('rename', old_name, new_name) if status == 0: self.remote_list[idx] = new_name else: item.setText(old_name)
def set_commit_message(self, message): """Set the commit message to match the observed model""" # Parse the "summary" and "description" fields umsg = ustr(message) lines = umsg.splitlines() num_lines = len(lines) if num_lines == 0: # Message is empty summary = '' description = '' elif num_lines == 1: # Message has a summary only summary = lines[0] description = '' elif num_lines == 2: # Message has two lines; this is not a common case summary = lines[0] description = lines[1] else: # Summary and several description lines summary = lines[0] if lines[1]: # We usually skip this line but check just in case description_lines = lines[1:] else: description_lines = lines[2:] description = '\n'.join(description_lines) focus_summary = not summary focus_description = not description # Update summary if not summary and not self.summary.hasFocus(): self.summary.hint.enable(True) else: self.summary.set_value(summary, block=True) # Update description if not description and not self.description.hasFocus(): self.description.hint.enable(True) else: self.description.set_value(description, block=True) # Update text color self.refresh_palettes() # Focus the empty summary or description if focus_summary: self.summary.setFocus() elif focus_description: self.description.setFocus() else: self.summary.cursor_position.emit() self.update_actions()
def viz_revision(self): """Launch a gitk-like viewer on the selection revision""" revision = ustr(self.revision.text()) if not revision: qtutils.information(N_("No Revision Specified"), N_("You must specify a revision to view.")) return cmds.do(cmds.VisualizeRevision, revision)
def context_menu(self): popup_menu = HintedTextEdit.createStandardContextMenu(self) # Select the word under the cursor. cursor = self.textCursor() cursor.select(QTextCursor.WordUnderCursor) self.setTextCursor(cursor) # Check if the selected word is misspelled and offer spelling # suggestions if it is. spell_menu = None if self.textCursor().hasSelection(): text = ustr(self.textCursor().selectedText()) if not self.spellcheck.check(text): spell_menu = QMenu(N_('Spelling Suggestions')) for word in self.spellcheck.suggest(text): action = SpellAction(word, spell_menu) self.connect(action, SIGNAL('correct'), self.correct) spell_menu.addAction(action) # Only add the spelling suggests to the menu if there are # suggestions. if len(spell_menu.actions()) > 0: popup_menu.addSeparator() popup_menu.addMenu(spell_menu) return popup_menu, spell_menu
def _open_bookmark(self, index): if(index.row() == 0): self._open() else: self._gitdir = ustr(self._bookmark_model.data(index).toString()) if self._gitdir: self.accept()
def opendir_dialog(title, path): """Prompts for a directory path""" flags = (QtGui.QFileDialog.ShowDirsOnly | QtGui.QFileDialog.DontResolveSymlinks) return ustr(QtGui.QFileDialog .getExistingDirectory(active_window(), title, path, flags))
def keyPressEvent(self, event): if event.key() == Qt.Key_Up: cursor = self.textCursor() position = cursor.position() if position == 0: # The cursor is at the beginning of the line. # If we have selection then simply reset the cursor. # Otherwise, emit a signal so that the parent can # change focus. if cursor.hasSelection(): cursor.setPosition(0) self.setTextCursor(cursor) else: self.emit_leave() event.accept() return text_before = ustr(self.toPlainText())[:position] lines_before = text_before.count('\n') if lines_before == 0: # If we're on the first line, but not at the # beginning, then move the cursor to the beginning # of the line. if event.modifiers() & Qt.ShiftModifier: mode = QtGui.QTextCursor.KeepAnchor else: mode = QtGui.QTextCursor.MoveAnchor cursor.setPosition(0, mode) self.setTextCursor(cursor) event.accept() return elif event.key() == Qt.Key_Down: cursor = self.textCursor() position = cursor.position() all_text = ustr(self.toPlainText()) text_after = all_text[position:] lines_after = text_after.count('\n') if lines_after == 0: if event.modifiers() & Qt.ShiftModifier: mode = QtGui.QTextCursor.KeepAnchor else: mode = QtGui.QTextCursor.MoveAnchor cursor.setPosition(len(all_text), mode) self.setTextCursor(cursor) event.accept() return SpellCheckTextEdit.keyPressEvent(self, event)
def update_title(self, dummy_txt=None): branch = self.model.currentbranch revision = ustr(self.revision.text()) if revision: txt = N_('Merge "%(revision)s" into "%(branch)s"') % dict(revision=revision, branch=branch) else: txt = N_('Merge into "%s"') % branch self.title_label.setText(txt) self.setWindowTitle(txt)
def python_to_git(self, value): if type(value) is bool: if value: return "true" else: return "false" if isinstance(value, int_types): return ustr(value) return value
def _last_word(self): if self._ends_with_whitespace(): return '' words = self._words() if not words: return ustr(self.text()) if not words[-1]: return '' return words[-1]
def python_to_git(self, value): if type(value) is bool: if value: return 'true' else: return 'false' if type(value) is int: return ustr(value) return value
def add_files(self): files = qtutils.open_files(N_('Select patch file(s)...'), directory=self.curdir, filter='Patches (*.patch *.mbox)') if not files: return files = [ustr(f) for f in files] self.curdir = os.path.dirname(files[0]) self.add_paths([os.path.relpath(f) for f in files])
def common_args(self): """Returns git arguments common to fetch/push/pulll""" remote_name = ustr(self.remote_name.text()) local_branch = ustr(self.local_branch.text()) remote_branch = ustr(self.remote_branch.text()) ffwd_only = self.ffwd_only_checkbox.isChecked() rebase = self.rebase_checkbox.isChecked() tags = self.tags_checkbox.isChecked() return (remote_name, { 'local_branch': local_branch, 'remote_branch': remote_branch, 'ffwd': ffwd_only, 'rebase': rebase, 'tags': tags, })
def select_remote(self, idx): """Selects a remote by index""" item = self.remotes.item(idx) if item: self.remotes.setItemSelected(item, True) self.remotes.setCurrentItem(item) self.set_remote_name(ustr(item.text())) return True else: return False
def _add_watch_failed_warning(self, directory, e): core.stderr('inotify: failed to watch "%s"' % directory) core.stderr(ustr(e)) core.stderr('') core.stderr('If you have run out of watches then you may be able to') core.stderr('increase the number of allowed watches by running:') core.stderr('') core.stderr(' echo fs.inotify.max_user_watches=100000 |') core.stderr(' sudo tee -a /etc/sysctl.conf &&') core.stderr(' sudo sysctl -p\n')
def get_selected_bookmark(self): selected = self.bookmarks.selectedIndexes() if (len(selected) > 0 and selected[0].row() != 0): return ustr(self.bookmarks_model.data(selected[0]).toString()) return None
def _set_revision_list(self): sender = ustr(self.sender().objectName()) revs = self._revdict[sender] qtutils.set_items(self._rev_list, revs)
def highlight_document(edit, filename): doc = edit.document() if not have_pygments: return try: lexer = get_lexer_for_filename(filename, stripnl=False) except ClassNotFound: return style = get_style_by_name("default") font = doc.defaultFont() base_format = QtGui.QTextCharFormat() base_format.setFont(font) token_formats = {} window = edit.window() if hasattr(window, "processEvents"): processEvents = window.processEvents else: processEvents = QtCore.QCoreApplication.processEvents def get_token_format(token): if token in token_formats: return token_formats[token] if token.parent: parent_format = get_token_format(token.parent) else: parent_format = base_format format = QtGui.QTextCharFormat(parent_format) font = format.font() if style.styles_token(token): tstyle = style.style_for_token(token) if tstyle['color']: format.setForeground (QtGui.QColor("#"+tstyle['color'])) if tstyle['bold']: font.setWeight(QtGui.QFont.Bold) if tstyle['italic']: font.setItalic (True) if tstyle['underline']: format.setFontUnderline(True) if tstyle['bgcolor']: format.setBackground (QtGui.QColor("#"+tstyle['bgcolor'])) # No way to set this for a QTextCharFormat #if tstyle['border']: format. token_formats[token] = format return format text = ustr(doc.toPlainText()) block_count = 0 block = doc.firstBlock() assert(isinstance(block, QtGui.QTextBlock)) block_pos = 0 block_len = block.length() block_formats = [] for token, ttext in lex(text, lexer): format_len = len(ttext) format = get_token_format(token) while format_len > 0: format_range = QtGui.QTextLayout.FormatRange() format_range.start = block_pos format_range.length = min(format_len, block_len) format_range.format = format block_formats.append(format_range) block_len -= format_range.length format_len -= format_range.length block_pos += format_range.length if block_len == 0: block.layout().setAdditionalFormats(block_formats) doc.markContentsDirty(block.position(), block.length()) block = block.next() block_pos = 0 block_len = block.length() block_formats = [] block_count += 1 if block_count % 100 == 0: processEvents()
def action_callback(self): action = self.action if action == FETCH: model_action = self.model.fetch elif action == PUSH: model_action = self.push_to_all else: # if action == PULL: model_action = self.model.pull remote_name = ustr(self.remote_name.text()) if not remote_name: errmsg = N_('No repository selected.') Interaction.log(errmsg) return remote, kwargs = self.common_args() self.selected_remotes = qtutils.selected_items(self.remotes, self.model.remotes) # Check if we're about to create a new branch and warn. remote_branch = ustr(self.remote_branch.text()) local_branch = ustr(self.local_branch.text()) if action == PUSH and not remote_branch: branch = local_branch candidate = '%s/%s' % (remote, branch) if candidate not in self.model.remote_branches: title = N_('Push') args = dict(branch=branch, remote=remote) msg = N_( 'Branch "%(branch)s" does not exist in "%(remote)s".\n' 'A new remote branch will be published.') % args info_txt = N_('Create a new remote branch?') ok_text = N_('Create Remote Branch') if not qtutils.confirm( title, msg, info_txt, ok_text, icon=qtutils.git_icon()): return if not self.ffwd_only_checkbox.isChecked(): if action == FETCH: title = N_('Force Fetch?') msg = N_('Non-fast-forward fetch overwrites local history!') info_txt = N_('Force fetching from %s?') % remote ok_text = N_('Force Fetch') elif action == PUSH: title = N_('Force Push?') msg = N_('Non-fast-forward push overwrites published ' 'history!\n(Did you pull first?)') info_txt = N_('Force push to %s?') % remote ok_text = N_('Force Push') else: # pull: shouldn't happen since the controls are hidden msg = "You probably don't want to do this.\n\tContinue?" return if not qtutils.confirm(title, msg, info_txt, ok_text, default=False, icon=qtutils.discard_icon()): return # Disable the GUI by default self.buttons.setEnabled(False) # Use a thread to update in the background task = ActionTask(self.task_runner, model_action, remote, kwargs) self.task_runner.start(task, progress=self.progress, finish=self.action_completed)
def font_size_changed(self, size): font = self.fixed_font.currentFont() font.setPointSize(size) cmds.do(SetConfig, self.model, 'user', FONTDIFF, ustr(font.toString()))
def current_font_changed(self, font): cmds.do(SetConfig, self.model, 'user', FONTDIFF, ustr(font.toString()))
def runner(): value = ustr(self.sender().text()) cmds.do(SetConfig, self.model, self.source, config, value)
def text(self): return ustr(self.lineedit.text())
def _argstxt_changed(self, value): """Store the argstxt value so that we can remember it between calls""" self.VALUES[self.name]['argstxt'] = ustr(value)