[tui,qt] Allow overriding ``maxfilesize`` config value in the UIs (closes #20597)

error while publishing ReST text :config: ``maxfilesize`` now accept negative values which means that all file are handled (not "file too big" anymore) :qt: add an action to toggle displaying big files in the diff toolbar and in the right click menu on file source area :tui: add a command ``set-max-file-size`` which allow to change the the ``maxfilesize`` config value.
authorAlain Leufroy <alain.leufroy@logilab.fr>
changeseta1a6e6e07459
branchdefault
phasepublic
hiddenno
parent revision#33d2b342c3a2 [tui] set attribute '_walker' to RepoViewer (closes #98686)
child revision#6770df1b686a [install] improve setup.py
files modified by this revision
hgviewlib/config.py
hgviewlib/curses/hgrepoviewer.py
hgviewlib/hggraph.py
hgviewlib/qt4/hgfileview.py
hgviewlib/qt4/hgqv.qrc
hgviewlib/qt4/hgrepoviewer.py
hgviewlib/qt4/icons/README
hgviewlib/qt4/icons/heavy.png
# HG changeset patch
# User Alain Leufroy <alain.leufroy@logilab.fr>
# Date 1340035620 -7200
# Mon Jun 18 18:07:00 2012 +0200
# Node ID a1a6e6e07459a759f387226139fdb2697d43f36f
# Parent 33d2b342c3a2752f4fe1671e7764b9dea45b09f3
[tui,qt] Allow overriding ``maxfilesize`` config value in the UIs (closes #20597)

:config: ``maxfilesize`` now accept negative values which means
that all file are handled (not "file too big" anymore)

:qt: add an action to toggle displaying big files
in the diff toolbar and in the right click menu on file source area

:tui: add a command ``set-max-file-size`` which allow to change the
the ``maxfilesize`` config value.

diff --git a/hgviewlib/config.py b/hgviewlib/config.py
@@ -227,11 +227,12 @@
1          return val.lower() in ['true', 'yes', '1', 'on']
2 
3      @cached
4      def getMaxFileSize(self, default=100000):
5          """
6 -        maxfilesize: max size of a file (for diff computations, display content, etc.)
7 +        maxfilesize: max size of a file for diff computations, display content, etc.
8 +                     (-1 means no max size)
9          """
10          return int(self._fromconfig('maxfilesize', default))
11 
12      @cached
13      def getDiffBGColor(self, default='black'):
diff --git a/hgviewlib/curses/hgrepoviewer.py b/hgviewlib/curses/hgrepoviewer.py
@@ -158,10 +158,13 @@
14  class ContextViewer(Columns):
15      """Context viewer (manifest and source)"""
16      signals = ['update source title']
17      MANIFEST_SIZE = 0.3
18      def __init__(self, walker, *args, **kwargs):
19 +        self._walker = walker
20 +        self._filename = None
21 +        self.cfg = HgConfig(walker.repo.ui)
22          self.manifest = ManifestViewer(walker=walker, ctx=None)
23          self.manifest_walker = self.manifest.manifest_walker
24          self.source = SourceViewer('')
25          self.source_text = self.source.text
26          self._source_title_cache = ''
@@ -177,10 +180,26 @@
27                                 self.update_source)
28          signals.connect_signal(self, 'update source title',
29                                 self.update_source_title_cache)
30          signals.connect_signal(self.source, 'translated', self.update_source_title)
31 
32 +    def register_commands(self):
33 +        """Register commands and commands of bodies"""
34 +        register_command('set-max-file-size',
35 +                         'max size of handled file for diff computation, and so on.',
36 +                         CA('size', int, 'octets (-1 means no max size)'))
37 +        connect_command('set-max-file-size', self.modify_max_file_size)
38 +
39 +    def unregister_commands(self):
40 +        """Unregister commands and commands of bodies"""
41 +        unregister_command('set-max-file-size')
42 +
43 +    def modify_max_file_size(self, size):
44 +        """Modify the max handled file size and update the source content."""
45 +        self._walker.graph.maxfilesize = size
46 +        self.update_source(self._filename)
47 +
48      def update_source_title_cache(self, filename, flag):
49          """
50          Display information about the file in the title of the source body.
51          """
52          ctx = self.manifest_walker.ctx
@@ -209,10 +228,11 @@
53      def update_source(self, filename):
54          """Update the source content."""
55          ctx = self.manifest_walker.ctx
56          if ctx is None:
57              return
58 +        self._filename = filename
59          numbering = False
60          flag = ''
61          if filename is None: # source content is the changeset description
62              wrap = 'space' # Do not cut description and wrap content
63              data = ctx.description()
@@ -311,18 +331,20 @@
64          register_command('show-context', 'Show context pane.',
65                           CA('height', float,
66                           'Relative height [0-1] of the context pane.'))
67          register_command('maximize-context', 'Maximize context pane.')
68          self.graphlog.register_commands()
69 +        self.context.register_commands()
70          connect_command('hide-context', self.hide_context)
71          connect_command('show-context', self.show_context)
72          connect_command('maximize-context', self.maximize_context)
73          connect_command('refresh', self.refresh)
74 
75      def unregister_commands(self):
76          """Unregister commands and commands of bodies"""
77          self.graphlog.unregister_commands()
78 +        self.context.unregister_commands()
79 
80      def refresh(self):
81          graphlog_walker = self.graphlog.graphlog_walker
82          manifest_walker = self.context.manifest_walker
83          self.refreshing = True
diff --git a/hgviewlib/hggraph.py b/hgviewlib/hggraph.py
@@ -471,22 +471,28 @@
84          try:
85              fctx = ctx.filectx(filename)
86              filesize = fctx.size() # compute size here to lookup data securely
87          except (LookupError, OSError):
88              fctx = None # may happen for renamed/removed files or mq patch ?
89 -
90          if isbfile(filename):
91              data = "[bfile]\n"
92              if fctx:
93                  data = fctx.data()
94                  data += "footprint: %s\n" % data
95              return "+", data
96          if flag not in ('-', '?'):
97              if fctx is None:# or fctx.node() is None:
98                  return '', None
99 -            if filesize > self.maxfilesize:
100 -                data = "file too big"
101 +            if self.maxfilesize >= 0 and filesize > self.maxfilesize:
102 +                try:
103 +                    div = int(filesize).bit_length() // 10
104 +                    sym = ('', 'K', 'M', 'G', 'T', 'E')[div] # more, really ???
105 +                    val = int(filesize / (2 ** (div * 10)))
106 +                except AttributeError: # py<2.7
107 +                    val = filesize
108 +                    sym = ''
109 +                data = "File too big ! (~%i%so)" % (val, sym)
110                  return flag, data
111              if flag == "+" or mode == 'file':
112                  flag = '+'
113                  # return the whole file
114                  data = fctx.data()
diff --git a/hgviewlib/qt4/hgfileview.py b/hgviewlib/qt4/hgfileview.py
@@ -105,10 +105,15 @@
115               self.tr('Anable/Disable Annotatte mode'), None, None),
116              ("next", self.tr('Next hunk'), 'down', self.tr('Jump to the next hunk'),
117               Qt.ALT + Qt.Key_Down, None),
118              ("prev", self.tr('Prior hunk'), 'up', self.tr('Jump to the previous hunk'),
119               Qt.ALT + Qt.Key_Up, None),
120 +            ("show-big-file", self.tr('Display heavy file'), 'heavy',
121 +             self.tr('Display file Content even if it is marked as too big'
122 +                     '[config: maxfilesize]'),
123 +             None, None),
124 +
125          ]
126 
127      def createActions(self):
128          self._actions = {}
129          for name, desc, icon, tip, key, cb in self._action_defs():
@@ -123,14 +128,16 @@
130                  connect(act, SIGNAL('triggered()'), cb)
131              self._actions[name] = act
132              self.addAction(act)
133          self._actions['diffmode'].setCheckable(True)
134          self._actions['annmode'].setCheckable(True)
135 +        self._actions['show-big-file'].setCheckable(True)
136 
137      def contextMenuEvent(self, event):
138 -        menu = self.createStandardContextMenu()
139 -        for act in [None, 'diffmode', 'prev', 'next']:
140 +        menu = QtGui.QMenu(self)
141 +        for act in [None, 'diffmode', 'prev', 'next',
142 +                    None, 'show-big-file']:
143              if act:
144                  menu.addAction(self._actions[act])
145              else:
146                  menu.addSeparator()
147          menu.exec_(event.globalPos())
@@ -234,18 +241,30 @@
148                       self.setAnnotate)
149          self.connect(self.sci._actions['prev'], SIGNAL('triggered()'),
150                       self.prevDiff)
151          self.connect(self.sci._actions['next'], SIGNAL('triggered()'),
152                       self.nextDiff)
153 +        self.connect(self.sci._actions['show-big-file'], SIGNAL('toggled(bool)'),
154 +                     self.showBigFile)
155          self.sci._actions['diffmode'].setChecked(True)
156 
157      def resizeEvent(self, event):
158          QtGui.QFrame.resizeEvent(self, event)
159          h = self.sci.horizontalScrollBar().height()
160          self._spacer.setMinimumHeight(h)
161          self._spacer.setMaximumHeight(h)
162 
163 +    def showBigFile(self, state):
164 +        """Force displaying the content related to a file considered previously as
165 +        too big.
166 +        """
167 +        if not state:
168 +            self._model.graph.maxfilesize = self.cfg.getMaxFileSize()
169 +        else:
170 +            self._model.graph.maxfilesize = -1
171 +        self.displayFile()
172 +
173      def setMode(self, mode):
174          if isinstance(mode, bool):
175              mode = ['file', 'diff'][mode]
176          assert mode in ('diff', 'file')
177 
@@ -265,10 +284,12 @@
178              self.displayFile()
179 
180      def setModel(self, model):
181          # XXX we really need only the "Graph" instance
182          self._model = model
183 +        self.cfg = HgConfig(self._model.repo.ui)
184 +        self.sci._actions['show-big-file'].setChecked(self._model.graph.maxfilesize < 0)
185          self.sci.clear()
186 
187      def setContext(self, ctx):
188          self._ctx = ctx
189          self._p_rev = None
@@ -316,12 +337,11 @@
190          if flag == '-':
191              return
192          if flag == '':
193              return
194 
195 -        cfg = HgConfig(self._model.repo.ui)
196 -        lexer = get_lexer(filename, data, flag, cfg)
197 +        lexer = get_lexer(filename, data, flag, self.cfg)
198          if flag == "+":
199              nlines = data.count('\n')
200              self.sci.setMarginWidth(1, str(nlines)+'0')
201          self.sci.setLexer(lexer)
202          self._cur_lexer = lexer
diff --git a/hgviewlib/qt4/hgqv.qrc b/hgviewlib/qt4/hgqv.qrc
@@ -21,7 +21,8 @@
203      <file>icons/mqpatch_x.svg</file>
204      <file>icons/showhide.png</file>
205      <file>icons/content.png</file>
206      <file>icons/unfilter.png</file>
207      <file>icons/diffmode.png</file>
208 +    <file>icons/heavy.png</file>
209    </qresource>
210  </RCC>
diff --git a/hgviewlib/qt4/hgrepoviewer.py b/hgviewlib/qt4/hgrepoviewer.py
@@ -194,11 +194,11 @@
211          self.startrev_label_action = self.toolBar_treefilters.addWidget(self.startrev_label)
212          self.startrev_entry_action = self.toolBar_treefilters.addWidget(self.startrev_entry)
213 
214          # diff mode toolbar
215          actions = self.textview_status.sci._actions
216 -        for action_name in ('diffmode', 'prev', 'next'):
217 +        for action_name in ('diffmode', 'prev', 'next', 'show-big-file'):
218              self.toolBar_diff.addAction(actions[action_name])
219          self.toolBar_diff.setVisible(self.cfg.getToolBarDiffAtStartup())
220 
221          # rev mod toolbar
222          if self.textview_header.rst_action is not None:
diff --git a/hgviewlib/qt4/icons/README b/hgviewlib/qt4/icons/README
@@ -1,6 +1,7 @@
223  Most of the icons used here are from the Tango Icon Theme. Some of them have been modified.
224 
225  showhide.png: Gnome Project (GPL) [http://art.gnome.org/themes/icon]
226  content.png: by PC (Creative Common v3) [http://www.iconfinder.com/icondetails/59552/32/cv_icon]
227  diffmode.png: by FatCow (Creative Common v3) [http://www.fatcow.com/free-icons]
228 -unfilter.png: Everaldo Coelho (GPL) [http://www.veryicon.com/icons/system/crystal-clear-actions/]
229 \ No newline at end of file
230 +unfilter.png: Everaldo Coelho (GPL) [http://www.veryicon.com/icons/system/crystal-clear-actions/]
231 +heavy.png: Everaldo Coelho (GPL) [http://www.iconfinder.com/icondetails/15543/128/animation_fat_run_icon]
232 \ No newline at end of file
diff --git a/hgviewlib/qt4/icons/heavy.png b/hgviewlib/qt4/icons/heavy.png