tizenmanifesteditorwidget.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586
  1. /****************************************************************************
  2. **
  3. ** Copyright (C) 2013 Jarek Pelczar <jpelczar@gmail.com>
  4. ** Copyright (C) 2013 Tomasz Olszak <olszak.tomasz@gmail.com>
  5. **
  6. ** This file is part of Qt Creator.
  7. **
  8. ** Commercial License Usage
  9. ** Licensees holding valid commercial Qt licenses may use this file in
  10. ** accordance with the commercial license agreement provided with the
  11. ** Software or, alternatively, in accordance with the terms contained in
  12. ** a written agreement between you and Digia. For licensing terms and
  13. ** conditions see http://qt.digia.com/licensing. For further information
  14. ** use the contact form at http://qt.digia.com/contact-us.
  15. **
  16. ** GNU Lesser General Public License Usage
  17. ** Alternatively, this file may be used under the terms of the GNU Lesser
  18. ** General Public License version 2.1 as published by the Free Software
  19. ** Foundation and appearing in the file LICENSE.LGPL included in the
  20. ** packaging of this file. Please review the following information to
  21. ** ensure the GNU Lesser General Public License version 2.1 requirements
  22. ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
  23. **
  24. ** In addition, as a special exception, Digia gives you certain additional
  25. ** rights. These rights are described in the Digia Qt LGPL Exception
  26. ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
  27. **
  28. ****************************************************************************/
  29. #include "tizenmanifesteditorwidget.h"
  30. #include "tizenmanifestdocument.h"
  31. #include "tizenmanifesteditor.h"
  32. #include "tizenconstants.h"
  33. #include <coreplugin/icore.h>
  34. #include <coreplugin/infobar.h>
  35. #include "botan/botan.h"
  36. #include <QResizeEvent>
  37. #include <QTimer>
  38. #include <QDomDocument>
  39. #include <QVBoxLayout>
  40. #include <QDebug>
  41. using namespace TextEditor;
  42. namespace Tizen {
  43. static const char TIZEN_MANIFEST_EDITOR_GENERAL_PANE_CONTEXT_ID[] = "Tizen.Manifest.Editor.General.Pane.Context";
  44. static const char TIZEN_MANIFEST_EDITOR_INFO_BAR_ID[] = "Tizen.Manifest.Editor.Info.Bar.Id";
  45. TizenManifestEditorWidget::TizenManifestEditorWidget(QWidget *parent, TextEditor::TextEditorActionHandler * ah) :
  46. TextEditor::PlainTextEditorWidget(parent),
  47. m_actionHandler(ah),
  48. m_activePage(GeneralPage),
  49. m_dirty(false),
  50. m_stayClean(false)
  51. {
  52. QSharedPointer<TizenManifestDocument> doc(new TizenManifestDocument(this));
  53. doc->setMimeType(QLatin1String(Constants::TIZEN_MANIFEST_MIME_TYPE));
  54. setBaseTextDocument(doc);
  55. ah->setupActions(this);
  56. configure(QLatin1String(Constants::TIZEN_MANIFEST_MIME_TYPE));
  57. initializePage();
  58. setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
  59. setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
  60. m_parseTimer = new QTimer(this);
  61. m_parseTimer->setSingleShot(true);
  62. m_parseTimer->setInterval(800);
  63. connect(m_parseTimer, SIGNAL(timeout()), SLOT(delayedParseCheck()));
  64. connect(document(), SIGNAL(contentsChanged()), SLOT(startParseCheck()));
  65. }
  66. bool TizenManifestEditorWidget::isModified() const
  67. {
  68. return m_dirty;
  69. }
  70. bool TizenManifestEditorWidget::open(QString *errorString, const QString &fileName, const QString &realFileName)
  71. {
  72. if(!TextEditor::PlainTextEditorWidget::open(errorString, fileName, realFileName))
  73. return false;
  74. int errorLine, errorColumn;
  75. QString error;
  76. QDomDocument doc;
  77. if(doc.setContent(toPlainText(), &error, &errorLine, &errorColumn)) {
  78. if(checkDocument(doc, &error, &errorLine, &errorColumn)) {
  79. if(activePage() != SourcePage)
  80. syncToWidgets(doc);
  81. return true;
  82. }
  83. }
  84. updateInfoBar(error, errorLine, errorColumn);
  85. setActivePage(SourcePage);
  86. return true;
  87. }
  88. void TizenManifestEditorWidget::preSave()
  89. {
  90. if(activePage() != SourcePage)
  91. syncToEditor();
  92. updateInfoBar();
  93. }
  94. TizenManifestEditorWidget::EditorPage TizenManifestEditorWidget::activePage() const
  95. {
  96. return m_activePage;
  97. }
  98. bool TizenManifestEditorWidget::setActivePage(EditorPage page)
  99. {
  100. EditorPage prevPage = activePage();
  101. if(prevPage == page)
  102. return true;
  103. m_activePage = page;
  104. if(page == SourcePage) {
  105. syncToEditor();
  106. m_overlayWidget->setVisible(false);
  107. setFocus();
  108. setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
  109. setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
  110. } else {
  111. if(!syncToWidgets())
  112. return false;
  113. m_overlayWidget->setVisible(true);
  114. QWidget * fw = m_overlayWidget->focusWidget();
  115. if(fw && fw != m_overlayWidget)
  116. fw->setFocus();
  117. setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
  118. setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
  119. }
  120. return true;
  121. }
  122. TextEditor::BaseTextEditor * TizenManifestEditorWidget::createEditor()
  123. {
  124. return new TizenManifestEditor(this);
  125. }
  126. void TizenManifestEditorWidget::resizeEvent(QResizeEvent * e)
  127. {
  128. PlainTextEditorWidget::resizeEvent(e);
  129. m_overlayWidget->resize(this->size());
  130. }
  131. void TizenManifestEditorWidget::initializePage()
  132. {
  133. QWidget * mainWidget = new QWidget(this);
  134. mainWidget->setAutoFillBackground(true);
  135. mainWidget->setFocusPolicy(Qt::WheelFocus);
  136. Core::IContext * myContext = new Core::IContext(this);
  137. myContext->setWidget(mainWidget);
  138. myContext->setContext(Core::Context(TIZEN_MANIFEST_EDITOR_GENERAL_PANE_CONTEXT_ID));
  139. Core::ICore::addContextObject(myContext);
  140. m_form.setupUi(mainWidget);
  141. connect(m_form.addFeatureButton, SIGNAL(clicked()), SLOT(addFeatureClicked()));
  142. connect(m_form.removeFeatureButton, SIGNAL(clicked()), SLOT(removeFeatureClicked()));
  143. connect(m_form.featuresList, SIGNAL(itemSelectionChanged()), SLOT(updateFeaturesButton()));
  144. connect(m_form.featureValueComboBox, SIGNAL(currentIndexChanged(int)), SLOT(featureValueIndexChanged(int)));
  145. connect(m_form.generateAppIdButton, SIGNAL(clicked()), SLOT(generateAppId()));
  146. connect(m_form.authorLineEdit, SIGNAL(textChanged(QString)), SLOT(authorChanged(QString)));
  147. connect(m_form.urlLineEdit, SIGNAL(textChanged(QString)), SLOT(urlChanged(QString)));
  148. connect(m_form.applicationNameEditor,SIGNAL(textChanged(QString)),SLOT(setDirty()));
  149. connect(m_form.versionEditor,SIGNAL(textChanged(QString)),SLOT(setDirty()));
  150. connect(m_form.checkBoxShowMainMenuIcon,SIGNAL(toggled(bool)),SLOT(setDirty()));
  151. connect(m_form.checkBoxShowHideFromHistoryList,SIGNAL(toggled(bool)),SLOT(setDirty()));
  152. updateFeaturesButton();
  153. m_overlayWidget = mainWidget;
  154. }
  155. void TizenManifestEditorWidget::delayedParseCheck()
  156. {
  157. m_parseTimer->start();
  158. }
  159. void TizenManifestEditorWidget::startParseCheck()
  160. {
  161. updateInfoBar();
  162. }
  163. void TizenManifestEditorWidget::updateInfoBar()
  164. {
  165. if(activePage() != SourcePage) {
  166. m_parseTimer->stop();
  167. return;
  168. }
  169. QDomDocument doc;
  170. int errorLine, errorColumn;
  171. QString error;
  172. if(doc.setContent(toPlainText(), &error, &errorLine, &errorColumn)) {
  173. if(checkDocument(doc, &error, &errorLine, &errorColumn)) {
  174. hideInfoBar();
  175. return;
  176. }
  177. }
  178. updateInfoBar(error, errorLine, errorColumn);
  179. }
  180. void TizenManifestEditorWidget::setDirty(bool dirty)
  181. {
  182. if(m_stayClean)
  183. return;
  184. m_dirty = dirty;
  185. emit changed();
  186. }
  187. bool TizenManifestEditorWidget::checkDocument(QDomDocument doc, QString * errorMessage, int * errorLine, int * errorColumn)
  188. {
  189. QDomElement manifest = doc.documentElement();
  190. if(manifest.tagName() != QLatin1String("Manifest")) {
  191. *errorMessage = tr("Tizen Manifest file must begin with \"Manifest\" element");
  192. *errorLine = manifest.lineNumber();
  193. *errorColumn = manifest.columnNumber();
  194. return false;
  195. }
  196. return true;
  197. }
  198. void TizenManifestEditorWidget::updateInfoBar(QString errorMessage, int errorLine, int errorColumn)
  199. {
  200. Core::InfoBar * bar = editorDocument()->infoBar();
  201. QString text;
  202. if(errorLine < 0)
  203. text = tr("Could not parse file: '%1'").arg(errorMessage);
  204. else
  205. text = tr("%2: Could not parse file: '%1'").arg(errorMessage).arg(errorLine);
  206. Core::InfoBarEntry infoBarEntry(TIZEN_MANIFEST_EDITOR_INFO_BAR_ID, text);
  207. bar->removeInfo(TIZEN_MANIFEST_EDITOR_INFO_BAR_ID);
  208. bar->addInfo(infoBarEntry);
  209. m_errorLine = errorLine;
  210. m_errorColumn = errorColumn;
  211. m_parseTimer->stop();
  212. }
  213. void TizenManifestEditorWidget::hideInfoBar()
  214. {
  215. Core::InfoBar * bar = editorDocument()->infoBar();
  216. bar->removeInfo(TIZEN_MANIFEST_EDITOR_INFO_BAR_ID);
  217. m_parseTimer->stop();
  218. }
  219. bool TizenManifestEditorWidget::syncToWidgets()
  220. {
  221. QDomDocument doc;
  222. QString errorMessage;
  223. int errorLine, errorColumn;
  224. if(doc.setContent(toPlainText(), &errorMessage, &errorLine, &errorColumn)) {
  225. if(checkDocument(doc, &errorMessage, &errorLine, &errorColumn)) {
  226. hideInfoBar();
  227. syncToWidgets(doc);
  228. return true;
  229. }
  230. }
  231. updateInfoBar(errorMessage, errorLine, errorColumn);
  232. return false;
  233. }
  234. void TizenManifestEditorWidget::syncToWidgets(QDomDocument doc)
  235. {
  236. m_stayClean = true;
  237. QDomElement manifest = doc.documentElement();
  238. QDomElement appId = manifest.firstChildElement(QLatin1String("Id"));
  239. m_form.appIdEditor->setText(appId.text());
  240. QDomElement version = manifest.firstChildElement(QLatin1String("Version"));
  241. m_form.versionEditor->setText(version.text());
  242. QDomElement requirements = manifest.firstChildElement(QLatin1String("Requirements"));
  243. const QString kFeature(QLatin1String("Feature"));
  244. const QString kName(QLatin1String("Name"));
  245. QDomElement author = manifest.firstChildElement(QLatin1String("Author"));
  246. m_form.authorLineEdit->setText(author.text());
  247. QDomElement url = manifest.firstChildElement(QLatin1String("Url"));
  248. m_form.urlLineEdit->setText(url.text());
  249. QDomElement type = manifest.firstChildElement(QLatin1String("Type"));
  250. m_form.appTypeCombo->setCurrentIndex(m_form.appTypeCombo->findText(type.text()));
  251. QDomElement apps = manifest.firstChildElement(QLatin1String("Apps"));
  252. QDomElement uiApp = apps.firstChildElement(QLatin1String("UiApp"));
  253. m_form.applicationNameEditor->setText(uiApp.attribute(QLatin1String("Name")));
  254. m_form.checkBoxShowMainMenuIcon->setChecked(uiApp.attribute(QLatin1String("MenuIconVisible")).toLower() == QLatin1String("true"));
  255. m_form.checkBoxShowHideFromHistoryList->setChecked(uiApp.attribute(QLatin1String("LaunchingHistoryVisible")).toLower() == QLatin1String("true"));
  256. QDomElement displayNames = uiApp.firstChildElement(QLatin1String("DisplayNames"));
  257. m_form.displayNameTable->clearContents();
  258. QDomNodeList displayNamesNodeList = displayNames.elementsByTagName(QLatin1String("DisplayName"));
  259. m_form.displayNameTable->setRowCount(displayNamesNodeList.size());
  260. QDomElement displayName;
  261. for(int i = 0; i < displayNamesNodeList.size(); i++) {
  262. displayName = displayNamesNodeList.at(i).toElement();
  263. m_form.displayNameTable->setItem(i,0,new QTableWidgetItem(displayName.text()));
  264. m_form.displayNameTable->setItem(i,1,new QTableWidgetItem(displayName.attribute(QLatin1String("Locale"))));
  265. }
  266. m_form.featuresList->clear();
  267. m_featureValues.clear();
  268. QStringList features;
  269. for(QDomElement child = requirements.firstChildElement(kFeature) ; !child.isNull() ; child = child.nextSiblingElement(kFeature)) {
  270. QString name = child.attribute(kName);
  271. QString value = child.text().trimmed();
  272. m_form.featuresList->addItem(name);
  273. m_featureValues[name] = value;
  274. }
  275. m_form.featuresList->addItems(features);
  276. updateFeaturesButton();
  277. m_stayClean = false;
  278. m_dirty = false;
  279. }
  280. void TizenManifestEditorWidget::updateValue(QDomElement parent, const QString& element, const QString& value)
  281. {
  282. QDomDocument doc = parent.ownerDocument();
  283. QDomElement prevChild = parent.firstChildElement(element);
  284. QDomElement newChild;
  285. if(!value.isEmpty()) {
  286. newChild = doc.createElement(element);
  287. newChild.appendChild(doc.createTextNode(value));
  288. }
  289. if(prevChild.isNull()) {
  290. if(!value.isEmpty())
  291. parent.appendChild(newChild);
  292. } else {
  293. if(value.isEmpty())
  294. parent.removeChild(prevChild);
  295. else
  296. parent.replaceChild(newChild, prevChild);
  297. }
  298. }
  299. void TizenManifestEditorWidget::syncToEditor()
  300. {
  301. QDomDocument doc;
  302. if(!doc.setContent(toPlainText())) {
  303. updateInfoBar();
  304. return;
  305. }
  306. QDomElement manifest = doc.documentElement();
  307. QDomElement appId = manifest.firstChildElement(QLatin1String("Id"));
  308. QDomElement newAppId = doc.createElement(QLatin1String("Id"));
  309. newAppId.appendChild(doc.createTextNode(m_form.appIdEditor->text()));
  310. manifest.replaceChild(newAppId, appId);
  311. QDomElement version = manifest.firstChildElement(QLatin1String("Version"));
  312. QDomElement newVersion = doc.createElement(QLatin1String("Version"));
  313. newVersion.appendChild(doc.createTextNode(m_form.versionEditor->text())) ;
  314. manifest.replaceChild(newVersion, version);
  315. QDomElement apps = manifest.firstChildElement(QLatin1String("Apps"));
  316. QDomElement uiApp = apps.firstChildElement(QLatin1String("UiApp"));
  317. uiApp.setAttribute(QLatin1String("Name"),m_form.applicationNameEditor->text());
  318. QString menuIconVisibleValue = QLatin1String(m_form.checkBoxShowMainMenuIcon->isChecked() ? "True" : "False");
  319. QString launchHistoryVisible = QLatin1String(m_form.checkBoxShowHideFromHistoryList->isChecked() ? "True" : "False");
  320. uiApp.setAttribute(QLatin1String("MenuIconVisible"),menuIconVisibleValue);
  321. uiApp.setAttribute(QLatin1String("LaunchingHistoryVisible"),launchHistoryVisible);
  322. const QString kRequirements(QLatin1String("Requirements"));
  323. QDomElement features = doc.createElement(kRequirements);
  324. const QString kFeature(QLatin1String("Feature"));
  325. const QString kName(QLatin1String("Name"));
  326. updateValue(manifest, QLatin1String("Author"), m_form.authorLineEdit->text().trimmed());
  327. updateValue(manifest, QLatin1String("Url"), m_form.urlLineEdit->text().trimmed());
  328. for(int i = 0 ; i < m_form.featuresList->count() ; ++i) {
  329. QDomElement feature = doc.createElement(kFeature);
  330. feature.setAttribute(kName, m_form.featuresList->item(i)->text());
  331. feature.appendChild(doc.createTextNode(m_featureValues[m_form.featuresList->item(i)->text()]));
  332. features.appendChild(feature);
  333. }
  334. manifest.replaceChild(features, manifest.firstChildElement(kRequirements));
  335. QString newText = doc.toString(4);
  336. if(newText == toPlainText())
  337. return;
  338. setPlainText(newText);
  339. document()->setModified(true);
  340. m_dirty = false;
  341. }
  342. void TizenManifestEditorWidget::addFeatureClicked()
  343. {
  344. }
  345. void TizenManifestEditorWidget::removeFeatureClicked()
  346. {
  347. QModelIndex featureIndex = m_form.featuresList->currentIndex();
  348. if(featureIndex.isValid()) {
  349. QAbstractItemModel * model = m_form.featuresList->model();
  350. model->removeRow(featureIndex.row());
  351. setDirty();
  352. }
  353. }
  354. void TizenManifestEditorWidget::updateFeaturesButton()
  355. {
  356. m_form.removeFeatureButton->setDisabled(m_form.featuresList->currentItem() == NULL);
  357. if(m_featureValues.isEmpty() && m_form.featurePropertiesGroup->isVisible()) {
  358. m_form.featurePropertiesGroup->hide();
  359. } else if(m_form.featuresList->currentItem() == NULL && m_form.featurePropertiesGroup->isVisible()) {
  360. m_form.featurePropertiesGroup->hide();
  361. } else if(m_form.featuresList->currentItem()) {
  362. QListWidgetItem * item = m_form.featuresList->currentItem();
  363. QString key = item->text();
  364. QString value = m_featureValues.value(key);
  365. QHash<QString, QList<TizenFeatureValue> > features = this->features();
  366. QList<TizenFeatureValue> values = features.value(key);
  367. m_form.featureDescriptionLabel->setText(QString());
  368. QStringList comboValues;
  369. comboValues.reserve(values.size());
  370. int currentIndex = -1;
  371. int index = 0;
  372. foreach(const TizenFeatureValue& v, values) {
  373. comboValues.append(v.value);
  374. if(v.value == value) {
  375. currentIndex = index;
  376. m_form.featureDescriptionLabel->setText(v.description);
  377. } else {
  378. ++index;
  379. }
  380. }
  381. m_form.featureValueComboBox->clear();
  382. m_form.featureValueComboBox->addItems(comboValues);
  383. if(currentIndex != -1) {
  384. m_form.featureValueComboBox->setDisabled(comboValues.count() < 2);
  385. m_form.featureValueComboBox->setCurrentIndex(currentIndex);
  386. } else
  387. m_form.featureValueComboBox->setDisabled(true);
  388. if(!m_form.featurePropertiesGroup->isVisible())
  389. m_form.featurePropertiesGroup->show();
  390. }
  391. }
  392. void TizenManifestEditorWidget::featureValueIndexChanged(int index)
  393. {
  394. if(index < 0)
  395. return;
  396. if(QListWidgetItem * item = m_form.featuresList->currentItem()) {
  397. QString key = item->text();
  398. if(key != m_featureValues[key]) {
  399. m_featureValues[key] = m_form.featureValueComboBox->currentText();
  400. setDirty(true);
  401. }
  402. }
  403. }
  404. QHash<QString, QList<TizenManifestEditorWidget::TizenFeatureValue> > TizenManifestEditorWidget::features()
  405. {
  406. if(!m_features.isEmpty())
  407. return m_features;
  408. QDomDocument doc;
  409. QFile srcFile(QLatin1String(":/tizen/resource/features.xml"));
  410. if(srcFile.open(QFile::ReadOnly)) {
  411. QString errorText;
  412. int errorLine, errorColumn;
  413. if(doc.setContent(&srcFile, &errorText, &errorLine, &errorColumn)) {
  414. const QString kFeature(QLatin1String("Feature"));
  415. const QString kName(QLatin1String("Name"));
  416. const QString kOption(QLatin1String("Option"));
  417. const QString kValue(QLatin1String("Value"));
  418. const QString kDescription(QLatin1String("Description"));
  419. const QString kDefault(QLatin1String("Default"));
  420. QDomElement root = doc.documentElement();
  421. for(QDomElement feature = root.firstChildElement(kFeature) ; !feature.isNull() ; feature = feature.nextSiblingElement(kFeature)) {
  422. QString name = feature.attribute(kName);
  423. QList<TizenFeatureValue> options;
  424. for(QDomElement option = feature.firstChildElement(kOption) ; !option.isNull() ; option = option.nextSiblingElement(kOption)) {
  425. bool isDefault = option.attribute(kDefault) == QLatin1String("true");
  426. options.append(TizenFeatureValue(option.attribute(kValue), option.attribute(kDescription), isDefault));
  427. }
  428. m_features[name] = options;
  429. }
  430. } else {
  431. #ifdef QT_DEBUG
  432. qWarning() << "Can't parse XML with error" << errorText << "@" << errorLine << ":" << errorColumn;
  433. #endif
  434. }
  435. } else {
  436. #ifdef QT_DEBUG
  437. qWarning() << "Can't open features XML:" << srcFile.errorString();
  438. #endif
  439. }
  440. return m_features;
  441. }
  442. void TizenManifestEditorWidget::generateAppId()
  443. {
  444. static const char APP_ID_CHARS[] = "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
  445. Botan::AutoSeeded_RNG rng;
  446. rng.reseed();
  447. Botan::byte bytes[10];
  448. rng.randomize(bytes, sizeof(bytes));
  449. QString appId;
  450. appId.reserve(sizeof(bytes));
  451. for(int i = 0 ; i < (int)sizeof(bytes) ; ++i) {
  452. appId.append(QLatin1Char(APP_ID_CHARS[bytes[i] % (sizeof(APP_ID_CHARS) - 1)]));
  453. }
  454. m_form.appIdEditor->setText(appId);
  455. setDirty();
  456. }
  457. void TizenManifestEditorWidget::authorChanged(QString author)
  458. {
  459. Q_UNUSED(author)
  460. setDirty();
  461. }
  462. void TizenManifestEditorWidget::urlChanged(QString url)
  463. {
  464. Q_UNUSED(url)
  465. setDirty();
  466. }
  467. } // namespace Tizen