qtmobility/tools/servicexmlgen/interfacewidget.cpp
changeset 1 2b40d63a9c3d
child 11 06b8e2af4411
--- /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 &current, 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 &current, 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"