fileutilities.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678
  1. #include <QString>
  2. #include <QDomDocument>
  3. #include <QDomElement>
  4. #include <QFile>
  5. #include <QDir>
  6. #include <QApplication>
  7. #include <QTextStream>
  8. #include <QRegExp>
  9. #include <QDateTime>
  10. #include <QBitArray>
  11. #include <QDebug>
  12. #include <QProcess>
  13. #include <QXmlQuery>
  14. #include "fileutilities.h"
  15. #include "directoryutilities.h"
  16. #include "settings.h"
  17. #include "common/fstraverseiterator.h"
  18. FileUtilities::FileUtilities(GeneratorOutputView &outputView, GeneratorData &generatorData) :
  19. m_outputView(outputView), m_generatorData(generatorData)
  20. {
  21. m_infoPlistFileNameNoSpaces = m_generatorData.infoPlistValue(INFO_PLIST_KEY_DISPLAY_NAME);
  22. m_infoPlistFileNameNoSpaces.replace(" ", "_");
  23. }
  24. bool FileUtilities::updateMainFile()
  25. {
  26. // OBS QString mainFileName = m_generatorData.projectDirectory() + MAIN_FILE;
  27. QString
  28. mainFileName = m_generatorData.srcDirectory() + MAIN_FILE;
  29. QFile projectTemplateFileIn(mainFileName);
  30. if(!projectTemplateFileIn.open(QIODevice::ReadOnly | QIODevice::Text)) {
  31. QString errMsg = QString(ERR_FILE_OPEN_READ_FAILED_CANNOT_CONTINUE).arg(MAIN_FILE);
  32. m_outputView.printOutput(errMsg);
  33. return false;
  34. }
  35. QTextStream streamIn(&projectTemplateFileIn);
  36. QString templateFileContent(streamIn.readAll());
  37. projectTemplateFileIn.close();
  38. if(templateFileContent.contains(FULL_SCREEN_TAG)) {
  39. templateFileContent.replace(FULL_SCREEN_TAG, Settings::get(Settings::ShowFullScreen).toBool() ? "1" : "0");
  40. }
  41. if(templateFileContent.contains(SOFT_KEYS_TAG)) {
  42. templateFileContent.replace(SOFT_KEYS_TAG, Settings::get(Settings::ShowSoftKeys).toBool() ? "1" : "0");
  43. }
  44. QFile mainFileOut(mainFileName);
  45. if(!mainFileOut.open(QIODevice::WriteOnly | QIODevice::Text)) {
  46. QString errMsg = QString(ERR_FILE_OPEN_WRITE_FAILED_CANNOT_CONTINUE).arg(MAIN_FILE);
  47. m_outputView.printOutput(errMsg);
  48. return false;
  49. }
  50. QTextStream streamOut(&mainFileOut);
  51. streamOut << templateFileContent;
  52. mainFileOut.close();
  53. QString msg = QString(MSG_FILE_UPDATED_SUCCESSFULLY).arg(MAIN_FILE);
  54. m_outputView.printOutput(msg);
  55. return true;
  56. }
  57. bool FileUtilities::updateMainWindowFile()
  58. {
  59. // OBS QString mainWindowFileName = m_generatorData.projectDirectory() + MAIN_WINDOW_FILE;
  60. QString
  61. mainWindowFileName = m_generatorData.srcDirectory() + MAIN_WINDOW_FILE;
  62. QFile projectTemplateFileIn(mainWindowFileName);
  63. if (!projectTemplateFileIn.open(QIODevice::ReadOnly | QIODevice::Text)) {
  64. QString errMsg = QString(ERR_FILE_OPEN_READ_FAILED_CANNOT_CONTINUE).arg(MAIN_WINDOW_FILE);
  65. m_outputView.printOutput(errMsg);
  66. return false;
  67. }
  68. QTextStream streamIn(&projectTemplateFileIn);
  69. QString templateFileContent(streamIn.readAll());
  70. projectTemplateFileIn.close();
  71. if (templateFileContent.contains(RESOURCE_FILE_TAG)) {
  72. QString mainHTMLRelative = m_generatorData.infoPlistValue(KEY_WIDGET_ROOT_DIR) + m_generatorData.infoPlistValue(INFO_PLIST_KEY_MAIN_HTML);
  73. // OBS mainHTMLRelative = "/" + mainHTMLRelative.mid(m_generatorData.projectDirectory().length());
  74. mainHTMLRelative = "/" + mainHTMLRelative.mid(m_generatorData.srcDirectory().length());
  75. templateFileContent.replace(RESOURCE_FILE_TAG, QString("qrc:%1").arg(mainHTMLRelative));
  76. }
  77. if (templateFileContent.contains(PANNING_ENABLED_TAG)) {
  78. templateFileContent.replace(PANNING_ENABLED_TAG, Settings::get(Settings::PanningEnabled).toBool() ? "1" : "0");
  79. }
  80. if (templateFileContent.contains(WIDGET_IDENTIFIER_TAG)) {
  81. templateFileContent.replace(WIDGET_IDENTIFIER_TAG, getWidgetIdentifier());
  82. }
  83. QFile mainWindowFileOut(mainWindowFileName);
  84. if (!mainWindowFileOut.open(QIODevice::WriteOnly | QIODevice::Text)) {
  85. QString errMsg = QString(ERR_FILE_OPEN_WRITE_FAILED_CANNOT_CONTINUE).arg(MAIN_WINDOW_FILE);
  86. m_outputView.printOutput(errMsg);
  87. return false;
  88. }
  89. QTextStream streamOut(&mainWindowFileOut);
  90. streamOut << templateFileContent;
  91. mainWindowFileOut.close();
  92. QString msg = QString(MSG_FILE_UPDATED_SUCCESSFULLY).arg(MAIN_WINDOW_FILE);
  93. m_outputView.printOutput(msg);
  94. return true;
  95. }
  96. /**
  97. * Updates .pro files. Currently, the only operation that is done
  98. * is replacing the @qt_mobility_path tag with the defined mobility
  99. * path.
  100. */
  101. bool FileUtilities::updateProjectFile(QString filename)
  102. {
  103. QFile projectFile(filename);
  104. if (!projectFile.open(QIODevice::ReadWrite | QIODevice::Text)) {
  105. // Could not open file for writing -- print error. We don't need the write access
  106. // yet, but let's check that it's available.
  107. m_outputView.printOutput(QString(ERR_FILE_OPEN_READ_FAILED_CANNOT_CONTINUE).arg(filename));
  108. return false;
  109. }
  110. else
  111. {
  112. // Read file to a variable
  113. QTextStream streamIn(&projectFile);
  114. QString fileContent(streamIn.readAll());
  115. // Replace the parts of file that are required
  116. if (fileContent.contains(SDK_VERSION_DEFINES_TAG)) {
  117. // SDK version: full S60 or Nokia Qt SDK (which is a crippled S60)
  118. fileContent.replace(SDK_VERSION_DEFINES_TAG, Settings::get(Settings::FullS60SDK).toBool() ? "" : "DEFINES += HAVE_NOKIAQTSDK");
  119. }
  120. // Reopen and truncate
  121. projectFile.close();
  122. projectFile.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate);
  123. QTextStream streamOut(&projectFile);
  124. streamOut << fileContent;
  125. projectFile.close();
  126. // Success, print message to the log
  127. m_outputView.printOutput(QString(MSG_FILE_UPDATED_SUCCESSFULLY).arg(filename));
  128. return true;
  129. }
  130. }
  131. QString FileUtilities::getMainHTMLFileFullPath()
  132. {
  133. QString path = m_generatorData.infoPlistValue(KEY_WIDGET_ROOT_DIR) + m_generatorData.infoPlistValue(INFO_PLIST_KEY_MAIN_HTML);
  134. return path;
  135. }
  136. QString FileUtilities::getWidgetIdentifier()
  137. {
  138. return m_generatorData.infoPlistValue(INFO_PLIST_KEY_IDENTIFIER);
  139. }
  140. QString FileUtilities::findFile(const QDir & dir,
  141. const QString & fileName)
  142. {
  143. FSTraverseIterator
  144. fsIt(dir.absolutePath(),
  145. FSTraverseIterator::DirsPreOrder),
  146. fsEnd;
  147. QString
  148. rv = "";
  149. for (; fsIt != fsEnd; ++fsIt)
  150. {
  151. QFileInfo
  152. fi = *fsIt;
  153. QDir
  154. curDir(fi.absoluteFilePath());
  155. // if (fi.fileName() == fileName)
  156. if (curDir.exists(fileName))
  157. {
  158. // OBS rv = fi.absoluteFilePath();
  159. rv = curDir.absolutePath() + QDir::separator() + fileName;
  160. break;
  161. }
  162. }
  163. return rv;
  164. }
  165. bool FileUtilities::clearUpDir(QDir tmpDir)
  166. {
  167. bool
  168. rv = false;
  169. if (tmpDir.exists())
  170. {
  171. FSTraverseIterator
  172. fsIt(tmpDir.absolutePath(),
  173. FSTraverseIterator::Files
  174. | FSTraverseIterator::DirsPostOrder),
  175. fsEnd;
  176. // directories will be enumerated after all their
  177. // content has been enumerated
  178. for (; fsIt != fsEnd; ++fsIt)
  179. {
  180. QFileInfo
  181. fi = *fsIt;
  182. if (fi.isFile())
  183. {
  184. tmpDir.remove(fi.absoluteFilePath());
  185. }
  186. else if (fi.isDir())
  187. {
  188. if (fi.absolutePath() != tmpDir.absolutePath())
  189. {
  190. tmpDir.rmdir(fi.absolutePath());
  191. }
  192. }
  193. }
  194. }
  195. else
  196. {
  197. rv = tmpDir.mkpath(tmpDir.absolutePath());
  198. }
  199. return rv;
  200. }
  201. bool FileUtilities::syncUnzipWidgetFile(const QString & wgzFile,
  202. const QString & unzipDir)
  203. {
  204. QFileInfo widgetFileInfo(wgzFile);
  205. QStringList arguments;
  206. arguments << "-xo" << wgzFile << "-d" << unzipDir;
  207. QProcess
  208. * process = new QProcess( NULL );
  209. // ? process->setReadChannelMode(QProcess::MergedChannels);
  210. // do we need to read output in order to prevent the process
  211. // from stalling?
  212. process->start(UNZIP_APP_NAME,
  213. arguments);
  214. process->waitForFinished(-1);
  215. bool
  216. rv = process->exitStatus() == QProcess::NormalExit
  217. && (process->exitCode() == 0);
  218. delete process;
  219. return rv;
  220. }
  221. QPair<QString, QString> FileUtilities::sniffAppNames(const QString & widgetFilePath)
  222. {
  223. QPair<QString, QString>
  224. rv("", "");
  225. QFileInfo
  226. widgetFile(widgetFilePath);
  227. if (widgetFile.isDir())
  228. {
  229. QDir
  230. widgetDir(widgetFilePath);
  231. rv.second = widgetDir.dirName();
  232. }
  233. else
  234. {
  235. QDir
  236. tmpDir(QDir::tempPath() + "/hybrid");
  237. bool
  238. success = clearUpDir(tmpDir);
  239. success = syncUnzipWidgetFile(widgetFilePath,
  240. tmpDir.absolutePath());
  241. if (success)
  242. {
  243. QXmlQuery
  244. xmlQuery;
  245. QString
  246. infoPlistPath(findFile(tmpDir, INFO_PLIST_FILE));
  247. QString
  248. xpath = "doc('%1')/descendant::dict/key[text()='DisplayName']/following-sibling::string[1]/child::text()";
  249. xpath = xpath.arg(infoPlistPath);
  250. xmlQuery.setQuery(xpath);
  251. QString
  252. text;
  253. success = xmlQuery.evaluateTo(&text);
  254. if (success)
  255. {
  256. rv.second = text.trimmed();
  257. }
  258. else
  259. {
  260. QString
  261. configXmlPath(findFile(tmpDir, W3C_CONFIG_FILE));
  262. xpath = "doc('%1')/widget/widgetname/child::text()";
  263. xpath = xpath.arg(configXmlPath);
  264. xmlQuery.setQuery(xpath);
  265. success = xmlQuery.evaluateTo(&text);
  266. if (success)
  267. {
  268. rv.second = text.trimmed();
  269. }
  270. else
  271. {
  272. // DEFAULT CASE
  273. rv.second = "Hybrid Widget";
  274. }
  275. }
  276. }
  277. }
  278. // ??? rv.second += " GeneratedApp";
  279. rv.first = rv.second.toLower();
  280. rv.first.replace(" ", "");
  281. return rv;
  282. }
  283. void FileUtilities::createWidgetResourceFile()
  284. {
  285. // OBS QString qtResourceFileName(m_generatorData.projectDirectory() + "/" + m_infoPlistFileNameNoSpaces + ".qrc");
  286. QString
  287. qtResourceFileName(m_generatorData.srcDirectory()
  288. + "/"
  289. + m_infoPlistFileNameNoSpaces
  290. + ".qrc");
  291. QDomDocument domDocument;
  292. QDomElement rccElem = domDocument.createElement(QRC_FILE_TAG_RCC);
  293. domDocument.appendChild(rccElem);
  294. QDomElement qresourceElem = domDocument.createElement(QRC_FILE_TAG_QRESOURCE);
  295. qresourceElem.setAttribute(QRC_FILE_ATTRIBUTE_PREFIX, "/");
  296. rccElem.appendChild(qresourceElem);
  297. foreach(const QString &widgetFile, m_generatorData.widgetSrcFiles()) {
  298. QDomElement fileElement = domDocument.createElement(QRC_FILE_TAG_FILE);
  299. QDomText newFileName = domDocument.createTextNode(widgetFile);
  300. fileElement.appendChild(newFileName);
  301. qresourceElem.appendChild(fileElement);
  302. }
  303. QFile qtResourceFile(qtResourceFileName);
  304. if(qtResourceFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
  305. QTextStream stream(&qtResourceFile);
  306. stream << domDocument.toString();
  307. qtResourceFile.close();
  308. }
  309. QString msg = QString(MSG_FILE_CREATED_SUCCESSFULLY).arg(m_infoPlistFileNameNoSpaces+".qrc");
  310. m_outputView.printOutput(msg);
  311. }
  312. bool FileUtilities::createWidgetProjectFile(const QList< QSharedPointer<HybridPlugin> > &plugins)
  313. {
  314. // OBS QString qtProjectTemplateFileName(m_generatorData.projectDirectory() + PROJECT_TEMPLATE_FILE);
  315. QString qtProjectTemplateFileName(m_generatorData.srcDirectory() + PROJECT_TEMPLATE_FILE);
  316. QString templateFileContent;
  317. QString errMsg = QString(ERR_FILE_OPEN_READ_FAILED_CANNOT_CONTINUE).arg(qtProjectTemplateFileName);
  318. if (!readTemplateFile(qtProjectTemplateFileName, templateFileContent, errMsg))
  319. return false;
  320. /// START CONTENT REPLACE
  321. // TODO: replace this whole class with the filecopier utility
  322. if (templateFileContent.contains(SDK_VERSION_DEFINES_TAG)) {
  323. templateFileContent.replace(SDK_VERSION_DEFINES_TAG, Settings::get(Settings::FullS60SDK).toBool() ? "" : "DEFINES += HAVE_NOKIAQTSDK");
  324. }
  325. if (templateFileContent.contains(TOOL_NAME_TAG)){
  326. templateFileContent.replace(TOOL_NAME_TAG, TOOL_NAME_STRING);
  327. }
  328. if (templateFileContent.contains(TIMSTAMP_TAG)) {
  329. templateFileContent.replace(TIMSTAMP_TAG, QDateTime::currentDateTime().toString(Qt::SystemLocaleShortDate));
  330. }
  331. if (templateFileContent.contains(APPLICATION_NAME_TAG)) {
  332. templateFileContent.replace(APPLICATION_NAME_TAG, m_generatorData.infoPlistValue(INFO_PLIST_KEY_DISPLAY_NAME));
  333. }
  334. if (templateFileContent.contains(RESOURCE_FILE_TAG)) {
  335. templateFileContent.replace(RESOURCE_FILE_TAG, m_infoPlistFileNameNoSpaces + ".qrc\n");
  336. }
  337. // Set plugin deployment directives
  338. if (templateFileContent.contains(PLUGIN_DEPLOYMENT_TAG)) {
  339. QString deployment;
  340. foreach (QSharedPointer<HybridPlugin> plugin, plugins)
  341. {
  342. if (plugin->selectedPlatform())
  343. {
  344. deployment += plugin->symbianDeploymentString(m_generatorData.isRemotelyCompiled());
  345. }
  346. }
  347. templateFileContent.replace(PLUGIN_DEPLOYMENT_TAG, deployment);
  348. }
  349. // UID3
  350. if (templateFileContent.contains(SYMBIAN_UID3_TAG)) {
  351. if (!Settings::get(Settings::UID3).toString().isEmpty()) {
  352. templateFileContent.replace(SYMBIAN_UID3_TAG, "TARGET.UID3 = " + Settings::get(Settings::UID3).toString());
  353. } else {
  354. templateFileContent.replace(SYMBIAN_UID3_TAG, "");
  355. }
  356. }
  357. /// END CONTENT REPLACE
  358. QString plainProjectFileName = m_infoPlistFileNameNoSpaces+".pro";
  359. // OBS QString qtProjectFileName(m_generatorData.projectDirectory() + "/" + plainProjectFileName);
  360. QString
  361. qtProjectFileName(m_generatorData.srcDirectory()
  362. + "/"
  363. + plainProjectFileName);
  364. QFile proFile(qtProjectFileName);
  365. if(proFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
  366. QTextStream stream(&proFile);
  367. stream << templateFileContent;
  368. QString msg = QString(MSG_FILE_CREATED_SUCCESSFULLY).arg(plainProjectFileName);
  369. m_outputView.printOutput(msg);
  370. }
  371. else {
  372. QString errMsg = QString(ERR_FILE_OPEN_WRITE_FAILED_CANNOT_CONTINUE).arg(qtProjectFileName);
  373. m_outputView.printOutput(errMsg);
  374. return false;
  375. }
  376. // remove the template file
  377. QFile::remove(qtProjectTemplateFileName);
  378. return true;
  379. }
  380. bool FileUtilities::createPluginsProjectFile(const QList< QSharedPointer<HybridPlugin> > &plugins)
  381. {
  382. QString pluginsProjectContent;
  383. foreach (QSharedPointer<HybridPlugin> plugin, plugins)
  384. {
  385. if (plugin->selectedPlatform())
  386. {
  387. qDebug() << "Plugin" << plugin->name() << "is selected, updating compilation list";
  388. if (plugin->selectedPlatform()->format() == HybridPluginPlatform::Source)
  389. {
  390. // Add the plugin to the plugins compilation list
  391. pluginsProjectContent += plugin->name() + " \\\n";
  392. // Prepare project file
  393. QString pluginProjectFile = m_generatorData.mwDirectory() + plugin->name() + "/" + plugin->name() + ".pro";
  394. if (!QFile::exists(pluginProjectFile))
  395. {
  396. // Plugin project file does not exist. Project file has to have a
  397. // same name as the directory -- qmake assumes so.
  398. m_outputView.printOutput("Could not find .pro file for plugin " + plugin->name() + "!");
  399. return false;
  400. }
  401. else
  402. {
  403. bool success = updateProjectFile(pluginProjectFile);
  404. if (!success)
  405. {
  406. // If project file update failed, the build process
  407. // won't be able to complete, so we should fail
  408. // already here.
  409. return false;
  410. }
  411. }
  412. }
  413. }
  414. }
  415. // Create the plugins project file
  416. QString fileName = m_generatorData.mwDirectory() + PLUGINS_PROJECT_FILE;
  417. QFile pluginsProjectFile(fileName);
  418. if (pluginsProjectFile.open(QIODevice::WriteOnly | QIODevice::Text))
  419. {
  420. QTextStream stream(&pluginsProjectFile);
  421. stream << QString(PLUGINS_PROJECT_FILE_CONTENT).arg(pluginsProjectContent);
  422. pluginsProjectFile.close();
  423. m_outputView.printOutput(QString(MSG_FILE_CREATED_SUCCESSFULLY).arg(PLUGINS_PROJECT_FILE));
  424. }
  425. else
  426. {
  427. m_outputView.printOutput(QString(ERR_FILE_OPEN_WRITE_FAILED_CANNOT_CONTINUE).arg(fileName));
  428. return false;
  429. }
  430. return true;
  431. }
  432. bool FileUtilities::configXmlToInfoPlistFile(WidgetType widgetType)
  433. {
  434. QMap<QString, QString> &configXmlData = m_generatorData.configXmlData();
  435. // OBS QString templateFullFileName = m_generatorData.projectDirectory() + INFO_PLIST_FILE;
  436. QString
  437. templateFullFileName = m_generatorData.srcDirectory() + INFO_PLIST_FILE;
  438. QString templateFileContent;
  439. QString errMsg = QString(ERR_FILE_OPEN_READ_FAILED_CANNOT_CONTINUE).arg(templateFullFileName);
  440. if (!readTemplateFile(templateFullFileName, templateFileContent, errMsg))
  441. return false;
  442. if (widgetType == OPERA_WIDGET)
  443. {
  444. templateFileContent.replace(INFO_PLIST_DISPLAY_NAME_TAG, configXmlData.value("widget.widgetname:", "OperaWidget"));
  445. templateFileContent.replace(INFO_PLIST_IDENTIFIER_TAG, configXmlData.value("widget.id.host:", "www.default.identifier"));
  446. templateFileContent.replace(INFO_PLIST_MAIN_HTML_TAG, W3C_MAIN_HTML_FILE);
  447. }
  448. else if(widgetType == W3C_WIDGET)
  449. {
  450. templateFileContent.replace(INFO_PLIST_DISPLAY_NAME_TAG, configXmlData.value("widget.name:", "W3CWidget"));
  451. templateFileContent.replace(INFO_PLIST_IDENTIFIER_TAG, configXmlData.value("widget:id", "www.default.identifier"));
  452. templateFileContent.replace(INFO_PLIST_MAIN_HTML_TAG, configXmlData.value("widget.content:src", "index.html"));
  453. }
  454. templateFileContent.replace(INFO_PLIST_VERSION_TAG, "1.0.0");
  455. QString infoPlistFullFileName = m_generatorData.widgetDirectory() + INFO_PLIST_FILE;
  456. QFile infoPlistFileOut(infoPlistFullFileName);
  457. if(!infoPlistFileOut.open(QIODevice::WriteOnly | QIODevice::Text)) {
  458. QString errMsg = QString(ERR_FILE_OPEN_WRITE_FAILED_CANNOT_CONTINUE).arg(infoPlistFullFileName);
  459. m_outputView.printOutput(errMsg);
  460. return false;
  461. }
  462. QTextStream streamOut(&infoPlistFileOut);
  463. streamOut << templateFileContent;
  464. infoPlistFileOut.close();
  465. QString msg = QString(MSG_FILE_CREATED_SUCCESSFULLY).arg(INFO_PLIST_FILE);
  466. m_outputView.printOutput(msg);
  467. // remove the template file
  468. QFile::remove(templateFullFileName);
  469. QString srcDir = m_generatorData.widgetDirectory();
  470. QString destDir;
  471. if(widgetType == OPERA_WIDGET)
  472. destDir = m_generatorData.widgetDirectory() + configXmlData.value("widget.widgetname;", "OperaWidget") + "/";
  473. else
  474. destDir = m_generatorData.widgetDirectory() + configXmlData.value("widget.name;", "W3CWidget") + "/";
  475. DirectoryUtilities dirUtil(m_outputView, m_generatorData);
  476. m_outputView.printOutput("OPERA1: " + srcDir);
  477. m_outputView.printOutput("OPERA2: " + destDir);
  478. return dirUtil.copyDirectory(srcDir, destDir, true);
  479. }
  480. /**
  481. * Creates a info.plist file for directories that do not contain one. Such
  482. * directory could be created by wget using the remote generator.
  483. */
  484. bool FileUtilities::directoryToInfoPlistFile()
  485. {
  486. // Find the name of the main HTML file. The directory may contains several
  487. // HTML files with arbitraty names, so detecting the right one may be a bit tricky.
  488. // TODO: this won't detect HTML files from subdirs
  489. m_outputView.printOutput("Preparing info.plist from directory contents");
  490. QStringList fileList = QFileInfo(m_generatorData.widgetDirectory()).dir().entryList(QDir::Files | QDir::Readable);
  491. QStringList htmlFiles;
  492. QString indexFile = "";
  493. foreach (QString file, fileList)
  494. {
  495. QRegExp rx;
  496. rx.setPattern("^(.*)\\.(htm|html)$");
  497. if (rx.indexIn(file) != -1)
  498. {
  499. if (rx.cap(1) == "index" || rx.cap(1) == "main")
  500. {
  501. // Main file found
  502. indexFile = file;
  503. }
  504. else
  505. {
  506. // Not a definite main file
  507. htmlFiles.append(file);
  508. }
  509. }
  510. }
  511. if (indexFile.isEmpty() && htmlFiles.count() > 0)
  512. {
  513. // For now, we'll just grab the first HTML
  514. // file if there was not a good candidate
  515. indexFile = htmlFiles.at(0);
  516. }
  517. if (indexFile.isEmpty())
  518. {
  519. m_outputView.printOutput("Appropriate main HTML file was not found!");
  520. return false;
  521. }
  522. else
  523. {
  524. m_outputView.printOutput("Using " + indexFile + " as the main HTML file");
  525. // OBS QString templateFullFileName = m_generatorData.projectDirectory() + INFO_PLIST_FILE;
  526. QString
  527. templateFullFileName = m_generatorData.srcDirectory() + INFO_PLIST_FILE;
  528. QString templateFileContent;
  529. QString errMsg = QString(ERR_FILE_OPEN_READ_FAILED_CANNOT_CONTINUE).arg(templateFullFileName);
  530. // Read template file contents to a variable
  531. if (!readTemplateFile(templateFullFileName, templateFileContent, errMsg))
  532. return false;
  533. templateFileContent.replace(INFO_PLIST_DISPLAY_NAME_TAG, m_generatorData.widgetFileName());
  534. templateFileContent.replace(INFO_PLIST_IDENTIFIER_TAG, m_generatorData.widgetFileName());
  535. templateFileContent.replace(INFO_PLIST_MAIN_HTML_TAG, indexFile);
  536. templateFileContent.replace(INFO_PLIST_VERSION_TAG, "1.0.0");
  537. // Try to open info.plist file for writing
  538. QString infoPlistFullFileName = m_generatorData.widgetDirectory() + INFO_PLIST_FILE;
  539. QFile infoPlistFileOut(infoPlistFullFileName);
  540. if (!infoPlistFileOut.open(QIODevice::WriteOnly | QIODevice::Text)) {
  541. m_outputView.printOutput(QString(ERR_FILE_OPEN_WRITE_FAILED_CANNOT_CONTINUE).arg(infoPlistFullFileName));
  542. return false;
  543. }
  544. // Write info.plist contents
  545. QTextStream streamOut(&infoPlistFileOut);
  546. streamOut << templateFileContent;
  547. infoPlistFileOut.close();
  548. // Print success note
  549. m_outputView.printOutput(QString(MSG_FILE_CREATED_SUCCESSFULLY).arg(INFO_PLIST_FILE));
  550. // remove the template file
  551. QFile::remove(templateFullFileName);
  552. return true;
  553. }
  554. }
  555. bool FileUtilities::readTemplateFile(const QString &fileName, QString &fileContent, const QString &onErrorMessage)
  556. {
  557. QFile templateFile(fileName);
  558. if (!templateFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
  559. m_outputView.printOutput(onErrorMessage);
  560. return false;
  561. }
  562. QTextStream stream(&templateFile);
  563. fileContent = stream.readAll();
  564. return true;
  565. }