by
Changes to 194 files · Browse files at 1c9faadf11e3 Showing diff from parent da7d19e195ce a1c36aaeb933 Diff from another changeset...
@@ -3,12 +3,14 @@ *.orig
*.rej
*.pyc
-hggtk/__version__.py
+thgutil/__version__.py
+thgutil/__paths__.py
build/
dist/
Output/
.*.swp
Thumbs.db
+MANIFEST
*.o
*.dll
*.exe
|
@@ -17,3 +17,5 @@ a4a7861b92459c4049d09064707d96e54662e506 0.7.1
39d55a62a43e01e3382fe29319cd9ff7ce7626b2 0.7.2
5215e780e9163cd7f2ce377692d7e719a6e82520 0.7.3
+ef5ab6bccf5ee5356a0d5f42987f55af0f75330f 0.7.4
+a88261eec1f43d37786bfdb492322bddd94dcf8d 0.7.5
|
|
@@ -0,0 +1,4 @@ + recursive-include icons *.png *.ico *.svg
+include contrib/_hgtk
+include contrib/nautilus-thg.py
+include COPYING.txt ReleaseNotes.txt
|
|
|
@@ -0,0 +1,552 @@ + #compdef hgtk
+
+# Zsh completion script for hgtk.
+# copy it into your zsh function path (/usr/share/zsh/site-functions)
+#
+# Copyright (C) 2009 Steve Borho
+#
+# This is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation; either version 2 of the License, or (at your
+# option) any later version.
+
+emulate -LR zsh
+setopt extendedglob
+
+local curcontext="$curcontext" state line
+typeset -A _hg_cmd_globals
+
+_hgtk() {
+ local cmd _hg_root
+ integer i=2
+ _hg_cmd_globals=()
+
+ while (( i < $#words ))
+ do
+ case "$words[$i]" in
+ -R|--repository)
+ eval _hg_root="$words[$i+1]"
+ _hg_cmd_globals+=("$words[$i]" "$_hg_root")
+ (( i += 2 ))
+ continue
+ ;;
+ -R*)
+ _hg_cmd_globals+="$words[$i]"
+ eval _hg_root="${words[$i]#-R}"
+ (( i++ ))
+ continue
+ ;;
+ --cwd|--config)
+ # pass along arguments to hg completer
+ _hg_cmd_globals+=("$words[$i]" "$words[$i+1]")
+ (( i += 2 ))
+ continue
+ ;;
+ -*)
+ # skip option
+ (( i++ ))
+ continue
+ ;;
+ esac
+ if [[ -z "$cmd" ]]
+ then
+ cmd="$words[$i]"
+ words[$i]=()
+ (( CURRENT-- ))
+ fi
+ (( i++ ))
+ done
+
+ if [[ -z "$cmd" ]]
+ then
+ _arguments -s -w : $_hg_global_opts \
+ ':hgtk command:_hg_commands'
+ return
+ fi
+
+ # resolve abbreviations and aliases
+ if ! (( $+functions[_hg_cmd_${cmd}] ))
+ then
+ local cmdexp
+ (( $#_hg_cmd_list )) || _hg_get_commands
+
+ cmdexp=$_hg_cmd_list[(r)${cmd}*]
+ if [[ $cmdexp == $_hg_cmd_list[(R)${cmd}*] ]]
+ then
+ # might be nice to rewrite the command line with the expansion
+ cmd="$cmdexp"
+ fi
+ if [[ -n $_hg_alias_list[$cmd] ]]
+ then
+ cmd=$_hg_alias_list[$cmd]
+ fi
+ fi
+
+ curcontext="${curcontext%:*:*}:hg-${cmd}:"
+
+ zstyle -s ":completion:$curcontext:" cache-policy update_policy
+
+ if [[ -z "$update_policy" ]]
+ then
+ zstyle ":completion:$curcontext:" cache-policy _hg_cache_policy
+ fi
+
+ if (( $+functions[_hg_cmd_${cmd}] ))
+ then
+ _hg_cmd_${cmd}
+ else
+ # complete unknown commands normally
+ _arguments -s -w : $_hg_global_opts \
+ '*:files:_hg_files'
+ fi
+}
+
+_hg_cache_policy() {
+ typeset -a old
+
+ # cache for a minute
+ old=( "$1"(mm+10) )
+ (( $#old )) && return 0
+
+ return 1
+}
+
+_hg_get_commands() {
+ typeset -ga _hg_cmd_list
+ typeset -gA _hg_alias_list
+ local hline cmd cmdalias
+
+ _call_program hgtk hgtk debugcomplete -v 2>/dev/null | while read -A hline
+ do
+ cmd=$hline[1]
+ _hg_cmd_list+=($cmd)
+
+ for cmdalias in $hline[2,-1]
+ do
+ _hg_cmd_list+=($cmdalias)
+ _hg_alias_list+=($cmdalias $cmd)
+ done
+ done
+}
+
+_hg_commands() {
+ (( $#_hg_cmd_list )) || _hg_get_commands
+ _describe -t commands 'hgtk command' _hg_cmd_list
+}
+
+_hg_revrange() {
+ compset -P 1 '*:'
+ _hg_tags "$@"
+}
+
+_hg_tags() {
+ typeset -a tags
+ local tag rev
+
+ _hg_cmd tags 2> /dev/null | while read tag
+ do
+ tags+=(${tag/ # [0-9]#:*})
+ done
+ (( $#tags )) && _describe -t tags 'tags' tags
+}
+
+_hg_files() {
+ if [[ -n "$_hg_root" ]]
+ then
+ [[ -d "$_hg_root/.hg" ]] || return
+ case "$_hg_root" in
+ /*)
+ _files -W $_hg_root
+ ;;
+ *)
+ _files -W $PWD/$_hg_root
+ ;;
+ esac
+ else
+ _files
+ fi
+}
+
+_hg_status() {
+ [[ -d $PREFIX ]] || PREFIX=$PREFIX:h
+ status_files=(${(ps:\0:)"$(_hg_cmd status -0n$1 ./$PREFIX 2>/dev/null)"})
+}
+
+_hg_unknown() {
+ typeset -a status_files
+ _hg_status u
+ _wanted files expl 'unknown files' _multi_parts / status_files
+}
+
+_hg_missing() {
+ typeset -a status_files
+ _hg_status d
+ _wanted files expl 'missing files' _multi_parts / status_files
+}
+
+_hg_modified() {
+ typeset -a status_files
+ _hg_status m
+ _wanted files expl 'modified files' _multi_parts / status_files
+}
+
+_hg_resolve() {
+ local rstate rpah
+
+ [[ -d $PREFIX ]] || PREFIX=$PREFIX:h
+
+ _hg_cmd resolve -l ./$PREFIX 2> /dev/null | while read rstate rpath
+ do
+ [[ $rstate == 'R' ]] && resolved_files+=($rpath)
+ [[ $rstate == 'U' ]] && unresolved_files+=($rpath)
+ done
+}
+
+_hg_resolved() {
+ typeset -a resolved_files unresolved_files
+ _hg_resolve
+ _wanted files expl 'resolved files' _multi_parts / resolved_files
+}
+
+_hg_unresolved() {
+ typeset -a resolved_files unresolved_files
+ _hg_resolve
+ _wanted files expl 'unresolved files' _multi_parts / unresolved_files
+}
+
+_hg_config() {
+ typeset -a items
+ items=(${${(%f)"$(_call_program hg hg showconfig)"}%%\=*})
+ (( $#items )) && _describe -t config 'config item' items
+}
+
+_hg_addremove() {
+ _alternative 'files:unknown files:_hg_unknown' \
+ 'files:missing files:_hg_missing'
+}
+
+_hg_ssh_urls() {
+ if [[ -prefix */ ]]
+ then
+ if zstyle -T ":completion:${curcontext}:files" remote-access
+ then
+ local host=${PREFIX%%/*}
+ typeset -a remdirs
+ compset -p $(( $#host + 1 ))
+ local rempath=${(M)PREFIX##*/}
+ local cacheid="hg:${host}-${rempath//\//_}"
+ cacheid=${cacheid%[-_]}
+ compset -P '*/'
+ if _cache_invalid "$cacheid" || ! _retrieve_cache "$cacheid"
+ then
+ remdirs=(${${(M)${(f)"$(_call_program files ssh -a -x $host ls -1FL "${(q)rempath}" 2> /dev/null)"}##*/}%/})
+ _store_cache "$cacheid" remdirs
+ fi
+ _describe -t directories 'remote directory' remdirs -S/
+ else
+ _message 'remote directory'
+ fi
+ else
+ if compset -P '*@'
+ then
+ _hosts -S/
+ else
+ _alternative 'hosts:remote host name:_hosts -S/' \
+ 'users:user:_users -S@'
+ fi
+ fi
+}
+
+_hg_urls() {
+ if compset -P bundle://
+ then
+ _files
+ elif compset -P ssh://
+ then
+ _hg_ssh_urls
+ elif [[ -prefix *: ]]
+ then
+ _urls
+ else
+ local expl
+ compset -S '[^:]*'
+ _wanted url-schemas expl 'URL schema' compadd -S '' - \
+ http:// https:// ssh:// bundle://
+ fi
+}
+
+_hg_paths() {
+ typeset -a paths pnames
+ _hg_cmd paths 2> /dev/null | while read -A pnames
+ do
+ paths+=($pnames[1])
+ done
+ (( $#paths )) && _describe -t path-aliases 'repository alias' paths
+}
+
+_hg_remote() {
+ _alternative 'path-aliases:repository alias:_hg_paths' \
+ 'directories:directory:_files -/' \
+ 'urls:URL:_hg_urls'
+}
+
+_hg_clone_dest() {
+ _alternative 'directories:directory:_files -/' \
+ 'urls:URL:_hg_urls'
+}
+
+# Common options
+_hg_global_opts=(
+ '(--repository -R)'{-R+,--repository}'[repository root directory]:repository:_files -/'
+ '(--verbose -v)'{-v,--verbose}'[enable additional output]'
+ '(--quiet -q)'{-q,--quiet}'[suppress output]'
+ '(--help -h)'{-h,--help}'[display help and exit]'
+ '--debugger[start debugger]'
+)
+
+_hg_pat_opts=(
+ '*'{-I+,--include}'[include names matching the given patterns]:dir:_files -W $(_hg_cmd root) -/'
+ '*'{-X+,--exclude}'[exclude names matching the given patterns]:dir:_files -W $(_hg_cmd root) -/')
+
+_hg_diff_opts=(
+ '(--text -a)'{-a,--text}'[treat all files as text]'
+ '(--git -g)'{-g,--git}'[use git extended diff format]'
+ "--nodates[don't include dates in diff headers]")
+
+_hg_style_opts=(
+ '--style[display using template map file]:'
+ '--template[display with template]:')
+
+_hg_commit_opts=(
+ '(-m --message -l --logfile --edit -e)'{-e,--edit}'[edit commit message]'
+ '(-e --edit -l --logfile --message -m)'{-m+,--message}'[use <text> as commit message]:message:'
+ '(-e --edit -m --message --logfile -l)'{-l+,--logfile}'[read the commit message from <file>]:log file:_files')
+
+_hg_remote_opts=(
+ '(--ssh -e)'{-e+,--ssh}'[specify ssh command to use]:'
+ '--remotecmd[specify hg command to run on the remote side]:')
+
+_hg_cmd() {
+ _call_program hg hg "$_hg_cmd_globals[@]" "$@"
+}
+
+_hg_cmd_add() {
+ _arguments -s -w : $_hg_global_opts $_hg_pat_opts \
+ '*:unknown files:_hg_unknown'
+}
+
+_hg_cmd_annotate() {
+ _arguments -s -w : $_hg_global_opts $_hg_pat_opts \
+ '(--rev -r)'{-r+,--rev}'[annotate the specified revision]:revision:_hg_tags' \
+ '(--follow -f)'{-f,--follow}'[follow file copies and renames]' \
+ '(--text -a)'{-a,--text}'[treat all files as text]' \
+ '(--user -u)'{-u,--user}'[list the author]' \
+ '(--date -d)'{-d,--date}'[list the date]' \
+ '(--number -n)'{-n,--number}'[list the revision number (default)]' \
+ '(--changeset -c)'{-c,--changeset}'[list the changeset]' \
+ '*:files:_hg_files'
+}
+
+_hg_cmd_clone() {
+ _arguments -s -w : $_hg_global_opts $_hg_remote_opts \
+ '(--noupdate -U)'{-U,--noupdate}'[do not update the new working directory]' \
+ '(--rev -r)'{-r+,--rev}'[a changeset you would like to have after cloning]:' \
+ '--uncompressed[use uncompressed transfer (fast over LAN)]' \
+ ':source repository:_hg_remote' \
+ ':destination:_hg_clone_dest'
+}
+
+_hg_cmd_commit() {
+ _arguments -s -w : $_hg_global_opts $_hg_pat_opts \
+ '(--addremove -A)'{-A,--addremove}'[mark new/missing files as added/removed before committing]' \
+ '(--message -m)'{-m+,--message}'[use <text> as commit message]:text:' \
+ '(--logfile -l)'{-l+,--logfile}'[read commit message from <file>]:log file:_files -g \*.txt' \
+ '(--date -d)'{-d+,--date}'[record datecode as commit date]:date code:' \
+ '(--user -u)'{-u+,--user}'[record user as commiter]:user:' \
+ '*:file:_hg_files'
+}
+
+_hg_cmd_vdiff() {
+ typeset -A opt_args
+ _arguments -s -w : $_hg_global_opts $_hg_pat_opts $_hg_diff_opts \
+ '*'{-r,--rev}'+[revision]:revision:_hg_revrange' \
+ '(--show-function -p)'{-p,--show-function}'[show which function each change is in]' \
+ '(--ignore-all-space -w)'{-w,--ignore-all-space}'[ignore white space when comparing lines]' \
+ '(--ignore-space-change -b)'{-b,--ignore-space-change}'[ignore changes in the amount of white space]' \
+ '(--ignore-blank-lines -B)'{-B,--ignore-blank-lines}'[ignore changes whose lines are all blank]' \
+ '*:file:->diff_files'
+
+ if [[ $state == 'diff_files' ]]
+ then
+ if [[ -n $opt_args[-r] ]]
+ then
+ _hg_files
+ else
+ _hg_modified
+ fi
+ fi
+}
+
+_hg_cmd_export() {
+ _arguments -s -w : $_hg_global_opts $_hg_diff_opts \
+ '(--outout -o)'{-o+,--output}'[print output to file with formatted name]:filespec:' \
+ '--switch-parent[diff against the second parent]' \
+ '*:revision:_hg_tags'
+}
+
+_hg_cmd_grep() {
+ _arguments -s -w : $_hg_global_opts $_hg_pat_opts \
+ '(--print0 -0)'{-0,--print0}'[end filenames with NUL]' \
+ '--all[print all revisions with matches]' \
+ '(--follow -f)'{-f,--follow}'[follow changeset or file history]' \
+ '(--ignore-case -i)'{-i,--ignore-case}'[ignore case when matching]' \
+ '(--files-with-matches -l)'{-l,--files-with-matches}'[print only filenames and revs that match]' \
+ '(--line-number -n)'{-n,--line-number}'[print matching line numbers]' \
+ '*'{-r+,--rev}'[search in given revision range]:revision:_hg_revrange' \
+ '(--user -u)'{-u,--user}'[print user who committed change]' \
+ '1:search pattern:' \
+ '*:files:_hg_files'
+}
+
+_hg_cmd_heads() {
+ _arguments -s -w : $_hg_global_opts $_hg_style_opts \
+ '(--rev -r)'{-r+,--rev}'[show only heads which are descendants of rev]:revision:_hg_tags'
+}
+
+_hg_cmd_help() {
+ _arguments -s -w : $_hg_global_opts \
+ '*:hgtk command:_hg_commands'
+}
+
+_hg_cmd_incoming() {
+ _arguments -s -w : $_hg_global_opts $_hg_remote_opts $_hg_style_opts \
+ '(--no-merges -M)'{-M,--no-merges}'[do not show merge revisions]' \
+ '(--force -f)'{-f,--force}'[run even when the remote repository is unrelated]' \
+ '(--patch -p)'{-p,--patch}'[show patch]' \
+ '(--rev -r)'{-r+,--rev}'[a specific revision up to which you would like to pull]:revision:_hg_tags' \
+ '(--newest-first -n)'{-n,--newest-first}'[show newest record first]' \
+ '--bundle[file to store the bundles into]:bundle file:_files' \
+ ':source:_hg_remote'
+}
+
+_hg_cmd_init() {
+ _arguments -s -w : $_hg_global_opts $_hg_remote_opts \
+ ':dir:_files -/'
+}
+
+_hg_cmd_log() {
+ _arguments -s -w : $_hg_global_opts $_hg_pat_opts $_hg_style_opts \
+ '(--follow --follow-first -f)'{-f,--follow}'[follow changeset or history]' \
+ '(-f --follow)--follow-first[only follow the first parent of merge changesets]' \
+ '(--copies -C)'{-C,--copies}'[show copied files]' \
+ '(--keyword -k)'{-k+,--keyword}'[search for a keyword]:' \
+ '(--limit -l)'{-l+,--limit}'[limit number of changes displayed]:' \
+ '*'{-r,--rev}'[show the specified revision or range]:revision:_hg_revrange' \
+ '(--no-merges -M)'{-M,--no-merges}'[do not show merges]' \
+ '(--only-merges -m)'{-m,--only-merges}'[show only merges]' \
+ '(--patch -p)'{-p,--patch}'[show patch]' \
+ '(--prune -P)'{-P+,--prune}'[do not display revision or any of its ancestors]:revision:_hg_tags' \
+ '*:files:_hg_files'
+}
+
+_hg_cmd_outgoing() {
+ _arguments -s -w : $_hg_global_opts $_hg_remote_opts $_hg_style_opts \
+ '(--no-merges -M)'{-M,--no-merges}'[do not show merge revisions]' \
+ '(--force -f)'{-f,--force}'[run even when the remote repository is unrelated]' \
+ '(--patch -p)'{-p,--patch}'[show patch]' \
+ '(--rev -r)'{-r+,--rev}'[a specific revision you would like to push]' \
+ '(--newest-first -n)'{-n,--newest-first}'[show newest record first]' \
+ ':destination:_hg_remote'
+}
+
+_hg_cmd_pull() {
+ _arguments -s -w : $_hg_global_opts $_hg_remote_opts \
+ '(--force -f)'{-f,--force}'[run even when the remote repository is unrelated]' \
+ '(--update -u)'{-u,--update}'[update to new tip if changesets were pulled]' \
+ '(--rev -r)'{-r+,--rev}'[a specific revision up to which you would like to pull]:revision:' \
+ ':source:_hg_remote'
+}
+
+_hg_cmd_push() {
+ _arguments -s -w : $_hg_global_opts $_hg_remote_opts \
+ '(--force -f)'{-f,--force}'[force push]' \
+ '(--rev -r)'{-r+,--rev}'[a specific revision you would like to push]:revision:_hg_tags' \
+ ':destination:_hg_remote'
+}
+
+_hg_cmd_remove() {
+ _arguments -s -w : $_hg_global_opts $_hg_pat_opts \
+ '(--after -A)'{-A,--after}'[record remove that has already occurred]' \
+ '(--force -f)'{-f,--force}'[remove file even if modified]' \
+ '*:file:_hg_files'
+}
+
+_hg_cmd_rename() {
+ _arguments -s -w : $_hg_global_opts $_hg_pat_opts \
+ '(--after -A)'{-A,--after}'[record a rename that has already occurred]' \
+ '(--force -f)'{-f,--force}'[forcibly copy over an existing managed file]' \
+ '*:file:_hg_files'
+}
+
+_hg_cmd_revert() {
+ local context state line
+ typeset -A opt_args
+
+ _arguments -s -w : $_hg_global_opts $_hg_pat_opts \
+ '(--all -a :)'{-a,--all}'[revert all changes when no arguments given]' \
+ '(--rev -r)'{-r+,--rev}'[revision to revert to]:revision:_hg_tags' \
+ '--no-backup[do not save backup copies of files]' \
+ '*:file:->diff_files'
+
+ if [[ $state == 'diff_files' ]]
+ then
+ if [[ -n $opt_args[-r] ]]
+ then
+ _hg_files
+ else
+ typeset -a status_files
+ _hg_status mard
+ _wanted files expl 'modified, added, removed or deleted file' _multi_parts / status_files
+ fi
+ fi
+}
+
+_hg_cmd_serve() {
+ _arguments -s -w : $_hg_global_opts \
+ '(--accesslog -A)'{-A+,--accesslog}'[name of access log file]:log file:_files' \
+ '(--errorlog -E)'{-E+,--errorlog}'[name of error log file]:log file:_files' \
+ '(--daemon -d)'{-d,--daemon}'[run server in background]' \
+ '(--port -p)'{-p+,--port}'[listen port]:listen port:' \
+ '(--address -a)'{-a+,--address}'[interface address]:interface address:' \
+ '(--name -n)'{-n+,--name}'[name to show in web pages]:repository name:' \
+ '(--templates -t)'{-t,--templates}'[web template directory]:template dir:_files -/' \
+ '--style[web template style]:style' \
+ '--stdio[for remote clients]' \
+ '(--ipv6 -6)'{-6,--ipv6}'[use IPv6 in addition to IPv4]'
+}
+
+_hg_cmd_status() {
+ _arguments -s -w : $_hg_global_opts $_hg_pat_opts \
+ '(--all -A)'{-A,--all}'[show status of all files]' \
+ '(--modified -m)'{-m,--modified}'[show only modified files]' \
+ '(--added -a)'{-a,--added}'[show only added files]' \
+ '(--removed -r)'{-r,--removed}'[show only removed files]' \
+ '(--deleted -d)'{-d,--deleted}'[show only deleted (but tracked) files]' \
+ '(--clean -c)'{-c,--clean}'[show only files without changes]' \
+ '(--unknown -u)'{-u,--unknown}'[show only unknown files]' \
+ '(--ignored -i)'{-i,--ignored}'[show ignored files]' \
+ '(--no-status -n)'{-n,--no-status}'[hide status prefix]' \
+ '(--copies -C)'{-C,--copies}'[show source of copied files]' \
+ '(--print0 -0)'{-0,--print0}'[end filenames with NUL, for use with xargs]' \
+ '--rev[show difference from revision]:revision:_hg_tags' \
+ '*:files:_files'
+}
+
+_hg_cmd_update() {
+ _arguments -s -w : $_hg_global_opts \
+ '(--clean -C)'{-C,--clean}'[overwrite locally modified files]' \
+ '(--rev -r)'{-r+,--rev}'[revision]:revision:_hg_tags' \
+ ':revision:_hg_tags'
+}
+
+_hgtk "$@"
|
@@ -8,7 +8,20 @@ # of the GNU General Public License, incorporated herein by reference.
# enable importing on demand to reduce startup time
-from mercurial import demandimport; demandimport.enable()
+try:
+ from mercurial import demandimport; demandimport.enable()
+except ImportError:
+ import sys
+ sys.stderr.write("abort: couldn't find mercurial libraries in [%s]\n" %
+ ' '.join(sys.path))
+ sys.stderr.write("(check your install and PYTHONPATH)\n")
+ sys.exit(-1)
+import sys
+import mercurial.util
import mercurial.dispatch
+
+for fp in (sys.stdin, sys.stdout, sys.stderr):
+ mercurial.util.set_binary(fp)
+
mercurial.dispatch.run()
|
|
|
@@ -1,6 +1,6 @@ - # Trivial Mercurial plugin for Nautilus
+# TortoiseHg plugin for Nautilus
#
-# Copyright (C) 2007 Steve Borho
+# Copyright (C) 2007-9 Steve Borho
#
# Stolen mercilessly from nautilus-bzr, thanks guys
# Copyright (C) 2006 Jeff Bailey
@@ -9,26 +9,35 @@#
# Published under the GNU GPL
-import gconf
import gtk
import gobject
-from mercurial import hg, ui, match, util
-from mercurial.node import short
import nautilus
+
+try:
+ from mercurial import demandimport
+except ImportError:
+ # workaround to use user's local python libs
+ userlib = os.path.expanduser('~/lib/python')
+ if os.path.exists(userlib) and userlib not in sys.path:
+ sys.path.append(userlib)
+ from mercurial import demandimport
+demandimport.enable()
+
import os
import subprocess
import sys
-import tempfile
-import time
import urllib
+from mercurial import hg, ui, match, util
try:
from mercurial.error import RepoError
except ImportError:
from mercurial.repo import RepoError
+from mercurial.node import short
-TORTOISEHG_PATH = '~/tools/tortoisehg-dev'
-TERMINAL_KEY = '/desktop/gnome/applications/terminal/exec'
+nofilecmds = 'about serve synch repoconfig userconfig merge unmerge'.split()
+nocachecmds = 'about serve repoconfig userconfig'.split()
+
class HgExtension(nautilus.MenuProvider,
nautilus.ColumnProvider,
@@ -38,26 +47,44 @@ def __init__(self):
self.cacherepo = None
self.cacheroot = None
- self.client = gconf.client_get_default()
- thgpath = os.environ.get('TORTOISEHG_PATH',
- os.path.expanduser(TORTOISEHG_PATH))
- os.environ['TORTOISEHG_PATH'] = thgpath
- os.environ['THG_ICON_PATH'] = os.path.join(thgpath, 'icons')
- self.hgproc = os.path.join(thgpath, 'hgproc.py')
- self.ipath = os.path.join(thgpath, 'icons', 'tortoise')
+ self.scanStack = []
+
+ # check if nautilus-thg.py is a symlink first
+ pfile = __file__
+ if pfile.endswith('.pyc'):
+ pfile = pfile[:-1]
+ path = os.path.dirname(os.path.realpath(pfile))
+ thgpath = os.path.normpath(os.path.join(path, '..'))
+ testpath = os.path.join(thgpath, 'tortoise')
+ if os.path.isdir(testpath):
+ if thgpath not in sys.path:
+ sys.path.insert(0, thgpath)
+ # else assume thgutil is already in PYTHONPATH
+ try:
+ from thgutil import paths, debugthg, menuthg
+ except ImportError, e:
+ print e
+ self.menu = None
+ return
+
+ self.hgtk = paths.find_in_path('hgtk')
+ self.menu = menuthg.menuThg()
+
+ global debugf
+ if debugthg.debug('N'):
+ debugf = debugthg.debugf
+ else:
+ debugf = debugthg.debugf_No
def icon(self, iname):
- return os.path.join(self.ipath, iname)
+ from thgutil import paths
+ return paths.get_tortoise_icon(iname)
def get_path_for_vfs_file(self, vfs_file):
- if vfs_file.get_uri_scheme() != 'file':
+ if vfs_file.is_gone() or vfs_file.get_uri_scheme() != 'file':
return None
return urllib.unquote(vfs_file.get_uri()[7:])
- def clear_cached_repo(self):
- self.cacheroot = None
- self.cacherepo = None
-
def get_repo_for_path(self, path):
'''
Find mercurial repository for vfs_file
@@ -72,362 +99,133 @@
if p == self.cacheroot:
return self.cacherepo
+ from thgutil import hglib
# Keep one repo cached
try:
self.cacheroot = p
self.cacherepo = hg.repository(ui.ui(), path=p)
return self.cacherepo
- except RepoError:
+ except hglib.RepoError:
self.cacheroot = None
self.cacherepo = None
return None
+ except StandardError, e:
+ debugf(e)
+ return None
- def _open_terminal_cb(self, window, vfs_file):
- path = self.get_path_for_vfs_file(vfs_file)
- if path is None:
+ def run_dialog(self, menuitem, hgtkcmd, cwd = None):
+ '''
+ hgtkcmd - hgtk subcommand
+ '''
+ if cwd: #bg
+ self.files = []
+ else:
+ cwd = self.cwd
+ repo = self.get_repo_for_path(cwd)
+
+ cmdopts = [sys.executable, self.hgtk, hgtkcmd]
+
+ if hgtkcmd not in nofilecmds and self.files:
+ pipe = subprocess.PIPE
+ cmdopts += ['--listfile', '-']
+ else:
+ pipe = None
+
+ proc = subprocess.Popen(cmdopts, cwd=cwd, stdin=pipe, shell=False)
+ if pipe:
+ proc.stdin.write('\n'.join(self.files))
+ proc.stdin.close()
+
+ if hgtkcmd not in nocachecmds:
+ # Remove cached repo object, dirstate may change
+ self.cacherepo = None
+ self.cacheroot = None
+
+ def buildMenu(self, vfs_files, bg):
+ '''Build menu'''
+ self.pos = 0
+ self.files = []
+ files = []
+ for vfs_file in vfs_files:
+ f = self.get_path_for_vfs_file(vfs_file)
+ if f:
+ files.append(f)
+ if not files:
return
- os.chdir(path)
- terminal = self.client.get_string(TERMINAL_KEY)
- os.system('%s &' % terminal)
+ if bg or len(files) == 1 and vfs_files[0].is_directory():
+ cwd = files[0]
+ files = []
+ else:
+ cwd = os.path.dirname(files[0])
+ repo = self.get_repo_for_path(cwd)
+ if repo:
+ menus = self.menu.get_commands(repo, cwd, files)
+ if cwd == repo.root:
+ cwd_rel = ''
+ else:
+ cwd_rel = cwd[len(repo.root+os.sep):] + os.sep
+ for f in files:
+ try:
+ cpath = util.canonpath(repo.root, cwd, f)
+ if cpath.startswith(cwd_rel):
+ cpath = cpath[len(cwd_rel):]
+ self.files.append(cpath)
+ else:
+ self.files.append(f)
+ except util.Abort: # canonpath will abort on .hg/ paths
+ pass
+ else:
+ menus = self.menu.get_norepo_commands(cwd, files)
+ self.cwd = cwd
+ return self._buildMenu(menus)
- def _about_cb(self, window, vfs_file):
- self._run_dialog('about', [vfs_file])
-
- def _add_cb(self, window, vfs_files):
- self._run_dialog('add', vfs_files)
- self.clear_cached_repo()
-
- def _clone_cb(self, window, vfs_file):
- self._run_dialog('clone', [vfs_file])
-
- def _commit_cb(self, window, vfs_files):
- self._run_dialog('commit', vfs_files)
- self.clear_cached_repo()
-
- def _datamine_cb(self, window, vfs_files):
- self._run_dialog('datamine', vfs_files)
-
- def _diff_cb(self, window, vfs_files):
- path = self.get_path_for_vfs_file(vfs_files[0])
- if path is None:
- return
- repo = self.get_repo_for_path(path)
- if repo is None:
- return
- diffcmd = repo.ui.config('tortoisehg', 'vdiff', 'vdiff')
- if not diffcmd:
- self._run_dialog('diff', vfs_files)
- else:
- cmdline = ['hg', diffcmd]
- cwd = os.path.isdir(path) and path or os.path.dirname(path)
- paths = [self.get_path_for_vfs_file(f) for f in vfs_files]
- subprocess.Popen(cmdline + paths, shell=False, cwd=cwd)
-
- def _history_cb(self, window, vfs_files):
- self._run_dialog('history', vfs_files)
- self.clear_cached_repo()
-
- def _init_cb(self, window, vfs_file):
- self._run_dialog('init', [vfs_file])
-
- def _recovery_cb(self, window, vfs_file):
- self._run_dialog('recovery', [vfs_file])
- self.clear_cached_repo()
-
- def _revert_cb(self, window, vfs_files):
- self._run_dialog('revert', vfs_files)
- self.clear_cached_repo()
-
- def _serve_cb(self, window, vfs_file):
- self._run_dialog('serve', [vfs_file], filelist=False)
-
- def _status_cb(self, window, vfs_file):
- self._run_dialog('status', [vfs_file])
-
- def _sync_cb(self, window, vfs_file):
- self._run_dialog('synch', [vfs_file], filelist=False)
- self.clear_cached_repo()
-
- def _thgconfig_repo_cb(self, window, vfs_file):
- self._run_dialog('config', [vfs_file])
-
- def _thgconfig_user_cb(self, window, vfs_file):
- self._run_dialog('config', [vfs_file], filelist=False)
-
- def _unmerge_cb(self, window, vfs_file):
- self._run_dialog('checkout', [vfs_file], filelist=False,
- extras=['--', '--clean', str(self.rev0)])
- self.clear_cached_repo()
-
- def _run_dialog(self, hgcmd, vfs_files, filelist=True, extras=[]):
- '''
- hgcmd - hgproc subcommand
- vfs_files - directory, or list of selected files
- filelist - bool for whether to generate file list for hgproc
- '''
- paths = [self.get_path_for_vfs_file(f) for f in vfs_files]
- if paths[0] is None:
- return
-
- path = paths[0]
- repo = self.get_repo_for_path(path)
- cwd = os.path.isdir(path) and path or os.path.dirname(path)
-
- if repo is not None:
- root = repo.root
- else:
- root = cwd
-
- cmdopts = [sys.executable, self.hgproc]
- cmdopts += ['--root', root]
- cmdopts += ['--cwd', cwd]
- cmdopts += ['--command', hgcmd]
-
- if filelist:
- # Use temporary file to store file list (avoid shell command
- # line limitations)
- fd, tmpfile = tempfile.mkstemp(prefix="tortoisehg_filelist_")
- os.write(fd, "\n".join(paths))
- os.close(fd)
- cmdopts += ['--listfile', tmpfile, '--deletelistfile']
- cmdopts.extend(extras)
-
- subprocess.Popen(cmdopts, cwd=cwd, shell=False)
-
- # Remove cached repo object, dirstate may change
- self.cacherepo = None
- self.cacheroot = None
+ def _buildMenu(self, menus):
+ '''Build one level of a menu'''
+ items = []
+ if self.files:
+ passcwd = None
+ else: #bg
+ passcwd = self.cwd
+ for menu_info in menus:
+ idstr = 'HgNautilus::%02d%s' % (self.pos, menu_info.hgcmd)
+ self.pos += 1
+ if menu_info.isSep():
+ # can not insert a separator till now
+ pass
+ elif menu_info.isSubmenu():
+ if hasattr(nautilus, 'Menu'):
+ item = nautilus.MenuItem(idstr, menu_info.menutext,
+ menu_info.helptext)
+ submenu = nautilus.Menu()
+ item.set_submenu(submenu)
+ for subitem in self._buildMenu(menu_info.get_menus()):
+ submenu.append_item(subitem)
+ items.append(item)
+ else: #submenu not suported
+ for subitem in self._buildMenu(menu_info.get_menus()):
+ items.append(subitem)
+ else:
+ if menu_info.state:
+ item = nautilus.MenuItem(idstr,
+ menu_info.menutext,
+ menu_info.helptext,
+ self.icon(menu_info.icon))
+ item.connect('activate', self.run_dialog, menu_info.hgcmd,
+ passcwd)
+ items.append(item)
+ return items
def get_background_items(self, window, vfs_file):
'''Build context menu for current directory'''
- mainitem = nautilus.MenuItem('HgNautilus', 'Mercurial', '')
- submenu = nautilus.Menu()
- mainitem.set_submenu(submenu)
-
- path = self.get_path_for_vfs_file(vfs_file)
- if path is None:
- return
-
- repo = self.get_repo_for_path(path)
- if repo is None:
- ''' The name given to nautilus.MenuItem decides the
- of the menu, which is ordered alpahbetically '''
- item = nautilus.MenuItem('HgNautilus::newtree',
- 'Create New Repository',
- 'Make directory versioned',
- self.icon('menucreaterepos.ico'))
- item.connect('activate', self._init_cb, vfs_file)
- submenu.append_item(item)
-
- item = nautilus.MenuItem('HgNautilus::clone',
- 'Create Clone',
- 'Create clone here from source',
- self.icon('menuclone.ico'))
- item.connect('activate', self._clone_cb, vfs_file)
- submenu.append_item(item)
-
- item = nautilus.MenuItem('HgNautilus::99about',
- 'About TortoiseHg',
- 'Information about TortoiseHg installation',
- self.icon('menuabout.ico'))
- item.connect('activate', self._about_cb, vfs_file)
- submenu.append_item(item)
-
- return mainitem,
-
- if len(repo.changectx(None).parents()) > 1:
- self.rev0 = repo.changectx(None).parents()[0].rev()
- item = nautilus.MenuItem('HgNautilus::undomerge',
- 'Undo Merge',
- 'Clean checkout of original parent revision',
- self.icon('menuunmerge.ico'))
- item.connect('activate', self._unmerge_cb, vfs_file)
- submenu.append_item(item)
-
- item = nautilus.MenuItem('HgNautilus::10commit',
- 'Commit',
- 'Commit changes',
- self.icon('menucommit.ico'))
- item.connect('activate', self._commit_cb, [vfs_file])
- submenu.append_item(item)
-
- item = nautilus.MenuItem('HgNautilus::20status',
- 'Show Status',
- 'Show Repository Status',
- self.icon('menushowchanged.ico'))
- item.connect('activate', self._status_cb, vfs_file)
- submenu.append_item(item)
-
- item = nautilus.MenuItem('HgNautilus::30diff',
- 'Visual Diff',
- 'Show Changes to Repository',
- self.icon('menudiff.ico'))
- item.connect('activate', self._diff_cb, [vfs_file])
- submenu.append_item(item)
-
- item = nautilus.MenuItem('HgNautilus::40dag',
- 'Revision History',
- 'Show revision DAG',
- self.icon('menurevisiongraph.ico'))
- item.connect('activate', self._history_cb, [vfs_file])
- submenu.append_item(item)
-
- item = nautilus.MenuItem('HgNautilus::50datamine',
- 'Data Mining',
- 'Search revision history',
- self.icon('menulog.ico'))
- item.connect('activate', self._datamine_cb, [vfs_file])
- submenu.append_item(item)
-
- item = nautilus.MenuItem('HgNautilus::60sync',
- 'Synchronize',
- 'Sync with another repository',
- self.icon('menusynch.ico'))
- item.connect('activate', self._sync_cb, vfs_file)
- submenu.append_item(item)
-
- item = nautilus.MenuItem('HgNautilus::70serve',
- 'Web Server',
- 'Start internal web server',
- self.icon('proxy.ico'))
- item.connect('activate', self._serve_cb, vfs_file)
- submenu.append_item(item)
-
- item = nautilus.MenuItem('HgNautilus::75recover',
- 'Recovery',
- 'General repair and recovery of repository',
- self.icon('general.ico'))
- item.connect('activate', self._recovery_cb, vfs_file)
- submenu.append_item(item)
-
- item = nautilus.MenuItem('HgNautilus::80repoconfig',
- 'Repository Settings',
- 'Configure Mercurial settings for this repo',
- self.icon('menusettings.ico'))
- item.connect('activate', self._thgconfig_repo_cb, vfs_file)
- submenu.append_item(item)
-
- item = nautilus.MenuItem('HgNautilus::85userconfig',
- 'User-Global Settings',
- 'Configure global Mercurial settings',
- self.icon('menusettings.ico'))
- item.connect('activate', self._thgconfig_user_cb, vfs_file)
- submenu.append_item(item)
-
- item = nautilus.MenuItem('HgNautilus::99about',
- 'About TortoiseHg',
- 'Information about TortoiseHg installation',
- self.icon('menuabout.ico'))
- item.connect('activate', self._about_cb, vfs_file)
- submenu.append_item(item)
-
- return mainitem,
+ if vfs_file and self.menu:
+ return self.buildMenu([vfs_file], True)
+ else:
+ self.files = []
def get_file_items(self, window, vfs_files):
- mainitem = nautilus.MenuItem('HgNautilus', 'Mercurial', '')
- submenu = nautilus.Menu()
- mainitem.set_submenu(submenu)
-
- '''Build context menu for selected files'''
- if not vfs_files:
- return None
-
- vfs_file = vfs_files[0]
- path = self.get_path_for_vfs_file(vfs_file)
- repo = self.get_repo_for_path(path)
- if repo is None:
- if not vfs_file.is_directory():
- return None
-
- # Menu for unrevisioned subdirectory
- name = vfs_files[0].get_name()
- item = nautilus.MenuItem('HgNautilus::10newtree',
- 'Make directory versioned',
- 'Create Repository in %s' % name,
- self.icon('menucreaterepos.ico'))
- item.connect('activate', self._init_cb, vfs_file)
- submenu.append_item(item)
-
- item = nautilus.MenuItem('HgNautilus::20clone',
- 'Create clone from source',
- 'Create Clone in %s' % name,
- self.icon('menuclone.ico'))
- item.connect('activate', self._clone_cb, vfs_file)
- submenu.append_item(item)
-
- item = nautilus.MenuItem('HgNautilus::99about',
- 'About TortoiseHg',
- 'Information about TortoiseHg installation',
- self.icon('menuabout.ico'))
- item.connect('activate', self._about_cb, vfs_file)
- submenu.append_item(item)
-
- return mainitem,
-
- localpaths = []
- for vfs_file in vfs_files:
- path = self.get_path_for_vfs_file(vfs_file)
- if path is None:
- continue
- localpath = path[len(repo.root)+1:]
- localpaths.append(localpath)
-
- if not localpaths:
- return
- path = localpaths[0]
- cwd = os.path.isdir(path) and path or os.path.dirname(path)
- matcher = match.exact(repo.root, cwd, localpaths)
- changes = repo.dirstate.status(matcher, True, True, True)
- (lookup, modified, added, removed, deleted, unknown,
- ignored, clean) = changes
-
- # Add menu items based on states list
- if unknown:
- item = nautilus.MenuItem('HgNautilus::30add',
- 'Add Files',
- 'Add unversioned files',
- self.icon('menuadd.ico'))
- item.connect('activate', self._add_cb, vfs_files)
- submenu.append_item(item)
-
- if modified or added or removed or deleted or unknown:
- item = nautilus.MenuItem('HgNautilus::40commit',
- 'Commit Files',
- 'Commit changes',
- self.icon('menucommit.ico'))
- item.connect('activate', self._commit_cb, vfs_files)
- submenu.append_item(item)
-
- item = nautilus.MenuItem('HgNautilus::50revert',
- 'Undo Changes',
- 'Revert changes to files',
- self.icon('menurevert.ico'))
- item.connect('activate', self._revert_cb, vfs_files)
- submenu.append_item(item)
-
- if modified or clean:
- item = nautilus.MenuItem('HgNautilus::60log',
- 'File Changelog',
- 'Show file revision history',
- self.icon('menulog.ico'))
- item.connect('activate', self._history_cb, vfs_files)
- item = nautilus.MenuItem('HgNautilus::annotate',
- 'Annotate File',
- 'Annotate file at current revision',
- self.icon('menulog.ico'))
- item.connect('activate', self._datamine_cb, vfs_files)
- submenu.append_item(item)
-
-
- if modified:
- item = nautilus.MenuItem('HgNautilus::70diff',
- 'File Diffs',
- 'Show file changes',
- self.icon('menudiff.ico'))
- item.connect('activate', self._diff_cb, vfs_files)
- submenu.append_item(item)
-
- return mainitem,
+ '''Build context menu for selected files/directories'''
+ if vfs_files and self.menu:
+ return self.buildMenu(vfs_files, False)
def get_columns(self):
return nautilus.Column("HgNautilus::80hg_status",
@@ -436,64 +234,52 @@ "Version control status"),
def _get_file_status(self, repo, localpath):
- emblem = None
- status = '?'
-
- # This is not what the API is optimized for, but this appears
- # to work efficiently enough
- matcher = match.always(repo.root, localpath)
- changes = repo.dirstate.status(matcher, True, True, True)
- (lookup, modified, added, removed, deleted, unknown,
- ignored, clean) = changes
-
- if localpath in clean:
- emblem = 'default'
- status = 'clean'
- elif localpath in modified:
- emblem = 'cvs-modified'
- status = 'modified'
- elif localpath in added:
- emblem = 'cvs-aded'
- status = 'added'
- elif localpath in unknown:
- emblem = 'new'
- status = 'unrevisioned'
- elif localpath in ignored:
- status = 'ignored'
- elif localpath in deleted:
- # Should be hard to reach this state
- emblem = 'stockmail-priority-high'
- status = 'deleted'
+ from thgutil import cachethg
+ cachestate = cachethg.get_state(localpath, repo)
+ cache2state = {cachethg.UNCHANGED: ('default', 'clean'),
+ cachethg.ADDED: ('cvs-added', 'added'),
+ cachethg.MODIFIED: ('cvs-modified', 'modified'),
+ cachethg.UNKNOWN: ('new', 'unrevisioned'),
+ cachethg.IGNORED: (None, 'ignored'),
+ cachethg.NOT_IN_REPO: (None, ''),
+ cachethg.ROOT: ('generic', 'root'),
+ cachethg.UNRESOLVED: ('cvs-confilict', 'unresolved')}
+ emblem, status = cache2state.get(cachestate, (None, '?'))
return emblem, status
+ def update_file_info(self, file):
+ '''Queue file for emblem and hg status update'''
+ self.scanStack.append(file)
+ if len(self.scanStack) == 1:
+ gobject.idle_add(self.fileinfo_on_idle)
- def update_file_info(self, file):
- '''Return emblem and hg status for this file'''
- path = self.get_path_for_vfs_file(file)
- if path is None or file.is_directory():
- return
- repo = self.get_repo_for_path(path)
- if repo is None:
- return
- localpath = path[len(repo.root)+1:]
- emblem, status = self._get_file_status(repo, localpath)
+ def fileinfo_on_idle(self):
+ '''Update emblem and hg status for files when there is time'''
+ if not self.scanStack:
+ return False
+ vfs_file = self.scanStack.pop()
+ path = self.get_path_for_vfs_file(vfs_file)
+ if not path:
+ return True
+ emblem, status = self._get_file_status(self.cacherepo, path)
if emblem is not None:
- file.add_emblem(emblem)
- file.add_string_attribute('hg_status', status)
+ vfs_file.add_emblem(emblem)
+ vfs_file.add_string_attribute('hg_status', status)
+ return True
# property page borrowed from http://www.gnome.org/~gpoo/hg/nautilus-hg/
- def __add_row(self, table, row, label_item, label_value):
+ def __add_row(self, row, label_item, label_value):
label = gtk.Label(label_item)
label.set_use_markup(True)
label.set_alignment(1, 0)
- table.attach(label, 0, 1, row, row + 1, gtk.FILL, gtk.FILL, 0, 0)
+ self.table.attach(label, 0, 1, row, row + 1, gtk.FILL, gtk.FILL, 0, 0)
label.show()
label = gtk.Label(label_value)
label.set_use_markup(True)
label.set_alignment(0, 1)
label.show()
- table.attach(label, 1, 2, row, row + 1, gtk.FILL, 0, 0, 0)
+ self.table.attach(label, 1, 2, row, row + 1, gtk.FILL, 0, 0, 0)
def get_property_pages(self, vfs_files):
if len(vfs_files) != 1:
@@ -505,12 +291,11 @@ repo = self.get_repo_for_path(path)
if repo is None:
return
-
localpath = path[len(repo.root)+1:]
- emblem, status = self._get_file_status(repo, localpath)
+ emblem, status = self._get_file_status(repo, path)
# Get the information from Mercurial
- ctx = repo.changectx(None).parents()[0]
+ ctx = repo['.']
try:
fctx = ctx.filectx(localpath)
rev = fctx.filelog().linkrev(fctx.filerev())
@@ -528,22 +313,21 @@
self.property_label = gtk.Label('Mercurial')
- table = gtk.Table(7, 2, False)
- table.set_border_width(5)
- table.set_row_spacings(5)
- table.set_col_spacings(5)
+ self.table = gtk.Table(7, 2, False)
+ self.table.set_border_width(5)
+ self.table.set_row_spacings(5)
+ self.table.set_col_spacings(5)
- self.__add_row(table, 0, '<b>Status</b>:', status)
- self.__add_row(table, 1, '<b>Last-Commit-Revision</b>:', str(rev))
- self.__add_row(table, 2, '<b>Last-Commit-Description</b>:', description)
- self.__add_row(table, 3, '<b>Last-Commit-Date</b>:', date)
- self.__add_row(table, 4, '<b>Last-Commit-User</b>:', user)
+ self.__add_row(0, '<b>Status</b>:', status)
+ self.__add_row(1, '<b>Last-Commit-Revision</b>:', str(rev))
+ self.__add_row(2, '<b>Last-Commit-Description</b>:', description)
+ self.__add_row(3, '<b>Last-Commit-Date</b>:', date)
+ self.__add_row(4, '<b>Last-Commit-User</b>:', user)
if tags:
- self.__add_row(table, 5, '<b>Tags</b>:', tags)
+ self.__add_row(5, '<b>Tags</b>:', tags)
if branch != 'default':
- self.__add_row(table, 6, '<b>Branch</b>:', branch)
+ self.__add_row(6, '<b>Branch</b>:', branch)
- table.show()
-
+ self.table.show()
return nautilus.PropertyPage("MercurialPropertyPage::status",
- self.property_label, table),
+ self.property_label, self.table),
|
@@ -26,20 +26,20 @@ def __init__(self):
self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.window.set_title("Python Trace Collector")
-
+
# construct window
self.window.set_default_size(700, 400)
self.main_area = gtk.VBox()
self.window.add(self.main_area)
-
+
# mimic standard dialog widgets
self.action_area = gtk.HBox()
self.main_area.pack_end(self.action_area, False, False, 5)
sep = gtk.HSeparator()
self.main_area.pack_end(sep, False, False, 0)
self.vbox = gtk.VBox()
- self.main_area.pack_end(self.vbox)
-
+ self.main_area.pack_end(self.vbox)
+
# add python trace ouput window
scrolledwindow = gtk.ScrolledWindow()
scrolledwindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
@@ -55,7 +55,7 @@ # add buttons
self._button_quit = gtk.Button("Quit")
self._button_quit.connect('clicked', self._on_ok_clicked)
- self.action_area.pack_end(self._button_quit, False, False, 5)
+ self.action_area.pack_end(self._button_quit, False, False, 5)
self._button_clear = gtk.Button("Clear")
self._button_clear.connect('clicked', self._on_clear_clicked)
@@ -68,24 +68,24 @@ def _on_ok_clicked(self, button):
self._stop_read_thread()
gtk.main_quit()
-
+
def _on_clear_clicked(self, button):
self.write("", False)
-
+
def _on_window_close_clicked(self, event, param):
self._stop_read_thread()
gtk.main_quit()
-
+
def _on_window_map_event(self, event, param):
self._begin_trace()
-
+
def _begin_trace(self):
self.queue = Queue.Queue()
win32trace.InitRead()
self.write("Collecting Python Trace Output...\n")
gobject.timeout_add(10, self._process_queue)
self._start_read_thread()
-
+
def _start_read_thread(self):
self._read_trace = True
self.thread1 = threading.Thread(target=self._do_read_trace)
@@ -95,8 +95,8 @@ self._read_trace = False
# wait for worker thread to to fix Unhandled exception in thread
- self.thread1.join()
-
+ self.thread1.join()
+
def _process_queue(self):
"""
Handle all the messages currently in the queue (if any).
@@ -109,9 +109,9 @@ self.write(ts + line)
except Queue.Empty:
pass
-
+
return True
-
+
def _do_read_trace(self):
"""
print buffer collected in win32trace
@@ -120,7 +120,7 @@ msg = win32trace.read()
if msg:
self.queue.put(msg)
-
+
def write(self, msg, append=True):
msg = toutf(msg)
if append:
@@ -132,11 +132,11 @@ def main(self):
self.window.show_all()
gtk.main()
-
+
def run():
dlg = TraceLog()
dlg.main()
-
+
if __name__ == "__main__":
run()
|
|
|
@@ -0,0 +1,187 @@ + ; System-wide Mercurial config file.
+
+;
+; !!! Do Not Edit This File !!!
+;
+; This file is intended to be replaced by the installer on every upgrade.
+; Editing this file can cause strange side effects on Vista.
+;
+; http://bitbucket.org/tortoisehg/stable/issue/135
+;
+; To change settings you see in this file, override (or enable) them in
+; your user Mercurial.ini file. See the hgrc man page for details.
+;
+
+[ui]
+; editor used to enter commit logs, etc. Most any text editor
+; will suffice.
+editor = notepad
+
+; In order to push/pull over ssh you must specify a ssh tool
+ssh = "{app}\TortoisePlink.exe" -ssh -2
+;ssh = C:\cygwin\bin\ssh
+
+[merge-tools]
+kdiff3.priority=-1
+kdiff3.args=-L1 base --L2 local --L3 other $base $local $other -o $output
+kdiff3.regkey=Software\KDiff3
+kdiff3.regappend=\kdiff3.exe
+kdiff3.fixeol=True
+kdiff3.gui=True
+beyondcompare3.priority=-2
+beyondcompare3.args=$local $other $base $output /ro /lefttitle=local /centertitle=base /righttitle=other /automerge /reviewconflicts /solo
+beyondcompare3.regkey=Software\Scooter Software\Beyond Compare 3
+beyondcompare3.regname=ExePath
+beyondcompare3.gui=True
+diffmerge.priority=-7
+diffmerge.args=--nosplash --merge --title1=base --title2=local --title3=other $base $local $other
+diffmerge.checkchanged=True
+diffmerge.gui=True
+p4merge.priority=-8
+p4merge.args=$base $local $other $output
+p4merge.regkey=Software\Perforce\Environment
+p4merge.regname=P4INSTROOT
+p4merge.regappend=\p4merge.exe
+p4merge.gui=True
+tortoisemerge.priority=-9
+tortoisemerge.args=/base:$output /mine:$local /theirs:$other /merged:$output
+tortoisemerge.regkey=Software\TortoiseSVN
+tortoisemerge.gui=True
+winmergeu.regkey=Software\Thingamahoochie\WinMerge\
+winmergeu.regname=Executable
+winmergeu.priority=-10
+winmergeu.args=/e /ub /dl other /dr local $other $local $output
+winmergeu.fixeol=True
+winmergeu.gui=True
+
+;
+; For more information about mercurial extensions, start here
+; http://www.selenic.com/mercurial/wiki/index.cgi/UsingExtensions
+;
+
+[extensions]
+; extensions shipped with Mercurial by default
+;
+;acl =
+;alias =
+;bookmarks =
+;bugzilla =
+;children =
+;churn =
+; Warning: the color extension is not recommended for Windows
+;color =
+;convert =
+extdiff =
+;fetch =
+;gpg =
+;graphlog =
+;hgcia =
+;hgk =
+;highlight =
+;interhg =
+;keyword =
+;mq =
+;notify =
+;pager =
+;parentrevspec =
+;patchbomb =
+;purge =
+;rebase =
+;record =
+;transplant =
+;win32mbcs =
+;win32text =
+;zeroconf =
+;
+; extra extensions provided by TortoiseHg
+;
+;qct =
+;forest =
+
+; To use cleverencode/cleverdecode, you must enable win32text extension
+;
+; By default, we try to encode and decode all files that do not
+; contain ASCII NUL characters. What this means is that we try to set
+; line endings to Windows style on update, and to Unix style on
+; commit. This lets us cooperate with Linux and Unix users, so
+; everybody sees files with their native line endings.
+
+[encode]
+; Encode files that don't contain NUL characters.
+
+; ** = cleverencode:
+
+; Alternatively, you can explicitly specify each file extension that
+; you want encoded (any you omit will be left untouched), like this:
+
+; *.txt = dumbencode:
+
+
+[decode]
+; Decode files that don't contain NUL characters.
+
+; ** = cleverdecode:
+
+; Alternatively, you can explicitly specify each file extension that
+; you want decoded (any you omit will be left untouched), like this:
+
+; **.txt = dumbdecode:
+
+
+;
+; Define external diff commands
+;
+[extdiff]
+cmd.vdiff = {app}\kdiff3
+;cmd.vdiff = C:\Progra~1\TortoiseSVN\bin\TortoiseMerge.exe
+;cmd.vimdiff = gvim.exe
+;opts.vimdiff = -f '+next' '+execute "DirDiff ".argv(0)." ".argv(1)'
+
+[qct]
+;See http://bitbucket.org/tortoisehg/stable/wiki/FAQ for details
+;path="C:\Program Files\qct\qct.exe"
+
+[hgk]
+;See http://bitbucket.org/tortoisehg/stable/wiki/FAQ for details
+;path={app}\scripts\hgk.cmd
+;vdiff=vdiff
+
+;
+; The git extended diff format will properly store binary files,
+; file permission changes, and rename information that the normal
+; patch format cannot cover. However it is also not 100% compatible
+; with tools which expect normal patches. so enable these at your
+; own risk.
+;
+[diff]
+;git = false
+;nodates = false
+
+;
+; Some optional defaults
+;
+[defaults]
+;view = --limit 100
+;log = --limit 100
+;revert = --no-backup
+;log = --style=changelog
+
+;
+; Keyword extension example configuration. To use, one must
+; enable the keyword extension, then uncomment and modify these
+; two sections. Before using the keyword extension, be sure to
+; thoroughly read it's documentation and understand how it works,
+; and why it is not a core feature of Mercurial.
+;
+; http://www.selenic.com/mercurial/wiki/index.cgi/KeywordExtension
+; http://www.selenic.com/mercurial/wiki/index.cgi/KeywordPlan
+;
+; If you encounter strange problems using Mercurial, a good first
+; debugging step would be to disable this extension.
+;
+[keyword]
+; expand keywords in all python files in working dir
+;**.py =
+
+[keywordmaps]
+; See documentation for examples
|
|
|
@@ -0,0 +1,214 @@ + ; Script generated by the Inno Setup Script Wizard.
+; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
+
+[Setup]
+AppCopyright=Copyright 2005-2009 Matt Mackall and others
+AppName=TortoiseHg
+AppVerName=TortoiseHg-0.7
+InfoAfterFile=contrib/win32/postinstall.txt
+LicenseFile=COPYING.txt
+ShowLanguageDialog=yes
+AppPublisher=TK Soh and others
+AppPublisherURL=http://bitbucket.org/tortoisehg/stable/
+AppSupportURL=http://bitbucket.org/tortoisehg/stable/
+AppUpdatesURL=http://bitbucket.org/tortoisehg/stable/
+AppID=TortoiseHg
+AppContact=teekaysoh@gmail.com
+OutputBaseFilename=TortoiseHg-0.7
+DefaultDirName={pf}\TortoiseHg
+SourceDir=..\..
+VersionInfoDescription=Mercurial distributed SCM
+VersionInfoCopyright=Copyright 2005-2009 Matt Mackall and others
+VersionInfoCompany=Matt Mackall and others
+InternalCompressLevel=max
+SolidCompression=true
+SetupIconFile=..\icons\hgicon.ico
+UninstallDisplayIcon={app}\hgicon.ico
+WizardImageFile=..\icons\install-wizard.bmp
+WizardImageStretch=no
+WizardImageBackColor=$ffffff
+WizardSmallImageFile=..\icons\install-wizard-small.bmp
+AllowNoIcons=true
+DefaultGroupName=TortoiseHg
+PrivilegesRequired=poweruser
+AlwaysRestart=yes
+SetupLogging=yes
+
+[Files]
+Source: contrib\mercurial.el; DestDir: {app}/contrib
+Source: contrib\vim\*.*; DestDir: {app}/contrib/Vim
+Source: contrib\zsh_completion; DestDir: {app}/contrib
+Source: contrib\hgk; DestDir: {app}/contrib
+Source: contrib\win32\ReadMe.html; DestDir: {app}; Flags: isreadme
+Source: {app}\Mercurial.ini; DestDir: {app}\backup; Flags: external skipifsourcedoesntexist uninsneveruninstall
+Source: contrib\win32\mercurial.ini; DestDir: {app}; DestName: Mercurial.ini; AfterInstall: FileExpandString('{app}\Mercurial.ini')
+Source: ..\stable.snap; DestDir: {app}; DestName: ReleaseNotes.txt
+Source: ..\contrib\*.exe; DestDir: {app}; Flags: ignoreversion restartreplace uninsrestartdelete
+Source: ..\contrib\TortoiseOverlays\*.*; DestDir: {app}/TortoiseOverlays;
+Source: dist\*.exe; DestDir: {app}; Flags: ignoreversion restartreplace uninsrestartdelete
+Source: dist\*.dll; DestDir: {app}; Flags: ignoreversion restartreplace uninsrestartdelete
+Source: dist\*.pyd; DestDir: {app}; Flags: ignoreversion restartreplace uninsrestartdelete
+Source: dist\library.zip; DestDir: {app}
+Source: doc\*.html; DestDir: {app}\docs
+Source: icons\*; DestDir: {app}\icons; Flags: ignoreversion recursesubdirs createallsubdirs
+Source: dist\share\*; DestDir: {app}\share; Flags: ignoreversion recursesubdirs createallsubdirs
+Source: dist\lib\*; DestDir: {app}\lib; Flags: ignoreversion recursesubdirs createallsubdirs
+Source: dist\etc\*; DestDir: {app}\etc; Flags: ignoreversion recursesubdirs createallsubdirs
+Source: templates\*.*; DestDir: {app}\templates; Flags: recursesubdirs createallsubdirs
+Source: locale\*.*; DestDir: {app}\locale; Flags: recursesubdirs createallsubdirs
+Source: i18n\*.*; DestDir: {app}\i18n; Flags:
+Source: CONTRIBUTORS; DestDir: {app}; DestName: Contributors.txt
+Source: COPYING.txt; DestDir: {app}; DestName: Copying.txt
+Source: ..\icons\hgicon.ico; DestDir: {app}
+Source: ..\files\gtkrc; DestDir: {app}\etc\gtk-2.0; AfterInstall: EditOptions()
+
+[INI]
+Filename: {app}\Mercurial.url; Section: InternetShortcut; Key: URL; String: http://www.selenic.com/mercurial/
+Filename: {app}\TortoiseHg.url; Section: InternetShortcut; Key: URL; String: http://bitbucket.org/tortoisehg/stable/
+
+[Icons]
+Name: {group}\TortoiseHg Web Site; Filename: {app}\TortoiseHg.url
+Name: {group}\Mercurial Web Site; Filename: {app}\Mercurial.url
+Name: {group}\Mercurial Command Reference; Filename: {app}\docs\hg.1.html
+Name: {group}\Python Trace Collector; Filename: {app}\tracelog.exe
+Name: {group}\Uninstall TortoiseHg; Filename: {uninstallexe}
+
+[Run]
+Filename: {app}\add_path.exe; Parameters: {app}; StatusMsg: Adding the installation path to the search path...
+Filename: msiexec.exe; Parameters: "/i ""{app}\TortoiseOverlays\TortoiseOverlays-1.0.4.11886-win32.msi"" /qn /norestart ALLUSERS=1"; StatusMsg: Installing TortoiseOverlays.dll ...
+Filename: regsvr32.exe; Parameters: "/s ""{app}\tortoisehg.dll"""; StatusMsg: Installing shell extension...
+
+[UninstallRun]
+Filename: {app}\add_path.exe; Parameters: /del {app}
+Filename: regsvr32.exe; Parameters: "/s /u ""{app}\tortoisehg.dll"""
+
+[UninstallDelete]
+Type: files; Name: {app}\Mercurial.url
+Type: files; Name: {app}\TortoiseHg.url
+
+[Registry]
+Root: HKLM; Subkey: Software\TortoiseHg; Flags: uninsdeletekey; ValueData: {app}
+Root: HKLM; Subkey: Software\Mercurial; Flags: uninsdeletekey; ValueData: {app}\Mercurial.ini
+
+[Code]
+procedure FileExpandString(fn: String);
+var
+ InFile: String;
+ i: Integer;
+ InFileLines: TArrayOfString;
+begin
+ InFile := ExpandConstant(fn);
+ LoadStringsFromFile(InFile, InFileLines);
+ for i:= 0 to GetArrayLength(InFileLines)-1 do
+ InFileLines[i] := ExpandConstant(InFileLines[i]);
+ SaveStringsToFile(InFile, InFileLines, False);
+end;
+
+var ThemePage: TInputOptionWizardPage;
+var IsUpgrade: Boolean;
+
+procedure InitializeWizard;
+begin
+ ThemePage := CreateInputOptionPage(wpSelectComponents,
+ 'Theme Selection', '',
+ 'Please select a theme, then click Next.',
+ True, False);
+ ThemePage.Add('Neutrino (recommended, especially on Vista)');
+ ThemePage.Add('Brushed');
+ ThemePage.Add('Blue-Steel');
+ ThemePage.Add('MS-Windows (original)');
+
+ case GetPreviousData('Theme', '') of
+ 'Neutrino': ThemePage.SelectedValueIndex := 0;
+ 'Brushed': ThemePage.SelectedValueIndex := 1;
+ 'Blue-Steel': ThemePage.SelectedValueIndex := 2;
+ 'MS-Windows': ThemePage.SelectedValueIndex := 3;
+ else
+ ThemePage.SelectedValueIndex := 0;
+ end;
+end;
+
+procedure RegisterPreviousData(PreviousDataKey: Integer);
+var
+ Theme: String;
+begin
+ { Store the settings so we can restore them next time }
+ case ThemePage.SelectedValueIndex of
+ 0: Theme := 'Neutrino';
+ 1: Theme := 'Brushed';
+ 2: Theme := 'Blue-Steel';
+ 3: Theme := 'MS-Windows';
+ end;
+ SetPreviousData(PreviousDataKey, 'Theme', Theme);
+end;
+
+procedure SetCommentMarker(var lines: TArrayOfString; option: String; selected: boolean);
+var
+ i : integer;
+begin
+ if selected then exit;
+ for i := 0 to pred(GetArrayLength(lines)) do
+ if pos(option, lines[i]) > 0 then
+ begin
+ lines[i][1] := '#';
+ end;
+end;
+
+procedure EditOptions();
+var
+ lines : TArrayOfString;
+ filename : String;
+begin
+ filename := ExpandConstant(CurrentFilename);
+ LoadStringsFromFile(filename, lines);
+
+ SetCommentMarker(lines, 'gtk-theme-name = "Neutrino"', ThemePage.SelectedValueIndex = 0);
+ SetCommentMarker(lines, 'gtk-theme-name = "Brushed"', ThemePage.SelectedValueIndex = 1);
+ SetCommentMarker(lines, 'gtk-theme-name = "Blue-Steel"', ThemePage.SelectedValueIndex = 2);
+ SetCommentMarker(lines, 'gtk-theme-name = "MS-Windows"', ThemePage.SelectedValueIndex = 3);
+
+ SaveStringsToFile(filename, lines, False);
+end;
+
+function InitializeSetup(): Boolean;
+var
+ ThgSwReg: String;
+ CRLF: String;
+ msg: String;
+begin
+ CRLF := chr(10) + chr(13);
+ Result := True;
+
+ {abort installation if TortoiseHg 0.4 or earlier is installed}
+ if RegQueryStringValue(HKLM, 'Software\TortoiseHg', '', ThgSwReg) then
+ begin
+ IsUpgrade := True;
+ {gpyfm was unbundled after 0.4, so it's a good guess}
+ if (FileExists(ThgSwReg + '\gpyfm.exe')) then
+ begin
+ msg := 'TortoiseHg Setup Error:' + CRLF + CRLF +
+ 'The version of TortoiseHg installed is too old to upgrade in place.' + CRLF +
+ 'You must uninstall it before installing this version.' + CRLF + CRLF +
+ 'Please uninstall the existing version, then run the installer again ' +
+ 'to continue.';
+ MsgBox(msg, mbError, MB_OK);
+ Result := False; {quit and abort installation}
+ end else begin
+ msg := 'Your current site-wide Mercurial.ini will be copied into' + CRLF +
+ ThgSwReg + '\backup' + CRLF +
+ 'After install you may merge changes back into the new Mercurial.ini'
+ MsgBox(msg, mbInformation, MB_OK);
+ end;
+ end;
+end;
+
+function ShouldSkipPage(PageID: Integer): Boolean;
+begin
+ { Skip wpSelectDir page if upgrading; show all others }
+ case PageID of
+ wpSelectDir:
+ Result := IsUpgrade;
+ else
+ Result := False;
+ end;
+end;
|
|
@@ -0,0 +1,11 @@ + [py2exe]
+excludes=pywin, pywin.dialogs, pywin.dialogs.list, PyQt, PyQt4.QtCode, PyQt4.QtGui
+includes=cairo, pango, pangocairo, atk, gobject, dbhash
+packages=email, hgext, hgext.convert, encodings, hggtk, hggtk.vis, hggtk.iniparse, tortoise
+
+# Disabled for 0.7 release
+#dll_excludes=iconv.dll, intl.dll, libatk-1.0-0.dll, libgdk_pixbuf-2.0-0.dll, libgdk-win32-2.0-0.dll, libglib-2.0-0.dll, libgmodule-2.0-0.dll, libgobject-2.0-0.dll, libgthread-2.0-0.dll, libgtk-win32-2.0-0.dll, libpango-1.0-0.dll, libpangowin32-1.0-0.dll, libcairo-2.dll, libglade-2.0-0.dll, libpangocairo-1.0-0.dll, libpangoft2-1.0-0.dll
+
+
+[build]
+compiler=mingw32
|
|
|
@@ -0,0 +1,234 @@ + #!/usr/bin/env python
+#
+# This is the mercurial setup script.
+#
+# 'python setup.py install', or
+# 'python setup.py --help' for more options
+
+import sys
+if not hasattr(sys, 'version_info') or sys.version_info < (2, 3, 0, 'final'):
+ raise SystemExit("Mercurial requires python 2.3 or later.")
+
+# Solaris Python packaging brain damage
+try:
+ import hashlib
+ sha = hashlib.sha1()
+except:
+ try:
+ import sha
+ except:
+ raise SystemExit(
+ "Couldn't import standard hashlib (incomplete Python install).")
+
+try:
+ import zlib
+except:
+ raise SystemExit(
+ "Couldn't import standard zlib (incomplete Python install).")
+
+import os, time
+import shutil
+import tempfile
+from distutils.core import setup, Extension
+from distutils.dist import Distribution
+from distutils.command.install_data import install_data
+from distutils.command.build import build
+from distutils.command.build_py import build_py
+from distutils.spawn import spawn, find_executable
+from distutils.ccompiler import new_compiler
+
+extra = {}
+scripts = ['hg']
+if os.name == 'nt':
+ scripts.append('contrib/win32/hg.bat')
+
+# simplified version of distutils.ccompiler.CCompiler.has_function
+# that actually removes its temporary files.
+def has_function(cc, funcname):
+ tmpdir = tempfile.mkdtemp(prefix='hg-install-')
+ devnull = oldstderr = None
+ try:
+ try:
+ fname = os.path.join(tmpdir, 'funcname.c')
+ f = open(fname, 'w')
+ f.write('int main(void) {\n')
+ f.write(' %s();\n' % funcname)
+ f.write('}\n')
+ f.close()
+ # Redirect stderr to /dev/null to hide any error messages
+ # from the compiler.
+ # This will have to be changed if we ever have to check
+ # for a function on Windows.
+ devnull = open('/dev/null', 'w')
+ oldstderr = os.dup(sys.stderr.fileno())
+ os.dup2(devnull.fileno(), sys.stderr.fileno())
+ objects = cc.compile([fname])
+ cc.link_executable(objects, os.path.join(tmpdir, "a.out"))
+ except:
+ return False
+ return True
+ finally:
+ if oldstderr is not None:
+ os.dup2(oldstderr, sys.stderr.fileno())
+ if devnull is not None:
+ devnull.close()
+ shutil.rmtree(tmpdir)
+
+# py2exe needs to be installed to work
+try:
+ import py2exe
+
+ # Help py2exe to find win32com.shell
+ try:
+ import modulefinder
+ import win32com
+ for p in win32com.__path__[1:]: # Take the path to win32comext
+ modulefinder.AddPackagePath("win32com", p)
+ pn = "win32com.shell"
+ __import__(pn)
+ m = sys.modules[pn]
+ for p in m.__path__[1:]:
+ modulefinder.AddPackagePath(pn, p)
+ except ImportError:
+ pass
+
+ extra['windows'] = [
+ {'script':'contrib/tracelog.py',
+ 'icon_resources':[(1, 'icons/tortoise/python.ico')]}
+ ]
+ extra['com_server'] = ['tortoisehg']
+ extra['console'] = ['hg', 'hgtk']
+
+except ImportError:
+ pass
+
+try:
+ from mercurial.__version__ import version
+except ImportError:
+ version = 'unknown'
+
+class install_package_data(install_data):
+ def finalize_options(self):
+ self.set_undefined_options('install',
+ ('install_lib', 'install_dir'))
+ install_data.finalize_options(self)
+
+class build_mo(build):
+
+ description = "build translations (.mo files)"
+
+ def run(self):
+ if not find_executable('msgfmt'):
+ self.warn("could not find msgfmt executable, no translations "
+ "will be built")
+ return
+
+ podir = 'i18n'
+ if not os.path.isdir(podir):
+ self.warn("could not find %s/ directory" % podir)
+ return
+
+ join = os.path.join
+ for po in os.listdir(podir):
+ if not po.endswith('.po'):
+ continue
+ pofile = join(podir, po)
+ modir = join('locale', po[:-3], 'LC_MESSAGES')
+ mofile = join(modir, 'hg.mo')
+ cmd = ['msgfmt', '-v', '-o', mofile, pofile]
+ if sys.platform != 'sunos5':
+ # msgfmt on Solaris does not know about -c
+ cmd.append('-c')
+ self.mkpath(modir)
+ self.make_file([pofile], mofile, spawn, (cmd,))
+ self.distribution.data_files.append((join('mercurial', modir),
+ [mofile]))
+
+build.sub_commands.append(('build_mo', None))
+
+Distribution.pure = 0
+Distribution.global_options.append(('pure', None, "use pure (slow) Python "
+ "code instead of C extensions"))
+
+class hg_build_py(build_py):
+
+ def finalize_options(self):
+ build_py.finalize_options(self)
+
+ if self.distribution.pure:
+ if self.py_modules is None:
+ self.py_modules = []
+ for ext in self.distribution.ext_modules:
+ if ext.name.startswith("mercurial."):
+ self.py_modules.append("mercurial.pure.%s" % ext.name[10:])
+ self.distribution.ext_modules = []
+
+ def find_modules(self):
+ modules = build_py.find_modules(self)
+ for module in modules:
+ if module[0] == "mercurial.pure":
+ if module[1] != "__init__":
+ yield ("mercurial", module[1], module[2])
+ else:
+ yield module
+
+cmdclass = {'install_data': install_package_data,
+ 'build_mo': build_mo,
+ 'build_py': hg_build_py}
+
+ext_modules=[
+ Extension('mercurial.base85', ['mercurial/base85.c']),
+ Extension('mercurial.bdiff', ['mercurial/bdiff.c']),
+ Extension('mercurial.diffhelpers', ['mercurial/diffhelpers.c']),
+ Extension('mercurial.mpatch', ['mercurial/mpatch.c']),
+ Extension('mercurial.parsers', ['mercurial/parsers.c']),
+ ]
+
+packages = ['mercurial', 'mercurial.hgweb', 'hgext', 'hgext.convert',
+ 'hgext.highlight', 'hgext.zeroconf', 'hggtk', 'hggtk.vis',
+ 'hggtk.iniparse', 'tortoise']
+
+try:
+ import msvcrt
+ ext_modules.append(Extension('mercurial.osutil', ['mercurial/osutil.c']))
+except ImportError:
+ pass
+
+try:
+ import posix
+ ext_modules.append(Extension('mercurial.osutil', ['mercurial/osutil.c']))
+
+ if sys.platform == 'linux2' and os.uname()[2] > '2.6':
+ # The inotify extension is only usable with Linux 2.6 kernels.
+ # You also need a reasonably recent C library.
+ cc = new_compiler()
+ if has_function(cc, 'inotify_add_watch'):
+ ext_modules.append(Extension('hgext.inotify.linux._inotify',
+ ['hgext/inotify/linux/_inotify.c']))
+ packages.extend(['hgext.inotify', 'hgext.inotify.linux'])
+except ImportError:
+ pass
+
+datafiles = []
+for root in ('templates', 'i18n'):
+ for dir, dirs, files in os.walk(root):
+ datafiles.append((os.path.join('mercurial', dir),
+ [os.path.join(dir, file_) for file_ in files]))
+
+setup(name='mercurial',
+ version=version,
+ author='Matt Mackall',
+ author_email='mpm@selenic.com',
+ url='http://selenic.com/mercurial',
+ description='Scalable distributed SCM',
+ license='GNU GPL',
+ scripts=scripts,
+ packages=packages,
+ ext_modules=ext_modules,
+ data_files=datafiles,
+ cmdclass=cmdclass,
+ options=dict(bdist_mpkg=dict(zipdist=True,
+ license='COPYING',
+ readme='contrib/macosx/Readme.html',
+ welcome='contrib/macosx/Welcome.html')),
+ **extra)
|
@@ -1,9 +1,1 @@ - import pygtk
-pygtk.require('2.0')
-import gtk
-
-# Default icon for apps which do not set one
-from shlib import get_tortoise_icon
-icon = get_tortoise_icon("hg.ico")
-if icon:
- gtk.window_set_default_icon_from_file(icon)
+#placeholder
|
@@ -6,27 +6,19 @@
import os
import sys
-
-import pygtk
-pygtk.require('2.0')
import gtk
-import shlib
-
-try:
- # post 1.1.2
- from mercurial import util
- hgversion = util.version()
-except AttributeError:
- # <= 1.1.2
- from mercurial import version
- hgversion = version.get_version()
+import gtklib
+from thgutil.i18n import _
+from thgutil.hglib import hgversion
+from thgutil import shlib
+from thgutil import paths
def browse_url(url):
import threading
def start_browser():
if os.name == 'nt':
import win32api, win32con
- win32api.ShellExecute(0, "open", url, None, "",
+ win32api.ShellExecute(0, "open", url, None, "",
win32con.SW_SHOW)
else:
import gconf
@@ -38,16 +30,17 @@
def url_handler(dialog, link, user_data):
browse_url(link)
-
+
gtk.about_dialog_set_url_hook(url_handler, None)
def make_version(tuple):
vers = ".".join([str(x) for x in tuple])
return vers
-
+
class AboutDialog(gtk.AboutDialog):
def __init__(self):
super(AboutDialog, self).__init__()
+ gtklib.set_tortoise_keys(self)
lib_versions = ', '.join([
"Mercurial-%s" % hgversion,
@@ -55,8 +48,8 @@ "PyGTK-%s" % make_version(gtk.pygtk_version),
"GTK-%s" % make_version(gtk.gtk_version),
])
-
- comment = "Several icons are courtesy of the TortoiseSVN project"
+
+ comment = _("Several icons are courtesy of the TortoiseSVN project")
self.set_website("http://bitbucket.org/tortoisehg/stable/")
self.set_name("TortoiseHg")
@@ -65,27 +58,23 @@ self.set_wrap_license(True)
self.set_copyright("Copyright 2009 TK Soh and others")
- thg_logo = os.path.normpath(shlib.get_tortoise_icon('thg_logo_92x50.png'))
- thg_icon = os.path.normpath(shlib.get_tortoise_icon('thg_logo.ico'))
- prog_root = os.path.dirname(os.path.dirname(os.path.dirname(thg_icon)))
- license_file = os.path.join(prog_root, "COPYING.txt")
+ thg_logo = paths.get_tortoise_icon('thg_logo_92x50.png')
+ thg_icon = paths.get_tortoise_icon('thg_logo.ico')
+ try:
+ license_file = paths.get_license_path()
+ self.set_license(file(license_file).read())
+ except IOError:
+ import hgtk
+ license = hgtk.shortlicense.splitlines()[1:]
+ self.set_license('\n'.join(license))
- self.set_license(file(license_file).read())
self.set_comments("with " + lib_versions + "\n\n" + comment)
self.set_logo(gtk.gdk.pixbuf_new_from_file(thg_logo))
self.set_icon_from_file(thg_icon)
-
- # somehow clicking on the Close button doesn't automatically
- # close the About dialog...
- self.connect('response', gtk.main_quit)
+ self.connect('response', self.response)
-def run(*args, **opts):
- dialog = AboutDialog()
- dialog.show_all()
- gtk.gdk.threads_init()
- gtk.gdk.threads_enter()
- gtk.main()
- gtk.gdk.threads_leave()
+ def response(self, widget, respid):
+ self.destroy()
-if __name__ == "__main__":
- run()
+def run(_ui, *pats, **opts):
+ return AboutDialog()
|
|
@@ -1,50 +0,0 @@ - #
-# Add/Remove dialog for TortoiseHg
-#
-# Copyright (C) 2007 TK Soh <teekaysoh@gmail.com>
-#
-
-try:
- import pygtk
- pygtk.require("2.0")
-except:
- pass
-
-import gtk
-import gobject
-from mercurial import ui, util, hg
-from mercurial.i18n import _
-from status import GStatus
-
-def run(hgcmd='add', root='', cwd='', files=[], **opts):
- u = ui.ui()
- u.updateopts(debug=False, traceback=False)
- repo = hg.repository(u, path=root)
-
- cmdoptions = {
- 'all':False, 'clean':False, 'ignored':False, 'modified':False,
- 'added':True, 'removed':True, 'deleted':True, 'unknown':False, 'rev':[],
- 'exclude':[], 'include':[], 'debug':True,'verbose':True
- }
-
- if hgcmd == 'add':
- cmdoptions['unknown'] = True
- elif hgcmd == 'remove':
- cmdoptions['clean'] = True
- else:
- raise "Invalid command '%s'" % hgcmd
-
- dialog = GStatus(u, repo, cwd, files, cmdoptions, True)
-
- gtk.gdk.threads_init()
- gtk.gdk.threads_enter()
- dialog.display()
- gtk.main()
- gtk.gdk.threads_leave()
-
-if __name__ == "__main__":
- import sys
- opts = {}
- opts['hgcmd'] = 'adda'
- opts['root'] = len(sys.argv) > 1 and sys.argv[1] or ''
- run(**opts)
|
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
|
|
@@ -6,8 +6,6 @@ #
import os
-import pygtk
-pygtk.require('2.0')
import gtk
import gobject
import pango
@@ -15,14 +13,15 @@
from mercurial.node import *
from mercurial import ui, hg, commands, extensions
+
+from thgutil.i18n import _
+from thgutil import hglib, paths
+
from gdialog import *
from changeset import ChangeSet
-from logfilter import FilterDialog
-from update import UpdateDialog
-from merge import MergeDialog
-from vis import treemodel
-from vis.treeview import TreeView
-from hglib import toutf, LookupError
+from logview import treemodel
+from logview.treeview import TreeView as LogTreeView
+
import gtklib
def create_menu(label, callback):
@@ -35,7 +34,7 @@ """GTK+ based dialog for displaying repository logs
"""
def get_title(self):
- return os.path.basename(self.repo.root) + ' log'
+ return os.path.basename(self.repo.root) + ' log'
def get_icon(self):
return 'menulog.ico'
@@ -45,24 +44,38 @@ self.ui.quiet = False
def get_tbbuttons(self):
- return [
+ tbar = [
self.make_toolbutton(gtk.STOCK_REFRESH,
- 'Re_fresh',
+ _('Re_fresh'),
self._refresh_clicked,
- tip='Reload revision history'),
+ tip=_('Reload revision history')),
gtk.SeparatorToolItem(),
self.make_toolbutton(gtk.STOCK_INDEX,
- '_Filter',
+ _('_Filter'),
self._filter_clicked,
menu=self._filter_menu(),
- tip='Filter revisions for display'),
+ tip=_('Filter revisions for display')),
gtk.SeparatorToolItem(),
self.make_toolbutton(gtk.STOCK_FIND,
- '_DataMine',
+ _('_DataMine'),
self._datamine_clicked,
- tip='Search Repository History'),
+ tip=_('Search Repository History')),
gtk.SeparatorToolItem()
] + self.changeview.get_tbbuttons()
+ if not self.opts.get('from-synch'):
+ tbar += [
+ gtk.SeparatorToolItem(),
+ self.make_toolbutton(gtk.STOCK_NETWORK,
+ _('Synchronize'),
+ self._synch_clicked,
+ tip=_('Launch synchronize tool')),
+ ]
+ return tbar
+
+ def _synch_clicked(self, toolbutton, data):
+ from synch import SynchDialog
+ dlg = SynchDialog([], False)
+ dlg.show_all()
def toggle_view_column(self, button, property):
active = button.get_active()
@@ -87,9 +100,8 @@
def _datamine_clicked(self, toolbutton, data=None):
from datamine import DataMineDialog
- dialog = DataMineDialog(self.ui, self.repo, self.cwd, [], {}, False)
+ dialog = DataMineDialog(self.ui, self.repo, self.cwd, [], {})
dialog.display()
- dialog.add_search_page()
def _filter_clicked(self, toolbutton, data=None):
if self._filter_dialog:
@@ -109,19 +121,20 @@
def delete_event(dialog, event, data=None):
# return True to prevent the dialog from being destroyed
- return True
+ return True
revs = []
if self.currow is not None:
revs.append(self.currow[treemodel.REVID])
-
+
+ from logfilter import FilterDialog
dlg = FilterDialog(self.repo.root, revs, self.pats,
filterfunc=do_reload)
dlg.connect('response', close_filter_dialog)
dlg.connect('delete-event', delete_event)
dlg.set_modal(False)
dlg.show()
-
+
self._filter_dialog = dlg
def _filter_selected(self, widget, data=None):
@@ -132,22 +145,28 @@ def _view_menu(self):
menu = gtk.Menu()
- button = gtk.CheckMenuItem("Show Rev")
+ button = gtk.CheckMenuItem(_('Show Rev'))
button.connect("toggled", self.toggle_view_column,
'rev-column-visible')
- button.set_active(self._show_rev)
+ button.set_active(self.showcol.get('rev', True))
button.set_draw_as_radio(True)
menu.append(button)
- button = gtk.CheckMenuItem("Show ID")
+ button = gtk.CheckMenuItem(_('Show ID'))
button.connect("toggled", self.toggle_view_column,
'id-column-visible')
- button.set_active(self._show_id)
+ button.set_active(self.showcol.get('id', False))
button.set_draw_as_radio(True)
menu.append(button)
- button = gtk.CheckMenuItem("Show Date")
+ button = gtk.CheckMenuItem(_('Show Date'))
button.connect("toggled", self.toggle_view_column,
'date-column-visible')
- button.set_active(self._show_date)
+ button.set_active(self.showcol.get('date', True))
+ button.set_draw_as_radio(True)
+ menu.append(button)
+ button = gtk.CheckMenuItem(_("Show Branch"))
+ button.connect("toggled", self.toggle_view_column,
+ 'branch-column-visible')
+ button.set_active(self.showcol.get('branch', False))
button.set_draw_as_radio(True)
menu.append(button)
menu.show_all()
@@ -155,36 +174,40 @@
def _filter_menu(self):
menu = gtk.Menu()
-
- button = gtk.RadioMenuItem(None, "Show All Revisions")
+
+ button = gtk.RadioMenuItem(None, _('Show All Revisions'))
button.set_active(True)
- button.connect("toggled", self._filter_selected, 'all')
+ button.connect('toggled', self._filter_selected, 'all')
menu.append(button)
-
- button = gtk.RadioMenuItem(button, "Show Tagged Revisions")
- button.connect("toggled", self._filter_selected, 'tagged')
+
+ button = gtk.RadioMenuItem(button, _('Show Tagged Revisions'))
+ button.connect('toggled', self._filter_selected, 'tagged')
menu.append(button)
-
- button = gtk.RadioMenuItem(button, "Show Parent Revisions")
- button.connect("toggled", self._filter_selected, 'parents')
+
+ button = gtk.RadioMenuItem(button, _('Show Revision Ancestry'))
+ button.connect('toggled', self._filter_selected, 'ancestry')
menu.append(button)
-
- button = gtk.RadioMenuItem(button, "Show Head Revisions")
- button.connect("toggled", self._filter_selected, 'heads')
+
+ button = gtk.RadioMenuItem(button, _('Show Working Parents'))
+ button.connect('toggled', self._filter_selected, 'parents')
menu.append(button)
-
- button = gtk.RadioMenuItem(button, "Show Only Merge Revisions")
- button.connect("toggled", self._filter_selected, 'only_merges')
+
+ button = gtk.RadioMenuItem(button, _('Show Head Revisions'))
+ button.connect('toggled', self._filter_selected, 'heads')
menu.append(button)
-
- button = gtk.RadioMenuItem(button, "Show Non-Merge Revisions")
- button.connect("toggled", self._filter_selected, 'no_merges')
+
+ button = gtk.RadioMenuItem(button, _('Show Only Merge Revisions'))
+ button.connect('toggled', self._filter_selected, 'only_merges')
menu.append(button)
-
- self.custombutton = gtk.RadioMenuItem(button, "Custom Filter")
+
+ button = gtk.RadioMenuItem(button, _('Show Non-Merge Revisions'))
+ button.connect('toggled', self._filter_selected, 'no_merges')
+ menu.append(button)
+
+ self.custombutton = gtk.RadioMenuItem(button, _('Custom Filter'))
self.custombutton.set_sensitive(False)
menu.append(self.custombutton)
-
+
menu.show_all()
return menu
@@ -200,12 +223,11 @@ self.curfile = None
self.opts['rev'] = [] # This option is dangerous - used directly by hg
self.opts['revs'] = None
- os.chdir(self.repo.root) # paths relative to repo root do not work otherwise
+ os.chdir(self.repo.root) # for paths relative to repo root
if 'filehist' in self.opts:
self.custombutton.set_active(True)
- self.graphview.refresh(True, None, self.opts)
- del self.opts['filehist']
+ self.reload_log({'pats' : [self.opts['filehist']]})
elif 'revrange' in self.opts:
self.custombutton.set_active(True)
self.graphview.refresh(True, None, self.opts)
@@ -214,19 +236,10 @@ self.reload_log()
elif self.pats:
self.custombutton.set_active(True)
- self.graphview.refresh(False, self.pats, self.opts)
+ self.reload_log({'pats' : self.pats})
else:
self.reload_log()
- def save_settings(self):
- settings = GDialog.save_settings(self)
- settings['glog'] = (self._vpaned.get_position(),
- self._hpaned.get_position(),
- self.graphview.get_property('rev-column-visible'),
- self.graphview.get_property('date-column-visible'),
- self.graphview.get_property('id-column-visible'))
- return settings
-
def get_graphlimit(self, suggestion):
limit_opt = self.repo.ui.config('tortoisehg', 'graphlimit', '500')
l = 0
@@ -239,6 +252,15 @@ pass
return l or 500
+ def save_settings(self):
+ settings = GDialog.save_settings(self)
+ settings['glog-vpane'] = self._vpaned.get_position()
+ settings['glog-hpane'] = self._hpaned.get_position()
+ for col in ('rev', 'date', 'id', 'branch'):
+ vis = self.graphview.get_property(col+'-column-visible')
+ settings['glog-vis-'+col] = vis
+ return settings
+
def load_settings(self, settings):
'''Called at beginning of display() method'''
@@ -248,33 +270,32 @@ # Allocate TreeView instance to use internally
if 'limit' in self.opts:
firstlimit = self.get_graphlimit(self.opts['limit'])
- self.graphview = TreeView(self.repo, firstlimit, self.stbar)
+ self.graphview = LogTreeView(self.repo, firstlimit, self.stbar)
else:
- self.graphview = TreeView(self.repo, self.limit, self.stbar)
+ self.graphview = LogTreeView(self.repo, self.limit, self.stbar)
# Allocate ChangeSet instance to use internally
self.changeview = ChangeSet(self.ui, self.repo, self.cwd, [],
- self.opts, False, self.stbar)
+ self.opts, self.stbar)
self.changeview.display(False)
self.changeview.glog_parent = self
GDialog.load_settings(self, settings)
self._setting_vpos = -1
self._setting_hpos = -1
- self._show_rev, self._show_date, self._show_id = True, True, False
- if settings:
- data = settings['glog']
- if type(data) == int:
- self._setting_vpos = data
- elif len(data) == 2:
- (self._setting_vpos, self._setting_hpos) = data
- elif len(data) == 5:
- (self._setting_vpos, self._setting_hpos,
- self._show_rev, self._show_date, self._show_id) = data
+ self.showcol = {}
+ try:
+ self._setting_vpos = settings['glog-vpane']
+ self._setting_hpos = settings['glog-hpane']
+ for col in ('rev', 'date', 'id', 'branch'):
+ vis = settings['glog-vis-'+col]
+ self.showcol[col] = vis
+ except KeyError:
+ pass
def reload_log(self, filteropts={}):
"""Send refresh event to treeview object"""
- os.chdir(self.repo.root) # paths relative to repo root do not work otherwise
+ os.chdir(self.repo.root) # for paths relative to repo root
self.nextbutton.set_sensitive(True)
self.allbutton.set_sensitive(True)
self.opts['rev'] = []
@@ -285,12 +306,12 @@ self.opts['date'] = filteropts.get('date', None)
self.opts['keyword'] = filteropts.get('keyword', [])
if filteropts:
- branch = filteropts.get('branch', None)
if 'revrange' in filteropts or 'branch' in filteropts:
+ branch = filteropts.get('branch', None)
self.graphview.refresh(True, branch, self.opts)
else:
- pattern = filteropts.get('pats', [])
- self.graphview.refresh(False, pattern, self.opts)
+ self.pats = filteropts.get('pats', [])
+ self.graphview.refresh(False, self.pats, self.opts)
elif self._filter == "all":
self.graphview.refresh(True, None, self.opts)
elif self._filter == "only_merges":
@@ -299,6 +320,12 @@ elif self._filter == "no_merges":
self.opts['no_merges'] = True
self.graphview.refresh(False, [], self.opts)
+ elif self._filter == "ancestry":
+ if not self.currow:
+ return
+ range = [self.currow[treemodel.REVID], 0]
+ sopts = {'noheads': True, 'revrange': range}
+ self.graphview.refresh(True, None, sopts)
elif self._filter == "tagged":
tagged = []
for t, r in self.repo.tagslist():
@@ -318,38 +345,45 @@
def tree_context_menu(self):
_menu = gtk.Menu()
- _menu.append(create_menu('di_splay', self._show_status))
- _menu.append(create_menu('_update', self._checkout))
- self._cmenu_merge = create_menu('_merge with', self._merge)
+ _menu.append(create_menu(_('di_splay'), self._show_status))
+ _menu.append(create_menu(_('visualize change'), self._vdiff_change))
+ _menu.append(create_menu(_('diff to local'), self._vdiff_local))
+ _menu.append(create_menu(_('_update'), self._checkout))
+ self._cmenu_merge = create_menu(_('_merge with'), self._merge)
_menu.append(self._cmenu_merge)
- _menu.append(create_menu('_export patch', self._export_patch))
- _menu.append(create_menu('e_mail patch', self._email_patch))
- _menu.append(create_menu('_bundle rev:tip', self._bundle_rev_to_tip))
- _menu.append(create_menu('add/remove _tag', self._add_tag))
- _menu.append(create_menu('backout revision', self._backout_rev))
- _menu.append(create_menu('_revert', self._revert))
-
+ _menu.append(create_menu(_('_copy hash'), self._copy_hash))
+ _menu.append(create_menu(_('_export patch'), self._export_patch))
+ _menu.append(create_menu(_('e_mail patch'), self._email_patch))
+ _menu.append(create_menu(_('_bundle rev:tip'), self._bundle_rev_to_tip))
+ _menu.append(create_menu(_('add/remove _tag'), self._add_tag))
+ _menu.append(create_menu(_('backout revision'), self._backout_rev))
+ _menu.append(create_menu(_('_revert'), self._revert))
+
# need mq extension for strip command
extensions.loadall(self.ui)
extensions.load(self.ui, 'mq', None)
- _menu.append(create_menu('strip revision', self._strip_rev))
-
+ _menu.append(create_menu(_('strip revision'), self._strip_rev))
+
_menu.show_all()
return _menu
-
+
def _restore_original_selection(self, widget, *args):
self.tree.get_selection().set_mode(gtk.SELECTION_SINGLE)
self.tree.get_selection().select_path(self._orig_sel)
-
+
def tree_diff_context_menu(self):
_menu = gtk.Menu()
- _menu.append(create_menu('_diff with selected', self._diff_revs))
- _menu.append(create_menu('visual diff with selected',
+ _menu.append(create_menu(_('_diff with selected'), self._diff_revs))
+ _menu.append(create_menu(_('visual diff with selected'),
self._vdiff_selected))
+ _menu.append(create_menu(_('email from here to selected'),
+ self._email_revs))
+ _menu.append(create_menu(_('bundle from here to selected'),
+ self._bundle_revs))
_menu.connect_after('selection-done', self._restore_original_selection)
_menu.show_all()
return _menu
-
+
def get_body(self):
self._filter_dialog = None
self._menu = self.tree_context_menu()
@@ -359,7 +393,7 @@ self.tree_frame.set_shadow_type(gtk.SHADOW_ETCHED_IN)
# PyGtk 2.6 and below did not automatically register types
- if gobject.pygtk_version < (2, 8, 0):
+ if gobject.pygtk_version < (2, 8, 0):
gobject.type_register(TreeView)
self.tree = self.graphview.treeview
@@ -371,7 +405,20 @@ #self.tree.connect('popup-menu', self._tree_popup_menu)
self.tree.connect('row-activated', self._tree_row_act)
#self.tree.modify_font(pango.FontDescription(self.fontlist))
-
+
+ accelgroup = gtk.AccelGroup()
+ self.add_accel_group(accelgroup)
+ mod = gtklib.get_thg_modifier()
+ key, modifier = gtk.accelerator_parse(mod+'d')
+ self.tree.add_accelerator('thg-diff', accelgroup, key,
+ modifier, gtk.ACCEL_VISIBLE)
+ self.tree.connect('thg-diff', self.thgdiff)
+ key, modifier = gtk.accelerator_parse(mod+'p')
+ self.tree.add_accelerator('thg-parent', accelgroup, key,
+ modifier, gtk.ACCEL_VISIBLE)
+ self.tree.connect('thg-parent', self.thgparent)
+ self.connect('thg-refresh', self.thgrefresh)
+
hbox = gtk.HBox()
hbox.pack_start(self.graphview, True, True, 0)
vbox = gtk.VBox()
@@ -392,9 +439,9 @@ vbox.pack_start(self.allbutton, False, False)
self.nextbutton.set_tooltip(self.tooltips,
- 'show next %d revisions' % self.limit)
+ _('show next %d revisions') % self.limit)
self.allbutton.set_tooltip(self.tooltips,
- 'show all remaining revisions')
+ _('show all remaining revisions'))
hbox.pack_start(vbox, False, False, 0)
self.tree_frame.add(hbox)
@@ -407,8 +454,7 @@ self._vpaned = gtk.VPaned()
self._vpaned.pack1(self.tree_frame, True, False)
self._vpaned.pack2(self._hpaned)
- self._vpaned.set_position(self._setting_vpos)
- self._hpaned.set_position(self._setting_hpos)
+ gobject.idle_add(self.realize_settings)
vbox = gtk.VBox()
vbox.pack_start(self._vpaned, True, True)
@@ -416,13 +462,25 @@ # Append status bar
vbox.pack_start(gtk.HSeparator(), False, False)
vbox.pack_start(self.stbar, False, False)
+ return vbox
- return vbox
+ def realize_settings(self):
+ self._vpaned.set_position(self._setting_vpos)
+ self._hpaned.set_position(self._setting_hpos)
+
+ def thgdiff(self, treeview):
+ 'ctrl-d handler'
+ self._vdiff_change(None)
+
+ def thgparent(self, treeview):
+ 'ctrl-p handler'
+ parent = self.repo['.'].rev()
+ self.graphview.set_revision_id(parent)
def _strip_rev(self, menuitem):
rev = self.currow[treemodel.REVID]
- res = Confirm('Strip Revision(s)', [], self,
- 'Remove revision %d and all descendants?' % rev).run()
+ res = Confirm(_('Confirm Strip Revision(s)'), [], self,
+ _('Remove revision %d and all descendants?') % rev).run()
if res != gtk.RESPONSE_YES:
return
from hgcmd import CmdDialog
@@ -439,7 +497,7 @@ rev = self.currow[treemodel.REVID]
rev = short(self.repo.changelog.node(rev))
parents = [x.node() for x in self.repo.changectx(None).parents()]
- dialog = BackoutDialog(self.repo.root, rev)
+ dialog = BackoutDialog(rev)
dialog.set_transient_for(self)
dialog.show_all()
dialog.set_notify_func(self.checkout_completed, parents)
@@ -448,9 +506,9 @@
def _revert(self, menuitem):
rev = self.currow[treemodel.REVID]
- res = Confirm('Revert Revision(s)', [], self,
- 'Revert all files to revision %d?\nThis will overwrite your '
- 'local changes' % rev).run()
+ res = Confirm(_('Confirm Revert Revision(s)'), [], self,
+ _('Revert all files to revision %d?\nThis will overwrite your '
+ 'local changes') % rev).run()
if res != gtk.RESPONSE_YES:
return
@@ -463,24 +521,68 @@ dlg.run()
dlg.hide()
+ def _vdiff_change(self, menuitem, pats=[]):
+ rev = self.currow[treemodel.REVID]
+ self._do_diff(pats, {'change' : rev}, modal=True)
+
+ def _vdiff_local(self, menuitem, pats=[]):
+ rev = self.currow[treemodel.REVID]
+ opts = {'rev' : ["%s:." % rev]}
+ self._do_diff(pats, opts, modal=True)
+
def _diff_revs(self, menuitem):
from status import GStatus
- from gtools import cmdtable
rev0, rev1 = self._revs
- statopts = self.merge_opts(cmdtable['gstatus|gst'][1],
+ statopts = self.merge_opts(commands.table['^status|st'][1],
('include', 'exclude', 'git'))
statopts['rev'] = ['%u:%u' % (rev0, rev1)]
statopts['modified'] = True
statopts['added'] = True
statopts['removed'] = True
- dialog = GStatus(self.ui, self.repo, self.cwd, [], statopts, False)
+ dialog = GStatus(self.ui, self.repo, self.cwd, self.pats,
+ statopts)
dialog.display()
return True
def _vdiff_selected(self, menuitem):
rev0, rev1 = self._revs
self.opts['rev'] = ["%s:%s" % (rev0, rev1)]
- self._diff_file(None, '')
+ if len(self.pats) == 1:
+ self._diff_file(None, self.pats[0])
+ else:
+ self._diff_file(None, None)
+
+ def _email_revs(self, menuitem):
+ from hgemail import EmailDialog
+ revs = list(self._revs)
+ revs.sort()
+ opts = ['--rev', str(revs[0]) + ':' + str(revs[1])]
+ dlg = EmailDialog(self.repo.root, opts)
+ dlg.set_transient_for(self)
+ dlg.show_all()
+ dlg.present()
+ dlg.set_transient_for(None)
+
+ def _bundle_revs(self, menuitem):
+ revs = list(self._revs)
+ revs.sort()
+ parent = self.repo[revs[0]].parents()[0].rev()
+ # Special case for revision 0's parent.
+ if parent == -1: parent = 'null'
+
+ filename = "%s_rev%d_to_rev%s.hg" % (os.path.basename(self.repo.root),
+ revs[0], revs[1])
+ result = NativeSaveFileDialogWrapper(Title=_('Write bundle to'),
+ InitialDir=self.repo.root,
+ FileName=filename).run()
+ if result:
+ from hgcmd import CmdDialog
+ cmdline = ['hg', 'bundle', '--base', str(parent),
+ '--rev', str(revs[1]), result]
+ dlg = CmdDialog(cmdline)
+ dlg.show_all()
+ dlg.run()
+ dlg.hide()
def _add_tag(self, menuitem):
from tagadd import TagAddDialog
@@ -488,7 +590,7 @@ # save tag info for detecting new tags added
oldtags = self.repo.tagslist()
rev = self.currow[treemodel.REVID]
-
+
def refresh(*args):
self.repo.invalidate()
newtags = self.repo.tagslist()
@@ -505,13 +607,20 @@ def _show_status(self, menuitem):
rev = self.currow[treemodel.REVID]
statopts = {'rev' : [str(rev)] }
- dialog = ChangeSet(self.ui, self.repo, self.cwd, [], statopts, False)
+ dialog = ChangeSet(self.ui, self.repo, self.cwd, [], statopts)
dialog.display()
+ def _copy_hash(self, menuitem):
+ rev = self.currow[treemodel.REVID]
+ node = self.repo[rev].node()
+ sel = (os.name == 'nt') and 'CLIPBOARD' or 'PRIMARY'
+ clipboard = gtk.Clipboard(selection=sel)
+ clipboard.set_text(hex(node))
+
def _export_patch(self, menuitem):
rev = self.currow[treemodel.REVID]
filename = "%s_rev%s.patch" % (os.path.basename(self.repo.root), rev)
- fd = NativeSaveFileDialogWrapper(Title = "Save patch to",
+ fd = NativeSaveFileDialogWrapper(Title=_('Save patch to'),
InitialDir=self.repo.root,
FileName=filename)
result = fd.run()
@@ -519,7 +628,7 @@ if result:
if os.path.exists(result):
os.remove(result)
-
+
# In case new export args are added in the future, merge the
# hg defaults
exportOpts= self.merge_opts(commands.table['^export'][1], ())
@@ -534,10 +643,10 @@ parent = self.repo[rev].parents()[0].rev()
# Special case for revision 0's parent.
if parent == -1: parent = 'null'
- except (ValueError, LookupError):
+ except (ValueError, hglib.LookupError):
return
filename = "%s_rev%d_to_tip.hg" % (os.path.basename(self.repo.root), rev)
- result = NativeSaveFileDialogWrapper(Title = "Write bundle to",
+ result = NativeSaveFileDialogWrapper(Title=_('Write bundle to'),
InitialDir=self.repo.root,
FileName=filename).run()
if result:
@@ -558,9 +667,10 @@ dlg.set_transient_for(None)
def _checkout(self, menuitem):
+ from update import UpdateDialog
rev = self.currow[treemodel.REVID]
parents = [x.node() for x in self.repo.changectx(None).parents()]
- dialog = UpdateDialog(self.cwd, rev)
+ dialog = UpdateDialog(rev)
dialog.set_transient_for(self)
dialog.show_all()
dialog.set_notify_func(self.checkout_completed, parents)
@@ -573,10 +683,10 @@ self.reload_log()
def _merge(self, menuitem):
+ from merge import MergeDialog
rev = self.currow[treemodel.REVID]
parents = [x.node() for x in self.repo.changectx(None).parents()]
- node = short(self.repo.changelog.node(rev))
- dialog = MergeDialog(self.repo.root, self.cwd, node)
+ dialog = MergeDialog(rev)
dialog.set_transient_for(self)
dialog.show_all()
dialog.set_notify_func(self.merge_completed, parents)
@@ -597,6 +707,9 @@ self.changeview.load_details(rev)
return False
+ def thgrefresh(self, window):
+ self.reload_log()
+
def _refresh_clicked(self, toolbutton, data=None):
self.reload_log()
return True
@@ -629,7 +742,7 @@
def _tree_popup_menu(self, treeview, button=0, time=0) :
selrev = self.currow[treemodel.REVID]
-
+
# disable/enable menus as required
parents = [self.repo.changelog.rev(x.node()) for x in
self.repo.changectx(None).parents()]
@@ -640,7 +753,7 @@ self._menu.popup(None, None, None, button, time)
return True
- def _tree_popup_menu_diff(self, treeview, button=0, time=0):
+ def _tree_popup_menu_diff(self, treeview, button=0, time=0):
# display the context menu
self._menu2.popup(None, None, None, button, time)
return True
@@ -651,33 +764,16 @@ self._menu.get_children()[0].activate()
return True
-def run(root='', cwd='', files=[], limit='', **opts):
- u = ui.ui()
- u.updateopts(debug=False, traceback=False)
- repo = hg.repository(u, path=root)
-
- files = [util.canonpath(root, cwd, f) for f in files]
-
+def run(ui, *pats, **opts):
+ limit = opts.get('limit')
cmdoptions = {
'follow':False, 'follow-first':False, 'copies':False, 'keyword':[],
- 'limit':limit, 'rev':[], 'removed':False, 'no_merges':False, 'date':None,
- 'only_merges':None, 'prune':[], 'git':False, 'verbose':False,
- 'include':[], 'exclude':[]
+ 'limit':limit, 'rev':[], 'removed':False, 'no_merges':False,
+ 'date':None, 'only_merges':None, 'prune':[], 'git':False,
+ 'verbose':False, 'include':[], 'exclude':[]
}
-
- dialog = GLog(u, repo, cwd, files, cmdoptions, True)
-
- gtk.gdk.threads_init()
- gtk.gdk.threads_enter()
- dialog.display()
- gtk.main()
- gtk.gdk.threads_leave()
-
-if __name__ == "__main__":
- import sys
- opts = {}
- path = len(sys.argv) > 1 and sys.argv[1] or os.getcwd()
- opts['root'] = os.path.abspath(path)
- opts['files'] = [opts['root']]
- opts['limit'] = ''
- run(**opts)
+ root = paths.find_root()
+ canonpats = []
+ for f in pats:
+ canonpats.append(util.canonpath(root, os.getcwd(), f))
+ return GLog(ui, None, None, canonpats, cmdoptions)
|
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
Change 1 of 2
Show Entire File
hggtk/logview/revgraph.py
Stacked
renamed from hggtk/vis/revgraph.py
|
||
---|---|---|
@@ -14,7 +14,7 @@ def __get_parents(repo, rev):
return [x for x in repo.changelog.parentrevs(rev) if x != nullrev]
-def revision_grapher(repo, start_rev, stop_rev, branch=None):
+def revision_grapher(repo, start_rev, stop_rev, branch=None, noheads=False):
"""incremental revision grapher
This generator function walks through the revision history from
@@ -37,6 +37,9 @@ while curr_rev >= stop_rev:
# Compute revs and next_revs.
if curr_rev not in revs:
+ if noheads and curr_rev != start_rev:
+ curr_rev -= 1
+ continue
if branch:
ctx = repo.changectx(curr_rev)
if ctx.branch() != branch:
|
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
|
@@ -1,20 +0,0 @@ - ::
-:: Win32 batch file to handle TortoiseHg external proc calls
-::
-
-@echo off
-setlocal
-
-:: Look in the registry for TortoiseHg location
-for /f "skip=2 tokens=3*" %%A in (
- '"reg query "HKEY_LOCAL_MACHINE\SOFTWARE\TortoiseHg" /ve 2> nul"' ) do set TortoisePath=%%B
-if "%TortoisePath%"=="" (goto :notfound) else (goto :hgproc)
-
-:hgproc
-python "%TortoisePath%\hgproc.py" %*
-goto end
-
-:notfound
-echo hgproc: cannot find TortoiseHg location in the registry.
-
-:end
\ No newline at end of file |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
This image was not loaded automatically because this changeset is very large.
Click to load this image...
|
This image was not loaded automatically because this changeset is very large.
Click to load this image...
|
This image was not loaded automatically because this changeset is very large.
Click to load this image...
|
This image was not loaded automatically because this changeset is very large.
Click to load this image...
|
This image was not loaded automatically because this changeset is very large.
Click to load this image...
|
This image was not loaded automatically because this changeset is very large.
Click to load this image...
|
This image was not loaded automatically because this changeset is very large.
Click to load this image...
|
This image was not loaded automatically because this changeset is very large.
Click to load this image...
|
This image was not loaded automatically because this changeset is very large.
Click to load this image...
|
This image was not loaded automatically because this changeset is very large.
Click to load this image...
|
This image was not loaded automatically because this changeset is very large.
Click to load this image...
|
This image was not loaded automatically because this changeset is very large.
Click to load this image...
|
This image was not loaded automatically because this changeset is very large.
Click to load this image...
|
This image was not loaded automatically because this changeset is very large.
Click to load this image...
|
This image was not loaded automatically because this changeset is very large.
Click to load this image...
|
This image was not loaded automatically because this changeset is very large.
Click to load this image...
|
This image was not loaded automatically because this changeset is very large.
Click to load this image...
|
This image was not loaded automatically because this changeset is very large.
Click to load this image...
|
This image was not loaded automatically because this changeset is very large.
Click to load this image...
|
This image was not loaded automatically because this changeset is very large.
Click to load this image...
|
This image was not loaded automatically because this changeset is very large.
Click to load this image...
|
This image was not loaded automatically because this changeset is very large.
Click to load this image...
|
This image was not loaded automatically because this changeset is very large.
Click to load this image...
|
This image was not loaded automatically because this changeset is very large.
Click to load this image...
|
This image was not loaded automatically because this changeset is very large.
Click to load this image...
|
This image was not loaded automatically because this changeset is very large.
Click to load this image...
|
This image was not loaded automatically because this changeset is very large.
Click to load this image...
|
This image was not loaded automatically because this changeset is very large.
Click to load this image...
|
This image was not loaded automatically because this changeset is very large.
Click to load this image...
|
renamed from icons/tortoise/svg/detect_rename.svg
|
||
---|---|---|
This image was not loaded automatically because this changeset is very large.
Click to load this image...
|
This image was not loaded automatically because this changeset is very large.
Click to load this image...
|
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
|
@@ -0,0 +1,1 @@ + #placeholder
|
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
|
@@ -0,0 +1,14 @@ + """
+i18n.py
+ Copyright (C) 2009 Steve Borho <steve@borho.org>
+
+This software may be used and distributed according to the terms
+of the GNU General Public License, incorporated herein by reference.
+"""
+
+import gettext
+from gettext import gettext as _
+import paths
+
+gettext.bindtextdomain("thg", paths.get_locale_path())
+gettext.textdomain("thg")
|
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
|
@@ -1,6 +0,0 @@ -
-import gettext
-
-# Add '_' to the builtin namespace
-gettext.install('olive-gtk')
-
|
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
|
@@ -1,14 +0,0 @@ - # Published under the GNU GPL, v2 or later.
-# Copyright (C) 2007 Henry Ludemann <misc@hl.id.au>
-# Copyright (C) 2007 TK Soh <teekaysoh@gmail.com>
-
-from mercurial import ui
-
-# overlay icons display setting
-show_overlay_icons = False
-
-def read():
- global show_overlay_icons
- overlayicons = ui.ui().config('tortoisehg', 'overlayicons', '')
- print "tortoisehg.overlayicons = ", overlayicons
- show_overlay_icons = overlayicons != 'disabled'
|
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
This file's diff was not loaded because this changeset is very large. Load changes Loading... |
renamed from tortoise/shellext/ContextMenu.cpp
|
||
---|---|---|
renamed from tortoise/shellext/Directory.cpp
|
||
---|---|---|
renamed from tortoise/shellext/DirectoryStatus.cpp
|
||
---|---|---|
renamed from tortoise/shellext/DirectoryStatus.h
|
||
---|---|---|
renamed from tortoise/shellext/Dirstatecache.cpp
|
||
---|---|---|
renamed from tortoise/shellext/Dirstatecache.h
|
||
---|---|---|
renamed from tortoise/shellext/HgRepoRoot.cpp
|
||
---|---|---|
renamed from tortoise/shellext/IconOverlay.cpp
|
||
---|---|---|
renamed from tortoise/shellext/MenuActions.cpp
|
||
---|---|---|
renamed from tortoise/shellext/PipeUtils.cpp
|
||
---|---|---|
renamed from tortoise/shellext/QueryDirstate.cpp
|
||
---|---|---|
renamed from tortoise/shellext/QueryDirstate.h
|
||
---|---|---|
renamed from tortoise/shellext/ShellUtils.cpp
|
||
---|---|---|
renamed from tortoise/shellext/ShellUtils2.cpp
|
||
---|---|---|
renamed from tortoise/shellext/StringUtils.cpp
|
||
---|---|---|
renamed from tortoise/shellext/StringUtils.h
|
||
---|---|---|
renamed from tortoise/shellext/TortoiseUtils.cpp
|
||
---|---|---|
renamed from tortoise/shellext/TortoiseUtils.h
|
||
---|---|---|
Loading...