def update_sensitives(self, affectlocal=False): """ update bottom button sensitives based on rev and tag """ rev = self.reventry.get_text() tag = self.tagentry.get_text() if not rev or not tag: self.addbtn.set_sensitive(False) self.removebtn.set_sensitive(False) return # check if valid revision try: self.repo[hglib.fromutf(rev)] except (error.LookupError, error.RepoLookupError, error.RepoError): self.addbtn.set_sensitive(False) self.removebtn.set_sensitive(False) return # check tag existence force = self.replacechk.get_active() is_exist = hglib.fromutf(tag) in self.repo.tags() self.addbtn.set_sensitive(not is_exist or force) self.removebtn.set_sensitive(is_exist) # check if local is_local = self.repo.tagtype(hglib.fromutf(tag)) if affectlocal and is_local is not None: self.localchk.set_active(is_local == "local") self.update_revision()
def rundlg(q): import win32gui, win32con, pywintypes cwd = os.getcwd() fname = None try: f = '' for name, mask in self.filter: f += '\0'.join([name, mask,'']) flags = win32con.OFN_EXPLORER if self.multi: flags |= win32con.OFN_ALLOWMULTISELECT opts = dict(InitialDir=self.initial, Flags=flags, File=self.filename, DefExt=None, Title=hglib.fromutf(self.title), Filter= hglib.fromutf(f), CustomFilter=None, FilterIndex=self.filterindex) if self.open: ret = win32gui.GetOpenFileNameW(**opts) else: ret = win32gui.GetSaveFileNameW(**opts) fname = ret[0] except pywintypes.error: pass os.chdir(cwd) q.put(fname)
def update_revision(self): """ update revision entry based on tag """ tagmap = self.repo.tags() tag = self.tagentry.get_text() replace = self.replacechk.get_active() if not tag or hglib.fromutf(tag) not in tagmap or replace: if self.initial_rev: self.reventry.set_text(self.initial_rev) return node = tagmap[hglib.fromutf(tag)] ctx = self.repo[node] self.reventry.set_text(str(ctx.rev()))
def add_hg_tag(self, name, revision, message, local, user=None, date=None, force=False, english=False): if hglib.fromutf(name) in self.repo.tags() and not force: raise util.Abort(_('a tag named "%s" already exists') % name) ctx = self.repo[revision] r = ctx.node() if not message: msgset = keep._("Added tag %s for changeset %s") message = (english and msgset["id"] or msgset["str"]) % (name, str(ctx)) if name in self.repo.tags() and not force: raise util.Abort(_("Tag '%s' already exist") % name) lname = hglib.fromutf(name) self.repo.tag(lname, r, hglib.fromutf(message), local, user, date)
def _refresh(self, initial): def fill_history(history, vlist, cpath): vlist.clear() if cpath not in history.get_keys(): return for v in history.get_value(cpath): vlist.append([v]) history = settings.Settings('email') try: repo = hg.repository(ui.ui(), path=self.root) self.repo = repo except error.RepoError: self.repo = None return def getfromaddr(ui): """Get sender address in the same manner as patchbomb""" addr = ui.config('email', 'from') or ui.config('patchbomb', 'from') if addr: return addr try: return repo.ui.username() except error.Abort: return '' if initial: # Only zap these fields at startup self._tobox.child.set_text(hglib.fromutf(repo.ui.config('email', 'to', ''))) self._ccbox.child.set_text(hglib.fromutf(repo.ui.config('email', 'cc', ''))) self._frombox.child.set_text(hglib.fromutf(getfromaddr(repo.ui))) self._subjbox.child.set_text(hglib.fromutf(repo.ui.config('email', 'subject', ''))) self.tips.set_tip(self._eventbox, _('Patch series description is sent in initial summary ' 'email with [PATCH 0 of N] subject. It should describe ' 'the effects of the entire patch series. When emailing ' 'a bundle, these fields make up the message subject and ' 'body. Flags is a comma separated list of tags ' 'which are inserted into the message subject prefix.') ) gtklib.addspellcheck(self.descview, self.repo.ui) fill_history(history, self._tolist, 'email.to') fill_history(history, self._cclist, 'email.cc') fill_history(history, self._fromlist, 'email.from') fill_history(history, self._subjlist, 'email.subject') fill_history(history, self._flaglist, 'email.flags') if len(self._flaglist) == 0: self._flaglist.append(['STABLE'])
def move_clicked(self, toolbutton, data=None): move_list = self.relevant_checked_files('C') if move_list: # get destination directory to files into dlg = gtklib.NativeFolderSelectDialog( title=_('Move files to directory...'), initial=self.repo.root) destdir = dlg.run() if not destdir: return True # verify directory destroot = paths.find_root(destdir) if destroot != self.repo.root: gdialog.Prompt(_('Nothing Moved'), _('Cannot move outside repo!'), self).run() return True # move the files to dest directory move_list.append(hglib.fromutf(destdir)) self.act.hg_move(move_list) else: gdialog.Prompt(_('Nothing Moved'), _('No movable files selected\n\n' 'Note: only clean files can be moved.'), self).run() return True
def exec_cmd(self, cmd): if self.cmd_running(): dialog.error_dialog(self, _('Cannot run now'), _('Please try again after the previous command has completed')) return self.stop_button.set_sensitive(True) proxy_host = ui.ui().config('http_proxy', 'host', '') use_proxy = self.use_proxy.get_active() text_entry = self.pathbox.get_child() remote_path = hglib.fromutf(text_entry.get_text()).strip() remote_path = hglib.validate_synch_path(remote_path, self.repo) cmdline = cmd[:] cmdline += ['--verbose'] if proxy_host and not use_proxy: cmdline += ["--config", "http_proxy.host="] cmdline += ['--', remote_path] self.lastcmd = cmdline # show command to be executed self.write("", False) # execute command and show output on text widget gobject.timeout_add(10, self.process_queue) self.hgthread = hgthread.HgThread(cmdline, parent=self) self.hgthread.start() self.stbar.begin() self.stbar.set_text('hg ' + ' '.join(cmd)) self.add_src_to_recent(remote_path)
def domerge(self): if self.discard.get_active(): c = self.repo[None] if c.modified() or c.added() or c.removed(): gdialog.Prompt(_('Cannot merge'), _('Uncommitted local changes'), self).run() return # '.' is safer than self.localrev, in case the user has # pulled a fast one on us and updated from the CLI ret = gdialog.Confirm(_('Confirm Discard Changes'), [], self, _('The changes from revision %s and all unmerged parents ' 'will be discarded.\n\n' 'Are you sure this is what you want to do?') % (self.otherframe.get_data('revid'))).run() if ret != gtk.RESPONSE_YES: return cmdline = ['hg', 'debugsetparents', '.', self.otherrev] else: tool = hglib.fromutf(self.mergetool.child.get_text()) if tool: cmdline = ['hg', '--config', 'ui.merge=%s' % tool] else: cmdline = ['hg'] cmdline.extend(['merge', '--rev', self.otherrev]) self.execute_command(cmdline, 'merge')
def version(ui, **opts): """output version and copyright information""" ui.write(_('TortoiseHg Dialogs (version %s), ' 'Mercurial (version %s)\n') % (hglib.fromutf(thgversion.version()), hglib.hgversion)) if not ui.quiet: ui.write(shortlicense)
def rundlg(q): from win32com.shell import shell, shellcon import win32gui, pywintypes def BrowseCallbackProc(hwnd, msg, lp, data): if msg == shellcon.BFFM_INITIALIZED: win32gui.SendMessage( hwnd, shellcon.BFFM_SETSELECTION, 1, data) elif msg == shellcon.BFFM_SELCHANGED: # Set the status text of the # For this message, 'lp' is the address of the PIDL. pidl = shell.AddressAsPIDL(lp) try: path = shell.SHGetPathFromIDList(pidl) win32gui.SendMessage( hwnd, shellcon.BFFM_SETSTATUSTEXT, 0, path) except shell.error: # No path for this PIDL pass fname = None try: flags = shellcon.BIF_EDITBOX | 0x40 #shellcon.BIF_NEWDIALOGSTYLE pidl, _, _ = shell.SHBrowseForFolder( 0, None, hglib.fromutf(self.title), flags, BrowseCallbackProc, # callback function self.initial) # 'data' param for the callback if pidl: fname = hglib.toutf(shell.SHGetPathFromIDList(pidl)) except (pywintypes.error, pywintypes.com_error): pass q.put(fname)
def rename_file(self, wfile): fdir, fname = os.path.split(wfile) utf_fname = hglib.toutf(fname) newfile = dialog.entry_dialog(self.stat, _('Rename file to:'), True, utf_fname) if newfile and newfile != utf_fname: self.hg_move([wfile, os.path.join(fdir, hglib.fromutf(newfile))]) return True
def remove_hg_tag(self, name, message, local, user=None, date=None, english=False): lname = hglib.fromutf(name) tagtype = self.repo.tagtype(lname) if not tagtype: raise util.Abort(_("tag '%s' does not exist") % lname) if local: if tagtype != "local": raise util.Abort(_("tag '%s' is not a local tag") % lname) else: if tagtype != "global": raise util.Abort(_("tag '%s' is not a global tag") % lname) if not message: msgset = keep._("Removed tag %s") message = (english and msgset["id"] or msgset["str"]) % name r = self.repo[-1].node() self.repo.tag(lname, r, hglib.fromutf(message), local, user, date)
def add_glob(self, widget): newglob = hglib.fromutf(self.glob_entry.get_text()) if newglob == '': return newglob = 'glob:' + newglob try: match.match(self.repo.root, '', [], [newglob]) except util.Abort, inst: gdialog.Prompt(_('Invalid glob expression'), str(inst), self).run() return
def add_regexp(self, widget): newregexp = hglib.fromutf(self.regexp_entry.get_text()) if newregexp == '': return try: match.match(self.repo.root, '', [], ['relre:' + newregexp]) re.compile(newregexp) except (util.Abort, re.error), inst: gdialog.Prompt(_('Invalid regexp expression'), str(inst), self).run() return
def grep_selection_changed(self, treeview): """ Callback for when the user selects grep output. """ (path, focus) = treeview.get_cursor() model = treeview.get_model() if path is not None and model is not None: iter = model.get_iter(path) self.currev = model[iter][GCOL_REVID] self.curpath = hglib.fromutf(model[iter][GCOL_PATH]) self.cslabel.update(model[iter][GCOL_REVID])
def get_rev(self): """ Return integer revision number or None """ revstr = self.revcombo.get_active_text() if revstr is None or len(revstr) == 0: return None if isinstance(revstr, basestring): revstr = hglib.fromutf(revstr) try: revnum = self.repo[revstr].rev() except (error.RepoError, error.LookupError): return None return revnum
def agettext(message, context=''): """Translate message and convert to local encoding such as 'ascii' before being returned. Only use this if you need to output translated messages to command-line interface (ie: Windows Command Prompt). """ try: from tortoisehg.util import hglib u = _(message, context) return hglib.fromutf(u) except (LookupError, UnicodeEncodeError): return message
def backout(self): # do not auto-close when finished self.set_after_done(False) # prepare command line cmdline = ['hg', 'backout', '--rev', self.rev] if self.merge_button.get_active(): start, end = self.buf.get_bounds() msg = self.buf.get_text(start, end) cmdline += ['--merge'] cmdline += ['--message', hglib.fromutf(msg)] # start backing out self.execute_command(cmdline)
def email_clicked(self, toolbutton, data=None): opts = [] path = hglib.fromutf(self.pathtext.get_text()).strip() rev = self.get_advanced_options().get('rev') if path: opts.extend(['--outgoing', path]) elif not rev: dialog.info_dialog(self, _('No repository selected'), _('Select a peer repository to compare with')) self.pathbox.grab_focus() return if rev: opts.extend(rev) dlg = hgemail.EmailDialog(self.root, opts) self.show_dialog(dlg)
def rename_resp(dlg, response): if response != gtk.RESPONSE_OK: dlg.destroy() return try: root = paths.find_root() repo = hg.repository(ui.ui(), root) except (ImportError, error.RepoError): dlg.destroy() return new_name = hglib.fromutf(dlg.entry.get_text()) opts = {} opts['force'] = False # Checkbox? Nah. opts['after'] = True opts['dry_run'] = False saved = sys.stderr errors = cStringIO.StringIO() toquit = False try: sys.stderr = errors repo.ui.pushbuffer() repo.ui.quiet = True try: new_name = util.canonpath(root, root, new_name) targetdir = os.path.dirname(new_name) or '.' if dlg.orig.lower() == new_name.lower() and os.path.isdir(dlg.orig): os.rename(dlg.orig, new_name) else: if not os.path.isdir(targetdir): os.makedirs(targetdir) shutil.move(dlg.orig, new_name) commands.rename(repo.ui, repo, dlg.orig, new_name, **opts) toquit = True except (OSError, IOError, util.Abort, error.RepoError), inst: dialog.error_dialog(None, _('rename error'), str(inst)) toquit = False finally: sys.stderr = saved textout = errors.getvalue() + repo.ui.popbuffer() errors.close() if len(textout) > 1: dialog.error_dialog(None, _('rename error'), textout) elif toquit: dlg.destroy()
def conf_clicked(self, toolbutton, data=None): newpath = hglib.fromutf(self.pathtext.get_text()).strip() for alias, path in self.paths: if newpath in (path, url.hidepassword(path)): newpath = None break dlg = thgconfig.ConfigDialog(True) dlg.show_all() if newpath: dlg.new_path(newpath, 'default') else: dlg.focus_field('tortoisehg.postpull') dlg.run() dlg.hide() self.paths = self.get_paths() self.fill_path_combo() self.update_pull_setting()
def launch(self, st, fname): fname = hglib.fromutf(fname) source = self.copies.get(fname, None) dir1a, dir1b, dir2 = self.dirs rev1a, rev1b, rev2 = self.revs ctx1a, ctx1b, ctx2 = self.ctxs def getfile(ctx, dir, fname, source): m = ctx.manifest() if fname in m: path = os.path.join(dir, util.localpath(fname)) return fname, path elif source and source in m: path = os.path.join(dir, util.localpath(source)) return source, path else: nullfile = os.path.join(self.tmproot, 'empty') fp = open(nullfile, 'w') fp.close() return _nonexistant, nullfile local, file1a = getfile(ctx1a, dir1a, fname, source) if ctx1b: other, file1b = getfile(ctx1b, dir1b, fname, source) else: other = fname file1b = None fname, file2 = getfile(ctx2, dir2, fname, None) label1a = local+rev1a label1b = other+rev1b label2 = fname+rev2 if ctx1b: label1a += '[local]' label1b += '[other]' label2 += '[merged]' # Function to quote file/dir names in the argument string replace = dict(parent=file1a, parent1=file1a, plabel1=label1a, parent2=file1b, plabel2=label1b, repo=self.reponame, phash1=str(ctx1a), phash2=str(ctx1b), chash=str(ctx2), clabel=label2, child=file2) args = ctx1b and self.mergeopts or self.diffopts launchtool(self.diffpath, args, replace, False)
def get_files_from_listfile(): global _lines global _linesutf8 lines = [] need_to_utf8 = False if os.name == 'nt': try: fixutf8 = extensions.find("fixutf8") if fixutf8: need_to_utf8 = True except KeyError: pass if need_to_utf8: lines += _linesutf8 for l in _lines: lines.append(hglib.toutf(l)) else: lines += _lines for l in _linesutf8: lines.append(hglib.fromutf(l)) # Convert absolute file paths to repo/cwd canonical cwd = os.getcwd() root = paths.find_root(cwd) if not root: return lines if cwd == root: cwd_rel = '' else: cwd_rel = cwd[len(root + os.sep):] + os.sep files = [] for f in lines: try: cpath = scmutil.canonpath(root, cwd, f) # canonpath will abort on .hg/ paths except util.Abort: continue if cpath.startswith(cwd_rel): cpath = cpath[len(cwd_rel):] files.append(cpath) else: files.append(f) return files
def get_files_from_listfile(): global _lines global _linesutf8 lines = [] need_to_utf8 = False if os.name == 'nt': try: fixutf8 = extensions.find("fixutf8") if fixutf8: need_to_utf8 = True except KeyError: pass if need_to_utf8: lines += _linesutf8 for l in _lines: lines.append(hglib.toutf(l)) else: lines += _lines for l in _linesutf8: lines.append(hglib.fromutf(l)) # Convert absolute file paths to repo/cwd canonical cwd = os.getcwd() root = paths.find_root(cwd) if not root: return lines if cwd == root: cwd_rel = '' else: cwd_rel = cwd[len(root+os.sep):] + os.sep files = [] for f in lines: try: cpath = hglib.canonpath(root, cwd, f) # canonpath will abort on .hg/ paths except util.Abort: continue if cpath.startswith(cwd_rel): cpath = cpath[len(cwd_rel):] files.append(cpath) else: files.append(f) return files
def save_file_rev(self, menuitem): wfile = util.localpath(self.curfile) wfile, ext = os.path.splitext(os.path.basename(wfile)) if wfile: filename = "%s@%d%s" % (wfile, self.currev, ext) else: filename = "%s@%d" % (ext, self.currev) result = gtklib.NativeSaveFileDialogWrapper(title=_("Save file to"), initial=self.cwd, filename=filename).run() if not result: return try: q = Queue.Queue() hglib.hgcmd_toq(q, False, ('cat', '--rev', str(self.currev), '--output', hglib.fromutf(result), self.curfile)) except (util.Abort, IOError), e: gdialog.Prompt(_('Unable to save file'), str(e), self).run()
def update_summaries(self): ctxs = self.ctxs self.parent1_label.update(ctxs[0]) merge = len(ctxs) == 2 if merge: self.parent2_label.update(ctxs[1]) newrev = hglib.fromutf(self.revcombo.get_active_text()) try: new_ctx = self.repo[newrev] if not merge and new_ctx.rev() == ctxs[0].rev(): self.target_label.set_label(_('(same as parent)')) clean = self.opt_clean.get_active() self.buttons['update'].set_sensitive(clean) else: self.target_label.update(self.repo[newrev]) self.buttons['update'].set_sensitive(True) except (error.LookupError, error.RepoLookupError, error.RepoError): self.target_label.set_label(_('unknown revision!')) self.buttons['update'].set_sensitive(False)
def browse_clicked(self, button): """Select the destination directory or file""" dest = hglib.fromutf(self.destentry.get_text()) if not os.path.exists(dest): dest = os.path.dirname(dest) select = self.get_selected_archive_type() if select['type'] == 'files': response = gtklib.NativeFolderSelectDialog( initial=dest, title=_('Select Destination Folder')).run() else: ext = '*' + select['ext'] label = '%s (%s)' % (select['label'], ext) response = gtklib.NativeSaveFileDialogWrapper( initial=dest, title=_('Select Destination File'), filter=((label, ext), (_('All Files (*.*)'), '*.*'))).run() if response: self.destentry.set_text(response)
def archive(self): # verify input type = self.get_selected_archive_type()['type'] dest = self.destentry.get_text() if os.path.exists(dest): if type != 'files': ret = gdialog.Confirm(_('Confirm Overwrite'), [], self, _('The destination "%s" already exists!\n\n' 'Do you want to overwrite it?') % dest).run() if ret != gtk.RESPONSE_YES: return False elif len(os.listdir(dest)) > 0: ret = gdialog.Confirm(_('Confirm Overwrite'), [], self, _('The directory "%s" isn\'t empty!\n\n' 'Do you want to overwrite it?') % dest).run() if ret != gtk.RESPONSE_YES: return False # prepare command line cmdline = ['hg', 'archive', '--verbose'] rev = self.combo.get_active_text() if rev != WD_PARENT: cmdline.append('--rev') cmdline.append(rev) cmdline.append('-t') cmdline.append(type) if self.opt_files_in_rev.get_active(): ctx = self.repo[rev] for f in ctx.files(): cmdline.append('-I') cmdline.append(f) cmdline.append('--') cmdline.append(hglib.fromutf(dest)) # start archiving self.execute_command(cmdline)
def test_fromutf_fallback(): assert_equals(JAPANESE_KANA_I.encode('euc-jp'), hglib.fromutf(JAPANESE_KANA_I.encode('utf-8')))
def file_selected(self, combo): 'select another ignore file' self.ignorefile = hglib.fromutf(combo.get_active_text()) self.refresh()
def test_fromutf_replace(): assert_equals('?', hglib.fromutf(JAPANESE_KANA_I.encode('utf-8')))
def test_lossless_utf_cannot_roundtrip(): u = JAPANESE_KANA_I.encode('cp932') # bad encoding l = hglib.fromutf(u) assert_not_equals(u, hglib.toutf(l))
def test_lossless_utf_replaced(): u = JAPANESE_KANA_I.encode('utf-8') l = hglib.fromutf(u) assert_equals('?', l) assert_equals(u, hglib.toutf(l))