/* * Copyright (c) 2010-2011 Kevin Smith * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ #include #include #include #include #include #include #include #include #include #include #include namespace Swift { QtFormWidget::QtFormWidget(Form::ref form, QWidget* parent) : QWidget(parent), form_(form) { QGridLayout* thisLayout = new QGridLayout(this); int row = 0; if (!form->getTitle().empty()) { QLabel* instructions = new QLabel(("" + form->getTitle() + "").c_str(), this); thisLayout->addWidget(instructions, row++, 0, 1, 2); } if (!form->getInstructions().empty()) { QLabel* instructions = new QLabel(form->getInstructions().c_str(), this); thisLayout->addWidget(instructions, row++, 0, 1, 2); } QScrollArea* scrollArea = new QScrollArea(this); thisLayout->addWidget(scrollArea); QWidget* scroll = new QWidget(this); QGridLayout* layout = new QGridLayout(scroll); foreach (boost::shared_ptr field, form->getFields()) { QWidget* widget = createWidget(field); if (widget) { layout->addWidget(new QLabel(field->getLabel().c_str(), this), row, 0); layout->addWidget(widget, row++, 1); } } scrollArea->setWidget(scroll); scrollArea->setWidgetResizable(true); setEditable(form->getType() != Form::CancelType && form->getType() != Form::ResultType); } QtFormWidget::~QtFormWidget() { } QListWidget* QtFormWidget::createList(FormField::ref field) { QListWidget* listWidget = new QListWidget(this); listWidget->setSortingEnabled(false); listWidget->setSelectionMode(boost::dynamic_pointer_cast(field) ? QAbstractItemView::MultiSelection : QAbstractItemView::SingleSelection); boost::shared_ptr listMultiField = boost::dynamic_pointer_cast(field); boost::shared_ptr listSingleField = boost::dynamic_pointer_cast(field); std::vector selected; foreach (FormField::Option option, field->getOptions()) { listWidget->addItem(option.label.c_str()); if (listSingleField) { selected.push_back(option.value == listSingleField->getValue()); } else if (listMultiField) { std::string text = option.value; selected.push_back(std::find(listMultiField->getValue().begin(), listMultiField->getValue().end(), text) != listMultiField->getValue().end()); } } for (int i = 0; i < listWidget->count(); i++) { QListWidgetItem* item = listWidget->item(i); item->setSelected(selected[i]); } return listWidget; } QWidget* QtFormWidget::createWidget(FormField::ref field) { QWidget* widget = NULL; boost::shared_ptr booleanField = boost::dynamic_pointer_cast(field); if (booleanField) { QCheckBox* checkWidget = new QCheckBox(this); checkWidget->setCheckState(booleanField->getValue() ? Qt::Checked : Qt::Unchecked); widget = checkWidget; } boost::shared_ptr fixedField = boost::dynamic_pointer_cast(field); if (fixedField) { QString value = fixedField->getValue().c_str(); widget = new QLabel(value, this); } boost::shared_ptr listSingleField = boost::dynamic_pointer_cast(field); if (listSingleField) { widget = createList(field); } boost::shared_ptr textMultiField = boost::dynamic_pointer_cast(field); if (textMultiField) { QString value = textMultiField->getValue().c_str(); QTextEdit* textWidget = new QTextEdit(this); textWidget->setPlainText(value); widget = textWidget; } boost::shared_ptr textPrivateField = boost::dynamic_pointer_cast(field); if (textPrivateField) { QString value = textPrivateField->getValue().c_str(); QLineEdit* lineWidget = new QLineEdit(value, this); lineWidget->setEchoMode(QLineEdit::Password); widget = lineWidget; } boost::shared_ptr textSingleField = boost::dynamic_pointer_cast(field); if (textSingleField) { QString value = textSingleField->getValue().c_str(); widget = new QLineEdit(value, this); } boost::shared_ptr jidSingleField = boost::dynamic_pointer_cast(field); if (jidSingleField) { QString value = jidSingleField->getValue().toString().c_str(); widget = new QLineEdit(value, this); } boost::shared_ptr jidMultiField = boost::dynamic_pointer_cast(field); if (jidMultiField) { QString text; bool prev = false; foreach (JID line, jidMultiField->getValue()) { if (prev) { text += "\n"; } prev = true; text += line.toString().c_str(); } QTextEdit* textWidget = new QTextEdit(this); textWidget->setPlainText(text); widget = textWidget; } boost::shared_ptr listMultiField = boost::dynamic_pointer_cast(field); if (listMultiField) { widget = createList(field); } boost::shared_ptr hiddenField = boost::dynamic_pointer_cast(field); if (hiddenField) { } fields_[field->getName()] = widget; return widget; } Form::ref QtFormWidget::getCompletedForm() { Form::ref result(new Form(Form::SubmitType)); foreach (boost::shared_ptr field, form_->getFields()) { boost::shared_ptr resultField; boost::shared_ptr booleanField = boost::dynamic_pointer_cast(field); if (booleanField) { resultField = FormField::ref(BooleanFormField::create(qobject_cast(fields_[field->getName()])->checkState() == Qt::Checked)); } boost::shared_ptr fixedField = boost::dynamic_pointer_cast(field); if (fixedField) { resultField = FormField::ref(FixedFormField::create(fixedField->getValue())); } boost::shared_ptr listSingleField = boost::dynamic_pointer_cast(field); if (listSingleField) { QListWidget* listWidget = qobject_cast(fields_[field->getName()]); if (listWidget->selectedItems().size() > 0) { int i = listWidget->row(listWidget->selectedItems()[0]); resultField = FormField::ref(ListSingleFormField::create(field->getOptions()[i].value)); } else { resultField = FormField::ref(ListSingleFormField::create()); } } boost::shared_ptr textMultiField = boost::dynamic_pointer_cast(field); if (textMultiField) { QTextEdit* widget = qobject_cast(fields_[field->getName()]); QString string = widget->toPlainText(); if (string.isEmpty()) { resultField = FormField::ref(TextMultiFormField::create()); } else { resultField = FormField::ref(TextMultiFormField::create(Q2PSTRING(string))); } } boost::shared_ptr textPrivateField = boost::dynamic_pointer_cast(field); if (textPrivateField) { QLineEdit* widget = qobject_cast(fields_[field->getName()]); QString string = widget->text(); if (string.isEmpty()) { resultField = FormField::ref(TextPrivateFormField::create()); } else { resultField = FormField::ref(TextPrivateFormField::create(Q2PSTRING(string))); } } boost::shared_ptr textSingleField = boost::dynamic_pointer_cast(field); if (textSingleField) { QLineEdit* widget = qobject_cast(fields_[field->getName()]); QString string = widget->text(); if (string.isEmpty()) { resultField = FormField::ref(TextSingleFormField::create()); } else { resultField = FormField::ref(TextSingleFormField::create(Q2PSTRING(string))); } } boost::shared_ptr jidSingleField = boost::dynamic_pointer_cast(field); if (jidSingleField) { QLineEdit* widget = qobject_cast(fields_[field->getName()]); QString string = widget->text(); JID jid(Q2PSTRING(string)); if (string.isEmpty()) { resultField = FormField::ref(JIDSingleFormField::create()); } else { resultField = FormField::ref(JIDSingleFormField::create(jid)); } } boost::shared_ptr jidMultiField = boost::dynamic_pointer_cast(field); if (jidMultiField) { QTextEdit* widget = qobject_cast(fields_[field->getName()]); QString string = widget->toPlainText(); if (string.isEmpty()) { resultField = FormField::ref(JIDMultiFormField::create()); } else { QStringList lines = string.split("\n"); std::vector value; foreach (QString line, lines) { value.push_back(JID(Q2PSTRING(line))); } resultField = FormField::ref(JIDMultiFormField::create(value)); } } boost::shared_ptr listMultiField = boost::dynamic_pointer_cast(field); if (listMultiField) { QListWidget* listWidget = qobject_cast(fields_[field->getName()]); std::vector values; foreach (QListWidgetItem* item, listWidget->selectedItems()) { values.push_back(field->getOptions()[listWidget->row(item)].value); } resultField = FormField::ref(ListMultiFormField::create(values)); } boost::shared_ptr hiddenField = boost::dynamic_pointer_cast(field); if (hiddenField) { resultField = FormField::ref(HiddenFormField::create(hiddenField->getValue())); } resultField->setName(field->getName()); result->addField(resultField); } return result; } template void QtFormWidget::setEnabled(QWidget* rawWidget, bool editable) { T* widget = qobject_cast(rawWidget); if (widget) { widget->setEnabled(editable); } } template void QtFormWidget::setEditable(QWidget* rawWidget, bool editable) { T* widget = qobject_cast(rawWidget); if (widget) { widget->setReadOnly(!editable); } } void QtFormWidget::setEditable(bool editable) { if (!form_) { return; } foreach (boost::shared_ptr field, form_->getFields()) { QWidget* widget = NULL; if (field) { widget = fields_[field->getName()]; } setEnabled(widget, editable); setEnabled(widget, editable); setEditable(widget, editable); setEditable(widget, editable); } } }