[qt4] sourceviewer: fix font + factorize lexer selection
authoralain leufroy <alain@leufroy.fr>
Wed, 25 Sep 2013 10:05:34 +0200
changeset 1564 513355b23047
parent 1563 98b7c56a9611
child 1565 56e30650ac16
[qt4] sourceviewer: fix font + factorize lexer selection This patch mainly contains some factorisations to simplify code. I've also fixed a small but annoying bug spourious font fammily changes of line numbers. .. note:: This change removes a small optimization that sometimes computes the lexer only once. We now compute the lexer when a new content is given. This is not a very big deal because finding the lexer from the filename - most often case - is very quick.
hgviewlib/qt4/config.py
hgviewlib/qt4/hgfiledialog.py
hgviewlib/qt4/hgfileview.py
hgviewlib/qt4/hgmanifestdialog.py
hgviewlib/qt4/mixins.py
hgviewlib/qt4/widgets.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hgviewlib/qt4/config.py	Wed Sep 25 10:05:34 2013 +0200
@@ -0,0 +1,38 @@
+# -*- coding: utf-8 -*-
+# Copyright (c) 2013 LOGILAB S.A. (Paris, FRANCE).
+# http://www.logilab.fr/ -- mailto:contact@logilab.fr
+#
+# This program 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.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program.  If not, see <http://www.gnu.org/licenses/>.
+
+#
+# make sure the Qt rc files are converted into python modules, then load them
+# this must be done BEFORE other hgview qt4 modules are loaded.
+"""This module contains qt4 specific function for hgview configuration."""
+from PyQt4.QtGui import QFont
+
+def get_font(cfg):
+    """Return a QFont instance initialized using parameters of the hgview
+    configuration ``cfg``"""
+    fontstr = cfg.getFont()
+    fontsize = cfg.getFontSize()
+    font = QFont()
+    try:
+        if not repr(font.fromString(fontstr)):
+            raise Exception
+        font.setPointSize(fontsize)
+    except:
+        print "bad font name '%s'" % fontstr
+        font.setFamily("Monospace")
+        font.setFixedPitch(True)
+        font.setPointSize(10)
+    return font
--- a/hgviewlib/qt4/hgfiledialog.py	Sat Sep 14 16:55:25 2013 +0200
+++ b/hgviewlib/qt4/hgfiledialog.py	Wed Sep 25 10:05:34 2013 +0200
@@ -35,7 +35,6 @@
 from hgviewlib.qt4.mixins import HgDialogMixin, ActionsMixin, ui2cls
 from hgviewlib.qt4.hgrepomodel import FileRevModel
 from hgviewlib.qt4.blockmatcher import BlockList, BlockMatch
-from hgviewlib.qt4.lexers import get_lexer
 from hgviewlib.qt4.quickbar import FindInGraphlogQuickBar
 from hgviewlib.qt4.widgets import SourceViewer
 
@@ -54,7 +53,6 @@
         self._show_rev = None
 
         self.filename = filename
-        self.findLexer()
 
         self.createActions()
         self.setupToolbars()
@@ -71,20 +69,6 @@
         self.repo = util.build_repo(self.repo.ui, self.repo.root)
         self.setupModels()
 
-    def findLexer(self):
-        # try to find a lexer for our file.
-        f = self.repo.file(self.filename)
-        head = f.heads()[0]
-        if f.size(f.rev(head)) < 1e6:
-            data = f.read(head)
-        else:
-            data = '' # too big
-        lexer = get_lexer(self.filename, data)
-        if lexer:
-            lexer.setDefaultFont(self._font)
-            lexer.setFont(self._font)
-        self.lexer = lexer
-
     def modelFilled(self):
         self.filerevmodel.filled.disconnect(self.modelFilled)
         if isinstance(self._show_rev, int):
@@ -265,8 +249,6 @@
             textview.verticalScrollBar().setFocusPolicy(Qt.StrongFocus)
             textview.setFocusProxy(textview.verticalScrollBar())
             textview.verticalScrollBar().installEventFilter(self)
-            if self.lexer:
-                textview.setLexer(self.lexer)
 
             lay.addWidget(textview)
 
@@ -482,7 +464,10 @@
             self._diffmatch = {'left': [x[1:3] for x in blocks],
                                'right': [x[3:5] for x in blocks]}
             for side in sides:
-                self.viewers[side].setText('\n'.join(self.filedata[side]))
+                self.viewers[side].set_text(self.filename,
+                                            '\n'.join(self.filedata[side]),
+                                            flag='+',
+                                            cfg=self.cfg)
             self.update_page_steps(keeppos)
             self.timer.start()
 
--- a/hgviewlib/qt4/hgfileview.py	Sat Sep 14 16:55:25 2013 +0200
+++ b/hgviewlib/qt4/hgfileview.py	Wed Sep 25 10:05:34 2013 +0200
@@ -35,7 +35,7 @@
 from hgviewlib.config import HgConfig
 
 from hgviewlib.qt4.mixins import ActionsMixin
-from hgviewlib.qt4.lexers import get_lexer
+from hgviewlib.qt4.config import get_font
 from hgviewlib.qt4.blockmatcher import BlockList
 from hgviewlib.qt4.widgets import SourceViewer, Annotator
 
@@ -247,6 +247,7 @@
         self.sci.set_action('show-big-file', checked=is_show_big_file)
         self.sci.set_action('ignorews',
                             checked=model.repo.ui.configbool('diff', 'ignorews'))
+        self.sci.setFont(get_font(self.cfg))
         self.sci.clear()
 
     def setContext(self, ctx):
@@ -317,20 +318,14 @@
             return
         self.sci.toggle_openexternal(status=True)
 
-        lexer = get_lexer(filename, data, flag, self.cfg)
-        if flag == "+":
-            nlines = data.count('\n')
-            self.sci.setMarginWidth(1, str(nlines)+'0')
-        self.sci.setLexer(lexer)
-        self._cur_lexer = lexer
         if data not in (u'file too big', u'binary file'):
             self.filedata = data
         else:
             self.filedata = None
 
-        flag = exec_flag_changed(filectx)
-        if flag:
-            self.execflaglabel.setText(u"<b>exec mode has been <font color='red'>%s</font></b>" % flag)
+        exec_flag = exec_flag_changed(filectx)
+        if exec_flag:
+            self.execflaglabel.setText(u"<b>exec mode has been <font color='red'>%s</font></b>" % exec_flag)
             self.execflaglabel.show()
         else:
             self.execflaglabel.hide()
@@ -347,7 +342,7 @@
             labeltxt += u' <i>(renamed from %s)</i>' % tounicode(bfilepath(renamed[0]))
         self.filenamelabel.setText(labeltxt)
 
-        self.sci.setText(data)
+        self.sci.set_text(filename, data, flag, self.cfg)
         if self._find_text:
             self.highlightSearchString(self._find_text)
         self.sci.set_action('prev', enabled=False)
@@ -357,10 +352,7 @@
                 self.ann.setVisible(False)
             else:
                 self.ann.setVisible(self._annotate)
-                if lexer is not None:
-                    self.ann.setFont(lexer.font(0))
-                else:
-                    self.ann.setFont(self.sci.font())
+                self.ann.setFont(self.sci.font())
                 self.ann.set_line_ticks([str(f.rev()) for f, __ in filectx.annotate(follow=True)])
         return True
 
--- a/hgviewlib/qt4/hgmanifestdialog.py	Sat Sep 14 16:55:25 2013 +0200
+++ b/hgviewlib/qt4/hgmanifestdialog.py	Wed Sep 25 10:05:34 2013 +0200
@@ -32,7 +32,6 @@
 from hgviewlib.qt4 import icon as geticon
 from hgviewlib.qt4.mixins import HgDialogMixin, ActionsMixin, ui2cls
 from hgviewlib.qt4.hgrepomodel import ManifestModel
-from hgviewlib.qt4.lexers import get_lexer
 from hgviewlib.qt4.widgets import SourceViewer
 
 class ManifestViewer(ActionsMixin, HgDialogMixin, ui2cls('manifestviewer.ui'), QtGui.QMainWindow, _ManifestViewer):
@@ -76,6 +75,7 @@
         lay.setSpacing(0)
         lay.setContentsMargins(0,0,0,0)
         self.textView = SourceViewer(self.mainFrame)
+        self.setFont(self._font)
         lay.addWidget(self.textView)
 
     def fileSelected(self, index, *args):
@@ -99,14 +99,7 @@
                 data = u"binary file"
             else:
                 data = tounicode(data)
-                lexer = get_lexer(path, data)
-                if lexer:
-                    lexer.setFont(self._font)
-                    self.textView.setLexer(lexer)
-                self._cur_lexer = lexer
-        nlines = data.count('\n')
-        self.textView.setMarginWidth(1, str(nlines)+'00')
-        self.textView.setText(data)
+        self.textView.set_text(path, data, flag='+', cfg=self.cfg)
 
     def setCurrentFile(self, filename):
         index = QtCore.QModelIndex()
--- a/hgviewlib/qt4/mixins.py	Sat Sep 14 16:55:25 2013 +0200
+++ b/hgviewlib/qt4/mixins.py	Wed Sep 25 10:05:34 2013 +0200
@@ -23,11 +23,12 @@
 
 from PyQt4 import uic
 from PyQt4.QtCore import QTimer, Qt
-from PyQt4.QtGui import QAction, QActionGroup, QMenu, QShortcut, QFont
+from PyQt4.QtGui import QAction, QActionGroup, QMenu, QShortcut
 
 from hgviewlib.config import HgConfig
 from hgviewlib.qt4 import should_rebuild
 from hgviewlib.qt4 import icon as geticon
+from hgviewlib.qt4.config import get_font
 
 class ActionsMixin(object):
     """
@@ -191,6 +192,10 @@
     preferences.
     The main class must define a '_uifile' class attribute.
     """
+    def __init__(self, *args, **kwargs):
+        self._cfg = None
+        self._font = None
+        super(HgDialogMixin, self).__init__(*args, **kwargs)
 
     def load_ui(self):
         self.setupUi(self)
@@ -230,18 +235,7 @@
 
     def load_config(self, repo):
         self.cfg = HgConfig(repo.ui)
-        fontstr = self.cfg.getFont()
-        font = QFont()
-        try:
-            if not font.fromString(fontstr):
-                raise Exception
-        except:
-            print "bad font name '%s'" % fontstr
-            font.setFamily("Monospace")
-            font.setFixedPitch(True)
-            font.setPointSize(10)
-        self._font = font
-
+        self._font = get_font(self.cfg)
         self.rowheight = self.cfg.getRowHeight()
         self.users, self.aliases = self.cfg.getUsers()
 
--- a/hgviewlib/qt4/widgets.py	Sat Sep 14 16:55:25 2013 +0200
+++ b/hgviewlib/qt4/widgets.py	Wed Sep 25 10:05:34 2013 +0200
@@ -25,6 +25,7 @@
 from hgviewlib.util import tounicode
 from hgviewlib.qt4 import icon as geticon
 from hgviewlib.qt4.styleditemdelegate import StyledItemDelegate
+from hgviewlib.qt4.lexers import get_lexer
 
 class StyledTableView(QTableView):
     """An Abstract QTableView with some Columns rendered with css. """
@@ -220,7 +221,6 @@
         self.setFrameStyle(0)
         self.setFrameShape(QFrame.NoFrame)
 
-
         self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
         self.setReadOnly(True)
 
@@ -278,3 +278,12 @@
             self.SendScintilla(qsci.SCI_INDICATORFILLRANGE, pos[-1], n)
             pos.append(data.find(text, pos[-1]+1))
         return [x for x in pos if x > -1]
+
+    def set_text(self, filename, data, flag=None, cfg=None):
+        lexer = get_lexer(filename, data, flag, cfg)
+        if lexer:
+            # lexer.setFont(self.font())
+            self.setLexer(lexer)
+        nlines = data.count('\n')
+        self.setMarginWidth(1, str(nlines)+'00')
+        self.setText(data)