userguide/src/HelpDataProvider.cpp
changeset 13 1eb8015a8491
child 15 c0dfc135a46c
equal deleted inserted replaced
12:2cd891dccbbe 13:1eb8015a8491
       
     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 = NULL;
       
    38 }
       
    39 
       
    40 HelpDataProvider::~HelpDataProvider()
       
    41 {
       
    42 	delete mHelpModel;
       
    43 	delete mSearhResultModel;
       
    44 	delete mKeywordModel;
       
    45 }
       
    46 
       
    47 
       
    48 ///////////////////////////////////////////////////////////////////////////////////////
       
    49 
       
    50 HelpDataProvider* gHelpDataProviderInstance = NULL;
       
    51 
       
    52 HelpDataProvider* HelpDataProvider::instance()
       
    53 {
       
    54     if(!gHelpDataProviderInstance)
       
    55     {
       
    56         gHelpDataProviderInstance = new HelpDataProvider();
       
    57     }
       
    58 
       
    59     return gHelpDataProviderInstance;
       
    60 }
       
    61 
       
    62 void HelpDataProvider::destroyInstance()
       
    63 {
       
    64     delete gHelpDataProviderInstance;
       
    65     gHelpDataProviderInstance = NULL;
       
    66 }
       
    67 
       
    68 
       
    69 ///////////////////////////////////////////////////////////////////////////////////////
       
    70 
       
    71 QAbstractItemModel* HelpDataProvider::getCategoryData()
       
    72 {
       
    73     if(!mHelpModel->rowCount())
       
    74     {
       
    75         createHelpCategory();
       
    76     }
       
    77 
       
    78     return mHelpModel;
       
    79 }
       
    80 
       
    81 QAbstractItemModel* HelpDataProvider::getSearchData(const QString& key)
       
    82 {
       
    83     delete mSearhResultModel;
       
    84     mSearhResultModel = NULL;
       
    85     
       
    86     mSearhResultModel = new HelpProxyModel();;
       
    87     mSearhResultModel->setSourceModel(mKeywordModel);
       
    88     mSearhResultModel->setFilterRole(KeywordRole);
       
    89     mSearhResultModel->setFilterRegExp(key);
       
    90 
       
    91     return mSearhResultModel;
       
    92 }
       
    93 
       
    94 void HelpDataProvider::setHelpContentUrl(const QString& uid, const QString& href)
       
    95 {
       
    96     QUrl url = QUrl::fromLocalFile(uid+BACKSLASH+href);
       
    97     mHelpContentRoot = url.toString();
       
    98 }
       
    99 
       
   100 void HelpDataProvider::getHelpContentData(QString& content, QString& url)
       
   101 {
       
   102     // url
       
   103     if(url.isEmpty())
       
   104     {
       
   105         url = mHelpContentRoot;
       
   106     }
       
   107     url.remove(URL_HEADER_LOCAL);
       
   108 
       
   109     // uid
       
   110     QString uid = url.section(BACKSLASH, 0, -3);
       
   111     uid.append(BACKSLASH + url.section(BACKSLASH, -2,-2));
       
   112 
       
   113     // href
       
   114     QString href = url.section(BACKSLASH, -1,-1);
       
   115     int anchorPos = href.indexOf(HASHMARK);
       
   116     if(anchorPos != -1)
       
   117     {
       
   118         href = href.section(HASHMARK, 0, 0);
       
   119     }
       
   120 
       
   121     QString path(uid);
       
   122     path.append(BACKSLASH);
       
   123     path.append(CONTENTSZIP);
       
   124     HelpUtils::loadHtmlFromZipFile(path , href, content);
       
   125 }
       
   126 
       
   127 
       
   128 ///////////////////////////////////////////////////////////////////////////////////////
       
   129 
       
   130 void HelpDataProvider::createHelpCategory()
       
   131 {
       
   132 	QFileInfoList driveList = QDir::drives();
       
   133 	QDir dir;
       
   134 	QString lang = HelpUtils::UILocaleFromQtToSymbian();
       
   135 
       
   136 	QString path(HelpUtils::rootPath());
       
   137 	path.append(XHTMLPATH);
       
   138 	path.append(lang);
       
   139 
       
   140 	//construct help in rom
       
   141 	createBuiltInCategory(path);
       
   142 
       
   143 	//scan other root path and construct 3rd party help
       
   144 	foreach(QFileInfo fi, driveList)
       
   145 	{
       
   146 		path.clear();
       
   147 		path.append(fi.absolutePath());
       
   148 		path.append(XHTMLPATH);
       
   149 		path.append(lang);
       
   150 		dir.setPath(path);
       
   151 		if(dir.exists())
       
   152 		{
       
   153 			if(QString::compare(fi.absolutePath(), HelpUtils::rootPath(), Qt::CaseInsensitive) == 0)
       
   154 			{
       
   155 				continue;
       
   156 			}
       
   157 			constructAppHelp(path);
       
   158 		}
       
   159 	}
       
   160 }
       
   161 
       
   162 void HelpDataProvider::createBuiltInCategory(const QString& path)
       
   163 {
       
   164 	QString pathIndex(path);
       
   165 	pathIndex.append(BACKSLASH);
       
   166 	pathIndex.append(INDEXXML);
       
   167 
       
   168 	QFile file(pathIndex);
       
   169 	if (!file.open(QIODevice::ReadOnly)) {
       
   170 		return;
       
   171 	}
       
   172 
       
   173 	//parse index xml to a stringlist, each string include id and navtitle and seperate by "specilchar"
       
   174 	QXmlQuery query;
       
   175 	query.bindVariable("inputdoc", &file);
       
   176 	QXmlItem xmlItem(SPECIALCHAR);
       
   177 	query.bindVariable("specilchar", xmlItem);
       
   178 	query.setQuery("doc($inputdoc)/collections/collection/ \
       
   179 					string-join((xs:string(@id), xs:string(@navtitle)), $specilchar)");
       
   180 
       
   181 	if(!query.isValid())
       
   182 	{
       
   183 		return;
       
   184 	}
       
   185 	QStringList strLst;
       
   186 	if(!query.evaluateTo(&strLst))
       
   187 	{
       
   188 		return;
       
   189 	}
       
   190 
       
   191 	foreach(QString str, strLst)
       
   192 	{
       
   193 		QStringList temp;
       
   194 		temp = str.split(SPECIALCHAR);
       
   195 		QString uid(path);
       
   196 		uid.append(BACKSLASH);
       
   197 		uid.append(temp[0]);
       
   198 		HelpStandardItem* item = constructCategory2(temp[1], uid);
       
   199 		if(item)
       
   200 		{
       
   201 			mHelpModel->appendRow(item);
       
   202 			constructKeywordModel(uid);
       
   203 		}
       
   204 	}
       
   205 	file.close();
       
   206 	mHelpModel->sort(0, HelpUtils::sortOrder());
       
   207 }
       
   208 
       
   209 HelpStandardItem* HelpDataProvider::constructCategory2(const QString& title, const QString& uid)
       
   210 {
       
   211 	QString pathIndex(uid);
       
   212 	pathIndex.append(BACKSLASH);
       
   213 	pathIndex.append(INDEXXML);
       
   214 
       
   215 	QFile file(pathIndex);
       
   216 	if (!file.open(QIODevice::ReadOnly)) {
       
   217 		return NULL;
       
   218 	}
       
   219 
       
   220 	//parse index xml to a stringlist, each string include href and navtitle and seperate by "specilchar"
       
   221 	QXmlQuery query;
       
   222 	QXmlItem xmlItem(SPECIALCHAR);
       
   223 	query.bindVariable("inputdoc", &file);
       
   224 	query.bindVariable("specilchar", xmlItem);
       
   225 	query.setQuery("doc($inputdoc)/topics/topicref/ \
       
   226 					string-join((xs:string(@href), xs:string(@navtitle)), $specilchar)");
       
   227 	if(!query.isValid())
       
   228 	{
       
   229 		return NULL;
       
   230 	}
       
   231 
       
   232 	QStringList strLst;
       
   233 	if(!query.evaluateTo(&strLst))
       
   234 	{
       
   235 		return NULL;
       
   236 	}	
       
   237 	if(strLst.count() <= 0)
       
   238 	{
       
   239 		return NULL;
       
   240 	}
       
   241 
       
   242 	HelpStandardItem* itemParent = NULL;
       
   243 	itemParent = new HelpStandardItem(title);
       
   244 	itemParent->setData(uid, UidRole);
       
   245 	foreach(QString str, strLst)
       
   246 	{
       
   247 		QStringList temp;
       
   248 		temp = str.split(SPECIALCHAR);
       
   249 		HelpStandardItem* item = new HelpStandardItem(temp[1]);
       
   250 		item->setData(temp[0], HrefRole);
       
   251 		itemParent->appendRow(item);
       
   252 	}
       
   253 
       
   254 	file.close();
       
   255 	itemParent->sortChildren(0, HelpUtils::sortOrder());
       
   256 	return itemParent;
       
   257 }
       
   258 
       
   259 void HelpDataProvider::constructAppHelp(const QString& path)
       
   260 {
       
   261 	QDir dir(path);	
       
   262 	if(!dir.exists())
       
   263 	{
       
   264 		return;
       
   265 	}
       
   266 
       
   267 	QStringList uidList = dir.entryList();
       
   268 	HelpStandardItem* itemApp = NULL;
       
   269 	QString pathTemp;
       
   270 	foreach(QString uid, uidList)
       
   271 	{
       
   272 		pathTemp.clear();
       
   273 		pathTemp.append(path);
       
   274 		pathTemp.append(BACKSLASH);
       
   275 		pathTemp.append(uid);
       
   276 		pathTemp.append(BACKSLASH);
       
   277 		pathTemp.append(METAXML);
       
   278 		QFile file(pathTemp);
       
   279 		if (!file.open(QIODevice::ReadOnly)) {
       
   280 			continue;
       
   281 		}
       
   282 
       
   283 		//parse meta xml, get the title string
       
   284 		QXmlQuery query;
       
   285 		query.bindVariable("inputdoc", &file);
       
   286 		query.setQuery("doc($inputdoc)/meta/string(title)");
       
   287 		if(!query.isValid())
       
   288 		{
       
   289 			continue;
       
   290 		}
       
   291 		QString titleStr;
       
   292 		if(!query.evaluateTo(&titleStr))
       
   293 		{
       
   294 			continue;
       
   295 		}
       
   296 
       
   297 		pathTemp.clear();
       
   298 		pathTemp.append(path);
       
   299 		pathTemp.append(BACKSLASH);
       
   300 		pathTemp.append(uid);
       
   301 		HelpStandardItem* item = constructCategory2(titleStr, pathTemp);
       
   302 		if(item)
       
   303 		{
       
   304 			if(!itemApp)
       
   305 			{
       
   306 				itemApp = new HelpStandardItem("Applications");
       
   307 			}
       
   308 			itemApp->appendRow(item);
       
   309 			constructKeywordModel(pathTemp);
       
   310 		}
       
   311 		file.close();
       
   312 	}
       
   313 
       
   314 	if(itemApp)
       
   315 	{
       
   316 		itemApp->sortChildren(0, HelpUtils::sortOrder());
       
   317 		mHelpModel->appendRow(itemApp);
       
   318 	}
       
   319 }
       
   320 
       
   321 void HelpDataProvider::constructKeywordModel(const QString& path)
       
   322 {
       
   323 	QString pathKeyword(path);
       
   324 	pathKeyword.append(BACKSLASH);
       
   325 	pathKeyword.append(KEYWORDXML);
       
   326 
       
   327 	QFile file(pathKeyword);
       
   328 	if (!file.open(QIODevice::ReadOnly)) {
       
   329 		return;
       
   330 	}
       
   331 
       
   332 	//construct keyword model, title and keyword is one to more
       
   333 	QXmlStreamReader reader(&file);
       
   334 	QString keyword;
       
   335 	QString title;
       
   336 
       
   337 	while (!reader.atEnd()) {
       
   338 		if (!reader.readNextStartElement()) 
       
   339 		{	
       
   340 			continue;
       
   341 		}
       
   342 		if (reader.name() == "text")
       
   343 		{
       
   344 			keyword = reader.readElementText();
       
   345 		}
       
   346 		else if (reader.name() == "target")
       
   347 		{
       
   348 			QString href = reader.attributes().value("href").toString();
       
   349 			HelpStandardItem* item = findItemWithHref((HelpStandardItem *)(mKeywordModel->invisibleRootItem()), href);
       
   350 			QStringList keywordLst;
       
   351 			if(item)
       
   352 			{
       
   353 				keywordLst = item->data(KeywordRole).toStringList();
       
   354 				keywordLst.append(keyword);
       
   355 				item->setData(keywordLst,KeywordRole);
       
   356 			}
       
   357 			else
       
   358 			{
       
   359 				item = new HelpStandardItem(reader.readElementText());
       
   360 				item->setData(path, UidRole);
       
   361 				item->setData(href, HrefRole);
       
   362 
       
   363 				keywordLst.append(keyword);
       
   364 				item->setData(keywordLst,KeywordRole);
       
   365 				mKeywordModel->appendRow(item);
       
   366 			}				
       
   367 		}			
       
   368 	}
       
   369 	file.close();
       
   370 	mKeywordModel->sort(0, HelpUtils::sortOrder());
       
   371 }
       
   372 
       
   373 HelpStandardItem* HelpDataProvider::findItemWithHref(HelpStandardItem* itemParent, const QString& href)
       
   374 {
       
   375 	for(int i = 0; i < itemParent->rowCount(); i++)
       
   376 	{
       
   377 		if(QString::compare(itemParent->child(i)->data(HrefRole).toString(), href, Qt::CaseInsensitive) == 0)
       
   378 		{
       
   379 			return (HelpStandardItem *)(itemParent->child(i));
       
   380 		}
       
   381 	}
       
   382 	return NULL;
       
   383 }