diff -r cfcbf08528c4 -r 2b40d63a9c3d qtmobility/tools/servicexmlgen/interfacewidget.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/qtmobility/tools/servicexmlgen/interfacewidget.cpp Fri Apr 16 15:51:22 2010 +0300 @@ -0,0 +1,428 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Mobility Components. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** 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, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "interfacewidget.h" +#include "mandatorylineedit.h" +#include "errorcollector.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +QTM_USE_NAMESPACE + +class EditableListWidgetGroup : public QWidget +{ + Q_OBJECT +public: + EditableListWidgetGroup(QWidget *parent = 0); + +signals: + void dataChanged(); + +protected: + virtual int addItem() = 0; + virtual bool removeItemAt(int index) = 0; + virtual QStringList listValues() const = 0; + + void initLayout(QLayout *addItemLayout, const QString &buttonAddText); + void refreshView(); + void setAddButtonEnabled(bool enabled); + +private slots: + void clickedAdd(); + void clickedRemove(); + void currentRowChanged(const QModelIndex ¤t, const QModelIndex &previous); + +private: + QString defaultValue() const; + + QStringListModel *m_model; + QListView *m_listView; + QPushButton *m_buttonAdd; + QPushButton *m_buttonDel; + QGridLayout *m_grid; +}; + +EditableListWidgetGroup::EditableListWidgetGroup(QWidget *parent) + : QWidget(parent), + m_model(new QStringListModel(this)), + m_listView(new QListView), + m_buttonAdd(new QPushButton), + m_buttonDel(new QPushButton(tr("Delete"))), + m_grid(new QGridLayout) +{ + m_listView->setEditTriggers(QAbstractItemView::NoEditTriggers); +} + +void EditableListWidgetGroup::initLayout(QLayout *addItemLayout, const QString &buttonAddText) +{ + m_buttonAdd->setText(buttonAddText); + + m_grid->setContentsMargins(0, 0, 0, 0); + m_grid->addWidget(m_listView, 0, 0); + m_grid->addWidget(m_buttonDel, 0, 1, Qt::AlignTop); + m_grid->addWidget(m_buttonAdd, 1, 1); + + if (addItemLayout) + m_grid->addLayout(addItemLayout, 1, 0); + + m_model->setStringList(QStringList(defaultValue())); + m_listView->setModel(m_model); + + m_buttonAdd->setEnabled(false); + m_buttonDel->setEnabled(false); + + connect(m_buttonAdd, SIGNAL(clicked()), SLOT(clickedAdd())); + connect(m_buttonDel, SIGNAL(clicked()), SLOT(clickedRemove())); + connect(m_listView->selectionModel(), SIGNAL(currentRowChanged(QModelIndex,QModelIndex)), + SLOT(currentRowChanged(QModelIndex,QModelIndex))); + + setLayout(m_grid); +} + +void EditableListWidgetGroup::refreshView() +{ + QStringList values = listValues(); + if (values.isEmpty()) + m_model->setStringList(QStringList(defaultValue())); + else + m_model->setStringList(values); +} + +void EditableListWidgetGroup::setAddButtonEnabled(bool enabled) +{ + m_buttonAdd->setEnabled(enabled); +} + +void EditableListWidgetGroup::clickedAdd() +{ + int index = addItem(); + if (index >= 0) { + refreshView(); + m_listView->setCurrentIndex(m_model->index(index)); + emit dataChanged(); + } +} + +void EditableListWidgetGroup::clickedRemove() +{ + QModelIndex index = m_listView->currentIndex(); + if (index.isValid() && removeItemAt(index.row())) { + refreshView(); + m_listView->setCurrentIndex(m_model->index(index.row() == 0 ? 0 : index.row()-1)); + emit dataChanged(); + } +} + +void EditableListWidgetGroup::currentRowChanged(const QModelIndex ¤t, const QModelIndex &previous) +{ + Q_UNUSED(previous); + m_buttonDel->setEnabled(current.isValid() && listValues().count() > 0); +} + +QString EditableListWidgetGroup::defaultValue() const +{ + return tr("(None)"); +} + + +class CapabilitiesWidget : public EditableListWidgetGroup +{ + Q_OBJECT +public: + CapabilitiesWidget(QWidget *parent = 0); + + void setCapabilities(const QStringList &values); + const QStringList &capabilities() const { return m_values; } + +protected: + virtual int addItem(); + virtual bool removeItemAt(int index); + virtual QStringList listValues() const; + +private slots: + void valueToAddChanged(const QString &text); + +private: + QStringList m_values; + QLineEdit *m_newValueEdit; +}; + +CapabilitiesWidget::CapabilitiesWidget(QWidget *parent) + : EditableListWidgetGroup(parent), + m_newValueEdit(new QLineEdit) +{ + connect(m_newValueEdit, SIGNAL(textChanged(QString)), + SLOT(valueToAddChanged(QString))); + + QHBoxLayout *box = new QHBoxLayout; + box->addWidget(m_newValueEdit); + initLayout(box, tr("Add")); +} + +void CapabilitiesWidget::setCapabilities(const QStringList &values) +{ + m_values = values; + refreshView(); +} + +int CapabilitiesWidget::addItem() +{ + if (!m_newValueEdit->text().isEmpty()) { + m_values << m_newValueEdit->text(); + m_newValueEdit->clear(); + return m_values.count() - 1; + } + return -1; +} + +bool CapabilitiesWidget::removeItemAt(int index) +{ + if (index >= 0 && index < m_values.count()) { + m_values.removeAt(index); + return true; + } + return false; +} + +QStringList CapabilitiesWidget::listValues() const +{ + return m_values; +} + +void CapabilitiesWidget::valueToAddChanged(const QString &text) +{ + setAddButtonEnabled(!text.isEmpty()); +} + + +class CustomPropertiesWidget : public EditableListWidgetGroup +{ + Q_OBJECT +public: + CustomPropertiesWidget(QWidget *parent = 0); + + void setProperties(const QHash &values); + + const QStringList &propertyKeys() const { return m_keys; } + const QHash &properties() const { return m_pairs; } + +protected: + virtual int addItem(); + virtual bool removeItemAt(int index); + virtual QStringList listValues() const; + +private slots: + void keyToAddChanged(const QString &text); + +private: + QStringList m_keys; + QHash m_pairs; + QLineEdit *m_newKeyEdit; + QLineEdit *m_newValueEdit; +}; + +CustomPropertiesWidget::CustomPropertiesWidget(QWidget *parent) + : EditableListWidgetGroup(parent), + m_newKeyEdit(new QLineEdit), + m_newValueEdit(new QLineEdit) +{ + connect(m_newKeyEdit, SIGNAL(textChanged(QString)), + SLOT(keyToAddChanged(QString))); + + QHBoxLayout *box = new QHBoxLayout; + box->addWidget(m_newKeyEdit); + box->addWidget(new QLabel(QLatin1String("=>"))); + box->addWidget(m_newValueEdit); + initLayout(box, tr("Add / Modify")); +} + +void CustomPropertiesWidget::setProperties(const QHash &values) +{ + m_pairs = values; + m_keys = m_pairs.keys(); + refreshView(); +} + +int CustomPropertiesWidget::addItem() +{ + int index = -1; + QString key = m_newKeyEdit->text(); + if (!key.isEmpty()) { + index = m_keys.indexOf(key); + if (index < 0) { + m_keys << key; + index = m_keys.count() - 1; + } + m_pairs[key] = m_newValueEdit->text(); + m_newKeyEdit->clear(); + m_newValueEdit->clear(); + } + return index; +} + +bool CustomPropertiesWidget::removeItemAt(int index) +{ + if (index >= 0 && index < m_keys.count()) { + m_pairs.remove(m_keys.takeAt(index)); + return true; + } + return false; +} + +QStringList CustomPropertiesWidget::listValues() const +{ + QStringList values; + for (int i=0; i " + m_pairs[m_keys[i]]); + return values; +} + +void CustomPropertiesWidget::keyToAddChanged(const QString &text) +{ + setAddButtonEnabled(!text.isEmpty()); +} + + +InterfaceWidget::InterfaceWidget(QWidget *parent) + : QWidget(parent), + m_name(new MandatoryLineEdit(tr("(Name required)"))), + m_verMajor(new QSpinBox), + m_verMinor(new QSpinBox), + m_desc(new QLineEdit), + m_capWidget(new CapabilitiesWidget), + m_customPropWidget(new CustomPropertiesWidget) +{ + m_verMajor->setMinimum(1); // min version as documented for interfaces + + QHBoxLayout *versions = new QHBoxLayout; + versions->addWidget(m_verMajor); + versions->addWidget(new QLabel(tr("(Major)"))); + versions->addWidget(m_verMinor); + versions->addWidget(new QLabel(tr("(Minor)"))); + + QFormLayout *form = new QFormLayout; + form->addRow(tr("* Name"), m_name); + form->addRow(tr("* Version"), versions); + form->addRow(tr("Description"), m_desc); + form->addRow(tr("Capabilities"), m_capWidget); + form->addRow(tr("Custom attributes"), m_customPropWidget); + setLayout(form); + + connect(m_name, SIGNAL(textEdited(QString)), SLOT(changedNameOrVersion())); + connect(m_verMajor, SIGNAL(valueChanged(int)), SLOT(changedNameOrVersion())); + connect(m_verMinor, SIGNAL(valueChanged(int)), SLOT(changedNameOrVersion())); + + connect(m_desc, SIGNAL(textEdited(QString)), SIGNAL(dataChanged())); + connect(m_capWidget, SIGNAL(dataChanged()), SIGNAL(dataChanged())); + connect(m_customPropWidget, SIGNAL(dataChanged()), SIGNAL(dataChanged())); +} + +void InterfaceWidget::init() +{ + m_name->setFocus(); +} + +void InterfaceWidget::load(const QServiceInterfaceDescriptor &info) +{ + const QServiceInterfaceDescriptorPrivate *p = QServiceInterfaceDescriptorPrivate::getPrivate(&info); + if (!p) + return; + + m_name->setText(p->interfaceName); + m_verMajor->setValue(p->major); + m_verMinor->setValue(p->minor); + if (p->attributes.contains(QServiceInterfaceDescriptor::InterfaceDescription)) + m_desc->setText(p->attributes[QServiceInterfaceDescriptor::InterfaceDescription].toString()); + + if (p->attributes.contains(QServiceInterfaceDescriptor::Capabilities)) + m_capWidget->setCapabilities(p->attributes[QServiceInterfaceDescriptor::Capabilities].toStringList()); + if (!p->customAttributes.isEmpty()) + m_customPropWidget->setProperties(p->customAttributes); +} + +void InterfaceWidget::validate(ErrorCollector *errors) +{ + m_name->validate(errors); +} + +void InterfaceWidget::writeXml(QXmlStreamWriter *writer) const +{ + writer->writeTextElement(QLatin1String("name"), !m_name->hasText() ? QString() : m_name->text()); + writer->writeTextElement(QLatin1String("version"), + QString("%1.%2").arg(m_verMajor->value()).arg(m_verMinor->value())); + writer->writeTextElement(QLatin1String("description"), m_desc->text()); + writer->writeTextElement(QLatin1String("capabilities"), + m_capWidget->capabilities().join(QLatin1String(","))); + + const QStringList &customPropKeys = m_customPropWidget->propertyKeys(); + const QHash &customProps = m_customPropWidget->properties(); + for (int i=0; iwriteStartElement(QLatin1String("customproperty")); + writer->writeAttribute(QLatin1String("key"), customPropKeys[i]); + writer->writeCharacters(customProps[customPropKeys[i]]); + writer->writeEndElement(); + } +} + +QString InterfaceWidget::title() const +{ + QString name = m_name->text().isEmpty() ? tr("[New Interface]") : m_name->text(); + return QString("%1 %2.%3").arg(name).arg(m_verMajor->value()).arg(m_verMinor->value()); +} + +void InterfaceWidget::changedNameOrVersion() +{ + emit titleChanged(title()); + emit dataChanged(); +} + +#include "interfacewidget.moc"