1 /*
2    Bacula(R) - The Network Backup Solution
3 
4    Copyright (C) 2000-2020 Kern Sibbald
5 
6    The original author of Bacula is Kern Sibbald, with contributions
7    from many others, a complete list can be found in the file AUTHORS.
8 
9    You may use this file and others of this release according to the
10    license defined in the LICENSE file, which includes the Affero General
11    Public License, v3.0 ("AGPLv3") and some additional permissions and
12    terms pursuant to its AGPLv3 Section 7.
13 
14    This notice must be preserved when any source code is
15    conveyed and/or propagated.
16 
17    Bacula(R) is a registered trademark of Kern Sibbald.
18 */
19 /*
20  * Restore Wizard: Plugin selection page
21  *
22  * Written by Norbert Bizet, May MMXVII
23  *
24  */
25 #include "common.h"
26 #include "pluginwizardpage.h"
27 #include "ui_pluginwizardpage.h"
28 #include "pluginmodel.h"
29 #include "task.h"
30 #include <QStandardItemModel>
31 #include <QFormLayout>
32 #include <QLineEdit>
33 #include <QCheckBox>
34 #include <QDateTimeEdit>
35 #include "lib/ini.h"
36 
PluginWizardPage(QWidget * parent)37 PluginWizardPage::PluginWizardPage(QWidget *parent) :
38     QWizardPage(parent),
39     ui(new Ui::PluginWizardPage),
40     res(NULL)
41 {
42     ui->setupUi(this);
43     ui->tabWidget->clear();
44     registerField("pluginKeysStr", this, "pluginKeysStr", "pluginKeysStrChanged");
45 }
46 
~PluginWizardPage()47 PluginWizardPage::~PluginWizardPage()
48 {
49     delete ui;
50 }
51 
initializePage()52 void PluginWizardPage::initializePage()
53 {
54     /* build plugin form UI dynamically*/
55     task t;
56     t.init(res, -1);
57     QStringList idsList = field("pluginIds").toString().split(",");
58     QStringList nameList = field("pluginNames").toString().split(",");
59     /* process ids and name lists with the assumption that indexes match */
60     ASSERT(idsList.count() == nameList.count());
61     for( int c=0; c<idsList.count(); ++c ) {
62         QString pluginId = idsList[c];
63         QString pluginName = nameList[c];
64 
65         /* don't tab the same plugin twice */
66         bool exists(false);
67         for (int j=0; j<ui->tabWidget->count(); ++j) {
68             if (ui->tabWidget->tabText(j) == pluginName) {
69                 exists=true;
70                 break;
71             }
72         }
73         if (exists) continue;
74         /* create a tab widget */
75         QWidget *pluginWidget = new QWidget();
76         /* insert a tab widget with an empty form layout */
77         QFormLayout *layout = new QFormLayout();
78         pluginWidget->setLayout(layout);
79         ui->tabWidget->addTab(pluginWidget, pluginName);
80 
81         /* parse each plugin fields*/
82         t.plugin(nameList[c], field("jobIds").toString(), pluginId.toInt());
83         ConfigFile cf;
84         cf.unserialize(pluginName.toLatin1().data());
85 
86         /* for each field */
87         for (int i=0; i < MAX_INI_ITEMS && cf.items[i].name; i++) {
88             ini_items f = cf.items[i];
89             /* create the w Widget dynamically, based on the field value type */
90             QWidget *w(NULL);
91             if (f.handler == ini_store_str ||
92                     f.handler == ini_store_name ||
93                     f.handler == ini_store_alist_str) /*FIXME: treat alist separatly*/
94             {
95                 QLineEdit *l = new QLineEdit();
96                 w=l;
97                 if (f.default_value)
98                     l->setText(f.default_value);
99             }
100             else if (f.handler == ini_store_pint64 ||
101                      f.handler == ini_store_int64 ||
102                      f.handler == ini_store_pint32 ||
103                      f.handler == ini_store_int32)
104             {
105                 QLineEdit *l = new QLineEdit();
106                 w=l;
107                 l->setValidator(new QIntValidator());
108                 if (f.default_value)
109                     l->setText(f.default_value);
110             }
111             else if (f.handler == ini_store_bool)
112             {
113                 QCheckBox *c = new QCheckBox();
114                 w=c;
115                 if (f.default_value)
116                     c->setChecked(f.default_value);
117             }
118             else if (f.handler == ini_store_date)
119             {
120                 QDateTimeEdit *d = new QDateTimeEdit();
121                 w=d;
122                 if (f.default_value)
123                     d->setDateTime(QDateTime::fromString(f.default_value, "yyyy-MM-dd hh:mm:ss"));
124             }
125 
126             if (w) {
127                 w->setToolTip(f.comment);
128                 QString field_name = QString("%1_%2").arg(nameList[c]).arg(f.name);
129                 /* This doesn't work FIXME
130                  * if (f.required) {
131                     field_name.append("*");
132                 }*/
133 
134                 registerField(field_name, w);
135                 /* there's no way to iterate thru page-register field */
136                 /* As a workaround we keep track of registered fields in a separate list */
137                 registeredFields.append(field_name);
138 
139                 layout->addRow(f.name, w);
140                 emit completeChanged();
141             }
142         }
143     }
144 }
145 
validatePage()146 bool PluginWizardPage::validatePage()
147 {
148     QStringList pluginKeys;
149     QStringList idsList = field("pluginIds").toString().split(",");
150     QStringList nameList = field("pluginNames").toString().split(",");
151     for (int idx=0; idx<ui->tabWidget->count(); ++idx) {
152         QString name = ui->tabWidget->tabText(idx);
153         ASSERT(name.compare(nameList[idx]) == 0);
154 
155         QFile file(name);
156         if (file.open(QIODevice::WriteOnly)) {
157             QTextStream outputStream(&file);
158             foreach(QString fld, registeredFields) {
159                 QStringList sl = fld.split("_");
160                 if ( (name.compare(sl[0]) == 0) && field(fld).isValid()) {
161                     QString s = QString("%1=%2\n").arg(sl[1]).arg(field(fld).toString());
162                     outputStream << s;
163                 }
164             }
165         }
166 
167         /* create the key */
168         QString key = QString("j%1i%2").arg(field("jobIds").toString().remove(',').simplified()).arg(idsList[idx].simplified());
169         QString restoreKey = QString("%1:%2").arg(idsList[idx].simplified()).arg(key);
170         pluginKeys.append(restoreKey);
171     }
172 
173     m_pluginKeysStr = pluginKeys.join(",");
174     emit pluginKeysStrChanged();
175 
176     return true;
177 }
178