blob: 4f9c695c1af89106c598fe54660c65cbbb759d7c [file] [log] [blame]
Masahiro Yamada0c874102018-12-18 21:13:35 +09001// SPDX-License-Identifier: GPL-2.0
Linus Torvalds1da177e2005-04-16 15:20:36 -07002/*
3 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
Boris Barbulovskib4ff1de2015-09-22 11:36:38 -07004 * Copyright (C) 2015 Boris Barbulovski <bbarbulovski@gmail.com>
Linus Torvalds1da177e2005-04-16 15:20:36 -07005 */
6
Alexander Stein133c5f72010-08-31 17:34:37 +02007#include <qglobal.h>
8
Boris Barbulovskib1f8a452015-09-22 11:36:02 -07009#include <QMainWindow>
Boris Barbulovski041fbdc2015-09-22 11:36:05 -070010#include <QList>
Boris Barbulovski924bbb52015-09-22 11:36:06 -070011#include <qtextbrowser.h>
Boris Barbulovski85eaf282015-09-22 11:36:03 -070012#include <QAction>
Boris Barbulovskibea00772015-09-22 11:36:04 -070013#include <QFileDialog>
Boris Barbulovski76bede82015-09-22 11:36:07 -070014#include <QMenu>
Alexander Stein133c5f72010-08-31 17:34:37 +020015
16#include <qapplication.h>
Markus Heidelberg8d90c972009-05-18 01:36:52 +020017#include <qdesktopwidget.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070018#include <qtoolbar.h>
Roman Zippel43bf6122006-06-08 22:12:45 -070019#include <qlayout.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070020#include <qsplitter.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070021#include <qlineedit.h>
Roman Zippel43bf6122006-06-08 22:12:45 -070022#include <qlabel.h>
23#include <qpushbutton.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070024#include <qmenubar.h>
25#include <qmessagebox.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070026#include <qregexp.h>
Alexander Stein133c5f72010-08-31 17:34:37 +020027#include <qevent.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070028
29#include <stdlib.h>
30
31#include "lkc.h"
32#include "qconf.h"
33
34#include "qconf.moc"
Masahiro Yamada3b541978562018-12-21 17:33:07 +090035#include "images.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070036
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -070037
Linus Torvalds1da177e2005-04-16 15:20:36 -070038static QApplication *configApp;
Roman Zippel7fc925f2006-06-08 22:12:46 -070039static ConfigSettings *configSettings;
Linus Torvalds1da177e2005-04-16 15:20:36 -070040
Boris Barbulovski85eaf282015-09-22 11:36:03 -070041QAction *ConfigMainWindow::saveAction;
Karsten Wiese3b354c52006-12-13 00:34:08 -080042
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -070043static inline QString qgettext(const char* str)
44{
Sam Ravnborg694c49a2018-05-22 21:36:12 +020045 return QString::fromLocal8Bit(str);
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -070046}
47
Ben Hutchings00d4f8f2013-10-06 19:21:31 +010048ConfigSettings::ConfigSettings()
49 : QSettings("kernel.org", "qconf")
50{
51}
52
Linus Torvalds1da177e2005-04-16 15:20:36 -070053/**
54 * Reads a list of integer values from the application settings.
55 */
Boris Barbulovski041fbdc2015-09-22 11:36:05 -070056QList<int> ConfigSettings::readSizes(const QString& key, bool *ok)
Linus Torvalds1da177e2005-04-16 15:20:36 -070057{
Boris Barbulovski041fbdc2015-09-22 11:36:05 -070058 QList<int> result;
Li Zefanc1f96f02010-05-07 13:58:04 +080059
Boris Barbulovski83c3a1b2016-11-30 14:57:55 -080060 if (contains(key))
61 {
62 QStringList entryList = value(key).toStringList();
63 QStringList::Iterator it;
64
65 for (it = entryList.begin(); it != entryList.end(); ++it)
66 result.push_back((*it).toInt());
67
68 *ok = true;
69 }
70 else
71 *ok = false;
Linus Torvalds1da177e2005-04-16 15:20:36 -070072
73 return result;
74}
75
76/**
77 * Writes a list of integer values to the application settings.
78 */
Boris Barbulovski041fbdc2015-09-22 11:36:05 -070079bool ConfigSettings::writeSizes(const QString& key, const QList<int>& value)
Linus Torvalds1da177e2005-04-16 15:20:36 -070080{
81 QStringList stringList;
Boris Barbulovski041fbdc2015-09-22 11:36:05 -070082 QList<int>::ConstIterator it;
Linus Torvalds1da177e2005-04-16 15:20:36 -070083
84 for (it = value.begin(); it != value.end(); ++it)
85 stringList.push_back(QString::number(*it));
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -070086 setValue(key, stringList);
Boris Barbulovski59e56442015-09-22 11:36:18 -070087
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -070088 return true;
Linus Torvalds1da177e2005-04-16 15:20:36 -070089}
Linus Torvalds1da177e2005-04-16 15:20:36 -070090
Boris Barbulovski59e56442015-09-22 11:36:18 -070091
92/*
93 * set the new data
94 * TODO check the value
95 */
96void ConfigItem::okRename(int col)
97{
98}
99
100/*
101 * update the displayed of a menu entry
102 */
103void ConfigItem::updateMenu(void)
104{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700105 ConfigList* list;
106 struct symbol* sym;
107 struct property *prop;
108 QString prompt;
109 int type;
110 tristate expr;
111
112 list = listView();
113 if (goParent) {
114 setPixmap(promptColIdx, list->menuBackPix);
115 prompt = "..";
116 goto set_prompt;
117 }
118
119 sym = menu->sym;
120 prop = menu->prompt;
Sam Ravnborg694c49a2018-05-22 21:36:12 +0200121 prompt = qgettext(menu_get_prompt(menu));
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700122
123 if (prop) switch (prop->type) {
124 case P_MENU:
125 if (list->mode == singleMode || list->mode == symbolMode) {
126 /* a menuconfig entry is displayed differently
127 * depending whether it's at the view root or a child.
128 */
129 if (sym && list->rootEntry == menu)
130 break;
131 setPixmap(promptColIdx, list->menuPix);
132 } else {
133 if (sym)
134 break;
135 setPixmap(promptColIdx, QIcon());
136 }
137 goto set_prompt;
138 case P_COMMENT:
139 setPixmap(promptColIdx, QIcon());
140 goto set_prompt;
141 default:
142 ;
143 }
144 if (!sym)
145 goto set_prompt;
146
147 setText(nameColIdx, QString::fromLocal8Bit(sym->name));
148
149 type = sym_get_type(sym);
150 switch (type) {
151 case S_BOOLEAN:
152 case S_TRISTATE:
153 char ch;
154
Marco Ammonbaa23ec2019-07-04 12:50:41 +0200155 if (!sym_is_changeable(sym) && list->optMode == normalOpt) {
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700156 setPixmap(promptColIdx, QIcon());
Mauro Carvalho Chehabcf497b92020-04-02 11:27:58 +0200157 setText(noColIdx, QString());
158 setText(modColIdx, QString());
159 setText(yesColIdx, QString());
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700160 break;
161 }
162 expr = sym_get_tristate_value(sym);
163 switch (expr) {
164 case yes:
165 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
166 setPixmap(promptColIdx, list->choiceYesPix);
167 else
168 setPixmap(promptColIdx, list->symbolYesPix);
169 setText(yesColIdx, "Y");
170 ch = 'Y';
171 break;
172 case mod:
173 setPixmap(promptColIdx, list->symbolModPix);
174 setText(modColIdx, "M");
175 ch = 'M';
176 break;
177 default:
178 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
179 setPixmap(promptColIdx, list->choiceNoPix);
180 else
181 setPixmap(promptColIdx, list->symbolNoPix);
182 setText(noColIdx, "N");
183 ch = 'N';
184 break;
185 }
186 if (expr != no)
187 setText(noColIdx, sym_tristate_within_range(sym, no) ? "_" : 0);
188 if (expr != mod)
189 setText(modColIdx, sym_tristate_within_range(sym, mod) ? "_" : 0);
190 if (expr != yes)
191 setText(yesColIdx, sym_tristate_within_range(sym, yes) ? "_" : 0);
192
193 setText(dataColIdx, QChar(ch));
194 break;
195 case S_INT:
196 case S_HEX:
197 case S_STRING:
198 const char* data;
199
200 data = sym_get_string_value(sym);
201
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700202 setText(dataColIdx, data);
203 if (type == S_STRING)
204 prompt = QString("%1: %2").arg(prompt).arg(data);
205 else
206 prompt = QString("(%2) %1").arg(prompt).arg(data);
207 break;
208 }
209 if (!sym_has_value(sym) && visible)
Sam Ravnborg694c49a2018-05-22 21:36:12 +0200210 prompt += " (NEW)";
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700211set_prompt:
212 setText(promptColIdx, prompt);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700213}
214
215void ConfigItem::testUpdateMenu(bool v)
216{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700217 ConfigItem* i;
218
219 visible = v;
220 if (!menu)
221 return;
222
223 sym_calc_value(menu->sym);
224 if (menu->flags & MENU_CHANGED) {
225 /* the menu entry changed, so update all list items */
226 menu->flags &= ~MENU_CHANGED;
227 for (i = (ConfigItem*)menu->data; i; i = i->nextItem)
228 i->updateMenu();
229 } else if (listView()->updateAll)
230 updateMenu();
Boris Barbulovski59e56442015-09-22 11:36:18 -0700231}
232
233
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700234/*
235 * construct a menu entry
236 */
237void ConfigItem::init(void)
238{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700239 if (menu) {
240 ConfigList* list = listView();
241 nextItem = (ConfigItem*)menu->data;
242 menu->data = this;
243
244 if (list->mode != fullMode)
245 setExpanded(true);
246 sym_calc_value(menu->sym);
247 }
248 updateMenu();
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700249}
250
251/*
252 * destruct a menu entry
253 */
254ConfigItem::~ConfigItem(void)
255{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700256 if (menu) {
257 ConfigItem** ip = (ConfigItem**)&menu->data;
258 for (; *ip; ip = &(*ip)->nextItem) {
259 if (*ip == this) {
260 *ip = nextItem;
261 break;
262 }
263 }
264 }
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700265}
266
Roman Zippel43bf6122006-06-08 22:12:45 -0700267ConfigLineEdit::ConfigLineEdit(ConfigView* parent)
268 : Parent(parent)
269{
Boris Barbulovskic14fa5e2015-09-22 11:36:21 -0700270 connect(this, SIGNAL(editingFinished()), SLOT(hide()));
Roman Zippel43bf6122006-06-08 22:12:45 -0700271}
272
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700273void ConfigLineEdit::show(ConfigItem* i)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700274{
275 item = i;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700276 if (sym_get_string_value(item->menu->sym))
277 setText(QString::fromLocal8Bit(sym_get_string_value(item->menu->sym)));
278 else
Mauro Carvalho Chehabcf497b92020-04-02 11:27:58 +0200279 setText(QString());
Linus Torvalds1da177e2005-04-16 15:20:36 -0700280 Parent::show();
281 setFocus();
282}
283
284void ConfigLineEdit::keyPressEvent(QKeyEvent* e)
285{
286 switch (e->key()) {
Markus Heidelbergfbb86372009-05-18 01:36:51 +0200287 case Qt::Key_Escape:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700288 break;
Markus Heidelbergfbb86372009-05-18 01:36:51 +0200289 case Qt::Key_Return:
290 case Qt::Key_Enter:
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700291 sym_set_string_value(item->menu->sym, text().toLatin1());
Linus Torvalds1da177e2005-04-16 15:20:36 -0700292 parent()->updateList(item);
293 break;
294 default:
295 Parent::keyPressEvent(e);
296 return;
297 }
298 e->accept();
299 parent()->list->setFocus();
300 hide();
301}
302
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700303ConfigList::ConfigList(ConfigView* p, const char *name)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700304 : Parent(p),
305 updateAll(false),
306 symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no),
307 choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no),
308 menuPix(xpm_menu), menuInvPix(xpm_menu_inv), menuBackPix(xpm_menuback), voidPix(xpm_void),
Boris Barbulovskidbf62932015-09-22 11:36:26 -0700309 showName(false), showRange(false), showData(false), mode(singleMode), optMode(normalOpt),
Boris Barbulovski59e56442015-09-22 11:36:18 -0700310 rootEntry(0), headerPopup(0)
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700311{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700312 setObjectName(name);
Boris Barbulovskia5225e92015-09-22 11:36:29 -0700313 setSortingEnabled(false);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700314 setRootIsDecorated(true);
315
Boris Barbulovskif999cc02015-09-22 11:36:31 -0700316 setVerticalScrollMode(ScrollPerPixel);
317 setHorizontalScrollMode(ScrollPerPixel);
318
Mauro Carvalho Chehab5752ff02020-04-02 11:27:59 +0200319 if (mode == symbolMode)
320 setHeaderLabels(QStringList() << "Item" << "Name" << "N" << "M" << "Y" << "Value");
321 else
322 setHeaderLabels(QStringList() << "Option" << "Name" << "N" << "M" << "Y" << "Value");
Boris Barbulovskia52cb322015-09-22 11:36:24 -0700323
Boris Barbulovskic14fa5e2015-09-22 11:36:21 -0700324 connect(this, SIGNAL(itemSelectionChanged(void)),
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700325 SLOT(updateSelection(void)));
326
327 if (name) {
328 configSettings->beginGroup(name);
329 showName = configSettings->value("/showName", false).toBool();
330 showRange = configSettings->value("/showRange", false).toBool();
331 showData = configSettings->value("/showData", false).toBool();
332 optMode = (enum optionMode)configSettings->value("/optionMode", 0).toInt();
333 configSettings->endGroup();
334 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
335 }
336
337 addColumn(promptColIdx);
338
339 reinit();
340}
341
342bool ConfigList::menuSkip(struct menu *menu)
343{
344 if (optMode == normalOpt && menu_is_visible(menu))
345 return false;
346 if (optMode == promptOpt && menu_has_prompt(menu))
347 return false;
348 if (optMode == allOpt)
349 return false;
350 return true;
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700351}
Boris Barbulovski59e56442015-09-22 11:36:18 -0700352
353void ConfigList::reinit(void)
354{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700355 removeColumn(dataColIdx);
356 removeColumn(yesColIdx);
357 removeColumn(modColIdx);
358 removeColumn(noColIdx);
359 removeColumn(nameColIdx);
360
361 if (showName)
362 addColumn(nameColIdx);
363 if (showRange) {
364 addColumn(noColIdx);
365 addColumn(modColIdx);
366 addColumn(yesColIdx);
367 }
368 if (showData)
369 addColumn(dataColIdx);
370
371 updateListAll();
Boris Barbulovski59e56442015-09-22 11:36:18 -0700372}
373
374void ConfigList::saveSettings(void)
375{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700376 if (!objectName().isEmpty()) {
377 configSettings->beginGroup(objectName());
378 configSettings->setValue("/showName", showName);
379 configSettings->setValue("/showRange", showRange);
380 configSettings->setValue("/showData", showData);
381 configSettings->setValue("/optionMode", (int)optMode);
382 configSettings->endGroup();
383 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700384}
385
386ConfigItem* ConfigList::findConfigItem(struct menu *menu)
387{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700388 ConfigItem* item = (ConfigItem*)menu->data;
389
390 for (; item; item = item->nextItem) {
391 if (this == item->listView())
392 break;
393 }
394
395 return item;
Boris Barbulovski59e56442015-09-22 11:36:18 -0700396}
397
398void ConfigList::updateSelection(void)
399{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700400 struct menu *menu;
401 enum prop_type type;
402
Mauro Carvalho Chehab5752ff02020-04-02 11:27:59 +0200403 if (mode == symbolMode)
404 setHeaderLabels(QStringList() << "Item" << "Name" << "N" << "M" << "Y" << "Value");
405 else
406 setHeaderLabels(QStringList() << "Option" << "Name" << "N" << "M" << "Y" << "Value");
407
Boris Barbulovskibe596aa2015-09-22 11:36:28 -0700408 if (selectedItems().count() == 0)
409 return;
410
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700411 ConfigItem* item = (ConfigItem*)selectedItems().first();
412 if (!item)
413 return;
414
415 menu = item->menu;
416 emit menuChanged(menu);
417 if (!menu)
418 return;
419 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
420 if (mode == menuMode && type == P_MENU)
421 emit menuSelected(menu);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700422}
423
424void ConfigList::updateList(ConfigItem* item)
425{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700426 ConfigItem* last = 0;
427
428 if (!rootEntry) {
429 if (mode != listMode)
430 goto update;
431 QTreeWidgetItemIterator it(this);
432 ConfigItem* item;
433
434 while (*it) {
435 item = (ConfigItem*)(*it);
436 if (!item->menu)
437 continue;
438 item->testUpdateMenu(menu_is_visible(item->menu));
439
440 ++it;
441 }
442 return;
443 }
444
445 if (rootEntry != &rootmenu && (mode == singleMode ||
446 (mode == symbolMode && rootEntry->parent != &rootmenu))) {
Boris Barbulovskiee7298f2015-09-22 11:36:37 -0700447 item = (ConfigItem *)topLevelItem(0);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700448 if (!item)
449 item = new ConfigItem(this, 0, true);
450 last = item;
451 }
452 if ((mode == singleMode || (mode == symbolMode && !(rootEntry->flags & MENU_ROOT))) &&
453 rootEntry->sym && rootEntry->prompt) {
454 item = last ? last->nextSibling() : firstChild();
455 if (!item)
456 item = new ConfigItem(this, last, rootEntry, true);
457 else
458 item->testUpdateMenu(true);
459
460 updateMenuList(item, rootEntry);
461 update();
Boris Barbulovskif999cc02015-09-22 11:36:31 -0700462 resizeColumnToContents(0);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700463 return;
464 }
465update:
466 updateMenuList(this, rootEntry);
467 update();
Boris Barbulovskif999cc02015-09-22 11:36:31 -0700468 resizeColumnToContents(0);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700469}
470
471void ConfigList::setValue(ConfigItem* item, tristate val)
472{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700473 struct symbol* sym;
474 int type;
475 tristate oldval;
476
477 sym = item->menu ? item->menu->sym : 0;
478 if (!sym)
479 return;
480
481 type = sym_get_type(sym);
482 switch (type) {
483 case S_BOOLEAN:
484 case S_TRISTATE:
485 oldval = sym_get_tristate_value(sym);
486
487 if (!sym_set_tristate_value(sym, val))
488 return;
489 if (oldval == no && item->menu->list)
490 item->setExpanded(true);
491 parent()->updateList(item);
492 break;
493 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700494}
495
496void ConfigList::changeValue(ConfigItem* item)
497{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700498 struct symbol* sym;
499 struct menu* menu;
500 int type, oldexpr, newexpr;
501
502 menu = item->menu;
503 if (!menu)
504 return;
505 sym = menu->sym;
506 if (!sym) {
507 if (item->menu->list)
508 item->setExpanded(!item->isExpanded());
509 return;
510 }
511
512 type = sym_get_type(sym);
513 switch (type) {
514 case S_BOOLEAN:
515 case S_TRISTATE:
516 oldexpr = sym_get_tristate_value(sym);
517 newexpr = sym_toggle_tristate_value(sym);
518 if (item->menu->list) {
519 if (oldexpr == newexpr)
520 item->setExpanded(!item->isExpanded());
521 else if (oldexpr == no)
522 item->setExpanded(true);
523 }
524 if (oldexpr != newexpr)
525 parent()->updateList(item);
526 break;
527 case S_INT:
528 case S_HEX:
529 case S_STRING:
Boris Barbulovskie336b9f2015-09-22 11:36:34 -0700530 parent()->lineEdit->show(item);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700531 break;
532 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700533}
534
535void ConfigList::setRootMenu(struct menu *menu)
536{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700537 enum prop_type type;
538
539 if (rootEntry == menu)
540 return;
541 type = menu && menu->prompt ? menu->prompt->type : P_UNKNOWN;
542 if (type != P_MENU)
543 return;
544 updateMenuList(this, 0);
545 rootEntry = menu;
546 updateListAll();
547 if (currentItem()) {
548 currentItem()->setSelected(hasFocus());
549 scrollToItem(currentItem());
550 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700551}
552
553void ConfigList::setParentMenu(void)
554{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700555 ConfigItem* item;
556 struct menu *oldroot;
557
558 oldroot = rootEntry;
559 if (rootEntry == &rootmenu)
560 return;
561 setRootMenu(menu_get_parent_menu(rootEntry->parent));
562
563 QTreeWidgetItemIterator it(this);
564 while (*it) {
565 item = (ConfigItem *)(*it);
566 if (item->menu == oldroot) {
567 setCurrentItem(item);
568 scrollToItem(item);
569 break;
570 }
571
572 ++it;
573 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700574}
575
576/*
577 * update all the children of a menu entry
578 * removes/adds the entries from the parent widget as necessary
579 *
580 * parent: either the menu list widget or a menu entry widget
581 * menu: entry to be updated
582 */
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700583void ConfigList::updateMenuList(ConfigItem *parent, struct menu* menu)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700584{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700585 struct menu* child;
586 ConfigItem* item;
587 ConfigItem* last;
588 bool visible;
589 enum prop_type type;
590
591 if (!menu) {
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700592 while (parent->childCount() > 0)
593 {
594 delete parent->takeChild(0);
595 }
596
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700597 return;
598 }
599
600 last = parent->firstChild();
601 if (last && !last->goParent)
602 last = 0;
603 for (child = menu->list; child; child = child->next) {
604 item = last ? last->nextSibling() : parent->firstChild();
605 type = child->prompt ? child->prompt->type : P_UNKNOWN;
606
607 switch (mode) {
608 case menuMode:
609 if (!(child->flags & MENU_ROOT))
610 goto hide;
611 break;
612 case symbolMode:
613 if (child->flags & MENU_ROOT)
614 goto hide;
615 break;
616 default:
617 break;
618 }
619
620 visible = menu_is_visible(child);
621 if (!menuSkip(child)) {
622 if (!child->sym && !child->list && !child->prompt)
623 continue;
624 if (!item || item->menu != child)
625 item = new ConfigItem(parent, last, child, visible);
626 else
627 item->testUpdateMenu(visible);
628
629 if (mode == fullMode || mode == menuMode || type != P_MENU)
630 updateMenuList(item, child);
631 else
632 updateMenuList(item, 0);
633 last = item;
634 continue;
635 }
636 hide:
637 if (item && item->menu == child) {
638 last = parent->firstChild();
639 if (last == item)
640 last = 0;
641 else while (last->nextSibling() != item)
642 last = last->nextSibling();
643 delete item;
644 }
645 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700646}
647
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700648void ConfigList::updateMenuList(ConfigList *parent, struct menu* menu)
649{
650 struct menu* child;
651 ConfigItem* item;
652 ConfigItem* last;
653 bool visible;
654 enum prop_type type;
655
656 if (!menu) {
657 while (parent->topLevelItemCount() > 0)
658 {
659 delete parent->takeTopLevelItem(0);
660 }
661
662 return;
663 }
664
665 last = (ConfigItem*)parent->topLevelItem(0);
666 if (last && !last->goParent)
667 last = 0;
668 for (child = menu->list; child; child = child->next) {
669 item = last ? last->nextSibling() : (ConfigItem*)parent->topLevelItem(0);
670 type = child->prompt ? child->prompt->type : P_UNKNOWN;
671
672 switch (mode) {
673 case menuMode:
674 if (!(child->flags & MENU_ROOT))
675 goto hide;
676 break;
677 case symbolMode:
678 if (child->flags & MENU_ROOT)
679 goto hide;
680 break;
681 default:
682 break;
683 }
684
685 visible = menu_is_visible(child);
686 if (!menuSkip(child)) {
687 if (!child->sym && !child->list && !child->prompt)
688 continue;
689 if (!item || item->menu != child)
690 item = new ConfigItem(parent, last, child, visible);
691 else
692 item->testUpdateMenu(visible);
693
694 if (mode == fullMode || mode == menuMode || type != P_MENU)
695 updateMenuList(item, child);
696 else
697 updateMenuList(item, 0);
698 last = item;
699 continue;
700 }
701 hide:
702 if (item && item->menu == child) {
703 last = (ConfigItem*)parent->topLevelItem(0);
704 if (last == item)
705 last = 0;
706 else while (last->nextSibling() != item)
707 last = last->nextSibling();
708 delete item;
709 }
710 }
711}
712
Boris Barbulovski59e56442015-09-22 11:36:18 -0700713void ConfigList::keyPressEvent(QKeyEvent* ev)
714{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700715 QTreeWidgetItem* i = currentItem();
716 ConfigItem* item;
717 struct menu *menu;
718 enum prop_type type;
719
720 if (ev->key() == Qt::Key_Escape && mode != fullMode && mode != listMode) {
721 emit parentSelected();
722 ev->accept();
723 return;
724 }
725
726 if (!i) {
727 Parent::keyPressEvent(ev);
728 return;
729 }
730 item = (ConfigItem*)i;
731
732 switch (ev->key()) {
733 case Qt::Key_Return:
734 case Qt::Key_Enter:
735 if (item->goParent) {
736 emit parentSelected();
737 break;
738 }
739 menu = item->menu;
740 if (!menu)
741 break;
742 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
743 if (type == P_MENU && rootEntry != menu &&
744 mode != fullMode && mode != menuMode) {
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +0200745 if (mode == menuMode)
746 emit menuSelected(menu);
747 else
748 emit itemSelected(menu);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700749 break;
750 }
751 case Qt::Key_Space:
752 changeValue(item);
753 break;
754 case Qt::Key_N:
755 setValue(item, no);
756 break;
757 case Qt::Key_M:
758 setValue(item, mod);
759 break;
760 case Qt::Key_Y:
761 setValue(item, yes);
762 break;
763 default:
764 Parent::keyPressEvent(ev);
765 return;
766 }
767 ev->accept();
Boris Barbulovski59e56442015-09-22 11:36:18 -0700768}
769
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700770void ConfigList::mousePressEvent(QMouseEvent* e)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700771{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700772 //QPoint p(contentsToViewport(e->pos()));
773 //printf("contentsMousePressEvent: %d,%d\n", p.x(), p.y());
774 Parent::mousePressEvent(e);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700775}
776
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700777void ConfigList::mouseReleaseEvent(QMouseEvent* e)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700778{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700779 QPoint p = e->pos();
780 ConfigItem* item = (ConfigItem*)itemAt(p);
781 struct menu *menu;
782 enum prop_type ptype;
783 QIcon icon;
784 int idx, x;
785
786 if (!item)
787 goto skip;
788
789 menu = item->menu;
790 x = header()->offset() + p.x();
Boris Barbulovski76d53cb2015-09-22 11:36:35 -0700791 idx = header()->logicalIndexAt(x);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700792 switch (idx) {
793 case promptColIdx:
794 icon = item->pixmap(promptColIdx);
Boris Barbulovski76d53cb2015-09-22 11:36:35 -0700795 if (!icon.isNull()) {
796 int off = header()->sectionPosition(0) + visualRect(indexAt(p)).x() + 4; // 4 is Hardcoded image offset. There might be a way to do it properly.
797 if (x >= off && x < off + icon.availableSizes().first().width()) {
798 if (item->goParent) {
799 emit parentSelected();
800 break;
801 } else if (!menu)
802 break;
803 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
804 if (ptype == P_MENU && rootEntry != menu &&
805 mode != fullMode && mode != menuMode)
806 emit menuSelected(menu);
807 else
808 changeValue(item);
809 }
810 }
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700811 break;
812 case noColIdx:
813 setValue(item, no);
814 break;
815 case modColIdx:
816 setValue(item, mod);
817 break;
818 case yesColIdx:
819 setValue(item, yes);
820 break;
821 case dataColIdx:
822 changeValue(item);
823 break;
824 }
825
826skip:
827 //printf("contentsMouseReleaseEvent: %d,%d\n", p.x(), p.y());
828 Parent::mouseReleaseEvent(e);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700829}
830
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700831void ConfigList::mouseMoveEvent(QMouseEvent* e)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700832{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700833 //QPoint p(contentsToViewport(e->pos()));
834 //printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y());
835 Parent::mouseMoveEvent(e);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700836}
837
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700838void ConfigList::mouseDoubleClickEvent(QMouseEvent* e)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700839{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700840 QPoint p = e->pos(); // TODO: Check if this works(was contentsToViewport).
841 ConfigItem* item = (ConfigItem*)itemAt(p);
842 struct menu *menu;
843 enum prop_type ptype;
844
845 if (!item)
846 goto skip;
847 if (item->goParent) {
848 emit parentSelected();
849 goto skip;
850 }
851 menu = item->menu;
852 if (!menu)
853 goto skip;
854 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +0200855 if (ptype == P_MENU) {
856 if (mode == singleMode)
857 emit itemSelected(menu);
858 else if (mode == symbolMode)
859 emit menuSelected(menu);
860 } else if (menu->sym)
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700861 changeValue(item);
862
863skip:
864 //printf("contentsMouseDoubleClickEvent: %d,%d\n", p.x(), p.y());
865 Parent::mouseDoubleClickEvent(e);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700866}
867
868void ConfigList::focusInEvent(QFocusEvent *e)
869{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700870 struct menu *menu = NULL;
871
872 Parent::focusInEvent(e);
873
874 ConfigItem* item = (ConfigItem *)currentItem();
875 if (item) {
876 item->setSelected(true);
877 menu = item->menu;
878 }
879 emit gotFocus(menu);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700880}
881
882void ConfigList::contextMenuEvent(QContextMenuEvent *e)
883{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700884 if (e->y() <= header()->geometry().bottom()) {
885 if (!headerPopup) {
886 QAction *action;
887
888 headerPopup = new QMenu(this);
Sam Ravnborg694c49a2018-05-22 21:36:12 +0200889 action = new QAction("Show Name", this);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700890 action->setCheckable(true);
891 connect(action, SIGNAL(toggled(bool)),
892 parent(), SLOT(setShowName(bool)));
893 connect(parent(), SIGNAL(showNameChanged(bool)),
894 action, SLOT(setOn(bool)));
895 action->setChecked(showName);
896 headerPopup->addAction(action);
Sam Ravnborg694c49a2018-05-22 21:36:12 +0200897 action = new QAction("Show Range", this);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700898 action->setCheckable(true);
899 connect(action, SIGNAL(toggled(bool)),
900 parent(), SLOT(setShowRange(bool)));
901 connect(parent(), SIGNAL(showRangeChanged(bool)),
902 action, SLOT(setOn(bool)));
903 action->setChecked(showRange);
904 headerPopup->addAction(action);
Sam Ravnborg694c49a2018-05-22 21:36:12 +0200905 action = new QAction("Show Data", this);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700906 action->setCheckable(true);
907 connect(action, SIGNAL(toggled(bool)),
908 parent(), SLOT(setShowData(bool)));
909 connect(parent(), SIGNAL(showDataChanged(bool)),
910 action, SLOT(setOn(bool)));
911 action->setChecked(showData);
912 headerPopup->addAction(action);
913 }
914 headerPopup->exec(e->globalPos());
915 e->accept();
916 } else
917 e->ignore();
Boris Barbulovski59e56442015-09-22 11:36:18 -0700918}
919
Li Zefan39a48972010-05-10 16:33:41 +0800920ConfigView*ConfigView::viewList;
921QAction *ConfigView::showNormalAction;
922QAction *ConfigView::showAllAction;
923QAction *ConfigView::showPromptAction;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700924
Roman Zippel7fc925f2006-06-08 22:12:46 -0700925ConfigView::ConfigView(QWidget* parent, const char *name)
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -0700926 : Parent(parent)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700927{
Boris Barbulovski9bd36ed2015-09-22 11:36:22 -0700928 setObjectName(name);
Boris Barbulovski29a70162015-09-22 11:36:10 -0700929 QVBoxLayout *verticalLayout = new QVBoxLayout(this);
Boris Barbulovski92298b42015-09-22 11:36:11 -0700930 verticalLayout->setContentsMargins(0, 0, 0, 0);
Boris Barbulovski29a70162015-09-22 11:36:10 -0700931
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700932 list = new ConfigList(this);
Boris Barbulovski29a70162015-09-22 11:36:10 -0700933 verticalLayout->addWidget(list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700934 lineEdit = new ConfigLineEdit(this);
935 lineEdit->hide();
Boris Barbulovski29a70162015-09-22 11:36:10 -0700936 verticalLayout->addWidget(lineEdit);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700937
938 this->nextView = viewList;
939 viewList = this;
940}
941
942ConfigView::~ConfigView(void)
943{
944 ConfigView** vp;
945
946 for (vp = &viewList; *vp; vp = &(*vp)->nextView) {
947 if (*vp == this) {
948 *vp = nextView;
949 break;
950 }
951 }
952}
953
Li Zefan39a48972010-05-10 16:33:41 +0800954void ConfigView::setOptionMode(QAction *act)
Roman Zippel7fc925f2006-06-08 22:12:46 -0700955{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700956 if (act == showNormalAction)
957 list->optMode = normalOpt;
958 else if (act == showAllAction)
959 list->optMode = allOpt;
960 else
961 list->optMode = promptOpt;
962
963 list->updateListAll();
Roman Zippel7fc925f2006-06-08 22:12:46 -0700964}
965
966void ConfigView::setShowName(bool b)
967{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700968 if (list->showName != b) {
969 list->showName = b;
970 list->reinit();
971 emit showNameChanged(b);
972 }
Roman Zippel7fc925f2006-06-08 22:12:46 -0700973}
974
975void ConfigView::setShowRange(bool b)
976{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700977 if (list->showRange != b) {
978 list->showRange = b;
979 list->reinit();
980 emit showRangeChanged(b);
981 }
Roman Zippel7fc925f2006-06-08 22:12:46 -0700982}
983
984void ConfigView::setShowData(bool b)
985{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700986 if (list->showData != b) {
987 list->showData = b;
988 list->reinit();
989 emit showDataChanged(b);
990 }
991}
992
993void ConfigList::setAllOpen(bool open)
994{
995 QTreeWidgetItemIterator it(this);
996
997 while (*it) {
998 (*it)->setExpanded(open);
999
1000 ++it;
1001 }
Roman Zippel7fc925f2006-06-08 22:12:46 -07001002}
1003
Boris Barbulovski1019f1a2015-09-22 11:36:17 -07001004void ConfigView::updateList(ConfigItem* item)
Roman Zippel7fc925f2006-06-08 22:12:46 -07001005{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001006 ConfigView* v;
1007
1008 for (v = viewList; v; v = v->nextView)
1009 v->list->updateList(item);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001010}
1011
1012void ConfigView::updateListAll(void)
1013{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001014 ConfigView* v;
1015
1016 for (v = viewList; v; v = v->nextView)
1017 v->list->updateListAll();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001018}
1019
Roman Zippel43bf6122006-06-08 22:12:45 -07001020ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name)
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001021 : Parent(parent), sym(0), _menu(0)
Roman Zippel43bf6122006-06-08 22:12:45 -07001022{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001023 setObjectName(name);
1024
1025
1026 if (!objectName().isEmpty()) {
1027 configSettings->beginGroup(objectName());
Boris Barbulovskie0393032016-11-30 14:57:52 -08001028 setShowDebug(configSettings->value("/showDebug", false).toBool());
Roman Zippel7fc925f2006-06-08 22:12:46 -07001029 configSettings->endGroup();
1030 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
1031 }
1032}
1033
1034void ConfigInfoView::saveSettings(void)
1035{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001036 if (!objectName().isEmpty()) {
1037 configSettings->beginGroup(objectName());
1038 configSettings->setValue("/showDebug", showDebug());
1039 configSettings->endGroup();
1040 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001041}
1042
1043void ConfigInfoView::setShowDebug(bool b)
1044{
1045 if (_showDebug != b) {
1046 _showDebug = b;
Alexander Stein133c5f72010-08-31 17:34:37 +02001047 if (_menu)
Roman Zippel43bf6122006-06-08 22:12:45 -07001048 menuInfo();
Roman Zippelab45d192006-06-08 22:12:47 -07001049 else if (sym)
1050 symbolInfo();
Roman Zippel43bf6122006-06-08 22:12:45 -07001051 emit showDebugChanged(b);
1052 }
1053}
1054
1055void ConfigInfoView::setInfo(struct menu *m)
1056{
Alexander Stein133c5f72010-08-31 17:34:37 +02001057 if (_menu == m)
Roman Zippelb65a47e2006-06-08 22:12:47 -07001058 return;
Alexander Stein133c5f72010-08-31 17:34:37 +02001059 _menu = m;
Roman Zippel6fa1da82007-01-10 23:15:31 -08001060 sym = NULL;
Alexander Stein133c5f72010-08-31 17:34:37 +02001061 if (!_menu)
Roman Zippel43bf6122006-06-08 22:12:45 -07001062 clear();
Roman Zippel6fa1da82007-01-10 23:15:31 -08001063 else
Roman Zippel43bf6122006-06-08 22:12:45 -07001064 menuInfo();
1065}
1066
Roman Zippelab45d192006-06-08 22:12:47 -07001067void ConfigInfoView::symbolInfo(void)
1068{
1069 QString str;
1070
1071 str += "<big>Symbol: <b>";
1072 str += print_filter(sym->name);
1073 str += "</b></big><br><br>value: ";
1074 str += print_filter(sym_get_string_value(sym));
1075 str += "<br>visibility: ";
1076 str += sym->visible == yes ? "y" : sym->visible == mod ? "m" : "n";
1077 str += "<br>";
1078 str += debug_info(sym);
1079
1080 setText(str);
1081}
1082
Roman Zippel43bf6122006-06-08 22:12:45 -07001083void ConfigInfoView::menuInfo(void)
1084{
1085 struct symbol* sym;
1086 QString head, debug, help;
1087
Alexander Stein133c5f72010-08-31 17:34:37 +02001088 sym = _menu->sym;
Roman Zippel43bf6122006-06-08 22:12:45 -07001089 if (sym) {
Alexander Stein133c5f72010-08-31 17:34:37 +02001090 if (_menu->prompt) {
Roman Zippel43bf6122006-06-08 22:12:45 -07001091 head += "<big><b>";
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001092 head += print_filter(_menu->prompt->text);
Roman Zippel43bf6122006-06-08 22:12:45 -07001093 head += "</b></big>";
1094 if (sym->name) {
1095 head += " (";
Roman Zippelab45d192006-06-08 22:12:47 -07001096 if (showDebug())
1097 head += QString().sprintf("<a href=\"s%p\">", sym);
Roman Zippel43bf6122006-06-08 22:12:45 -07001098 head += print_filter(sym->name);
Roman Zippelab45d192006-06-08 22:12:47 -07001099 if (showDebug())
1100 head += "</a>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001101 head += ")";
1102 }
1103 } else if (sym->name) {
1104 head += "<big><b>";
Roman Zippelab45d192006-06-08 22:12:47 -07001105 if (showDebug())
1106 head += QString().sprintf("<a href=\"s%p\">", sym);
Roman Zippel43bf6122006-06-08 22:12:45 -07001107 head += print_filter(sym->name);
Roman Zippelab45d192006-06-08 22:12:47 -07001108 if (showDebug())
1109 head += "</a>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001110 head += "</b></big>";
1111 }
1112 head += "<br><br>";
1113
1114 if (showDebug())
1115 debug = debug_info(sym);
1116
Cheng Renquand74c15f2009-07-12 16:11:47 +08001117 struct gstr help_gstr = str_new();
Alexander Stein133c5f72010-08-31 17:34:37 +02001118 menu_get_ext_help(_menu, &help_gstr);
Cheng Renquand74c15f2009-07-12 16:11:47 +08001119 help = print_filter(str_get(&help_gstr));
1120 str_free(&help_gstr);
Alexander Stein133c5f72010-08-31 17:34:37 +02001121 } else if (_menu->prompt) {
Roman Zippel43bf6122006-06-08 22:12:45 -07001122 head += "<big><b>";
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001123 head += print_filter(_menu->prompt->text);
Roman Zippel43bf6122006-06-08 22:12:45 -07001124 head += "</b></big><br><br>";
1125 if (showDebug()) {
Alexander Stein133c5f72010-08-31 17:34:37 +02001126 if (_menu->prompt->visible.expr) {
Roman Zippel43bf6122006-06-08 22:12:45 -07001127 debug += "&nbsp;&nbsp;dep: ";
Alexander Stein133c5f72010-08-31 17:34:37 +02001128 expr_print(_menu->prompt->visible.expr, expr_print_help, &debug, E_NONE);
Roman Zippel43bf6122006-06-08 22:12:45 -07001129 debug += "<br><br>";
1130 }
1131 }
1132 }
1133 if (showDebug())
Alexander Stein133c5f72010-08-31 17:34:37 +02001134 debug += QString().sprintf("defined at %s:%d<br><br>", _menu->file->name, _menu->lineno);
Roman Zippel43bf6122006-06-08 22:12:45 -07001135
1136 setText(head + debug + help);
1137}
1138
1139QString ConfigInfoView::debug_info(struct symbol *sym)
1140{
1141 QString debug;
1142
1143 debug += "type: ";
1144 debug += print_filter(sym_type_name(sym->type));
1145 if (sym_is_choice(sym))
1146 debug += " (choice)";
1147 debug += "<br>";
1148 if (sym->rev_dep.expr) {
1149 debug += "reverse dep: ";
1150 expr_print(sym->rev_dep.expr, expr_print_help, &debug, E_NONE);
1151 debug += "<br>";
1152 }
1153 for (struct property *prop = sym->prop; prop; prop = prop->next) {
1154 switch (prop->type) {
1155 case P_PROMPT:
1156 case P_MENU:
Roman Zippelab45d192006-06-08 22:12:47 -07001157 debug += QString().sprintf("prompt: <a href=\"m%p\">", prop->menu);
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001158 debug += print_filter(prop->text);
Roman Zippelab45d192006-06-08 22:12:47 -07001159 debug += "</a><br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001160 break;
1161 case P_DEFAULT:
Roman Zippel93449082008-01-14 04:50:54 +01001162 case P_SELECT:
1163 case P_RANGE:
Roman Zippel93449082008-01-14 04:50:54 +01001164 debug += prop_get_type_name(prop->type);
1165 debug += ": ";
Roman Zippel43bf6122006-06-08 22:12:45 -07001166 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1167 debug += "<br>";
1168 break;
1169 case P_CHOICE:
1170 if (sym_is_choice(sym)) {
1171 debug += "choice: ";
1172 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1173 debug += "<br>";
1174 }
1175 break;
Roman Zippel43bf6122006-06-08 22:12:45 -07001176 default:
1177 debug += "unknown property: ";
1178 debug += prop_get_type_name(prop->type);
1179 debug += "<br>";
1180 }
1181 if (prop->visible.expr) {
1182 debug += "&nbsp;&nbsp;&nbsp;&nbsp;dep: ";
1183 expr_print(prop->visible.expr, expr_print_help, &debug, E_NONE);
1184 debug += "<br>";
1185 }
1186 }
1187 debug += "<br>";
1188
1189 return debug;
1190}
1191
1192QString ConfigInfoView::print_filter(const QString &str)
1193{
1194 QRegExp re("[<>&\"\\n]");
1195 QString res = str;
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001196 for (int i = 0; (i = res.indexOf(re, i)) >= 0;) {
1197 switch (res[i].toLatin1()) {
Roman Zippel43bf6122006-06-08 22:12:45 -07001198 case '<':
1199 res.replace(i, 1, "&lt;");
1200 i += 4;
1201 break;
1202 case '>':
1203 res.replace(i, 1, "&gt;");
1204 i += 4;
1205 break;
1206 case '&':
1207 res.replace(i, 1, "&amp;");
1208 i += 5;
1209 break;
1210 case '"':
1211 res.replace(i, 1, "&quot;");
1212 i += 6;
1213 break;
1214 case '\n':
1215 res.replace(i, 1, "<br>");
1216 i += 4;
1217 break;
1218 }
1219 }
1220 return res;
1221}
1222
Roman Zippelab45d192006-06-08 22:12:47 -07001223void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char *str)
Roman Zippel43bf6122006-06-08 22:12:45 -07001224{
Roman Zippelab45d192006-06-08 22:12:47 -07001225 QString* text = reinterpret_cast<QString*>(data);
1226 QString str2 = print_filter(str);
1227
1228 if (sym && sym->name && !(sym->flags & SYMBOL_CONST)) {
1229 *text += QString().sprintf("<a href=\"s%p\">", sym);
1230 *text += str2;
1231 *text += "</a>";
1232 } else
1233 *text += str2;
Roman Zippel43bf6122006-06-08 22:12:45 -07001234}
1235
Boris Barbulovski924bbb52015-09-22 11:36:06 -07001236QMenu* ConfigInfoView::createStandardContextMenu(const QPoint & pos)
Roman Zippel7fc925f2006-06-08 22:12:46 -07001237{
Boris Barbulovski924bbb52015-09-22 11:36:06 -07001238 QMenu* popup = Parent::createStandardContextMenu(pos);
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001239 QAction* action = new QAction("Show Debug Info", popup);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001240 action->setCheckable(true);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001241 connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
1242 connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool)));
Boris Barbulovski9c862352015-09-22 11:36:12 -07001243 action->setChecked(showDebug());
Boris Barbulovski924bbb52015-09-22 11:36:06 -07001244 popup->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001245 popup->addAction(action);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001246 return popup;
1247}
1248
Boris Barbulovski924bbb52015-09-22 11:36:06 -07001249void ConfigInfoView::contextMenuEvent(QContextMenuEvent *e)
Roman Zippel7fc925f2006-06-08 22:12:46 -07001250{
Boris Barbulovski924bbb52015-09-22 11:36:06 -07001251 Parent::contextMenuEvent(e);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001252}
1253
Marco Costalba63431e72006-10-05 19:12:59 +02001254ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow* parent, const char *name)
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001255 : Parent(parent), result(NULL)
Roman Zippel43bf6122006-06-08 22:12:45 -07001256{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001257 setObjectName(name);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001258 setWindowTitle("Search Config");
Roman Zippel43bf6122006-06-08 22:12:45 -07001259
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001260 QVBoxLayout* layout1 = new QVBoxLayout(this);
1261 layout1->setContentsMargins(11, 11, 11, 11);
1262 layout1->setSpacing(6);
1263 QHBoxLayout* layout2 = new QHBoxLayout(0);
1264 layout2->setContentsMargins(0, 0, 0, 0);
1265 layout2->setSpacing(6);
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001266 layout2->addWidget(new QLabel("Find:", this));
Roman Zippel43bf6122006-06-08 22:12:45 -07001267 editField = new QLineEdit(this);
1268 connect(editField, SIGNAL(returnPressed()), SLOT(search()));
1269 layout2->addWidget(editField);
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001270 searchButton = new QPushButton("Search", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001271 searchButton->setAutoDefault(false);
Roman Zippel43bf6122006-06-08 22:12:45 -07001272 connect(searchButton, SIGNAL(clicked()), SLOT(search()));
1273 layout2->addWidget(searchButton);
1274 layout1->addLayout(layout2);
1275
Roman Zippel7fc925f2006-06-08 22:12:46 -07001276 split = new QSplitter(this);
Markus Heidelberg7298b932009-05-18 01:36:50 +02001277 split->setOrientation(Qt::Vertical);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001278 list = new ConfigView(split, name);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001279 list->list->mode = listMode;
Roman Zippel7fc925f2006-06-08 22:12:46 -07001280 info = new ConfigInfoView(split, name);
Roman Zippel43bf6122006-06-08 22:12:45 -07001281 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1282 info, SLOT(setInfo(struct menu *)));
Marco Costalba63431e72006-10-05 19:12:59 +02001283 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1284 parent, SLOT(setMenuLink(struct menu *)));
1285
Roman Zippel43bf6122006-06-08 22:12:45 -07001286 layout1->addWidget(split);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001287
1288 if (name) {
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001289 QVariant x, y;
1290 int width, height;
Roman Zippel7fc925f2006-06-08 22:12:46 -07001291 bool ok;
1292
1293 configSettings->beginGroup(name);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001294 width = configSettings->value("/window width", parent->width() / 2).toInt();
1295 height = configSettings->value("/window height", parent->height() / 2).toInt();
Roman Zippel7fc925f2006-06-08 22:12:46 -07001296 resize(width, height);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001297 x = configSettings->value("/window x");
1298 y = configSettings->value("/window y");
1299 if ((x.isValid())&&(y.isValid()))
1300 move(x.toInt(), y.toInt());
Boris Barbulovski041fbdc2015-09-22 11:36:05 -07001301 QList<int> sizes = configSettings->readSizes("/split", &ok);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001302 if (ok)
1303 split->setSizes(sizes);
1304 configSettings->endGroup();
1305 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
1306 }
1307}
1308
1309void ConfigSearchWindow::saveSettings(void)
1310{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001311 if (!objectName().isEmpty()) {
1312 configSettings->beginGroup(objectName());
1313 configSettings->setValue("/window x", pos().x());
1314 configSettings->setValue("/window y", pos().y());
1315 configSettings->setValue("/window width", size().width());
1316 configSettings->setValue("/window height", size().height());
1317 configSettings->writeSizes("/split", split->sizes());
1318 configSettings->endGroup();
1319 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001320}
1321
1322void ConfigSearchWindow::search(void)
1323{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001324 struct symbol **p;
1325 struct property *prop;
1326 ConfigItem *lastItem = NULL;
1327
1328 free(result);
1329 list->list->clear();
1330 info->clear();
1331
1332 result = sym_re_search(editField->text().toLatin1());
1333 if (!result)
1334 return;
1335 for (p = result; *p; p++) {
1336 for_all_prompts((*p), prop)
1337 lastItem = new ConfigItem(list->list, lastItem, prop->menu,
1338 menu_is_visible(prop->menu));
1339 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001340}
1341
Linus Torvalds1da177e2005-04-16 15:20:36 -07001342/*
1343 * Construct the complete config widget
1344 */
1345ConfigMainWindow::ConfigMainWindow(void)
Roman Zippelf12aa702006-11-25 11:09:31 -08001346 : searchWindow(0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001347{
1348 QMenuBar* menu;
Boris Barbulovski92119932015-09-22 11:36:16 -07001349 bool ok = true;
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001350 QVariant x, y;
1351 int width, height;
Randy Dunlapa54bb702007-10-20 11:18:47 -07001352 char title[256];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001353
Markus Heidelberg8d90c972009-05-18 01:36:52 +02001354 QDesktopWidget *d = configApp->desktop();
Arnaud Lacombe09548282010-08-18 01:57:13 -04001355 snprintf(title, sizeof(title), "%s%s",
1356 rootmenu.prompt->text,
Michal Marek76a136c2010-09-01 17:39:27 +02001357 ""
Michal Marek76a136c2010-09-01 17:39:27 +02001358 );
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001359 setWindowTitle(title);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001360
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001361 width = configSettings->value("/window width", d->width() - 64).toInt();
1362 height = configSettings->value("/window height", d->height() - 64).toInt();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001363 resize(width, height);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001364 x = configSettings->value("/window x");
1365 y = configSettings->value("/window y");
1366 if ((x.isValid())&&(y.isValid()))
1367 move(x.toInt(), y.toInt());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001368
Mauro Carvalho Chehabcce1fab2020-04-02 11:28:00 +02001369 QWidget *widget = new QWidget(this);
1370 QVBoxLayout *layout = new QVBoxLayout(widget);
1371 setCentralWidget(widget);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001372
Mauro Carvalho Chehabcce1fab2020-04-02 11:28:00 +02001373 split1 = new QSplitter(widget);
1374 split1->setOrientation(Qt::Horizontal);
1375 split1->setChildrenCollapsible(false);
1376
1377 menuView = new ConfigView(widget, "menu");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001378 menuList = menuView->list;
1379
Mauro Carvalho Chehabcce1fab2020-04-02 11:28:00 +02001380 split2 = new QSplitter(widget);
1381 split2->setChildrenCollapsible(false);
Markus Heidelberg7298b932009-05-18 01:36:50 +02001382 split2->setOrientation(Qt::Vertical);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001383
1384 // create config tree
Mauro Carvalho Chehabcce1fab2020-04-02 11:28:00 +02001385 configView = new ConfigView(widget, "config");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001386 configList = configView->list;
1387
Mauro Carvalho Chehabcce1fab2020-04-02 11:28:00 +02001388 helpText = new ConfigInfoView(widget, "help");
1389
1390 layout->addWidget(split2);
1391 split2->addWidget(split1);
1392 split1->addWidget(configView);
1393 split1->addWidget(menuView);
1394 split2->addWidget(helpText);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001395
1396 setTabOrder(configList, helpText);
1397 configList->setFocus();
1398
1399 menu = menuBar();
Boris Barbulovskib1f8a452015-09-22 11:36:02 -07001400 toolBar = new QToolBar("Tools", this);
Boris Barbulovski29a70162015-09-22 11:36:10 -07001401 addToolBar(toolBar);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001402
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001403 backAction = new QAction(QPixmap(xpm_back), "Back", this);
Boris Barbulovski92119932015-09-22 11:36:16 -07001404 connect(backAction, SIGNAL(triggered(bool)), SLOT(goBack()));
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001405 backAction->setEnabled(false);
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001406 QAction *quitAction = new QAction("&Quit", this);
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001407 quitAction->setShortcut(Qt::CTRL + Qt::Key_Q);
Boris Barbulovski92119932015-09-22 11:36:16 -07001408 connect(quitAction, SIGNAL(triggered(bool)), SLOT(close()));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001409 QAction *loadAction = new QAction(QPixmap(xpm_load), "&Load", this);
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001410 loadAction->setShortcut(Qt::CTRL + Qt::Key_L);
Boris Barbulovski92119932015-09-22 11:36:16 -07001411 connect(loadAction, SIGNAL(triggered(bool)), SLOT(loadConfig()));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001412 saveAction = new QAction(QPixmap(xpm_save), "&Save", this);
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001413 saveAction->setShortcut(Qt::CTRL + Qt::Key_S);
Boris Barbulovski92119932015-09-22 11:36:16 -07001414 connect(saveAction, SIGNAL(triggered(bool)), SLOT(saveConfig()));
Karsten Wiese3b354c52006-12-13 00:34:08 -08001415 conf_set_changed_callback(conf_changed);
1416 // Set saveAction's initial state
1417 conf_changed();
Masahiro Yamada87419082019-03-11 01:13:15 +09001418 configname = xstrdup(conf_get_configname());
1419
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001420 QAction *saveAsAction = new QAction("Save &As...", this);
Boris Barbulovski92119932015-09-22 11:36:16 -07001421 connect(saveAsAction, SIGNAL(triggered(bool)), SLOT(saveConfigAs()));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001422 QAction *searchAction = new QAction("&Find", this);
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001423 searchAction->setShortcut(Qt::CTRL + Qt::Key_F);
Boris Barbulovski92119932015-09-22 11:36:16 -07001424 connect(searchAction, SIGNAL(triggered(bool)), SLOT(searchConfig()));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001425 singleViewAction = new QAction(QPixmap(xpm_single_view), "Single View", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001426 singleViewAction->setCheckable(true);
Boris Barbulovski92119932015-09-22 11:36:16 -07001427 connect(singleViewAction, SIGNAL(triggered(bool)), SLOT(showSingleView()));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001428 splitViewAction = new QAction(QPixmap(xpm_split_view), "Split View", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001429 splitViewAction->setCheckable(true);
Boris Barbulovski92119932015-09-22 11:36:16 -07001430 connect(splitViewAction, SIGNAL(triggered(bool)), SLOT(showSplitView()));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001431 fullViewAction = new QAction(QPixmap(xpm_tree_view), "Full View", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001432 fullViewAction->setCheckable(true);
Boris Barbulovski92119932015-09-22 11:36:16 -07001433 connect(fullViewAction, SIGNAL(triggered(bool)), SLOT(showFullView()));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001434
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001435 QAction *showNameAction = new QAction("Show Name", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001436 showNameAction->setCheckable(true);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001437 connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool)));
Boris Barbulovski9c862352015-09-22 11:36:12 -07001438 showNameAction->setChecked(configView->showName());
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001439 QAction *showRangeAction = new QAction("Show Range", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001440 showRangeAction->setCheckable(true);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001441 connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool)));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001442 QAction *showDataAction = new QAction("Show Data", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001443 showDataAction->setCheckable(true);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001444 connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool)));
Li Zefan39a48972010-05-10 16:33:41 +08001445
1446 QActionGroup *optGroup = new QActionGroup(this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001447 optGroup->setExclusive(true);
Boris Barbulovski92119932015-09-22 11:36:16 -07001448 connect(optGroup, SIGNAL(triggered(QAction*)), configView,
Li Zefan39a48972010-05-10 16:33:41 +08001449 SLOT(setOptionMode(QAction *)));
Boris Barbulovski92119932015-09-22 11:36:16 -07001450 connect(optGroup, SIGNAL(triggered(QAction *)), menuView,
Li Zefan39a48972010-05-10 16:33:41 +08001451 SLOT(setOptionMode(QAction *)));
1452
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001453 configView->showNormalAction = new QAction("Show Normal Options", optGroup);
1454 configView->showAllAction = new QAction("Show All Options", optGroup);
1455 configView->showPromptAction = new QAction("Show Prompt Options", optGroup);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001456 configView->showNormalAction->setCheckable(true);
1457 configView->showAllAction->setCheckable(true);
1458 configView->showPromptAction->setCheckable(true);
Li Zefan39a48972010-05-10 16:33:41 +08001459
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001460 QAction *showDebugAction = new QAction("Show Debug Info", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001461 showDebugAction->setCheckable(true);
Roman Zippel43bf6122006-06-08 22:12:45 -07001462 connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
Boris Barbulovski9c862352015-09-22 11:36:12 -07001463 showDebugAction->setChecked(helpText->showDebug());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001464
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001465 QAction *showIntroAction = new QAction("Introduction", this);
Boris Barbulovski92119932015-09-22 11:36:16 -07001466 connect(showIntroAction, SIGNAL(triggered(bool)), SLOT(showIntro()));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001467 QAction *showAboutAction = new QAction("About", this);
Boris Barbulovski92119932015-09-22 11:36:16 -07001468 connect(showAboutAction, SIGNAL(triggered(bool)), SLOT(showAbout()));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001469
1470 // init tool bar
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001471 toolBar->addAction(backAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001472 toolBar->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001473 toolBar->addAction(loadAction);
1474 toolBar->addAction(saveAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001475 toolBar->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001476 toolBar->addAction(singleViewAction);
1477 toolBar->addAction(splitViewAction);
1478 toolBar->addAction(fullViewAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001479
1480 // create config menu
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001481 QMenu* config = menu->addMenu("&File");
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001482 config->addAction(loadAction);
1483 config->addAction(saveAction);
1484 config->addAction(saveAsAction);
Boris Barbulovski76bede82015-09-22 11:36:07 -07001485 config->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001486 config->addAction(quitAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001487
Shlomi Fish66e7c722007-02-14 00:32:58 -08001488 // create edit menu
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001489 QMenu* editMenu = menu->addMenu("&Edit");
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001490 editMenu->addAction(searchAction);
Shlomi Fish66e7c722007-02-14 00:32:58 -08001491
Linus Torvalds1da177e2005-04-16 15:20:36 -07001492 // create options menu
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001493 QMenu* optionMenu = menu->addMenu("&Option");
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001494 optionMenu->addAction(showNameAction);
1495 optionMenu->addAction(showRangeAction);
1496 optionMenu->addAction(showDataAction);
Boris Barbulovski76bede82015-09-22 11:36:07 -07001497 optionMenu->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001498 optionMenu->addActions(optGroup->actions());
Boris Barbulovski76bede82015-09-22 11:36:07 -07001499 optionMenu->addSeparator();
Boris Barbulovskie0393032016-11-30 14:57:52 -08001500 optionMenu->addAction(showDebugAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001501
1502 // create help menu
Boris Barbulovski76bede82015-09-22 11:36:07 -07001503 menu->addSeparator();
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001504 QMenu* helpMenu = menu->addMenu("&Help");
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001505 helpMenu->addAction(showIntroAction);
1506 helpMenu->addAction(showAboutAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001507
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001508 connect(configList, SIGNAL(menuChanged(struct menu *)),
1509 helpText, SLOT(setInfo(struct menu *)));
1510 connect(configList, SIGNAL(menuSelected(struct menu *)),
1511 SLOT(changeMenu(struct menu *)));
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +02001512 connect(configList, SIGNAL(itemSelected(struct menu *)),
1513 SLOT(changeItens(struct menu *)));
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001514 connect(configList, SIGNAL(parentSelected()),
1515 SLOT(goBack()));
1516 connect(menuList, SIGNAL(menuChanged(struct menu *)),
1517 helpText, SLOT(setInfo(struct menu *)));
1518 connect(menuList, SIGNAL(menuSelected(struct menu *)),
1519 SLOT(changeMenu(struct menu *)));
1520
1521 connect(configList, SIGNAL(gotFocus(struct menu *)),
1522 helpText, SLOT(setInfo(struct menu *)));
1523 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1524 helpText, SLOT(setInfo(struct menu *)));
1525 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1526 SLOT(listFocusChanged(void)));
Roman Zippelb65a47e2006-06-08 22:12:47 -07001527 connect(helpText, SIGNAL(menuSelected(struct menu *)),
1528 SLOT(setMenuLink(struct menu *)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001529
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001530 QString listMode = configSettings->value("/listMode", "symbol").toString();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001531 if (listMode == "single")
1532 showSingleView();
1533 else if (listMode == "full")
1534 showFullView();
1535 else /*if (listMode == "split")*/
1536 showSplitView();
1537
1538 // UI setup done, restore splitter positions
Boris Barbulovski041fbdc2015-09-22 11:36:05 -07001539 QList<int> sizes = configSettings->readSizes("/split1", &ok);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001540 if (ok)
1541 split1->setSizes(sizes);
1542
Roman Zippel7fc925f2006-06-08 22:12:46 -07001543 sizes = configSettings->readSizes("/split2", &ok);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001544 if (ok)
1545 split2->setSizes(sizes);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001546}
1547
Linus Torvalds1da177e2005-04-16 15:20:36 -07001548void ConfigMainWindow::loadConfig(void)
1549{
Masahiro Yamada87419082019-03-11 01:13:15 +09001550 QString str;
1551 QByteArray ba;
1552 const char *name;
1553
1554 str = QFileDialog::getOpenFileName(this, "", configname);
1555 if (str.isNull())
Linus Torvalds1da177e2005-04-16 15:20:36 -07001556 return;
Masahiro Yamada87419082019-03-11 01:13:15 +09001557
1558 ba = str.toLocal8Bit();
1559 name = ba.data();
1560
1561 if (conf_read(name))
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001562 QMessageBox::information(this, "qconf", "Unable to load configuration!");
Masahiro Yamada87419082019-03-11 01:13:15 +09001563
1564 free(configname);
1565 configname = xstrdup(name);
1566
Linus Torvalds1da177e2005-04-16 15:20:36 -07001567 ConfigView::updateListAll();
1568}
1569
Michal Marekbac6aa82011-05-25 15:10:25 +02001570bool ConfigMainWindow::saveConfig(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001571{
Masahiro Yamada87419082019-03-11 01:13:15 +09001572 if (conf_write(configname)) {
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001573 QMessageBox::information(this, "qconf", "Unable to save configuration!");
Michal Marekbac6aa82011-05-25 15:10:25 +02001574 return false;
1575 }
Masahiro Yamada00c864f2018-07-20 16:46:31 +09001576 conf_write_autoconf(0);
1577
Michal Marekbac6aa82011-05-25 15:10:25 +02001578 return true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001579}
1580
1581void ConfigMainWindow::saveConfigAs(void)
1582{
Masahiro Yamada87419082019-03-11 01:13:15 +09001583 QString str;
1584 QByteArray ba;
1585 const char *name;
1586
1587 str = QFileDialog::getSaveFileName(this, "", configname);
1588 if (str.isNull())
Linus Torvalds1da177e2005-04-16 15:20:36 -07001589 return;
Masahiro Yamada87419082019-03-11 01:13:15 +09001590
1591 ba = str.toLocal8Bit();
1592 name = ba.data();
1593
1594 if (conf_write(name)) {
1595 QMessageBox::information(this, "qconf", "Unable to save configuration!");
1596 }
1597 conf_write_autoconf(0);
1598
1599 free(configname);
1600 configname = xstrdup(name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001601}
1602
Roman Zippel43bf6122006-06-08 22:12:45 -07001603void ConfigMainWindow::searchConfig(void)
1604{
1605 if (!searchWindow)
Roman Zippel7fc925f2006-06-08 22:12:46 -07001606 searchWindow = new ConfigSearchWindow(this, "search");
Roman Zippel43bf6122006-06-08 22:12:45 -07001607 searchWindow->show();
1608}
1609
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +02001610void ConfigMainWindow::changeItens(struct menu *menu)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001611{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001612 configList->setRootMenu(menu);
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +02001613
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001614 if (configList->rootEntry->parent == &rootmenu)
1615 backAction->setEnabled(false);
1616 else
1617 backAction->setEnabled(true);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001618}
1619
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +02001620void ConfigMainWindow::changeMenu(struct menu *menu)
1621{
1622 menuList->setRootMenu(menu);
1623
1624 if (menuList->rootEntry->parent == &rootmenu)
1625 backAction->setEnabled(false);
1626 else
1627 backAction->setEnabled(true);
1628}
1629
Roman Zippelb65a47e2006-06-08 22:12:47 -07001630void ConfigMainWindow::setMenuLink(struct menu *menu)
1631{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001632 struct menu *parent;
1633 ConfigList* list = NULL;
1634 ConfigItem* item;
1635
1636 if (configList->menuSkip(menu))
1637 return;
1638
1639 switch (configList->mode) {
1640 case singleMode:
1641 list = configList;
1642 parent = menu_get_parent_menu(menu);
1643 if (!parent)
1644 return;
1645 list->setRootMenu(parent);
1646 break;
1647 case symbolMode:
1648 if (menu->flags & MENU_ROOT) {
1649 configList->setRootMenu(menu);
1650 configList->clearSelection();
1651 list = menuList;
1652 } else {
1653 list = configList;
1654 parent = menu_get_parent_menu(menu->parent);
1655 if (!parent)
1656 return;
1657 item = menuList->findConfigItem(parent);
1658 if (item) {
1659 item->setSelected(true);
1660 menuList->scrollToItem(item);
1661 }
1662 list->setRootMenu(parent);
1663 }
1664 break;
1665 case fullMode:
1666 list = configList;
1667 break;
1668 default:
1669 break;
1670 }
1671
1672 if (list) {
1673 item = list->findConfigItem(menu);
1674 if (item) {
1675 item->setSelected(true);
1676 list->scrollToItem(item);
1677 list->setFocus();
1678 }
1679 }
Roman Zippelb65a47e2006-06-08 22:12:47 -07001680}
1681
Linus Torvalds1da177e2005-04-16 15:20:36 -07001682void ConfigMainWindow::listFocusChanged(void)
1683{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001684 if (menuList->mode == menuMode)
1685 configList->clearSelection();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001686}
1687
1688void ConfigMainWindow::goBack(void)
1689{
Boris Barbulovski5df9da92015-09-22 11:36:36 -07001690 ConfigItem* item, *oldSelection;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001691
1692 configList->setParentMenu();
1693 if (configList->rootEntry == &rootmenu)
1694 backAction->setEnabled(false);
Boris Barbulovskibe596aa2015-09-22 11:36:28 -07001695
1696 if (menuList->selectedItems().count() == 0)
1697 return;
1698
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001699 item = (ConfigItem*)menuList->selectedItems().first();
Boris Barbulovski5df9da92015-09-22 11:36:36 -07001700 oldSelection = item;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001701 while (item) {
1702 if (item->menu == configList->rootEntry) {
Boris Barbulovski5df9da92015-09-22 11:36:36 -07001703 oldSelection->setSelected(false);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001704 item->setSelected(true);
1705 break;
1706 }
1707 item = (ConfigItem*)item->parent();
1708 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001709}
1710
1711void ConfigMainWindow::showSingleView(void)
1712{
Boris Barbulovski780505e2015-09-22 11:36:13 -07001713 singleViewAction->setEnabled(false);
1714 singleViewAction->setChecked(true);
1715 splitViewAction->setEnabled(true);
1716 splitViewAction->setChecked(false);
1717 fullViewAction->setEnabled(true);
1718 fullViewAction->setChecked(false);
1719
Linus Torvalds1da177e2005-04-16 15:20:36 -07001720 menuView->hide();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001721 menuList->setRootMenu(0);
1722 configList->mode = singleMode;
1723 if (configList->rootEntry == &rootmenu)
1724 configList->updateListAll();
1725 else
1726 configList->setRootMenu(&rootmenu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001727 configList->setFocus();
1728}
1729
1730void ConfigMainWindow::showSplitView(void)
1731{
Boris Barbulovski780505e2015-09-22 11:36:13 -07001732 singleViewAction->setEnabled(true);
1733 singleViewAction->setChecked(false);
1734 splitViewAction->setEnabled(false);
1735 splitViewAction->setChecked(true);
1736 fullViewAction->setEnabled(true);
1737 fullViewAction->setChecked(false);
1738
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +02001739 configList->mode = menuMode;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001740 if (configList->rootEntry == &rootmenu)
1741 configList->updateListAll();
1742 else
1743 configList->setRootMenu(&rootmenu);
1744 configList->setAllOpen(true);
1745 configApp->processEvents();
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +02001746 menuList->mode = symbolMode;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001747 menuList->setRootMenu(&rootmenu);
1748 menuList->setAllOpen(true);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001749 menuView->show();
1750 menuList->setFocus();
1751}
1752
1753void ConfigMainWindow::showFullView(void)
1754{
Boris Barbulovski780505e2015-09-22 11:36:13 -07001755 singleViewAction->setEnabled(true);
1756 singleViewAction->setChecked(false);
1757 splitViewAction->setEnabled(true);
1758 splitViewAction->setChecked(false);
1759 fullViewAction->setEnabled(false);
1760 fullViewAction->setChecked(true);
1761
Linus Torvalds1da177e2005-04-16 15:20:36 -07001762 menuView->hide();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001763 menuList->setRootMenu(0);
1764 configList->mode = fullMode;
1765 if (configList->rootEntry == &rootmenu)
1766 configList->updateListAll();
1767 else
1768 configList->setRootMenu(&rootmenu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001769 configList->setFocus();
1770}
1771
Linus Torvalds1da177e2005-04-16 15:20:36 -07001772/*
1773 * ask for saving configuration before quitting
1774 * TODO ask only when something changed
1775 */
1776void ConfigMainWindow::closeEvent(QCloseEvent* e)
1777{
Karsten Wieseb3214292006-12-13 00:34:06 -08001778 if (!conf_get_changed()) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001779 e->accept();
1780 return;
1781 }
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001782 QMessageBox mb("qconf", "Save configuration?", QMessageBox::Warning,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001783 QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape);
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001784 mb.setButtonText(QMessageBox::Yes, "&Save Changes");
1785 mb.setButtonText(QMessageBox::No, "&Discard Changes");
1786 mb.setButtonText(QMessageBox::Cancel, "Cancel Exit");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001787 switch (mb.exec()) {
1788 case QMessageBox::Yes:
Michal Marekbac6aa82011-05-25 15:10:25 +02001789 if (saveConfig())
1790 e->accept();
1791 else
1792 e->ignore();
1793 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001794 case QMessageBox::No:
1795 e->accept();
1796 break;
1797 case QMessageBox::Cancel:
1798 e->ignore();
1799 break;
1800 }
1801}
1802
1803void ConfigMainWindow::showIntro(void)
1804{
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001805 static const QString str = "Welcome to the qconf graphical configuration tool.\n\n"
Linus Torvalds1da177e2005-04-16 15:20:36 -07001806 "For each option, a blank box indicates the feature is disabled, a check\n"
1807 "indicates it is enabled, and a dot indicates that it is to be compiled\n"
1808 "as a module. Clicking on the box will cycle through the three states.\n\n"
1809 "If you do not see an option (e.g., a device driver) that you believe\n"
1810 "should be present, try turning on Show All Options under the Options menu.\n"
1811 "Although there is no cross reference yet to help you figure out what other\n"
1812 "options must be enabled to support the option you are interested in, you can\n"
1813 "still view the help of a grayed-out option.\n\n"
1814 "Toggling Show Debug Info under the Options menu will show the dependencies,\n"
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001815 "which you can then match by examining other options.\n\n";
Linus Torvalds1da177e2005-04-16 15:20:36 -07001816
1817 QMessageBox::information(this, "qconf", str);
1818}
1819
1820void ConfigMainWindow::showAbout(void)
1821{
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001822 static const QString str = "qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n"
Boris Barbulovskib4ff1de2015-09-22 11:36:38 -07001823 "Copyright (C) 2015 Boris Barbulovski <bbarbulovski@gmail.com>.\n\n"
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001824 "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n";
Linus Torvalds1da177e2005-04-16 15:20:36 -07001825
1826 QMessageBox::information(this, "qconf", str);
1827}
1828
1829void ConfigMainWindow::saveSettings(void)
1830{
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001831 configSettings->setValue("/window x", pos().x());
1832 configSettings->setValue("/window y", pos().y());
1833 configSettings->setValue("/window width", size().width());
1834 configSettings->setValue("/window height", size().height());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001835
1836 QString entry;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001837 switch(configList->mode) {
1838 case singleMode :
1839 entry = "single";
1840 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001841
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001842 case symbolMode :
1843 entry = "split";
1844 break;
1845
1846 case fullMode :
1847 entry = "full";
1848 break;
1849
1850 default:
1851 break;
1852 }
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001853 configSettings->setValue("/listMode", entry);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001854
Roman Zippel7fc925f2006-06-08 22:12:46 -07001855 configSettings->writeSizes("/split1", split1->sizes());
1856 configSettings->writeSizes("/split2", split2->sizes());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001857}
1858
Karsten Wiese3b354c52006-12-13 00:34:08 -08001859void ConfigMainWindow::conf_changed(void)
1860{
1861 if (saveAction)
1862 saveAction->setEnabled(conf_get_changed());
1863}
1864
Linus Torvalds1da177e2005-04-16 15:20:36 -07001865void fixup_rootmenu(struct menu *menu)
1866{
1867 struct menu *child;
1868 static int menu_cnt = 0;
1869
1870 menu->flags |= MENU_ROOT;
1871 for (child = menu->list; child; child = child->next) {
1872 if (child->prompt && child->prompt->type == P_MENU) {
1873 menu_cnt++;
1874 fixup_rootmenu(child);
1875 menu_cnt--;
1876 } else if (!menu_cnt)
1877 fixup_rootmenu(child);
1878 }
1879}
1880
1881static const char *progname;
1882
1883static void usage(void)
1884{
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001885 printf("%s [-s] <config>\n", progname);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001886 exit(0);
1887}
1888
1889int main(int ac, char** av)
1890{
1891 ConfigMainWindow* v;
1892 const char *name;
1893
Linus Torvalds1da177e2005-04-16 15:20:36 -07001894 progname = av[0];
1895 configApp = new QApplication(ac, av);
1896 if (ac > 1 && av[1][0] == '-') {
1897 switch (av[1][1]) {
Michal Marek0a1f00a2015-04-08 13:30:42 +02001898 case 's':
1899 conf_set_message_callback(NULL);
1900 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001901 case 'h':
1902 case '?':
1903 usage();
1904 }
1905 name = av[2];
1906 } else
1907 name = av[1];
1908 if (!name)
1909 usage();
1910
1911 conf_parse(name);
1912 fixup_rootmenu(&rootmenu);
1913 conf_read(NULL);
1914 //zconfdump(stdout);
1915
Roman Zippel7fc925f2006-06-08 22:12:46 -07001916 configSettings = new ConfigSettings();
1917 configSettings->beginGroup("/kconfig/qconf");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001918 v = new ConfigMainWindow();
1919
1920 //zconfdump(stdout);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001921 configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit()));
1922 configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings()));
Roman Zippel43bf6122006-06-08 22:12:45 -07001923 v->show();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001924 configApp->exec();
1925
Roman Zippel7fc925f2006-06-08 22:12:46 -07001926 configSettings->endGroup();
1927 delete configSettings;
Chris Bainbridge5b61c7b2016-01-08 20:44:04 +00001928 delete v;
1929 delete configApp;
Roman Zippel7fc925f2006-06-08 22:12:46 -07001930
Linus Torvalds1da177e2005-04-16 15:20:36 -07001931 return 0;
1932}