|
a |
|
b/cfgui/confgui.h |
|
|
1 |
/* Copyright (C) 2007-2018 J.F.Dockes
|
|
|
2 |
* This program is free software; you can redistribute it and/or modify
|
|
|
3 |
* it under the terms of the GNU General Public License as published by
|
|
|
4 |
* the Free Software Foundation; either version 2 of the License, or
|
|
|
5 |
* (at your option) any later version.
|
|
|
6 |
*
|
|
|
7 |
* This program is distributed in the hope that it will be useful,
|
|
|
8 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
9 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
10 |
* GNU General Public License for more details.
|
|
|
11 |
*
|
|
|
12 |
* You should have received a copy of the GNU General Public License
|
|
|
13 |
* along with this program; if not, write to the
|
|
|
14 |
* Free Software Foundation, Inc.,
|
|
|
15 |
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
16 |
*/
|
|
|
17 |
#ifndef _confgui_h_included_
|
|
|
18 |
#define _confgui_h_included_
|
|
|
19 |
/**
|
|
|
20 |
* This file defines a number of simple classes (virtual base: ConfParamW)
|
|
|
21 |
* which let the user input configuration parameters.
|
|
|
22 |
*
|
|
|
23 |
* Subclasses are defined for entering different kind of data, ie a string,
|
|
|
24 |
* a file name, an integer, etc.
|
|
|
25 |
*
|
|
|
26 |
* Each configuration gui object is linked to the configuration data through
|
|
|
27 |
* a "link" object which knows the details of interacting with the actual
|
|
|
28 |
* configuration data, like the parameter name, the actual config object,
|
|
|
29 |
* the method to call etc.
|
|
|
30 |
*
|
|
|
31 |
* The link object is set when the input widget is created and cannot be
|
|
|
32 |
* changed.
|
|
|
33 |
*
|
|
|
34 |
* The widgets are typically linked to a temporary configuration object, which
|
|
|
35 |
* is then copied to the actual configuration if the data is accepted, or
|
|
|
36 |
* destroyed and recreated as a copy if Cancel is pressed (you have to
|
|
|
37 |
* delete/recreate the widgets in this case as the links are no longer valid).
|
|
|
38 |
*
|
|
|
39 |
* The set() methods of the link objects are only called if the
|
|
|
40 |
* current value() differs from the value obtained by get() when the
|
|
|
41 |
* object was initialized. This can be used to avoid cluttering the
|
|
|
42 |
* output with values which are unmodified from the defaults.
|
|
|
43 |
*
|
|
|
44 |
* The file also defines a multi-tabbed dialog container for the
|
|
|
45 |
* parameter objects, with simple interface methods to create/add
|
|
|
46 |
* panels and elements.
|
|
|
47 |
*/
|
|
|
48 |
|
|
|
49 |
#include <string>
|
|
|
50 |
#include <limits.h>
|
|
|
51 |
|
|
|
52 |
#include <memory>
|
|
|
53 |
#include <vector>
|
|
|
54 |
#include <string>
|
|
|
55 |
|
|
|
56 |
#include <QString>
|
|
|
57 |
#include <QWidget>
|
|
|
58 |
#include <QDialog>
|
|
|
59 |
|
|
|
60 |
class ConfNull;
|
|
|
61 |
class QCheckBox;
|
|
|
62 |
class QComboBox;
|
|
|
63 |
class QDialogButtonBox;
|
|
|
64 |
class QHBoxLayout;
|
|
|
65 |
class QLineEdit;
|
|
|
66 |
class QListWidget;
|
|
|
67 |
class QPushButton;
|
|
|
68 |
class QSpinBox;
|
|
|
69 |
class QTabWidget;
|
|
|
70 |
class QVBoxLayout;
|
|
|
71 |
|
|
|
72 |
namespace confgui {
|
|
|
73 |
|
|
|
74 |
/** Interface between the GUI widget and the config storage mechanism: */
|
|
|
75 |
class ConfLinkRep {
|
|
|
76 |
public:
|
|
|
77 |
virtual ~ConfLinkRep() {}
|
|
|
78 |
virtual bool set(const std::string& val) = 0;
|
|
|
79 |
virtual bool get(std::string& val) = 0;
|
|
|
80 |
};
|
|
|
81 |
typedef std::shared_ptr<ConfLinkRep> ConfLink;
|
|
|
82 |
|
|
|
83 |
/** Link maker class */
|
|
|
84 |
class ConfLinkFact {
|
|
|
85 |
public:
|
|
|
86 |
virtual ~ConfLinkFact() {}
|
|
|
87 |
virtual ConfLink operator()(const QString& nm) = 0;
|
|
|
88 |
};
|
|
|
89 |
|
|
|
90 |
class ConfPanelWIF {
|
|
|
91 |
public:
|
|
|
92 |
virtual ~ConfPanelWIF() {}
|
|
|
93 |
virtual void storeValues() = 0;
|
|
|
94 |
virtual void loadValues() = 0;
|
|
|
95 |
};
|
|
|
96 |
|
|
|
97 |
class ConfPanelW;
|
|
|
98 |
class ConfParamW;
|
|
|
99 |
|
|
|
100 |
/** The top level widget has tabs, each tab/panel has multiple widgets
|
|
|
101 |
* for setting parameter values */
|
|
|
102 |
class ConfTabsW : public QDialog {
|
|
|
103 |
Q_OBJECT;
|
|
|
104 |
|
|
|
105 |
public:
|
|
|
106 |
ConfTabsW(QWidget *parent, const QString& title, ConfLinkFact *linkfact);
|
|
|
107 |
|
|
|
108 |
enum ParamType {CFPT_BOOL, CFPT_INT, CFPT_STR, CFPT_CSTR, CFPT_FN,
|
|
|
109 |
CFPT_STRL, CFPT_DNL, CFPT_CSTRL
|
|
|
110 |
};
|
|
|
111 |
|
|
|
112 |
/** Add tab and return its identifier / index */
|
|
|
113 |
int addPanel(const QString& title);
|
|
|
114 |
|
|
|
115 |
/** Add foreign tab where we only know to call loadvalues/storevalues.
|
|
|
116 |
* The object has to derive from QWidget */
|
|
|
117 |
int addForeignPanel(ConfPanelWIF* w, const QString& title);
|
|
|
118 |
|
|
|
119 |
/** Add parameter setter to specified tab */
|
|
|
120 |
ConfParamW *addParam(int tabindex, ParamType tp,
|
|
|
121 |
const QString& varname, const QString& label,
|
|
|
122 |
const QString& tooltip, int isdirorminval = 0,
|
|
|
123 |
int maxval = 0, const QStringList* sl = 0);
|
|
|
124 |
bool enableLink(ConfParamW* boolw, ConfParamW* otherw, bool revert = false);
|
|
|
125 |
void endOfList(int tabindex);
|
|
|
126 |
|
|
|
127 |
/** Find param widget associated with given variable name */
|
|
|
128 |
ConfParamW *findParamW(const QString& varname);
|
|
|
129 |
|
|
|
130 |
void hideButtons();
|
|
|
131 |
|
|
|
132 |
public slots:
|
|
|
133 |
void acceptChanges();
|
|
|
134 |
void rejectChanges();
|
|
|
135 |
void reloadPanels();
|
|
|
136 |
void setCurrentIndex(int);
|
|
|
137 |
|
|
|
138 |
signals:
|
|
|
139 |
/** This is emitted when acceptChanges() is called, after the
|
|
|
140 |
* values have been stored */
|
|
|
141 |
void sig_prefsChanged();
|
|
|
142 |
|
|
|
143 |
private:
|
|
|
144 |
ConfLinkFact *m_makelink{nullptr};
|
|
|
145 |
std::vector<ConfPanelW *> m_panels;
|
|
|
146 |
// "Foreign" panels
|
|
|
147 |
std::vector<ConfPanelWIF *> m_widgets;
|
|
|
148 |
// All params
|
|
|
149 |
std::vector<ConfParamW *> m_params;
|
|
|
150 |
QTabWidget *tabWidget{nullptr};
|
|
|
151 |
QDialogButtonBox *buttonBox{nullptr};
|
|
|
152 |
};
|
|
|
153 |
|
|
|
154 |
/////////////////////////////////////////////////
|
|
|
155 |
// The rest of the class definitions are only useful if you need to
|
|
|
156 |
// access a specific element for customisation (use findParamW() and a
|
|
|
157 |
// dynamic cast).
|
|
|
158 |
|
|
|
159 |
/** A panel/tab contains multiple controls for parameters */
|
|
|
160 |
class ConfPanelW : public QWidget {
|
|
|
161 |
Q_OBJECT
|
|
|
162 |
public:
|
|
|
163 |
ConfPanelW(QWidget *parent);
|
|
|
164 |
void addWidget(QWidget *w);
|
|
|
165 |
void storeValues();
|
|
|
166 |
void loadValues();
|
|
|
167 |
void endOfList();
|
|
|
168 |
private:
|
|
|
169 |
QVBoxLayout *m_vboxlayout;
|
|
|
170 |
std::vector<QWidget *> m_widgets;
|
|
|
171 |
};
|
|
|
172 |
|
|
|
173 |
/** Config panel element: manages one configuration
|
|
|
174 |
* parameter. Subclassed for specific parameter types.
|
|
|
175 |
*/
|
|
|
176 |
class ConfParamW : public QWidget {
|
|
|
177 |
Q_OBJECT
|
|
|
178 |
public:
|
|
|
179 |
ConfParamW(const QString& varnm, QWidget *parent, ConfLink cflink)
|
|
|
180 |
: QWidget(parent), m_varname(varnm),
|
|
|
181 |
m_cflink(cflink), m_fsencoding(false) {
|
|
|
182 |
}
|
|
|
183 |
virtual void loadValue() = 0;
|
|
|
184 |
virtual void setFsEncoding(bool onoff) {
|
|
|
185 |
m_fsencoding = onoff;
|
|
|
186 |
}
|
|
|
187 |
const QString& getVarName() {
|
|
|
188 |
return m_varname;
|
|
|
189 |
}
|
|
|
190 |
public slots:
|
|
|
191 |
virtual void setEnabled(bool) = 0;
|
|
|
192 |
virtual void storeValue() = 0;
|
|
|
193 |
|
|
|
194 |
protected:
|
|
|
195 |
QString m_varname;
|
|
|
196 |
ConfLink m_cflink;
|
|
|
197 |
QHBoxLayout *m_hl;
|
|
|
198 |
// File names are encoded as local8bit in the config files. Other
|
|
|
199 |
// are encoded as utf-8
|
|
|
200 |
bool m_fsencoding;
|
|
|
201 |
virtual bool createCommon(const QString& lbltxt, const QString& tltptxt);
|
|
|
202 |
void setValue(const QString& newvalue);
|
|
|
203 |
void setValue(int newvalue);
|
|
|
204 |
void setValue(bool newvalue);
|
|
|
205 |
};
|
|
|
206 |
|
|
|
207 |
//////// Widgets for setting the different types of configuration parameters:
|
|
|
208 |
|
|
|
209 |
/** Boolean */
|
|
|
210 |
class ConfParamBoolW : public ConfParamW {
|
|
|
211 |
Q_OBJECT
|
|
|
212 |
public:
|
|
|
213 |
ConfParamBoolW(const QString& varnm, QWidget *parent, ConfLink cflink,
|
|
|
214 |
const QString& lbltxt,
|
|
|
215 |
const QString& tltptxt, bool deflt = false);
|
|
|
216 |
virtual void loadValue();
|
|
|
217 |
virtual void storeValue();
|
|
|
218 |
public slots:
|
|
|
219 |
virtual void setEnabled(bool i) {
|
|
|
220 |
if (m_cb) {
|
|
|
221 |
((QWidget*)m_cb)->setEnabled(i);
|
|
|
222 |
}
|
|
|
223 |
}
|
|
|
224 |
public:
|
|
|
225 |
QCheckBox *m_cb;
|
|
|
226 |
bool m_dflt;
|
|
|
227 |
bool m_origvalue;
|
|
|
228 |
};
|
|
|
229 |
|
|
|
230 |
// Int
|
|
|
231 |
class ConfParamIntW : public ConfParamW {
|
|
|
232 |
Q_OBJECT
|
|
|
233 |
public:
|
|
|
234 |
// The default value is only used if none exists in the sample
|
|
|
235 |
// configuration file. Defaults are normally set in there.
|
|
|
236 |
ConfParamIntW(const QString& varnm, QWidget *parent, ConfLink cflink,
|
|
|
237 |
const QString& lbltxt,
|
|
|
238 |
const QString& tltptxt,
|
|
|
239 |
int minvalue = INT_MIN,
|
|
|
240 |
int maxvalue = INT_MAX,
|
|
|
241 |
int defaultvalue = 0);
|
|
|
242 |
virtual void loadValue();
|
|
|
243 |
virtual void storeValue();
|
|
|
244 |
public slots:
|
|
|
245 |
virtual void setEnabled(bool i) {
|
|
|
246 |
if (m_sb) {
|
|
|
247 |
((QWidget*)m_sb)->setEnabled(i);
|
|
|
248 |
}
|
|
|
249 |
}
|
|
|
250 |
protected:
|
|
|
251 |
QSpinBox *m_sb;
|
|
|
252 |
int m_defaultvalue;
|
|
|
253 |
int m_origvalue;
|
|
|
254 |
};
|
|
|
255 |
|
|
|
256 |
// Arbitrary string
|
|
|
257 |
class ConfParamStrW : public ConfParamW {
|
|
|
258 |
Q_OBJECT
|
|
|
259 |
public:
|
|
|
260 |
ConfParamStrW(const QString& varnm, QWidget *parent, ConfLink cflink,
|
|
|
261 |
const QString& lbltxt,
|
|
|
262 |
const QString& tltptxt);
|
|
|
263 |
virtual void loadValue();
|
|
|
264 |
virtual void storeValue();
|
|
|
265 |
public slots:
|
|
|
266 |
virtual void setEnabled(bool i) {
|
|
|
267 |
if (m_le) {
|
|
|
268 |
((QWidget*)m_le)->setEnabled(i);
|
|
|
269 |
}
|
|
|
270 |
}
|
|
|
271 |
protected:
|
|
|
272 |
QLineEdit *m_le;
|
|
|
273 |
QString m_origvalue;
|
|
|
274 |
};
|
|
|
275 |
|
|
|
276 |
// Constrained string: choose from list
|
|
|
277 |
class ConfParamCStrW : public ConfParamW {
|
|
|
278 |
Q_OBJECT
|
|
|
279 |
public:
|
|
|
280 |
ConfParamCStrW(const QString& varnm, QWidget *parent, ConfLink cflink,
|
|
|
281 |
const QString& lbltxt,
|
|
|
282 |
const QString& tltptxt, const QStringList& sl);
|
|
|
283 |
virtual void loadValue();
|
|
|
284 |
virtual void storeValue();
|
|
|
285 |
virtual void setList(const QStringList& sl);
|
|
|
286 |
public slots:
|
|
|
287 |
virtual void setEnabled(bool i) {
|
|
|
288 |
if (m_cmb) {
|
|
|
289 |
((QWidget*)m_cmb)->setEnabled(i);
|
|
|
290 |
}
|
|
|
291 |
}
|
|
|
292 |
protected:
|
|
|
293 |
QComboBox *m_cmb;
|
|
|
294 |
QString m_origvalue;
|
|
|
295 |
};
|
|
|
296 |
|
|
|
297 |
// File name
|
|
|
298 |
class ConfParamFNW : public ConfParamW {
|
|
|
299 |
Q_OBJECT
|
|
|
300 |
public:
|
|
|
301 |
ConfParamFNW(const QString& varnm, QWidget *parent, ConfLink cflink,
|
|
|
302 |
const QString& lbltxt,
|
|
|
303 |
const QString& tltptxt, bool isdir = false);
|
|
|
304 |
virtual void loadValue();
|
|
|
305 |
virtual void storeValue();
|
|
|
306 |
protected slots:
|
|
|
307 |
void showBrowserDialog();
|
|
|
308 |
public slots:
|
|
|
309 |
virtual void setEnabled(bool i) {
|
|
|
310 |
if (m_le) {
|
|
|
311 |
((QWidget*)m_le)->setEnabled(i);
|
|
|
312 |
}
|
|
|
313 |
if (m_pb) {
|
|
|
314 |
((QWidget*)m_pb)->setEnabled(i);
|
|
|
315 |
}
|
|
|
316 |
}
|
|
|
317 |
protected:
|
|
|
318 |
QLineEdit *m_le;
|
|
|
319 |
QPushButton *m_pb;
|
|
|
320 |
bool m_isdir;
|
|
|
321 |
QString m_origvalue;
|
|
|
322 |
};
|
|
|
323 |
|
|
|
324 |
// String list
|
|
|
325 |
class ConfParamSLW : public ConfParamW {
|
|
|
326 |
Q_OBJECT
|
|
|
327 |
public:
|
|
|
328 |
ConfParamSLW(const QString& varnm, QWidget *parent, ConfLink cflink,
|
|
|
329 |
const QString& lbltxt,
|
|
|
330 |
const QString& tltptxt);
|
|
|
331 |
virtual void loadValue();
|
|
|
332 |
virtual void storeValue();
|
|
|
333 |
QListWidget *getListBox() {
|
|
|
334 |
return m_lb;
|
|
|
335 |
}
|
|
|
336 |
|
|
|
337 |
public slots:
|
|
|
338 |
virtual void setEnabled(bool i) {
|
|
|
339 |
if (m_lb) {
|
|
|
340 |
((QWidget*)m_lb)->setEnabled(i);
|
|
|
341 |
}
|
|
|
342 |
}
|
|
|
343 |
protected slots:
|
|
|
344 |
virtual void showInputDialog();
|
|
|
345 |
void deleteSelected();
|
|
|
346 |
signals:
|
|
|
347 |
void entryDeleted(QString);
|
|
|
348 |
protected:
|
|
|
349 |
QListWidget *m_lb;
|
|
|
350 |
void listToConf();
|
|
|
351 |
std::string m_origvalue;
|
|
|
352 |
};
|
|
|
353 |
|
|
|
354 |
// Dir name list
|
|
|
355 |
class ConfParamDNLW : public ConfParamSLW {
|
|
|
356 |
Q_OBJECT
|
|
|
357 |
public:
|
|
|
358 |
ConfParamDNLW(const QString& varnm, QWidget *parent, ConfLink cflink,
|
|
|
359 |
const QString& lbltxt,
|
|
|
360 |
const QString& tltptxt)
|
|
|
361 |
: ConfParamSLW(varnm, parent, cflink, lbltxt, tltptxt) {
|
|
|
362 |
m_fsencoding = true;
|
|
|
363 |
}
|
|
|
364 |
protected slots:
|
|
|
365 |
virtual void showInputDialog();
|
|
|
366 |
};
|
|
|
367 |
|
|
|
368 |
// Constrained string list (chose from predefined)
|
|
|
369 |
class ConfParamCSLW : public ConfParamSLW {
|
|
|
370 |
Q_OBJECT
|
|
|
371 |
public:
|
|
|
372 |
ConfParamCSLW(const QString& varnm, QWidget *parent, ConfLink cflink,
|
|
|
373 |
const QString& lbltxt,
|
|
|
374 |
const QString& tltptxt,
|
|
|
375 |
const QStringList& sl)
|
|
|
376 |
: ConfParamSLW(varnm, parent, cflink, lbltxt, tltptxt), m_sl(sl) {
|
|
|
377 |
}
|
|
|
378 |
protected slots:
|
|
|
379 |
virtual void showInputDialog();
|
|
|
380 |
protected:
|
|
|
381 |
const QStringList m_sl;
|
|
|
382 |
};
|
|
|
383 |
|
|
|
384 |
#ifdef ENABLE_XMLCONF
|
|
|
385 |
/**
|
|
|
386 |
* Interpret an XML string and create a configuration interface. XML sample:
|
|
|
387 |
*
|
|
|
388 |
* <confcomments>
|
|
|
389 |
* <filetitle>Configuration file parameters for upmpdcli</filetitle>
|
|
|
390 |
* <grouptitle>MPD parameters</grouptitle>
|
|
|
391 |
* <var name="mpdhost" type="string">
|
|
|
392 |
* <brief>Host MPD runs on.</brief>
|
|
|
393 |
* <descr>Defaults to localhost. This can also be specified as -h</descr>
|
|
|
394 |
* </var>
|
|
|
395 |
* mpdhost = default-host
|
|
|
396 |
* <var name="mpdport" type="int" values="0 65635 6600">
|
|
|
397 |
* <brief>IP port used by MPD</brief>.
|
|
|
398 |
* <descr>Can also be specified as -p port. Defaults to the...</descr>
|
|
|
399 |
* </var>
|
|
|
400 |
* mpdport = defport
|
|
|
401 |
* <var name="ownqueue" type="bool" values="1">
|
|
|
402 |
* <brief>Set if we own the MPD queue.</brief>
|
|
|
403 |
* <descr>If this is set (on by default), we own the MPD...</descr>
|
|
|
404 |
* </var>
|
|
|
405 |
* ownqueue =
|
|
|
406 |
* </confcomments>
|
|
|
407 |
*
|
|
|
408 |
* <grouptitle> creates a panel in which the following <var> are set.
|
|
|
409 |
* The <var> attributes should be self-explanatory. "values"
|
|
|
410 |
* is used for different things depending on the var type
|
|
|
411 |
* (min/max, default, str list). Check the code about this.
|
|
|
412 |
* type values: "bool" "int" "string" "cstr" "cstrl" "fn" "dfn" "strl" "dnl"
|
|
|
413 |
*
|
|
|
414 |
* The XML would typically exist as comments inside a reference configuration
|
|
|
415 |
* file (ConfSimple can extract such comments).
|
|
|
416 |
*
|
|
|
417 |
* This means that the reference configuration file can generate both
|
|
|
418 |
* the documentation and the GUI interface.
|
|
|
419 |
*
|
|
|
420 |
* @param xml the input xml
|
|
|
421 |
* @param[output] toptxt the top level XML text (text not inside <var>,
|
|
|
422 |
* normally commented variable assignments). This will be evaluated
|
|
|
423 |
* as a config for default values.
|
|
|
424 |
* @lnkf factory to create the objects which link the GUI to the
|
|
|
425 |
* storage mechanism.
|
|
|
426 |
*/
|
|
|
427 |
extern ConfTabsW *xmlToConfGUI(const std::string& xml,
|
|
|
428 |
std::string& toptxt,
|
|
|
429 |
ConfLinkFact* lnkf,
|
|
|
430 |
QWidget *parent);
|
|
|
431 |
#endif
|
|
|
432 |
|
|
|
433 |
}
|
|
|
434 |
|
|
|
435 |
#endif /* _confgui_h_included_ */
|