ViewManager/ViewManager.py

changeset 2424
8fe1fdc174ab
parent 2415
814c66cb0746
child 2474
8727522a69d5
equal deleted inserted replaced
2423:bf4e888d72ab 2424:8fe1fdc174ab
6 """ 6 """
7 Module implementing the viewmanager base class. 7 Module implementing the viewmanager base class.
8 """ 8 """
9 9
10 import os 10 import os
11 import re
12 11
13 from PyQt4.QtCore import QSignalMapper, QTimer, QFileInfo, pyqtSignal, QRegExp, \ 12 from PyQt4.QtCore import QSignalMapper, QTimer, QFileInfo, pyqtSignal, QRegExp, \
14 QObject, Qt, QUrl 13 QObject, Qt
15 from PyQt4.QtGui import QColor, QKeySequence, QLineEdit, QToolBar, QWidgetAction, \ 14 from PyQt4.QtGui import QColor, QKeySequence, QLineEdit, QToolBar, QWidgetAction, \
16 QDialog, QApplication, QMenu, QPalette, QComboBox, QPixmap 15 QDialog, QApplication, QMenu, QPalette, QComboBox, QPixmap
17 from PyQt4.Qsci import QsciScintilla 16 from PyQt4.Qsci import QsciScintilla
18 17
19 from E5Gui.E5Application import e5App 18 from E5Gui.E5Application import e5App
88 Base class inherited by all specific viewmanager classes. 87 Base class inherited by all specific viewmanager classes.
89 88
90 It defines the interface to be implemented by specific 89 It defines the interface to be implemented by specific
91 viewmanager classes and all common methods. 90 viewmanager classes and all common methods.
92 91
92 @signal changeCaption(str) emitted if a change of the caption is necessary
93 @signal editorChanged(str) emitted when the current editor has changed
94 @signal editorChangedEd(Editor) emitted when the current editor has changed
93 @signal lastEditorClosed() emitted after the last editor window was closed 95 @signal lastEditorClosed() emitted after the last editor window was closed
94 @signal editorOpened(str) emitted after an editor window was opened 96 @signal editorOpened(str) emitted after an editor window was opened
95 @signal editorOpenedEd(Editor) emitted after an editor window was opened 97 @signal editorOpenedEd(Editor) emitted after an editor window was opened
96 @signal editorClosed(str) emitted just before an editor window gets closed 98 @signal editorClosed(str) emitted just before an editor window gets closed
97 @signal editorClosedEd(Editor) emitted just before an editor window gets closed 99 @signal editorClosedEd(Editor) emitted just before an editor window gets closed
98 @signal editorSaved(str) emitted after an editor window was saved 100 @signal editorSaved(str) emitted after an editor window was saved
99 @signal checkActions(Editor) emitted when some actions should be checked 101 @signal checkActions(Editor) emitted when some actions should be checked
100 for their status 102 for their status
101 @signal cursorChanged(Editor) emitted after the cursor position of the active 103 @signal cursorChanged(Editor) emitted after the cursor position of the active
102 window has changed 104 window has changed
103 @signal breakpointToggled(Editor) emitted when a breakpoint is toggled. 105 @signal breakpointToggled(Editor) emitted when a breakpoint is toggled
104 @signal bookmarkToggled(Editor) emitted when a bookmark is toggled. 106 @signal bookmarkToggled(Editor) emitted when a bookmark is toggled
107 @signal syntaxerrorToggled(Editor) emitted when a syntax error is toggled
108 @signal previewStateChanged(bool) emitted to signal a change in the preview state
109 @signal editorLanguageChanged(Editor) emitted to signal a change of an
110 editor's language
111 @signal editorTextChanged(Editor) emitted to signal a change of an editor's text
105 """ 112 """
113 changeCaption = pyqtSignal(str)
114 editorChanged = pyqtSignal(str)
115 editorChangedEd = pyqtSignal(Editor)
106 lastEditorClosed = pyqtSignal() 116 lastEditorClosed = pyqtSignal()
107 editorOpened = pyqtSignal(str) 117 editorOpened = pyqtSignal(str)
108 editorOpenedEd = pyqtSignal(Editor) 118 editorOpenedEd = pyqtSignal(Editor)
109 editorClosed = pyqtSignal(str) 119 editorClosed = pyqtSignal(str)
110 editorClosedEd = pyqtSignal(Editor) 120 editorClosedEd = pyqtSignal(Editor)
112 checkActions = pyqtSignal(Editor) 122 checkActions = pyqtSignal(Editor)
113 cursorChanged = pyqtSignal(Editor) 123 cursorChanged = pyqtSignal(Editor)
114 breakpointToggled = pyqtSignal(Editor) 124 breakpointToggled = pyqtSignal(Editor)
115 bookmarkToggled = pyqtSignal(Editor) 125 bookmarkToggled = pyqtSignal(Editor)
116 syntaxerrorToggled = pyqtSignal(Editor) 126 syntaxerrorToggled = pyqtSignal(Editor)
127 previewStateChanged = pyqtSignal(bool)
128 editorLanguageChanged = pyqtSignal(Editor)
129 editorTextChanged = pyqtSignal(Editor)
117 130
118 def __init__(self): 131 def __init__(self):
119 """ 132 """
120 Constructor 133 Constructor
121 """ 134 """
3036 3049
3037 self.previewAct = E5Action(QApplication.translate('ViewManager', 3050 self.previewAct = E5Action(QApplication.translate('ViewManager',
3038 'Preview'), 3051 'Preview'),
3039 UI.PixmapCache.getIcon("previewer.png"), 3052 UI.PixmapCache.getIcon("previewer.png"),
3040 QApplication.translate('ViewManager', 'Preview'), 3053 QApplication.translate('ViewManager', 'Preview'),
3041 0, 0, self, 'vm_preview') 3054 0, 0, self, 'vm_preview', True)
3042 self.previewAct.setStatusTip(QApplication.translate('ViewManager', 3055 self.previewAct.setStatusTip(QApplication.translate('ViewManager',
3043 'Preview the current file in the web browser')) 3056 'Preview the current file in the web browser'))
3044 self.previewAct.setWhatsThis(QApplication.translate('ViewManager', 3057 self.previewAct.setWhatsThis(QApplication.translate('ViewManager',
3045 """<b>Preview</b>""" 3058 """<b>Preview</b>"""
3046 """<p>This opens the web browser with a preview of""" 3059 """<p>This opens the web browser with a preview of"""
3047 """ the current file.</p>""" 3060 """ the current file.</p>"""
3048 )) 3061 ))
3049 self.previewAct.triggered[()].connect(self.__previewEditor) 3062 self.previewAct.setChecked(Preferences.getUI("ShowFilePreview"))
3063 self.previewAct.toggled[bool].connect(self.__previewEditor)
3050 self.viewActions.append(self.previewAct) 3064 self.viewActions.append(self.previewAct)
3051 3065
3052 self.viewActGrp.setEnabled(False) 3066 self.viewActGrp.setEnabled(False)
3053 self.viewFoldActGrp.setEnabled(False) 3067 self.viewFoldActGrp.setEnabled(False)
3054 self.unhighlightAct.setEnabled(False) 3068 self.unhighlightAct.setEnabled(False)
3055 self.splitViewAct.setEnabled(False) 3069 self.splitViewAct.setEnabled(False)
3056 self.splitOrientationAct.setEnabled(False) 3070 self.splitOrientationAct.setEnabled(False)
3057 self.splitRemoveAct.setEnabled(False) 3071 self.splitRemoveAct.setEnabled(False)
3058 self.nextSplitAct.setEnabled(False) 3072 self.nextSplitAct.setEnabled(False)
3059 self.prevSplitAct.setEnabled(False) 3073 self.prevSplitAct.setEnabled(False)
3060 self.previewAct.setEnabled(False) 3074 self.previewAct.setEnabled(True)
3061 3075
3062 def initViewMenu(self): 3076 def initViewMenu(self):
3063 """ 3077 """
3064 Public method to create the View menu 3078 Public method to create the View menu
3065 3079
3561 'Automatic spell checking'), 3575 'Automatic spell checking'),
3562 UI.PixmapCache.getIcon("autospellchecking.png"), 3576 UI.PixmapCache.getIcon("autospellchecking.png"),
3563 QApplication.translate('ViewManager', 3577 QApplication.translate('ViewManager',
3564 '&Automatic spell checking'), 3578 '&Automatic spell checking'),
3565 0, 0, 3579 0, 0,
3566 self.spellingActGrp, 'vm_spelling_autospellcheck') 3580 self.spellingActGrp, 'vm_spelling_autospellcheck', True)
3567 self.autoSpellCheckAct.setStatusTip(QApplication.translate('ViewManager', 3581 self.autoSpellCheckAct.setStatusTip(QApplication.translate('ViewManager',
3568 '(De-)Activate automatic spell checking')) 3582 '(De-)Activate automatic spell checking'))
3569 self.autoSpellCheckAct.setWhatsThis(QApplication.translate('ViewManager', 3583 self.autoSpellCheckAct.setWhatsThis(QApplication.translate('ViewManager',
3570 """<b>Automatic spell checking</b>""" 3584 """<b>Automatic spell checking</b>"""
3571 """<p>Activate or deactivate the automatic spell checking function of""" 3585 """<p>Activate or deactivate the automatic spell checking function of"""
3572 """ all editors.</p>""" 3586 """ all editors.</p>"""
3573 )) 3587 ))
3574 self.autoSpellCheckAct.setCheckable(True)
3575 self.autoSpellCheckAct.setChecked( 3588 self.autoSpellCheckAct.setChecked(
3576 Preferences.getEditor("AutoSpellCheckingEnabled")) 3589 Preferences.getEditor("AutoSpellCheckingEnabled"))
3577 self.autoSpellCheckAct.triggered[()].connect(self.__setAutoSpellChecking) 3590 self.autoSpellCheckAct.triggered[()].connect(self.__setAutoSpellChecking)
3578 self.spellingActions.append(self.autoSpellCheckAct) 3591 self.spellingActions.append(self.autoSpellCheckAct)
3579 3592
3870 editor.selectionChanged.connect(self.__searchWidget.selectionChanged) 3883 editor.selectionChanged.connect(self.__searchWidget.selectionChanged)
3871 editor.selectionChanged.connect(self.__replaceWidget.selectionChanged) 3884 editor.selectionChanged.connect(self.__replaceWidget.selectionChanged)
3872 editor.lastEditPositionAvailable.connect(self.__lastEditPositionAvailable) 3885 editor.lastEditPositionAvailable.connect(self.__lastEditPositionAvailable)
3873 editor.zoomValueChanged.connect(self.zoomValueChanged) 3886 editor.zoomValueChanged.connect(self.zoomValueChanged)
3874 3887
3888 editor.languageChanged.connect(lambda: self.editorLanguageChanged.emit(editor))
3889 editor.textChanged.connect(lambda: self.editorTextChanged.emit(editor))
3890
3875 def newEditorView(self, fn, caller, filetype=""): 3891 def newEditorView(self, fn, caller, filetype=""):
3876 """ 3892 """
3877 Public method to create a new editor displaying the given document. 3893 Public method to create a new editor displaying the given document.
3878 3894
3879 @param fn filename of this view 3895 @param fn filename of this view
5131 self.splitViewAct.setIcon( 5147 self.splitViewAct.setIcon(
5132 UI.PixmapCache.getIcon("splitVertical.png")) 5148 UI.PixmapCache.getIcon("splitVertical.png"))
5133 self.splitRemoveAct.setIcon( 5149 self.splitRemoveAct.setIcon(
5134 UI.PixmapCache.getIcon("remsplitVertical.png")) 5150 UI.PixmapCache.getIcon("remsplitVertical.png"))
5135 5151
5136 def __previewEditor(self): 5152 def __previewEditor(self, checked):
5137 """ 5153 """
5138 Private method to preview the contents of the current editor in a web browser. 5154 Private slot to handle a change of the preview selection state.
5139 """ 5155
5140 aw = self.activeWindow() 5156 @param checked state of the action (boolean)
5141 if aw is not None and aw.isPreviewable(): 5157 """
5142 fn = aw.getFileName() 5158 Preferences.setUI("ShowFilePreview", checked)
5143 if fn: 5159 self.previewStateChanged.emit(checked)
5144 project = e5App().getObject("Project")
5145 if project.isProjectFile(fn):
5146 baseUrl = QUrl.fromLocalFile(project.getAbsoluteUniversalPath(fn))
5147 fullName = project.getAbsoluteUniversalPath(fn)
5148 rootPath = project.getProjectPath()
5149 else:
5150 baseUrl = QUrl.fromLocalFile(fn)
5151 fullName = fn
5152 rootPath = os.path.dirname(os.path.abspath(fn))
5153 else:
5154 baseUrl = QUrl()
5155 fullName = ""
5156 rootPath = ""
5157 txt = self.__processSSI(aw.text(), fullName, rootPath)
5158 previewer = self.ui.getHelpViewer(preview=True).previewer()
5159 previewer.setHtml(txt, baseUrl)
5160
5161 def __processSSI(self, txt, filename, root):
5162 """
5163 Private method to process the given text for SSI statements.
5164
5165 Note: Only a limited subset of SSI statements are supported.
5166
5167 @param txt text to be processed (string)
5168 @param filename name of the file associated with the given text (string)
5169 @param root directory of the document root (string)
5170 @return processed text (string)
5171 """
5172 if not filename:
5173 return txt
5174
5175 # SSI include
5176 incRe = re.compile(
5177 r"""<!--#include[ \t]+(virtual|file)=[\"']([^\"']+)[\"']\s*-->""",
5178 re.IGNORECASE)
5179 baseDir = os.path.dirname(os.path.abspath(filename))
5180 docRoot = root if root != "" else baseDir
5181 while True:
5182 incMatch = incRe.search(txt)
5183 if incMatch is None:
5184 break
5185
5186 if incMatch.group(1) == "virtual":
5187 incFile = Utilities.normjoinpath(docRoot, incMatch.group(2))
5188 elif incMatch.group(1) == "file":
5189 incFile = Utilities.normjoinpath(baseDir, incMatch.group(2))
5190 else:
5191 incFile = ""
5192 if os.path.exists(incFile):
5193 try:
5194 f = open(incFile, "r")
5195 incTxt = f.read()
5196 f.close()
5197 except (IOError, OSError):
5198 # remove SSI include
5199 incTxt = ""
5200 else:
5201 # remove SSI include
5202 incTxt = ""
5203 txt = txt[:incMatch.start(0)] + incTxt + txt[incMatch.end(0):]
5204
5205 return txt
5206 5160
5207 ################################################################## 5161 ##################################################################
5208 ## Below are the action methods for the macro menu 5162 ## Below are the action methods for the macro menu
5209 ################################################################## 5163 ##################################################################
5210 5164
5643 self.viewActGrp.setEnabled(False) 5597 self.viewActGrp.setEnabled(False)
5644 self.viewFoldActGrp.setEnabled(False) 5598 self.viewFoldActGrp.setEnabled(False)
5645 self.unhighlightAct.setEnabled(False) 5599 self.unhighlightAct.setEnabled(False)
5646 self.splitViewAct.setEnabled(False) 5600 self.splitViewAct.setEnabled(False)
5647 self.splitOrientationAct.setEnabled(False) 5601 self.splitOrientationAct.setEnabled(False)
5648 self.previewAct.setEnabled(False) 5602 self.previewAct.setEnabled(True)
5649 self.macroActGrp.setEnabled(False) 5603 self.macroActGrp.setEnabled(False)
5650 self.bookmarkActGrp.setEnabled(False) 5604 self.bookmarkActGrp.setEnabled(False)
5651 self.__enableSpellingActions() 5605 self.__enableSpellingActions()
5652 self.__setSbFile(zoom=0) 5606 self.__setSbFile(zoom=0)
5653 5607
5718 5672
5719 self.undoAct.setEnabled(editor.isUndoAvailable()) 5673 self.undoAct.setEnabled(editor.isUndoAvailable())
5720 self.redoAct.setEnabled(editor.isRedoAvailable()) 5674 self.redoAct.setEnabled(editor.isRedoAvailable())
5721 self.gotoLastEditAct.setEnabled(editor.isLastEditPositionAvailable()) 5675 self.gotoLastEditAct.setEnabled(editor.isLastEditPositionAvailable())
5722 5676
5723 self.previewAct.setEnabled(editor.isPreviewable()) 5677 ## self.previewAct.setEnabled(editor.isPreviewable())
5724 5678 ##
5725 lex = editor.getLexer() 5679 lex = editor.getLexer()
5726 if lex is not None: 5680 if lex is not None:
5727 self.commentAct.setEnabled(lex.canBlockComment()) 5681 self.commentAct.setEnabled(lex.canBlockComment())
5728 self.uncommentAct.setEnabled(lex.canBlockComment()) 5682 self.uncommentAct.setEnabled(lex.canBlockComment())
5729 self.streamCommentAct.setEnabled(lex.canStreamComment()) 5683 self.streamCommentAct.setEnabled(lex.canStreamComment())
5930 if aw: 5884 if aw:
5931 aw.newLineBelow() 5885 aw.newLineBelow()
5932 5886
5933 def __editorConfigChanged(self): 5887 def __editorConfigChanged(self):
5934 """ 5888 """
5935 Private method to handle changes of an editors configuration (e.g. language). 5889 Private slot to handle changes of an editor's configuration (e.g. language).
5936 """ 5890 """
5937 editor = self.sender() 5891 editor = self.sender()
5938 fn = editor.getFileName() 5892 fn = editor.getFileName()
5939 line, pos = editor.getCursorPosition() 5893 line, pos = editor.getCursorPosition()
5940 enc = editor.getEncoding() 5894 enc = editor.getEncoding()

eric ide

mercurial