--- /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 <qserviceinterfacedescriptor_p.h>
+
+#include <QSpinBox>
+#include <QFormLayout>
+#include <QHBoxLayout>
+#include <QLineEdit>
+#include <QLabel>
+#include <QStringList>
+#include <QHash>
+#include <QListView>
+#include <QPushButton>
+#include <QStringListModel>
+#include <QDebug>
+
+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<QString, QString> &values);
+
+ const QStringList &propertyKeys() const { return m_keys; }
+ const QHash<QString, QString> &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<QString, QString> 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<QString, QString> &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_keys.count(); i++)
+ values << (m_keys[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<QString, QString> &customProps = m_customPropWidget->properties();
+ for (int i=0; i<customPropKeys.count(); i++) {
+ writer->writeStartElement(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"