eric7/UI/Previewer.py

branch
eric7
changeset 8312
800c432b34c8
parent 8218
7c09585bd960
child 8318
962bce857696
equal deleted inserted replaced
8311:4e8b98454baa 8312:800c432b34c8
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2013 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing a previewer widget for HTML, Markdown and ReST files.
8 """
9
10 import os
11
12 from PyQt5.QtCore import pyqtSlot, QTimer
13 from PyQt5.QtWidgets import QStackedWidget
14
15 import Preferences
16
17
18 class Previewer(QStackedWidget):
19 """
20 Class implementing a previewer widget containing a stack of
21 specialized previewers.
22 """
23 def __init__(self, viewmanager, splitter, parent=None):
24 """
25 Constructor
26
27 @param viewmanager reference to the viewmanager object (ViewManager)
28 @param splitter reference to the embedding splitter (QSplitter)
29 @param parent reference to the parent widget (QWidget)
30 """
31 super().__init__(parent)
32
33 self.__vm = viewmanager
34 self.__splitter = splitter
35
36 self.__firstShow = True
37
38 self.__htmlPreviewer = None
39 self.__qssPreviewer = None
40
41 # Don't update too often because the UI might become sluggish
42 self.__typingTimer = QTimer()
43 self.__typingTimer.setInterval(
44 Preferences.getEditor("PreviewRefreshWaitTimer")) # default 500ms
45 self.__typingTimer.timeout.connect(self.__processEditor)
46
47 self.__vm.editorChangedEd.connect(self.__editorChanged)
48 self.__vm.editorLanguageChanged.connect(self.__editorLanguageChanged)
49 self.__vm.editorTextChanged.connect(self.__editorTextChanged)
50
51 self.__vm.previewStateChanged.connect(self.__previewStateChanged)
52
53 self.__splitter.splitterMoved.connect(self.__splitterMoved)
54
55 self.hide()
56
57 @pyqtSlot()
58 def preferencesChanged(self):
59 """
60 Public slot handling a change of preferences.
61 """
62 self.__typingTimer.setInterval(
63 Preferences.getEditor("PreviewRefreshWaitTimer"))
64
65 def show(self):
66 """
67 Public method to show the preview widget.
68 """
69 super().show()
70 if self.__firstShow:
71 self.__splitter.restoreState(
72 Preferences.getUI("PreviewSplitterState"))
73 self.__firstShow = False
74 self.__typingTimer.start()
75
76 def hide(self):
77 """
78 Public method to hide the preview widget.
79 """
80 super().hide()
81 self.__typingTimer.stop()
82
83 def shutdown(self):
84 """
85 Public method to perform shutdown actions.
86 """
87 self.__typingTimer.stop()
88 self.__htmlPreviewer and self.__htmlPreviewer.shutdown()
89
90 def __splitterMoved(self):
91 """
92 Private slot to handle the movement of the embedding splitter's handle.
93 """
94 state = self.__splitter.saveState()
95 Preferences.setUI("PreviewSplitterState", state)
96
97 def __editorChanged(self, editor):
98 """
99 Private slot to handle a change of the current editor.
100
101 @param editor reference to the editor (Editor)
102 """
103 if editor is None:
104 self.hide()
105 return
106
107 if (
108 Preferences.getUI("ShowFilePreview") and
109 self.__isPreviewable(editor)
110 ):
111 self.show()
112 self.__processEditor()
113 else:
114 self.hide()
115
116 def __editorLanguageChanged(self, editor):
117 """
118 Private slot to handle a change of the current editor's language.
119
120 @param editor reference to the editor (Editor)
121 """
122 self.__editorChanged(editor)
123
124 def __editorTextChanged(self, editor):
125 """
126 Private slot to handle changes of an editor's text.
127
128 @param editor reference to the editor (Editor)
129 """
130 if self.isVisible():
131 self.__typingTimer.stop()
132 self.__typingTimer.start()
133
134 def __previewStateChanged(self, on):
135 """
136 Private slot to toggle the display of the preview.
137
138 @param on flag indicating to show a preview (boolean)
139 """
140 editor = self.__vm.activeWindow()
141 if on and editor and self.__isPreviewable(editor):
142 self.show()
143 else:
144 self.hide()
145
146 def __isPreviewable(self, editor):
147 """
148 Private method to check, if a preview can be shown for the given
149 editor.
150
151 @param editor reference to an editor (Editor)
152 @return flag indicating if a preview can be shown (boolean)
153 """
154 if editor:
155 if bool(editor.getFileName()):
156 extension = os.path.normcase(
157 os.path.splitext(editor.getFileName())[1][1:])
158 return extension in (
159 Preferences.getEditor("PreviewHtmlFileNameExtensions") +
160 Preferences.getEditor(
161 "PreviewMarkdownFileNameExtensions") +
162 Preferences.getEditor("PreviewRestFileNameExtensions") +
163 Preferences.getEditor("PreviewQssFileNameExtensions")
164 )
165 elif editor.getLanguage().lower() in [
166 "html", "markdown", "restructuredtext", "qss"]:
167 return True
168
169 return False
170
171 def __processEditor(self):
172 """
173 Private slot to schedule the processing of the current editor's text.
174 """
175 self.__typingTimer.stop()
176
177 editor = self.__vm.activeWindow()
178 if editor is not None:
179 fn = editor.getFileName()
180
181 if fn:
182 extension = os.path.normcase(os.path.splitext(fn)[1][1:])
183 else:
184 extension = ""
185 if (
186 extension in Preferences.getEditor(
187 "PreviewHtmlFileNameExtensions") or
188 editor.getLanguage().lower() == "html"
189 ):
190 language = "HTML"
191 elif (
192 extension in Preferences.getEditor(
193 "PreviewMarkdownFileNameExtensions") or
194 editor.getLanguage().lower() == "markdown"
195 ):
196 language = "Markdown"
197 elif (
198 extension in Preferences.getEditor(
199 "PreviewRestFileNameExtensions") or
200 editor.getLanguage().lower() == "restructuredtext"
201 ):
202 language = "ReST"
203 elif (
204 extension in Preferences.getEditor(
205 "PreviewQssFileNameExtensions") or
206 editor.getLanguage().lower() == "qss"
207 ):
208 language = "QSS"
209 else:
210 language = ""
211
212 if language in ["HTML", "Markdown", "ReST"]:
213 if self.__htmlPreviewer is None:
214 from .Previewers.PreviewerHTML import PreviewerHTML
215 self.__htmlPreviewer = PreviewerHTML()
216 self.addWidget(self.__htmlPreviewer)
217 self.setCurrentWidget(self.__htmlPreviewer)
218 self.__htmlPreviewer.processEditor(editor)
219 elif language == "QSS":
220 if self.__qssPreviewer is None:
221 from .Previewers.PreviewerQSS import PreviewerQSS
222 self.__qssPreviewer = PreviewerQSS()
223 self.addWidget(self.__qssPreviewer)
224 self.setCurrentWidget(self.__qssPreviewer)
225 self.__qssPreviewer.processEditor(editor)

eric ide

mercurial