|
1 # -*- coding: utf-8 -*- |
|
2 |
|
3 # Copyright (c) 2009 Detlev Offenbach <detlev@die-offenbachs.de> |
|
4 # |
|
5 |
|
6 """ |
|
7 Module implementing a thread class populating and updating the QtHelp |
|
8 documentation database. |
|
9 """ |
|
10 |
|
11 from PyQt4.QtCore import * |
|
12 from PyQt4.QtGui import * |
|
13 from PyQt4.QtHelp import QHelpEngineCore |
|
14 |
|
15 from eric4config import getConfig |
|
16 |
|
17 class HelpDocsInstaller(QThread): |
|
18 """ |
|
19 Class implementing the worker thread populating and updating the QtHelp |
|
20 documentation database. |
|
21 |
|
22 @signal errorMessage(const QString&) emitted, if an error occurred during |
|
23 the installation of the documentation |
|
24 @signal docsInstalled(bool) emitted after the installation has finished |
|
25 """ |
|
26 def __init__(self, collection): |
|
27 """ |
|
28 Constructor |
|
29 |
|
30 @param collection full pathname of the collection file (string) |
|
31 """ |
|
32 QThread.__init__(self) |
|
33 |
|
34 self.__abort = False |
|
35 self.__collection = collection |
|
36 self.__mutex = QMutex() |
|
37 |
|
38 def stop(self): |
|
39 """ |
|
40 Public slot to stop the installation procedure. |
|
41 """ |
|
42 if not self.isRunning(): |
|
43 return |
|
44 |
|
45 self.__mutex.lock() |
|
46 self.__abort = True |
|
47 self.__mutex.unlock() |
|
48 self.wait() |
|
49 |
|
50 def installDocs(self): |
|
51 """ |
|
52 Public method to start the installation procedure. |
|
53 """ |
|
54 self.start(QThread.LowPriority) |
|
55 |
|
56 def run(self): |
|
57 """ |
|
58 Protected method executed by the thread. |
|
59 """ |
|
60 engine = QHelpEngineCore(self.__collection) |
|
61 engine.setupData() |
|
62 changes = False |
|
63 |
|
64 qtDocs = ["designer", "linguist", "qt"] |
|
65 for doc in qtDocs: |
|
66 changes |= self.__installQtDoc(doc, engine) |
|
67 self.__mutex.lock() |
|
68 if self.__abort: |
|
69 engine = None |
|
70 self.__mutex.unlock() |
|
71 return |
|
72 self.__mutex.unlock() |
|
73 |
|
74 changes |= self.__installEric4Doc(engine) |
|
75 engine = None |
|
76 del engine |
|
77 self.emit(SIGNAL("docsInstalled(bool)"), changes) |
|
78 |
|
79 def __installQtDoc(self, name, engine): |
|
80 """ |
|
81 Private method to install/update a Qt help document. |
|
82 |
|
83 @param name name of the Qt help document (string) |
|
84 @param engine reference to the help engine (QHelpEngineCore) |
|
85 @return flag indicating success (boolean) |
|
86 """ |
|
87 versionKey = "qt_version_{0}@@{1}".format(qVersion(), name) |
|
88 info = engine.customValue(versionKey, QVariant("")).toString() |
|
89 lst = info.split('|') |
|
90 |
|
91 dt = QDateTime() |
|
92 if len(lst) and lst[0]: |
|
93 dt = QDateTime.fromString(lst[0], Qt.ISODate) |
|
94 |
|
95 qchFile = "" |
|
96 if len(lst) == 2: |
|
97 qchFile = lst[1] |
|
98 |
|
99 docsPath = QDir(QLibraryInfo.location(QLibraryInfo.DocumentationPath) + \ |
|
100 QDir.separator() + "qch") |
|
101 |
|
102 files = docsPath.entryList(["*.qch"]) |
|
103 if not files: |
|
104 engine.setCustomValue(versionKey, |
|
105 QVariant(QDateTime().toString(Qt.ISODate) + '|')) |
|
106 return False |
|
107 |
|
108 for f in files: |
|
109 if f.startswith(name): |
|
110 fi = QFileInfo(docsPath.absolutePath() + QDir.separator() + f) |
|
111 namespace = QHelpEngineCore.namespaceName(fi.absoluteFilePath()) |
|
112 if not namespace: |
|
113 continue |
|
114 |
|
115 if dt.isValid() and \ |
|
116 namespace in engine.registeredDocumentations() and \ |
|
117 fi.lastModified().toString(Qt.ISODate) == dt.toString(Qt.ISODate) and \ |
|
118 qchFile == fi.absoluteFilePath(): |
|
119 return False |
|
120 |
|
121 if namespace in engine.registeredDocumentations(): |
|
122 engine.unregisterDocumentation(namespace) |
|
123 |
|
124 if not engine.registerDocumentation(fi.absoluteFilePath()): |
|
125 self.emit(SIGNAL("errorMessage(const QString&)"), |
|
126 self.trUtf8("""The file <b>{0}</b> could not be registered.""" |
|
127 """<br/>Reason: {1}""")\ |
|
128 .format(fi.absoluteFilePath, engine.error()) |
|
129 ) |
|
130 return False |
|
131 |
|
132 engine.setCustomValue(versionKey, |
|
133 QVariant(fi.lastModified().toString(Qt.ISODate) + '|' + \ |
|
134 fi.absoluteFilePath())) |
|
135 return True |
|
136 |
|
137 return False |
|
138 |
|
139 def __installEric4Doc(self, engine): |
|
140 """ |
|
141 Private method to install/update the eric4 help documentation. |
|
142 |
|
143 @param engine reference to the help engine (QHelpEngineCore) |
|
144 @return flag indicating success (boolean) |
|
145 """ |
|
146 versionKey = "eric4_ide" |
|
147 info = engine.customValue(versionKey, QVariant("")).toString() |
|
148 lst = info.split('|') |
|
149 |
|
150 dt = QDateTime() |
|
151 if len(lst) and lst[0]: |
|
152 dt = QDateTime.fromString(lst[0], Qt.ISODate) |
|
153 |
|
154 qchFile = "" |
|
155 if len(lst) == 2: |
|
156 qchFile = lst[1] |
|
157 |
|
158 docsPath = QDir(getConfig("ericDocDir") + QDir.separator() + "Help") |
|
159 |
|
160 files = docsPath.entryList(["*.qch"]) |
|
161 if not files: |
|
162 engine.setCustomValue(versionKey, |
|
163 QVariant(QDateTime().toString(Qt.ISODate) + '|')) |
|
164 return False |
|
165 |
|
166 for f in files: |
|
167 if f == "source.qch": |
|
168 fi = QFileInfo(docsPath.absolutePath() + QDir.separator() + f) |
|
169 if dt.isValid() and \ |
|
170 fi.lastModified().toString(Qt.ISODate) == dt.toString(Qt.ISODate) and \ |
|
171 qchFile == fi.absoluteFilePath(): |
|
172 return False |
|
173 |
|
174 namespace = QHelpEngineCore.namespaceName(fi.absoluteFilePath()) |
|
175 if not namespace: |
|
176 continue |
|
177 |
|
178 if namespace in engine.registeredDocumentations(): |
|
179 engine.unregisterDocumentation(namespace) |
|
180 |
|
181 if not engine.registerDocumentation(fi.absoluteFilePath()): |
|
182 self.emit(SIGNAL("errorMessage(const QString&)"), |
|
183 self.trUtf8("""The file <b>{0}</b> could not be registered.""" |
|
184 """<br/>Reason: {1}""")\ |
|
185 .format(fi.absoluteFilePath, engine.error()) |
|
186 ) |
|
187 return False |
|
188 |
|
189 engine.setCustomValue(versionKey, |
|
190 QVariant(fi.lastModified().toString(Qt.ISODate) + '|' + \ |
|
191 fi.absoluteFilePath())) |
|
192 return True |
|
193 |
|
194 return False |