1 /* |
|
2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 #include <QStandardItemModel> |
|
19 #include <QXmlQuery> |
|
20 #include <QFile> |
|
21 #include <QXmlStreamReader> |
|
22 #include <QDebug> |
|
23 #include <QDir> |
|
24 |
|
25 #include "HelpUtils.h" |
|
26 #include "HelpCommon.h" |
|
27 #include "HelpProxyModel.h" |
|
28 #include "HelpStandardItem.h" |
|
29 |
|
30 #include "HelpDataProvider.h" |
|
31 |
|
32 |
|
33 HelpDataProvider::HelpDataProvider() |
|
34 { |
|
35 mHelpModel = new QStandardItemModel(); |
|
36 mKeywordModel = new QStandardItemModel(); |
|
37 mSearhResultModel = new HelpProxyModel(); |
|
38 mSearhResultModel->setSourceModel(mKeywordModel); |
|
39 mAppItem = NULL; |
|
40 } |
|
41 |
|
42 HelpDataProvider::~HelpDataProvider() |
|
43 { |
|
44 delete mHelpModel; |
|
45 delete mSearhResultModel; |
|
46 delete mKeywordModel; |
|
47 } |
|
48 |
|
49 |
|
50 /////////////////////////////////////////////////////////////////////////////////////// |
|
51 |
|
52 HelpDataProvider* gHelpDataProviderInstance = NULL; |
|
53 |
|
54 HelpDataProvider* HelpDataProvider::instance() |
|
55 { |
|
56 if(!gHelpDataProviderInstance) |
|
57 { |
|
58 gHelpDataProviderInstance = new HelpDataProvider(); |
|
59 } |
|
60 |
|
61 return gHelpDataProviderInstance; |
|
62 } |
|
63 |
|
64 void HelpDataProvider::destroyInstance() |
|
65 { |
|
66 delete gHelpDataProviderInstance; |
|
67 gHelpDataProviderInstance = NULL; |
|
68 } |
|
69 |
|
70 |
|
71 /////////////////////////////////////////////////////////////////////////////////////// |
|
72 |
|
73 QAbstractItemModel* HelpDataProvider::getCategoryData() |
|
74 { |
|
75 return mHelpModel; |
|
76 } |
|
77 |
|
78 QAbstractItemModel* HelpDataProvider::getSearchData(const QString& key) |
|
79 { |
|
80 if(key == mLastSrhKey) |
|
81 { |
|
82 return mSearhResultModel; |
|
83 } |
|
84 |
|
85 mLastSrhKey = key; |
|
86 mSearhResultModel->setFilterRegExp(key); |
|
87 |
|
88 |
|
89 return mSearhResultModel; |
|
90 } |
|
91 |
|
92 void HelpDataProvider::setHelpContentUrl(const QString& uid, const QString& href) |
|
93 { |
|
94 QUrl url = QUrl::fromLocalFile(uid+BACKSLASH+href); |
|
95 mHelpContentRoot = url.toString(); |
|
96 } |
|
97 |
|
98 void HelpDataProvider::getHelpContentData(QString& content, QString& url) |
|
99 { |
|
100 // url |
|
101 if(url.isEmpty()) |
|
102 { |
|
103 url = mHelpContentRoot; |
|
104 } |
|
105 url.remove(URL_HEADER_LOCAL); |
|
106 |
|
107 // uid |
|
108 QString uid = url.section(BACKSLASH, 0, -3); |
|
109 uid.append(BACKSLASH + url.section(BACKSLASH, -2,-2)); |
|
110 |
|
111 // href |
|
112 QString href = url.section(BACKSLASH, -1,-1); |
|
113 int anchorPos = href.indexOf(HASHMARK); |
|
114 if(anchorPos != -1) |
|
115 { |
|
116 href = href.section(HASHMARK, 0, 0); |
|
117 } |
|
118 |
|
119 QString path(uid); |
|
120 path.append(BACKSLASH); |
|
121 path.append(CONTENTSZIP); |
|
122 HelpUtils::loadHtmlFromZipFile(path , href, content); |
|
123 } |
|
124 |
|
125 |
|
126 /////////////////////////////////////////////////////////////////////////////////////// |
|
127 |
|
128 void HelpDataProvider::createHelpCategory() |
|
129 { |
|
130 constructCategory(); |
|
131 |
|
132 mHelpModel->setSortRole(Qt::DisplayRole); |
|
133 |
|
134 constructCategory2((HelpStandardItem*)mHelpModel->invisibleRootItem()); |
|
135 |
|
136 if(mAppItem) |
|
137 { |
|
138 mHelpModel->appendRow(mAppItem); |
|
139 mAppItem->sortChildren(0, HelpUtils::sortOrder()); |
|
140 constructCategory2(mAppItem); |
|
141 } |
|
142 |
|
143 mKeywordModel->sort(0, HelpUtils::sortOrder()); |
|
144 } |
|
145 |
|
146 void HelpDataProvider::constructCategory() |
|
147 { |
|
148 QFileInfoList driveList = QDir::drives(); |
|
149 QDir dir; |
|
150 QString lang = HelpUtils::UILocaleFromQtToSymbian(); |
|
151 |
|
152 QString path(HelpUtils::rootPath()); |
|
153 path.append(XHTMLPATH); |
|
154 path.append(lang); |
|
155 |
|
156 QStringList uidList; |
|
157 QStringList titleList; |
|
158 parseCategoryIndexXml(path, uidList, titleList); |
|
159 |
|
160 //scan other root path and construct 3rd party help |
|
161 foreach(QFileInfo fi, driveList) |
|
162 { |
|
163 path.clear(); |
|
164 path.append(fi.absolutePath()); |
|
165 path.append(XHTMLPATH); |
|
166 path.append(lang); |
|
167 dir.setPath(path); |
|
168 if(dir.exists()) |
|
169 { |
|
170 if(QString::compare(fi.absolutePath(), HelpUtils::rootPath(), Qt::CaseInsensitive) == 0) |
|
171 { |
|
172 continue; |
|
173 } |
|
174 constructAppCategory(path, uidList); |
|
175 } |
|
176 } |
|
177 |
|
178 constructBuiltInCategory(path, uidList, titleList); |
|
179 |
|
180 mHelpModel->setSortRole(PriorityRole); |
|
181 mHelpModel->sort(0, HelpUtils::sortOrder()); |
|
182 } |
|
183 |
|
184 void HelpDataProvider::constructBuiltInCategory(const QString& path, const QStringList& uidList, const QStringList& titleList) |
|
185 { |
|
186 if(uidList.count() != titleList.count()) |
|
187 { |
|
188 //ToDo |
|
189 return; |
|
190 } |
|
191 |
|
192 for(int i = 0; i < uidList.count(); i++) |
|
193 { |
|
194 if(mUpdateUidList.contains(uidList[i])) |
|
195 { |
|
196 continue; |
|
197 } |
|
198 |
|
199 QString uid(path); |
|
200 uid.append(BACKSLASH); |
|
201 uid.append(uidList[i]); |
|
202 |
|
203 constructBuiltInCategoryItem(uid, titleList[i]); |
|
204 } |
|
205 } |
|
206 |
|
207 void HelpDataProvider::constructAppCategory(const QString& path, QStringList& uidList) |
|
208 { |
|
209 QDir dir(path); |
|
210 if(!dir.exists()) |
|
211 { |
|
212 return; |
|
213 } |
|
214 |
|
215 QStringList uidDirList = dir.entryList(); |
|
216 QString pathUid; |
|
217 foreach(QString uid, uidDirList) |
|
218 { |
|
219 pathUid.clear(); |
|
220 pathUid.append(path); |
|
221 pathUid.append(BACKSLASH); |
|
222 pathUid.append(uid); |
|
223 |
|
224 QString titleStr; |
|
225 parseAppMetaxml(pathUid, titleStr); |
|
226 if(titleStr.isEmpty()) |
|
227 { |
|
228 continue; |
|
229 } |
|
230 |
|
231 if(uidList.contains(uid) || mUpdateUidList.contains(uid)) |
|
232 { |
|
233 mUpdateUidList.append(uid); |
|
234 constructBuiltInCategoryItem(pathUid, titleStr); |
|
235 continue; |
|
236 } |
|
237 |
|
238 HelpStandardItem* item = NULL; |
|
239 item = new HelpStandardItem(titleStr); |
|
240 |
|
241 if(!item) |
|
242 { |
|
243 //no memory |
|
244 return; |
|
245 } |
|
246 |
|
247 item->setData(pathUid, UidRole); |
|
248 |
|
249 if(!mAppItem) |
|
250 { |
|
251 mAppItem = new HelpStandardItem(qtTrId(TXT_APPLICATIONS)); |
|
252 if(!mAppItem) |
|
253 { |
|
254 //no memory |
|
255 return; |
|
256 } |
|
257 mAppItem->setData(APPPRIORITY, PriorityRole); |
|
258 } |
|
259 mAppItem->appendRow(item); |
|
260 } |
|
261 } |
|
262 |
|
263 void HelpDataProvider::constructBuiltInCategoryItem(const QString& uid, const QString& title) |
|
264 { |
|
265 int priority; |
|
266 parseBuiltInMetaxml(uid, priority); |
|
267 |
|
268 HelpStandardItem* item = NULL; |
|
269 item = new HelpStandardItem(title); |
|
270 |
|
271 if(!item) |
|
272 { |
|
273 //no memory |
|
274 return; |
|
275 } |
|
276 item->setData(uid, UidRole); |
|
277 item->setData(priority, PriorityRole); |
|
278 mHelpModel->appendRow(item); |
|
279 } |
|
280 |
|
281 void HelpDataProvider::constructCategory2(HelpStandardItem* itemParent) |
|
282 { |
|
283 int count = itemParent->rowCount(); |
|
284 for(int i =0; i < count; i++) |
|
285 { |
|
286 HelpStandardItem* item = (HelpStandardItem*)itemParent->child(i); |
|
287 constructCategory2Item(item); |
|
288 } |
|
289 } |
|
290 |
|
291 void HelpDataProvider::constructCategory2Item(HelpStandardItem* itemParent) |
|
292 { |
|
293 QStringList hrefList; |
|
294 QStringList titleList; |
|
295 |
|
296 QString uid = itemParent->data(UidRole).toString(); |
|
297 parseCategory2IndexXml(uid, hrefList, titleList); |
|
298 |
|
299 if(hrefList.count() == 0 || hrefList.count() != titleList.count()) |
|
300 { |
|
301 return; |
|
302 } |
|
303 |
|
304 for(int i = 0; i < hrefList.count(); i++) |
|
305 { |
|
306 HelpStandardItem* item = NULL; |
|
307 item = new HelpStandardItem(titleList[i]); |
|
308 if(!item) |
|
309 { |
|
310 //no memory |
|
311 return; |
|
312 } |
|
313 item->setData(hrefList[i], HrefRole); |
|
314 item->setData(uid, UidRole); |
|
315 itemParent->appendRow(item); |
|
316 constructKeywordModel(titleList[i], uid, hrefList[i]); |
|
317 } |
|
318 |
|
319 itemParent->sortChildren(0, HelpUtils::sortOrder()); |
|
320 } |
|
321 |
|
322 void HelpDataProvider::constructKeywordModel(const QString& title, const QString& uid, const QString& href) |
|
323 { |
|
324 HelpStandardItem* item = NULL; |
|
325 item = new HelpStandardItem(title); |
|
326 if(!item) |
|
327 { |
|
328 //no memory |
|
329 return; |
|
330 } |
|
331 item->setData(uid, UidRole); |
|
332 item->setData(href, HrefRole); |
|
333 mKeywordModel->appendRow(item); |
|
334 } |
|
335 |
|
336 void HelpDataProvider::parseCategoryIndexXml(const QString& path, QStringList& uidList, QStringList& titleList) |
|
337 { |
|
338 QString pathIndex(path); |
|
339 pathIndex.append(BACKSLASH); |
|
340 pathIndex.append(INDEXXML); |
|
341 |
|
342 QFile file(pathIndex); |
|
343 if (!file.open(QIODevice::ReadOnly)) { |
|
344 return; |
|
345 } |
|
346 |
|
347 //parse index xml to a stringlist, each string include id and navtitle and seperate by "specilchar" |
|
348 QXmlQuery query; |
|
349 query.bindVariable("inputdoc", &file); |
|
350 |
|
351 query.setQuery("doc($inputdoc)/collections/collection/xs:string(@id)"); |
|
352 if(!query.isValid()) |
|
353 { |
|
354 return; |
|
355 } |
|
356 if(!query.evaluateTo(&uidList)) |
|
357 { |
|
358 return; |
|
359 } |
|
360 |
|
361 query.setQuery("doc($inputdoc)/collections/collection/xs:string(@navtitle)"); |
|
362 if(!query.isValid()) |
|
363 { |
|
364 return; |
|
365 } |
|
366 if(!query.evaluateTo(&titleList)) |
|
367 { |
|
368 return; |
|
369 } |
|
370 |
|
371 QStringList featureIdLst; |
|
372 |
|
373 query.setQuery("doc($inputdoc)/collections/collection/number(@FeatureId)"); |
|
374 if(!query.isValid()) |
|
375 { |
|
376 return; |
|
377 } |
|
378 if(!query.evaluateTo(&featureIdLst)) |
|
379 { |
|
380 return; |
|
381 } |
|
382 |
|
383 if(featureIdLst.count() != uidList.count()) |
|
384 { |
|
385 return; |
|
386 } |
|
387 |
|
388 for(int i = featureIdLst.count() - 1; i >= 0; i--) |
|
389 { |
|
390 int featureID = featureIdLst.at(i).toInt(); |
|
391 if(!HelpUtils::suppportFeatureID(featureID)) |
|
392 { |
|
393 uidList.removeAt(i); |
|
394 titleList.removeAt(i); |
|
395 } |
|
396 } |
|
397 } |
|
398 |
|
399 void HelpDataProvider::parseCategory2IndexXml(const QString& path, QStringList& hrefList, QStringList& titleList) |
|
400 { |
|
401 QString pathIndex(path); |
|
402 pathIndex.append(BACKSLASH); |
|
403 pathIndex.append(INDEXXML); |
|
404 |
|
405 QFile file(pathIndex); |
|
406 if (!file.open(QIODevice::ReadOnly)) { |
|
407 return; |
|
408 } |
|
409 |
|
410 //parse index xml to a stringlist, each string include href and navtitle and seperate by "specilchar" |
|
411 QXmlQuery query; |
|
412 query.bindVariable("inputdoc", &file); |
|
413 |
|
414 query.setQuery("doc($inputdoc)/topics/topicref/xs:string(@href)"); |
|
415 if(!query.isValid()) |
|
416 { |
|
417 return; |
|
418 } |
|
419 if(!query.evaluateTo(&hrefList)) |
|
420 { |
|
421 return; |
|
422 } |
|
423 |
|
424 query.setQuery("doc($inputdoc)/topics/topicref/xs:string(@navtitle)"); |
|
425 if(!query.isValid()) |
|
426 { |
|
427 return; |
|
428 } |
|
429 if(!query.evaluateTo(&titleList)) |
|
430 { |
|
431 return; |
|
432 } |
|
433 |
|
434 QStringList featureIdLst; |
|
435 |
|
436 query.setQuery("doc($inputdoc)/topics/topicref/number(@FeatureId)"); |
|
437 if(!query.isValid()) |
|
438 { |
|
439 return; |
|
440 } |
|
441 if(!query.evaluateTo(&featureIdLst)) |
|
442 { |
|
443 return; |
|
444 } |
|
445 |
|
446 if(featureIdLst.count() != hrefList.count()) |
|
447 { |
|
448 return; |
|
449 } |
|
450 |
|
451 for(int i = featureIdLst.count() - 1; i >= 0; i--) |
|
452 { |
|
453 int featureID = featureIdLst.at(i).toInt(); |
|
454 if(!HelpUtils::suppportFeatureID(featureID)) |
|
455 { |
|
456 hrefList.removeAt(i); |
|
457 titleList.removeAt(i); |
|
458 } |
|
459 } |
|
460 } |
|
461 |
|
462 void HelpDataProvider::parseBuiltInMetaxml(const QString& path, int& priority) |
|
463 { |
|
464 QString pathMetaxml(path); |
|
465 pathMetaxml.append(BACKSLASH); |
|
466 pathMetaxml.append(METAXML); |
|
467 |
|
468 priority = -1; |
|
469 |
|
470 QFile file(pathMetaxml); |
|
471 if (!file.open(QIODevice::ReadOnly)) |
|
472 { |
|
473 return; |
|
474 } |
|
475 |
|
476 QXmlQuery query; |
|
477 QString str; |
|
478 query.bindVariable("inputdoc", &file); |
|
479 |
|
480 query.setQuery("doc($inputdoc)/meta/number(priority)"); |
|
481 if(query.isValid() && query.evaluateTo(&str)) |
|
482 { |
|
483 priority = str.toInt(); |
|
484 } |
|
485 } |
|
486 |
|
487 void HelpDataProvider::parseAppMetaxml(const QString& path, QString& title) |
|
488 { |
|
489 QString pathMetaxml(path); |
|
490 pathMetaxml.append(BACKSLASH); |
|
491 pathMetaxml.append(METAXML); |
|
492 QFile file(pathMetaxml); |
|
493 if (!file.open(QIODevice::ReadOnly)) { |
|
494 return; |
|
495 } |
|
496 |
|
497 //parse meta xml, get the title string |
|
498 QXmlQuery query; |
|
499 query.bindVariable("inputdoc", &file); |
|
500 query.setQuery("doc($inputdoc)/meta/string(title)"); |
|
501 if(!query.isValid()) |
|
502 { |
|
503 return; |
|
504 } |
|
505 |
|
506 if(!query.evaluateTo(&title)) |
|
507 { |
|
508 return; |
|
509 } |
|
510 } |
|