diff --git a/rhodecode/controllers/changeset.py b/rhodecode/controllers/changeset.py --- a/rhodecode/controllers/changeset.py +++ b/rhodecode/controllers/changeset.py @@ -25,12 +25,18 @@ # along with this program. If not, see . import logging import traceback +from collections import defaultdict +from webob.exc import HTTPForbidden from pylons import tmpl_context as c, url, request, response from pylons.i18n.translation import _ from pylons.controllers.util import redirect from pylons.decorators import jsonify +from vcs.exceptions import RepositoryError, ChangesetError, \ + ChangesetDoesNotExistError +from vcs.nodes import FileNode + import rhodecode.lib.helpers as h from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator from rhodecode.lib.base import BaseRepoController, render @@ -39,16 +45,109 @@ from rhodecode.lib.compat import Ordered from rhodecode.lib import diffs from rhodecode.model.db import ChangesetComment from rhodecode.model.comment import ChangesetCommentsModel - -from vcs.exceptions import RepositoryError, ChangesetError, \ - ChangesetDoesNotExistError -from vcs.nodes import FileNode -from webob.exc import HTTPForbidden from rhodecode.model.meta import Session log = logging.getLogger(__name__) +def anchor_url(revision,path): + fid = h.FID(revision, path) + return h.url.current(anchor=fid,**request.GET) + +def get_ignore_ws(fid, GET): + ig_ws_global = request.GET.get('ignorews') + ig_ws = filter(lambda k:k.startswith('WS'),GET.getall(fid)) + if ig_ws: + try: + return int(ig_ws[0].split(':')[-1]) + except: + pass + return ig_ws_global + +def _ignorews_url(fileid=None): + + params = defaultdict(list) + lbl = _('show white space') + ig_ws = get_ignore_ws(fileid, request.GET) + ln_ctx = get_line_ctx(fileid, request.GET) + # global option + if fileid is None: + if ig_ws is None: + params['ignorews'] += [1] + lbl = _('ignore white space') + ctx_key = 'context' + ctx_val = ln_ctx + # per file options + else: + if ig_ws is None: + params[fileid] += ['WS:1'] + lbl = _('ignore white space') + + ctx_key = fileid + ctx_val = 'C:%s' % ln_ctx + # if we have passed in ln_ctx pass it along to our params + if ln_ctx: + params[ctx_key] += [ctx_val] + + params['anchor'] = fileid + return h.link_to(lbl, h.url.current(**params)) + +def get_line_ctx(fid, GET): + ln_ctx_global = request.GET.get('context') + ln_ctx = filter(lambda k:k.startswith('C'),GET.getall(fid)) + + if ln_ctx: + retval = ln_ctx[0].split(':')[-1] + else: + retval = ln_ctx_global + + try: + return int(retval) + except: + return + +def _context_url(fileid=None): + """ + Generates url for context lines + + :param fileid: + """ + ig_ws = get_ignore_ws(fileid, request.GET) + ln_ctx = (get_line_ctx(fileid, request.GET) or 3) * 2 + + params = defaultdict(list) + + # global option + if fileid is None: + if ln_ctx > 0: + params['context'] += [ln_ctx] + + if ig_ws: + ig_ws_key = 'ignorews' + ig_ws_val = 1 + + # per file option + else: + params[fileid] += ['C:%s' % ln_ctx] + ig_ws_key = fileid + ig_ws_val = 'WS:%s' % 1 + + if ig_ws: + params[ig_ws_key] += [ig_ws_val] + + lbl = _('%s line context') % ln_ctx + + params['anchor'] = fileid + return h.link_to(lbl, h.url.current(**params)) + +def wrap_to_table(str_): + return ''' + + + + +
%s
''' % str_ + class ChangesetController(BaseRepoController): @LoginRequired() @@ -59,16 +158,10 @@ class ChangesetController(BaseRepoContro c.affected_files_cut_off = 60 def index(self, revision): - ignore_whitespace = request.GET.get('ignorews') == '1' - line_context = request.GET.get('context', 3) - def wrap_to_table(str): - return ''' - - - - -
%s
''' % str + c.anchor_url = anchor_url + c.ignorews_url = _ignorews_url + c.context_url = _context_url #get ranges of revisions if preset rev_range = revision.split('...')[:2] @@ -130,10 +223,13 @@ class ChangesetController(BaseRepoContro # added nodes and their size defines how many changes were # made c.sum_added += node.size + fid = h.FID(revision, node.path) + line_context_lcl = get_line_ctx(fid, request.GET) + ignore_whitespace_lcl = get_ignore_ws(fid, request.GET) if c.sum_added < self.cut_off_limit: f_gitdiff = diffs.get_gitdiff(filenode_old, node, - ignore_whitespace=ignore_whitespace, - context=line_context) + ignore_whitespace=ignore_whitespace_lcl, + context=line_context_lcl) d = diffs.DiffProcessor(f_gitdiff, format='gitdiff') st = d.stat() @@ -171,9 +267,12 @@ class ChangesetController(BaseRepoContro else: if c.sum_removed < self.cut_off_limit: + fid = h.FID(revision, node.path) + line_context_lcl = get_line_ctx(fid, request.GET) + ignore_whitespace_lcl = get_ignore_ws(fid, request.GET,) f_gitdiff = diffs.get_gitdiff(filenode_old, node, - ignore_whitespace=ignore_whitespace, - context=line_context) + ignore_whitespace=ignore_whitespace_lcl, + context=line_context_lcl) d = diffs.DiffProcessor(f_gitdiff, format='gitdiff') st = d.stat() diff --git a/rhodecode/lib/helpers.py b/rhodecode/lib/helpers.py --- a/rhodecode/lib/helpers.py +++ b/rhodecode/lib/helpers.py @@ -52,6 +52,17 @@ def _reset(name, value=None, id=NotGiven reset = _reset safeid = _make_safe_id_component + +def FID(raw_id,path): + """ + Creates a uniqe ID for filenode based on it's path and revision + + :param raw_id: + :param path: + """ + return 'C-%s-%s' % (short_id(raw_id), safeid(safe_unicode(path))) + + def get_token(): """Return the current authentication token, creating one if one doesn't already exist. diff --git a/rhodecode/public/css/style.css b/rhodecode/public/css/style.css --- a/rhodecode/public/css/style.css +++ b/rhodecode/public/css/style.css @@ -1890,7 +1890,9 @@ h3.files_location { color: #556CB5; white-space: pre-wrap; } - +#changeset_content .container .left .message a:hover { + text-decoration: none; +} .cs_files .cur_cs { margin: 10px 2px; font-weight: bold; @@ -2254,7 +2256,7 @@ table.code-browser .browser-file { float: left; } -.diffblock .changeset_header .diff-menu{ +.diffblock .diff-menu{ position: absolute; background: none repeat scroll 0 0 #FFFFFF; border-color: #003367 #666666 #666666; @@ -2267,14 +2269,14 @@ table.code-browser .browser-file { } -.diffblock .changeset_header .diff-menu ul li { +.diffblock .diff-menu ul li { padding: 0px 0px 0px 0px !important; } -.diffblock .changeset_header .diff-menu ul li a{ +.diffblock .diff-menu ul li a{ display: block; padding: 3px 8px 3px 8px !important; } -.diffblock .changeset_header .diff-menu ul li a:hover{ +.diffblock .diff-menu ul li a:hover{ text-decoration: none; background-color: #EEEEEE; } @@ -3689,6 +3691,11 @@ div.diffblock .code-header{ border-bottom: 1px solid #CCCCCC; background: #EEEEEE; padding:10px 0 10px 0; + height: 14px; +} +div.diffblock .code-header .date{ + float:left; + text-transform: uppercase; } div.diffblock .code-header div{ margin-left:4px; diff --git a/rhodecode/templates/changeset/changeset.html b/rhodecode/templates/changeset/changeset.html --- a/rhodecode/templates/changeset/changeset.html +++ b/rhodecode/templates/changeset/changeset.html @@ -18,12 +18,6 @@ ${self.menu('changelog')} -<%def name="fid(raw_id,path)" filter="strip"> - <% - return 'C-%s-%s' % (h.short_id(raw_id),h.safeid(h.safe_unicode(path))) - %> - - <%def name="main()">
@@ -33,19 +27,24 @@
-
- ${h.link_to(_('raw diff'), - h.url('raw_changeset_home',repo_name=c.repo_name,revision=c.changeset.raw_id,diff='show'))} - » ${h.link_to(_('download diff'), - h.url('raw_changeset_home',repo_name=c.repo_name,revision=c.changeset.raw_id,diff='download'))} -
${len(c.comments)} comment(s) (${c.inline_cnt} ${_('inline')})
-
+
${_('commit')} ${c.changeset.revision}:${h.short_id(c.changeset.raw_id)} ${c.changeset.date}
+
+ diff-menu + +
+
${len(c.comments)} comment(s) (${c.inline_cnt} ${_('inline')})
-
${_('commit')} ${c.changeset.revision}: ${h.short_id(c.changeset.raw_id)}@${c.changeset.date}
gravatar @@ -100,9 +99,9 @@
%if change != 'removed': - ${h.link_to(h.safe_unicode(filenode.path),h.url.current(anchor=self.fid(filenode.changeset.raw_id,filenode.path)))} + ${h.link_to(h.safe_unicode(filenode.path),c.anchor_url(filenode.changeset.raw_id,filenode.path))} %else: - ${h.link_to(h.safe_unicode(filenode.path),h.url.current(anchor=self.fid('',filenode.path)))} + ${h.link_to(h.safe_unicode(filenode.path),h.url.current(anchor=h.FID('',filenode.path)))} %endif
${h.fancy_file_stats(stat)}
@@ -118,8 +117,8 @@ %for change,filenode,diff,cs1,cs2,stat in c.changes: %if change !='removed': -
-
+
+
@@ -133,13 +132,15 @@
  • ${h.link_to(_('diff'),h.url('files_diff_home',repo_name=c.repo_name,f_path=h.safe_unicode(filenode.path),diff2=cs2,diff1=cs1,diff='diff'))}
  • ${h.link_to(_('raw diff'),h.url('files_diff_home',repo_name=c.repo_name,f_path=h.safe_unicode(filenode.path),diff2=cs2,diff1=cs1,diff='raw'))}
  • ${h.link_to(_('download diff'),h.url('files_diff_home',repo_name=c.repo_name,f_path=h.safe_unicode(filenode.path),diff2=cs2,diff1=cs1,diff='download'))}
  • +
  • ${c.ignorews_url(h.FID(filenode.changeset.raw_id,filenode.path))}
  • +
  • ${c.context_url(h.FID(filenode.changeset.raw_id,filenode.path))}
  • @@ -164,7 +165,7 @@
    ${len(c.comments)} comment(s) (${c.inline_cnt} ${_('inline')})
    %for path, lines in c.inline_comments: -