2 * Copyright (c) 2004 The DragonFly Project. All rights reserved.
4 * This code is derived from software contributed to The DragonFly Project
5 * by Shawn R. Walker <adonijah@gmail.com>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * 3. Neither the name of The DragonFly Project nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific, prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * $Id: form.cpp,v 1.24 2005/02/07 06:49:10 cpressey Exp $
35 * $DragonFly: src/contrib/bsdinstaller-1.1.6/src/frontends/qt/src/form.cpp,v 1.1.1.1 2008/03/12 22:15:53 dave Exp $
40 Form::Form(QWidget *parent, const char *name, struct dfui_connection *c)
41 : QScrollView(parent, name)
51 bool Form::buildProgress(struct dfui_progress *payload)
56 main = new QWidget(viewport(), "main");
59 QVBoxLayout *layout = new QVBoxLayout(main); // Overall
60 layout->setMargin(10);
61 layout->setSpacing(5);
63 QVBoxLayout *tLayout = new QVBoxLayout(layout); // Top
64 QVBoxLayout *bLayout = new QVBoxLayout(layout); // Bottom
67 setCaption("Processing...");
70 long_text = new QTextEdit(main);
71 long_text->setReadOnly(true);
73 tr(dfui_info_get_short_desc(dfui_progress_get_info(payload))));
74 tLayout->addWidget(long_text);
78 pbar = new QProgressBar(main);
79 if (dfui_progress_get_streaming(payload))
80 pbar->setTotalSteps(0);
82 pbar->setTotalSteps(100);
85 tLayout->addWidget(pbar);
88 QPushButton *button = new QPushButton(tr("Cancel"), main, "actProgress");
89 connect(button, SIGNAL(clicked()), this, SLOT(actProgress()));
90 bLayout->addWidget(button);
92 // Add Progress Text (for streaming case)
93 if (dfui_progress_get_streaming(payload)) {
94 long_text = new QTextEdit(main, "progress_text");
95 long_text->setReadOnly(true);
96 long_text->setText("");
97 bLayout->addWidget(long_text);
103 main->setMinimumWidth(viewport()->width() -
104 verticalScrollBar()->width());
105 main->setMinimumHeight(viewport()->height());
111 void Form::actProgress()
113 const QObject *wid = QObject::sender();
114 const QString text = ((QPushButton *)wid)->text();
116 if (text == "Cancel") {
118 } else if (text == "Ok") {
121 child("main")->deleteLater();
125 void Form::setProgress(int amount)
127 if (pbar && amount == -1) {
128 pbar->setProgress(pbar->totalSteps());
129 if (pbar->totalSteps() == 0) {
130 QObject *widget = child("main")->child("actProgress");
131 ((QPushButton *)widget)->setText("Ok");
133 // Trick the event loop into waiting for the user
134 // to acknowledge the streaming message output
138 child("main")->deleteLater();
141 pbar->setProgress(amount);
147 void Form::updateProgressText(const char *text)
149 QObject *progressText = NULL;
151 progressText = child("main")->child("progress_text");
154 ((QTextEdit *)progressText)->append(tr(text));
157 QObject *Form::buildWidget(QWidget *pwidget,
158 struct dfui_celldata *cd,
159 struct dfui_field *field)
162 struct dfui_option *option;
163 const char *desc = dfui_info_get_short_desc(dfui_field_get_info(field));
164 const char *name = dfui_field_get_id(field);
168 value = dfui_celldata_get_value(cd);
172 if (dfui_field_property_is(field, "control", "checkbox")) {
173 widget = new QCheckBox("", pwidget, name);
175 if (strcmp(value, "Y") == 0)
176 ((QCheckBox *)widget)->setDown(true);
178 } else if ((option = dfui_field_option_get_first(field)) != NULL) {
179 widget = new QComboBox(pwidget, name);
181 if (dfui_field_property_is(field, "editable", "false"))
182 ((QComboBox *)widget)->setEditable(false);
184 for (option = dfui_field_option_get_first(field);
185 option != NULL; option = dfui_option_get_next(option)) {
186 QString optval = tr(dfui_option_get_value(option));
187 ((QComboBox *)widget)->insertItem(optval);
188 if (strcmp(optval.ascii(), value) == 0)
189 ((QComboBox *)widget)->setCurrentText(
194 widget = new QLineEdit(value, pwidget, name);
196 if (dfui_field_property_is(field, "editable", "false"))
197 ((QLineEdit *)widget)->setReadOnly(true);
199 if (dfui_field_property_is(field, "obscured","true")) {
200 ((QLineEdit *)widget)->setEchoMode(
201 QLineEdit::Password);
205 QToolTip::add((QWidget *)widget, tr(desc));
209 QPushButton *Form::buildActWidget(QWidget *pwidget, struct dfui_action *action)
212 const char *name, *value;
214 name = dfui_action_get_id(action);
215 value = dfui_info_get_name(dfui_action_get_info(action));
217 button = new QPushButton(tr(value), pwidget, name);
218 connect(button, SIGNAL(clicked()), this, SLOT(actButton()));
222 bool Form::buildSingle()
224 struct dfui_action *action;
225 struct dfui_dataset *ds;
226 struct dfui_field *field;
228 QTextEdit *long_text;
231 main = new QWidget(viewport(), "main");
234 QVBoxLayout *layout = new QVBoxLayout(main); // Overall
235 layout->setMargin(10);
236 layout->setSpacing(5);
238 QVBoxLayout *tLayout = new QVBoxLayout(layout); // Top
239 QGridLayout *mLayout = new QGridLayout(layout); // Middle
240 QVBoxLayout *bLayout = new QVBoxLayout(layout); // Bottom
242 // Set our identifier for response later
243 setName(dfui_form_get_id(data));
246 setCaption(tr(dfui_info_get_name(dfui_form_get_info(data))));
249 long_text = new QTextEdit(main);
250 long_text->setReadOnly(true);
251 long_text->setText(tr(dfui_info_get_short_desc(dfui_form_get_info(data))));
252 tLayout->addWidget(long_text);
255 // Grab the dataset so we can get values from it during field generation
256 ds = dfui_form_dataset_get_first(data);
259 for (field = dfui_form_field_get_first(data); field != NULL;
260 field = dfui_field_get_next(field)) {
263 struct dfui_celldata *cd;
266 // Grab the incoming dataset celldata
267 cd = dfui_dataset_celldata_find(ds, dfui_field_get_id(field));
269 label = dfui_info_get_name(dfui_field_get_info(field));
270 wlabel = new QLabel(tr(label), main);
271 mLayout->addWidget(wlabel, row, 0);
273 widget = buildWidget(main, cd, field);
274 mLayout->addWidget((QWidget *)widget, row++, 1);
277 for (action = dfui_form_action_get_first(data); action != NULL;
278 action = dfui_action_get_next(action)) {
279 QPushButton *button = buildActWidget(main, action);
280 bLayout->addWidget(button);
284 main->setMinimumWidth(viewport()->width() -
285 verticalScrollBar()->width());
286 main->setMinimumHeight(viewport()->height());
292 void Form::buildRow(int row, QWidget *pwidget, QTable *mLayout, struct dfui_dataset *ds)
295 for (struct dfui_field *field = dfui_form_field_get_first(data);
296 field != NULL; field = dfui_field_get_next(field)) {
297 struct dfui_celldata *cd = NULL;
299 // Grab the incoming dataset celldata
301 cd = dfui_dataset_celldata_find(ds, dfui_field_get_id(field));
303 QObject *widget = buildWidget(pwidget, cd, field);
304 mLayout->setCellWidget(row, col++, (QWidget *)widget);
311 QPushButton *ins = new QPushButton(tr("Insert"), pwidget,
313 QPushButton *del = new QPushButton(tr("Delete"), pwidget,
316 mLayout->setCellWidget(row, col, ins);
317 connect(ins, SIGNAL(clicked()), this, SLOT(actInsertRow()));
319 mLayout->setCellWidget(row, col + 1, del);
320 connect(del, SIGNAL(clicked()), this, SLOT(actDeleteRow()));
324 bool Form::buildMultiple()
327 QTextEdit *long_text;
330 main = new QWidget(viewport(), "main");
333 QVBoxLayout *layout = new QVBoxLayout(main); // Overall
334 layout->setMargin(10);
335 layout->setSpacing(5);
337 QVBoxLayout *tLayout = new QVBoxLayout(layout); // Top
338 QTable *mLayout = new QTable(main, "table"); // Middle
339 layout->addWidget(mLayout);
341 QVBoxLayout *bLayout = new QVBoxLayout(layout); // Bottom
343 // Set our identifier for response later
344 setName(dfui_form_get_id(data));
347 setCaption(tr(dfui_info_get_name(dfui_form_get_info(data))));
350 long_text = new QTextEdit(main);
351 long_text->setReadOnly(true);
352 long_text->setText(tr(dfui_info_get_short_desc(dfui_form_get_info(data))));
353 tLayout->addWidget(long_text);
357 for (struct dfui_field *field = dfui_form_field_get_first(data); field != NULL;
358 field = dfui_field_get_next(field)) {
359 const char *label = dfui_info_get_name(dfui_field_get_info(field));
361 mLayout->insertColumns(col);
362 mLayout->horizontalHeader()->setLabel(col++, tr(label));
365 if (dfui_form_is_extensible(data)) {
367 for (int i = 0; i < 2; i++) {
368 mLayout->insertColumns(col, 1); // Needed for Ins, Del, Add
369 mLayout->horizontalHeader()->setLabel(col++, tr(""));
374 for (struct dfui_dataset *ds = dfui_form_dataset_get_first(data); ds != NULL;
375 ds = dfui_dataset_get_next(ds)) {
376 mLayout->insertRows(row);
377 buildRow(row, main, mLayout, ds);
382 QPushButton *add = new QPushButton(tr("Add"), main);
384 mLayout->insertRows(row);
385 mLayout->setRowReadOnly(row, true);
386 mLayout->setCellWidget(row, mLayout->numCols() - 2, add);
387 connect(add, SIGNAL(clicked()), this, SLOT(actAddRow()));
390 for (struct dfui_action *action = dfui_form_action_get_first(data); action != NULL;
391 action = dfui_action_get_next(action)) {
392 QPushButton *button = buildActWidget(main, action);
393 bLayout->addWidget(button);
397 main->setMinimumWidth(viewport()->width() -
398 verticalScrollBar()->width());
399 main->setMinimumHeight(viewport()->height());
405 void Form::actButton()
407 const QObject *wid = QObject::sender();
408 const QString widname = wid->name();
411 submitMultiple(&widname);
413 submitSingle(&widname);
416 dfui_form_free(data); // We're done with it
421 void Form::renumberControls(QTable *table)
423 int maxcols = table->numCols();
425 // Cycle through all rows except last since it's only used for Add
426 for (int row = 0; row < table->numRows() - 1; row++) {
430 // Change Insert Row ID
431 QWidget *widget = table->cellWidget(row, maxcols - 2);
433 widget->setName(row_id);
436 // Change Delete Row ID
437 widget = table->cellWidget(row, maxcols - 1);
439 widget->setName(row_id);
443 void Form::actAddRow()
445 QTable *table = ((QTable *)(child("main")->child("table")));
446 table->insertRows(table->numRows() - 1, 1);
447 buildRow(table->numRows() - 2, (QWidget *)child("main"), table, NULL);
450 void Form::actInsertRow()
452 const QObject *wid = QObject::sender();
453 const QString row = wid->name();
454 QTable *table = ((QTable *)(child("main")->child("table")));
455 table->insertRows(row.toInt());
456 buildRow(row.toInt(), (QWidget *)child("main"), table, NULL);
457 renumberControls(table);
460 void Form::actDeleteRow()
462 const QObject *wid = QObject::sender();
463 const QString row = wid->name();
464 QTable *table = ((QTable *)(child("main")->child("table")));
465 table->removeRow(row.toInt());
466 renumberControls(table);
469 void Form::submitSingle(const QString *action)
471 struct dfui_dataset *ds;
472 struct dfui_response *response;
474 ds = dfui_dataset_new();
475 response = dfui_response_new(name(), action->ascii());
477 QObjectList *widgets = topLevelWidget()->queryList();
478 QObjectListIterator it(*widgets);
481 while ((widget = it.current()) != 0) {
484 if (widget->isA("QCheckBox")) {
485 if (((QCheckBox *)widget)->isOn())
486 value.setAscii("Y", 1);
488 value.setAscii("N", 1);
489 } else if (widget->isA("QLineEdit")) {
490 QLineEdit *textbox = (QLineEdit *)widget;
491 value.setAscii(textbox->text());
492 } else if (widget->isA("QComboBox")) {
493 QComboBox *combobox = (QComboBox *)widget;
494 value.setAscii(combobox->currentText());
500 dfui_dataset_celldata_add(ds,
501 widget->name(), value.ascii());
507 dfui_response_dataset_add(response, ds);
509 dfui_fe_submit(connection, response);
510 dfui_response_free(response);
517 child("main")->deleteLater(); // Clear the form
520 void Form::submitMultiple(const QString *action)
522 struct dfui_dataset *ds;
523 struct dfui_response *response;
528 response = dfui_response_new(name(), action->ascii());
530 table = (QTable *)(child("main")->child("table"));
531 maxcols = table->numCols();
533 maxcols -= 2; // Ignore Insert / Delete Columns
535 for (row = 0; row < table->numRows(); row++) {
538 ds = dfui_dataset_new();
539 for (col = 0; col < maxcols; col++) {
541 QWidget *widget = table->cellWidget(row, col);
544 if (widget->isA("QCheckBox")) {
545 if (((QCheckBox *)widget)->isOn())
546 value.setAscii("Y", 1);
548 value.setAscii("N", 1);
549 } else if (widget->isA("QLineEdit")) {
550 QLineEdit *textbox = (QLineEdit *)widget;
551 value.setAscii(textbox->text());
552 } else if (widget->isA("QComboBox")) {
553 QComboBox *combobox = (QComboBox *)widget;
554 value.setAscii(combobox->currentText());
562 dfui_dataset_celldata_add(ds,
563 widget->name(), value.ascii());
568 dfui_response_dataset_add(response, ds);
570 dfui_dataset_free(ds);
573 dfui_fe_submit(connection, response);
574 dfui_response_free(response);
581 child("main")->deleteLater(); // Clear the form
584 bool Form::present(struct dfui_form *payload)
589 if (dfui_form_is_multiple(data))
590 result = buildMultiple();
592 result = buildSingle();
602 bool Form::present(struct dfui_progress *payload)
606 result = buildProgress((struct dfui_progress *)payload);