123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588 |
- /****************************************************************************
- **
- ** Copyright (C) 2013 Jarek Pelczar <jpelczar@gmail.com>
- ** Copyright (C) 2014 Tomasz Olszak <olszak.tomasz@gmail.com>
- **
- ** This file is part of Qt Creator.
- **
- ** Commercial License Usage
- ** Licensees holding valid commercial Qt licenses may use this file in
- ** accordance with the commercial license agreement provided with the
- ** Software or, alternatively, in accordance with the terms contained in
- ** a written agreement between you and Digia. For licensing terms and
- ** conditions see http://qt.digia.com/licensing. For further information
- ** use the contact form at http://qt.digia.com/contact-us.
- **
- ** GNU Lesser General Public License Usage
- ** Alternatively, this file may be used under the terms of the GNU Lesser
- ** General Public License version 2.1 as published by the Free Software
- ** Foundation and appearing in the file LICENSE.LGPL included in the
- ** packaging of this file. Please review the following information to
- ** ensure the GNU Lesser General Public License version 2.1 requirements
- ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
- **
- ** In addition, as a special exception, Digia gives you certain additional
- ** rights. These rights are described in the Digia Qt LGPL Exception
- ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
- **
- ****************************************************************************/
- #include "tizenmanifesteditorwidget.h"
- #include "tizenmanifestdocument.h"
- #include "tizenmanifesteditor.h"
- #include "tizenconstants.h"
- #include <coreplugin/icore.h>
- #include <coreplugin/infobar.h>
- #include "botan/botan.h"
- #include <QResizeEvent>
- #include <QTimer>
- #include <QDomDocument>
- #include <QVBoxLayout>
- #include <QDebug>
- using namespace TextEditor;
- namespace Tizen {
- namespace Internal {
- static const char TIZEN_MANIFEST_EDITOR_GENERAL_PANE_CONTEXT_ID[] = "Tizen.Manifest.Editor.General.Pane.Context";
- static const char TIZEN_MANIFEST_EDITOR_INFO_BAR_ID[] = "Tizen.Manifest.Editor.Info.Bar.Id";
- TizenManifestEditorWidget::TizenManifestEditorWidget(QWidget *parent, TextEditor::TextEditorActionHandler * ah) :
- TextEditor::PlainTextEditorWidget(parent),
- m_actionHandler(ah),
- m_activePage(GeneralPage),
- m_dirty(false),
- m_stayClean(false)
- {
- QSharedPointer<TizenManifestDocument> doc(new TizenManifestDocument(this));
- doc->setMimeType(QLatin1String(Constants::TIZEN_MANIFEST_MIME_TYPE));
- setBaseTextDocument(doc);
- ah->setupActions(this);
- configure(QLatin1String(Constants::TIZEN_MANIFEST_MIME_TYPE));
- initializePage();
- setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
- setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
- m_parseTimer = new QTimer(this);
- m_parseTimer->setSingleShot(true);
- m_parseTimer->setInterval(800);
- connect(m_parseTimer, SIGNAL(timeout()), SLOT(delayedParseCheck()));
- connect(document(), SIGNAL(contentsChanged()), SLOT(startParseCheck()));
- }
- bool TizenManifestEditorWidget::isModified() const
- {
- return m_dirty;
- }
- bool TizenManifestEditorWidget::open(QString *errorString, const QString &fileName, const QString &realFileName)
- {
- if(!TextEditor::PlainTextEditorWidget::open(errorString, fileName, realFileName))
- return false;
- int errorLine, errorColumn;
- QString error;
- QDomDocument doc;
- if(doc.setContent(toPlainText(), &error, &errorLine, &errorColumn)) {
- if(checkDocument(doc, &error, &errorLine, &errorColumn)) {
- if(activePage() != SourcePage)
- syncToWidgets(doc);
- return true;
- }
- }
- updateInfoBar(error, errorLine, errorColumn);
- setActivePage(SourcePage);
- return true;
- }
- void TizenManifestEditorWidget::preSave()
- {
- if(activePage() != SourcePage)
- syncToEditor();
- updateInfoBar();
- }
- TizenManifestEditorWidget::EditorPage TizenManifestEditorWidget::activePage() const
- {
- return m_activePage;
- }
- bool TizenManifestEditorWidget::setActivePage(EditorPage page)
- {
- EditorPage prevPage = activePage();
- if(prevPage == page)
- return true;
- m_activePage = page;
- if(page == SourcePage) {
- syncToEditor();
- m_overlayWidget->setVisible(false);
- setFocus();
- setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
- setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
- } else {
- if(!syncToWidgets())
- return false;
- m_overlayWidget->setVisible(true);
- QWidget * fw = m_overlayWidget->focusWidget();
- if(fw && fw != m_overlayWidget)
- fw->setFocus();
- setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
- setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
- }
- return true;
- }
- TextEditor::BaseTextEditor * TizenManifestEditorWidget::createEditor()
- {
- return new TizenManifestEditor(this);
- }
- void TizenManifestEditorWidget::resizeEvent(QResizeEvent * e)
- {
- PlainTextEditorWidget::resizeEvent(e);
- m_overlayWidget->resize(this->size());
- }
- void TizenManifestEditorWidget::initializePage()
- {
- QWidget * mainWidget = new QWidget(this);
- mainWidget->setAutoFillBackground(true);
- mainWidget->setFocusPolicy(Qt::WheelFocus);
- Core::IContext * myContext = new Core::IContext(this);
- myContext->setWidget(mainWidget);
- myContext->setContext(Core::Context(TIZEN_MANIFEST_EDITOR_GENERAL_PANE_CONTEXT_ID));
- Core::ICore::addContextObject(myContext);
- m_form.setupUi(mainWidget);
- connect(m_form.addFeatureButton, SIGNAL(clicked()), SLOT(addFeatureClicked()));
- connect(m_form.removeFeatureButton, SIGNAL(clicked()), SLOT(removeFeatureClicked()));
- connect(m_form.featuresList, SIGNAL(itemSelectionChanged()), SLOT(updateFeaturesButton()));
- connect(m_form.featureValueComboBox, SIGNAL(currentIndexChanged(int)), SLOT(featureValueIndexChanged(int)));
- connect(m_form.generateAppIdButton, SIGNAL(clicked()), SLOT(generateAppId()));
- connect(m_form.authorLineEdit, SIGNAL(textChanged(QString)), SLOT(authorChanged(QString)));
- connect(m_form.urlLineEdit, SIGNAL(textChanged(QString)), SLOT(urlChanged(QString)));
- connect(m_form.applicationNameEditor,SIGNAL(textChanged(QString)),SLOT(setDirty()));
- connect(m_form.versionEditor,SIGNAL(textChanged(QString)),SLOT(setDirty()));
- connect(m_form.checkBoxShowMainMenuIcon,SIGNAL(toggled(bool)),SLOT(setDirty()));
- connect(m_form.checkBoxShowHideFromHistoryList,SIGNAL(toggled(bool)),SLOT(setDirty()));
- updateFeaturesButton();
- m_overlayWidget = mainWidget;
- }
- void TizenManifestEditorWidget::delayedParseCheck()
- {
- m_parseTimer->start();
- }
- void TizenManifestEditorWidget::startParseCheck()
- {
- updateInfoBar();
- }
- void TizenManifestEditorWidget::updateInfoBar()
- {
- if(activePage() != SourcePage) {
- m_parseTimer->stop();
- return;
- }
- QDomDocument doc;
- int errorLine, errorColumn;
- QString error;
- if(doc.setContent(toPlainText(), &error, &errorLine, &errorColumn)) {
- if(checkDocument(doc, &error, &errorLine, &errorColumn)) {
- hideInfoBar();
- return;
- }
- }
- updateInfoBar(error, errorLine, errorColumn);
- }
- void TizenManifestEditorWidget::setDirty(bool dirty)
- {
- if(m_stayClean)
- return;
- m_dirty = dirty;
- emit changed();
- }
- bool TizenManifestEditorWidget::checkDocument(QDomDocument doc, QString * errorMessage, int * errorLine, int * errorColumn)
- {
- QDomElement manifest = doc.documentElement();
- if(manifest.tagName() != QLatin1String("Manifest")) {
- *errorMessage = tr("Tizen Manifest file must begin with \"Manifest\" element");
- *errorLine = manifest.lineNumber();
- *errorColumn = manifest.columnNumber();
- return false;
- }
- return true;
- }
- void TizenManifestEditorWidget::updateInfoBar(QString errorMessage, int errorLine, int errorColumn)
- {
- Core::InfoBar * bar = editorDocument()->infoBar();
- QString text;
- if(errorLine < 0)
- text = tr("Could not parse file: '%1'").arg(errorMessage);
- else
- text = tr("%2: Could not parse file: '%1'").arg(errorMessage).arg(errorLine);
- Core::InfoBarEntry infoBarEntry(TIZEN_MANIFEST_EDITOR_INFO_BAR_ID, text);
- bar->removeInfo(TIZEN_MANIFEST_EDITOR_INFO_BAR_ID);
- bar->addInfo(infoBarEntry);
- m_errorLine = errorLine;
- m_errorColumn = errorColumn;
- m_parseTimer->stop();
- }
- void TizenManifestEditorWidget::hideInfoBar()
- {
- Core::InfoBar * bar = editorDocument()->infoBar();
- bar->removeInfo(TIZEN_MANIFEST_EDITOR_INFO_BAR_ID);
- m_parseTimer->stop();
- }
- bool TizenManifestEditorWidget::syncToWidgets()
- {
- QDomDocument doc;
- QString errorMessage;
- int errorLine, errorColumn;
- if(doc.setContent(toPlainText(), &errorMessage, &errorLine, &errorColumn)) {
- if(checkDocument(doc, &errorMessage, &errorLine, &errorColumn)) {
- hideInfoBar();
- syncToWidgets(doc);
- return true;
- }
- }
- updateInfoBar(errorMessage, errorLine, errorColumn);
- return false;
- }
- void TizenManifestEditorWidget::syncToWidgets(QDomDocument doc)
- {
- m_stayClean = true;
- QDomElement manifest = doc.documentElement();
- QDomElement appId = manifest.firstChildElement(QLatin1String("Id"));
- m_form.appIdEditor->setText(appId.text());
- QDomElement version = manifest.firstChildElement(QLatin1String("Version"));
- m_form.versionEditor->setText(version.text());
- QDomElement requirements = manifest.firstChildElement(QLatin1String("Requirements"));
- const QString kFeature(QLatin1String("Feature"));
- const QString kName(QLatin1String("Name"));
- QDomElement author = manifest.firstChildElement(QLatin1String("Author"));
- m_form.authorLineEdit->setText(author.text());
- QDomElement url = manifest.firstChildElement(QLatin1String("Url"));
- m_form.urlLineEdit->setText(url.text());
- QDomElement type = manifest.firstChildElement(QLatin1String("Type"));
- m_form.appTypeCombo->setCurrentIndex(m_form.appTypeCombo->findText(type.text()));
- QDomElement apps = manifest.firstChildElement(QLatin1String("Apps"));
- QDomElement uiApp = apps.firstChildElement(QLatin1String("UiApp"));
- m_form.applicationNameEditor->setText(uiApp.attribute(QLatin1String("Name")));
- m_form.checkBoxShowMainMenuIcon->setChecked(uiApp.attribute(QLatin1String("MenuIconVisible")).toLower() == QLatin1String("true"));
- m_form.checkBoxShowHideFromHistoryList->setChecked(uiApp.attribute(QLatin1String("LaunchingHistoryVisible")).toLower() == QLatin1String("true"));
- QDomElement displayNames = uiApp.firstChildElement(QLatin1String("DisplayNames"));
- m_form.displayNameTable->clearContents();
- QDomNodeList displayNamesNodeList = displayNames.elementsByTagName(QLatin1String("DisplayName"));
- m_form.displayNameTable->setRowCount(displayNamesNodeList.size());
- QDomElement displayName;
- for(int i = 0; i < displayNamesNodeList.size(); i++) {
- displayName = displayNamesNodeList.at(i).toElement();
- m_form.displayNameTable->setItem(i,0,new QTableWidgetItem(displayName.text()));
- m_form.displayNameTable->setItem(i,1,new QTableWidgetItem(displayName.attribute(QLatin1String("Locale"))));
- }
- m_form.featuresList->clear();
- m_featureValues.clear();
- QStringList features;
- for(QDomElement child = requirements.firstChildElement(kFeature) ; !child.isNull() ; child = child.nextSiblingElement(kFeature)) {
- QString name = child.attribute(kName);
- QString value = child.text().trimmed();
- m_form.featuresList->addItem(name);
- m_featureValues[name] = value;
- }
- m_form.featuresList->addItems(features);
- updateFeaturesButton();
- m_stayClean = false;
- m_dirty = false;
- }
- void TizenManifestEditorWidget::updateValue(QDomElement parent, const QString& element, const QString& value)
- {
- QDomDocument doc = parent.ownerDocument();
- QDomElement prevChild = parent.firstChildElement(element);
- QDomElement newChild;
- if(!value.isEmpty()) {
- newChild = doc.createElement(element);
- newChild.appendChild(doc.createTextNode(value));
- }
- if(prevChild.isNull()) {
- if(!value.isEmpty())
- parent.appendChild(newChild);
- } else {
- if(value.isEmpty())
- parent.removeChild(prevChild);
- else
- parent.replaceChild(newChild, prevChild);
- }
- }
- void TizenManifestEditorWidget::syncToEditor()
- {
- QDomDocument doc;
- if(!doc.setContent(toPlainText())) {
- updateInfoBar();
- return;
- }
- QDomElement manifest = doc.documentElement();
- QDomElement appId = manifest.firstChildElement(QLatin1String("Id"));
- QDomElement newAppId = doc.createElement(QLatin1String("Id"));
- newAppId.appendChild(doc.createTextNode(m_form.appIdEditor->text()));
- manifest.replaceChild(newAppId, appId);
- QDomElement version = manifest.firstChildElement(QLatin1String("Version"));
- QDomElement newVersion = doc.createElement(QLatin1String("Version"));
- newVersion.appendChild(doc.createTextNode(m_form.versionEditor->text())) ;
- manifest.replaceChild(newVersion, version);
- QDomElement apps = manifest.firstChildElement(QLatin1String("Apps"));
- QDomElement uiApp = apps.firstChildElement(QLatin1String("UiApp"));
- uiApp.setAttribute(QLatin1String("Name"),m_form.applicationNameEditor->text());
- QString menuIconVisibleValue = QLatin1String(m_form.checkBoxShowMainMenuIcon->isChecked() ? "True" : "False");
- QString launchHistoryVisible = QLatin1String(m_form.checkBoxShowHideFromHistoryList->isChecked() ? "True" : "False");
- uiApp.setAttribute(QLatin1String("MenuIconVisible"),menuIconVisibleValue);
- uiApp.setAttribute(QLatin1String("LaunchingHistoryVisible"),launchHistoryVisible);
- const QString kRequirements(QLatin1String("Requirements"));
- QDomElement features = doc.createElement(kRequirements);
- const QString kFeature(QLatin1String("Feature"));
- const QString kName(QLatin1String("Name"));
- updateValue(manifest, QLatin1String("Author"), m_form.authorLineEdit->text().trimmed());
- updateValue(manifest, QLatin1String("Url"), m_form.urlLineEdit->text().trimmed());
- for(int i = 0 ; i < m_form.featuresList->count() ; ++i) {
- QDomElement feature = doc.createElement(kFeature);
- feature.setAttribute(kName, m_form.featuresList->item(i)->text());
- feature.appendChild(doc.createTextNode(m_featureValues[m_form.featuresList->item(i)->text()]));
- features.appendChild(feature);
- }
- manifest.replaceChild(features, manifest.firstChildElement(kRequirements));
- QString newText = doc.toString(4);
- if(newText == toPlainText())
- return;
- setPlainText(newText);
- document()->setModified(true);
- m_dirty = false;
- }
- void TizenManifestEditorWidget::addFeatureClicked()
- {
- }
- void TizenManifestEditorWidget::removeFeatureClicked()
- {
- QModelIndex featureIndex = m_form.featuresList->currentIndex();
- if(featureIndex.isValid()) {
- QAbstractItemModel * model = m_form.featuresList->model();
- model->removeRow(featureIndex.row());
- setDirty();
- }
- }
- void TizenManifestEditorWidget::updateFeaturesButton()
- {
- m_form.removeFeatureButton->setDisabled(m_form.featuresList->currentItem() == NULL);
- if(m_featureValues.isEmpty() && m_form.featurePropertiesGroup->isVisible()) {
- m_form.featurePropertiesGroup->hide();
- } else if(m_form.featuresList->currentItem() == NULL && m_form.featurePropertiesGroup->isVisible()) {
- m_form.featurePropertiesGroup->hide();
- } else if(m_form.featuresList->currentItem()) {
- QListWidgetItem * item = m_form.featuresList->currentItem();
- QString key = item->text();
- QString value = m_featureValues.value(key);
- QHash<QString, QList<TizenFeatureValue> > features = this->features();
- QList<TizenFeatureValue> values = features.value(key);
- m_form.featureDescriptionLabel->setText(QString());
- QStringList comboValues;
- comboValues.reserve(values.size());
- int currentIndex = -1;
- int index = 0;
- foreach(const TizenFeatureValue& v, values) {
- comboValues.append(v.value);
- if(v.value == value) {
- currentIndex = index;
- m_form.featureDescriptionLabel->setText(v.description);
- } else {
- ++index;
- }
- }
- m_form.featureValueComboBox->clear();
- m_form.featureValueComboBox->addItems(comboValues);
- if(currentIndex != -1) {
- m_form.featureValueComboBox->setDisabled(comboValues.count() < 2);
- m_form.featureValueComboBox->setCurrentIndex(currentIndex);
- } else
- m_form.featureValueComboBox->setDisabled(true);
- if(!m_form.featurePropertiesGroup->isVisible())
- m_form.featurePropertiesGroup->show();
- }
- }
- void TizenManifestEditorWidget::featureValueIndexChanged(int index)
- {
- if(index < 0)
- return;
- if(QListWidgetItem * item = m_form.featuresList->currentItem()) {
- QString key = item->text();
- if(key != m_featureValues[key]) {
- m_featureValues[key] = m_form.featureValueComboBox->currentText();
- setDirty(true);
- }
- }
- }
- QHash<QString, QList<TizenManifestEditorWidget::TizenFeatureValue> > TizenManifestEditorWidget::features()
- {
- if(!m_features.isEmpty())
- return m_features;
- QDomDocument doc;
- QFile srcFile(QLatin1String(":/tizen/resource/features.xml"));
- if(srcFile.open(QFile::ReadOnly)) {
- QString errorText;
- int errorLine, errorColumn;
- if(doc.setContent(&srcFile, &errorText, &errorLine, &errorColumn)) {
- const QString kFeature(QLatin1String("Feature"));
- const QString kName(QLatin1String("Name"));
- const QString kOption(QLatin1String("Option"));
- const QString kValue(QLatin1String("Value"));
- const QString kDescription(QLatin1String("Description"));
- const QString kDefault(QLatin1String("Default"));
- QDomElement root = doc.documentElement();
- for(QDomElement feature = root.firstChildElement(kFeature) ; !feature.isNull() ; feature = feature.nextSiblingElement(kFeature)) {
- QString name = feature.attribute(kName);
- QList<TizenFeatureValue> options;
- for(QDomElement option = feature.firstChildElement(kOption) ; !option.isNull() ; option = option.nextSiblingElement(kOption)) {
- bool isDefault = option.attribute(kDefault) == QLatin1String("true");
- options.append(TizenFeatureValue(option.attribute(kValue), option.attribute(kDescription), isDefault));
- }
- m_features[name] = options;
- }
- } else {
- #ifdef QT_DEBUG
- qWarning() << "Can't parse XML with error" << errorText << "@" << errorLine << ":" << errorColumn;
- #endif
- }
- } else {
- #ifdef QT_DEBUG
- qWarning() << "Can't open features XML:" << srcFile.errorString();
- #endif
- }
- return m_features;
- }
- void TizenManifestEditorWidget::generateAppId()
- {
- static const char APP_ID_CHARS[] = "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
- Botan::AutoSeeded_RNG rng;
- rng.reseed();
- Botan::byte bytes[10];
- rng.randomize(bytes, sizeof(bytes));
- QString appId;
- appId.reserve(sizeof(bytes));
- for(int i = 0 ; i < (int)sizeof(bytes) ; ++i) {
- appId.append(QLatin1Char(APP_ID_CHARS[bytes[i] % (sizeof(APP_ID_CHARS) - 1)]));
- }
- m_form.appIdEditor->setText(appId);
- setDirty();
- }
- void TizenManifestEditorWidget::authorChanged(QString author)
- {
- Q_UNUSED(author)
- setDirty();
- }
- void TizenManifestEditorWidget::urlChanged(QString url)
- {
- Q_UNUSED(url)
- setDirty();
- }
- } // namespace Internal
- } // namespace Tizen
|