blob: 3ba064af905c127adbebe15604b194def58c5203 [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
Boris Barbulovski85eaf282015-09-22 11:36:03 -07007#include <QAction>
Mauro Carvalho Chehabcf81dfa2020-06-30 08:26:35 +02008#include <QApplication>
9#include <QCloseEvent>
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +020010#include <QDebug>
Mauro Carvalho Chehabcf81dfa2020-06-30 08:26:35 +020011#include <QDesktopWidget>
Boris Barbulovskibea00772015-09-22 11:36:04 -070012#include <QFileDialog>
Mauro Carvalho Chehabcf81dfa2020-06-30 08:26:35 +020013#include <QLabel>
14#include <QLayout>
15#include <QList>
Boris Barbulovski76bede82015-09-22 11:36:07 -070016#include <QMenu>
Mauro Carvalho Chehabcf81dfa2020-06-30 08:26:35 +020017#include <QMenuBar>
18#include <QMessageBox>
19#include <QToolBar>
Linus Torvalds1da177e2005-04-16 15:20:36 -070020
21#include <stdlib.h>
22
23#include "lkc.h"
24#include "qconf.h"
25
Masahiro Yamada3b541978562018-12-21 17:33:07 +090026#include "images.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070027
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -070028
Linus Torvalds1da177e2005-04-16 15:20:36 -070029static QApplication *configApp;
Roman Zippel7fc925f2006-06-08 22:12:46 -070030static ConfigSettings *configSettings;
Linus Torvalds1da177e2005-04-16 15:20:36 -070031
Boris Barbulovski85eaf282015-09-22 11:36:03 -070032QAction *ConfigMainWindow::saveAction;
Karsten Wiese3b354c52006-12-13 00:34:08 -080033
Ben Hutchings00d4f8f2013-10-06 19:21:31 +010034ConfigSettings::ConfigSettings()
35 : QSettings("kernel.org", "qconf")
36{
37}
38
Linus Torvalds1da177e2005-04-16 15:20:36 -070039/**
40 * Reads a list of integer values from the application settings.
41 */
Boris Barbulovski041fbdc2015-09-22 11:36:05 -070042QList<int> ConfigSettings::readSizes(const QString& key, bool *ok)
Linus Torvalds1da177e2005-04-16 15:20:36 -070043{
Boris Barbulovski041fbdc2015-09-22 11:36:05 -070044 QList<int> result;
Li Zefanc1f96f02010-05-07 13:58:04 +080045
Boris Barbulovski83c3a1b2016-11-30 14:57:55 -080046 if (contains(key))
47 {
48 QStringList entryList = value(key).toStringList();
49 QStringList::Iterator it;
50
51 for (it = entryList.begin(); it != entryList.end(); ++it)
52 result.push_back((*it).toInt());
53
54 *ok = true;
55 }
56 else
57 *ok = false;
Linus Torvalds1da177e2005-04-16 15:20:36 -070058
59 return result;
60}
61
62/**
63 * Writes a list of integer values to the application settings.
64 */
Boris Barbulovski041fbdc2015-09-22 11:36:05 -070065bool ConfigSettings::writeSizes(const QString& key, const QList<int>& value)
Linus Torvalds1da177e2005-04-16 15:20:36 -070066{
67 QStringList stringList;
Boris Barbulovski041fbdc2015-09-22 11:36:05 -070068 QList<int>::ConstIterator it;
Linus Torvalds1da177e2005-04-16 15:20:36 -070069
70 for (it = value.begin(); it != value.end(); ++it)
71 stringList.push_back(QString::number(*it));
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -070072 setValue(key, stringList);
Boris Barbulovski59e56442015-09-22 11:36:18 -070073
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -070074 return true;
Linus Torvalds1da177e2005-04-16 15:20:36 -070075}
Linus Torvalds1da177e2005-04-16 15:20:36 -070076
Masahiro Yamada5cb255f2020-08-07 18:19:07 +090077QIcon ConfigItem::symbolYesIcon;
78QIcon ConfigItem::symbolModIcon;
79QIcon ConfigItem::symbolNoIcon;
80QIcon ConfigItem::choiceYesIcon;
81QIcon ConfigItem::choiceNoIcon;
82QIcon ConfigItem::menuIcon;
83QIcon ConfigItem::menubackIcon;
Boris Barbulovski59e56442015-09-22 11:36:18 -070084
85/*
Boris Barbulovski59e56442015-09-22 11:36:18 -070086 * update the displayed of a menu entry
87 */
88void ConfigItem::updateMenu(void)
89{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -070090 ConfigList* list;
91 struct symbol* sym;
92 struct property *prop;
93 QString prompt;
94 int type;
95 tristate expr;
96
97 list = listView();
98 if (goParent) {
Masahiro Yamada5cb255f2020-08-07 18:19:07 +090099 setIcon(promptColIdx, menubackIcon);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700100 prompt = "..";
101 goto set_prompt;
102 }
103
104 sym = menu->sym;
105 prop = menu->prompt;
Masahiro Yamada3c73ff02020-08-07 18:19:02 +0900106 prompt = menu_get_prompt(menu);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700107
108 if (prop) switch (prop->type) {
109 case P_MENU:
110 if (list->mode == singleMode || list->mode == symbolMode) {
111 /* a menuconfig entry is displayed differently
112 * depending whether it's at the view root or a child.
113 */
114 if (sym && list->rootEntry == menu)
115 break;
Masahiro Yamada5cb255f2020-08-07 18:19:07 +0900116 setIcon(promptColIdx, menuIcon);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700117 } else {
118 if (sym)
119 break;
Masahiro Yamada711b8752020-08-07 18:19:03 +0900120 setIcon(promptColIdx, QIcon());
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700121 }
122 goto set_prompt;
123 case P_COMMENT:
Masahiro Yamada711b8752020-08-07 18:19:03 +0900124 setIcon(promptColIdx, QIcon());
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700125 goto set_prompt;
126 default:
127 ;
128 }
129 if (!sym)
130 goto set_prompt;
131
Masahiro Yamada3c73ff02020-08-07 18:19:02 +0900132 setText(nameColIdx, sym->name);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700133
134 type = sym_get_type(sym);
135 switch (type) {
136 case S_BOOLEAN:
137 case S_TRISTATE:
138 char ch;
139
Marco Ammonbaa23ec2019-07-04 12:50:41 +0200140 if (!sym_is_changeable(sym) && list->optMode == normalOpt) {
Masahiro Yamada711b8752020-08-07 18:19:03 +0900141 setIcon(promptColIdx, QIcon());
Mauro Carvalho Chehabcf497b92020-04-02 11:27:58 +0200142 setText(noColIdx, QString());
143 setText(modColIdx, QString());
144 setText(yesColIdx, QString());
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700145 break;
146 }
147 expr = sym_get_tristate_value(sym);
148 switch (expr) {
149 case yes:
150 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
Masahiro Yamada5cb255f2020-08-07 18:19:07 +0900151 setIcon(promptColIdx, choiceYesIcon);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700152 else
Masahiro Yamada5cb255f2020-08-07 18:19:07 +0900153 setIcon(promptColIdx, symbolYesIcon);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700154 setText(yesColIdx, "Y");
155 ch = 'Y';
156 break;
157 case mod:
Masahiro Yamada5cb255f2020-08-07 18:19:07 +0900158 setIcon(promptColIdx, symbolModIcon);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700159 setText(modColIdx, "M");
160 ch = 'M';
161 break;
162 default:
163 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
Masahiro Yamada5cb255f2020-08-07 18:19:07 +0900164 setIcon(promptColIdx, choiceNoIcon);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700165 else
Masahiro Yamada5cb255f2020-08-07 18:19:07 +0900166 setIcon(promptColIdx, symbolNoIcon);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700167 setText(noColIdx, "N");
168 ch = 'N';
169 break;
170 }
171 if (expr != no)
172 setText(noColIdx, sym_tristate_within_range(sym, no) ? "_" : 0);
173 if (expr != mod)
174 setText(modColIdx, sym_tristate_within_range(sym, mod) ? "_" : 0);
175 if (expr != yes)
176 setText(yesColIdx, sym_tristate_within_range(sym, yes) ? "_" : 0);
177
178 setText(dataColIdx, QChar(ch));
179 break;
180 case S_INT:
181 case S_HEX:
182 case S_STRING:
183 const char* data;
184
185 data = sym_get_string_value(sym);
186
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700187 setText(dataColIdx, data);
188 if (type == S_STRING)
189 prompt = QString("%1: %2").arg(prompt).arg(data);
190 else
191 prompt = QString("(%2) %1").arg(prompt).arg(data);
192 break;
193 }
194 if (!sym_has_value(sym) && visible)
Sam Ravnborg694c49a2018-05-22 21:36:12 +0200195 prompt += " (NEW)";
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700196set_prompt:
197 setText(promptColIdx, prompt);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700198}
199
200void ConfigItem::testUpdateMenu(bool v)
201{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700202 ConfigItem* i;
203
204 visible = v;
205 if (!menu)
206 return;
207
208 sym_calc_value(menu->sym);
209 if (menu->flags & MENU_CHANGED) {
210 /* the menu entry changed, so update all list items */
211 menu->flags &= ~MENU_CHANGED;
212 for (i = (ConfigItem*)menu->data; i; i = i->nextItem)
213 i->updateMenu();
214 } else if (listView()->updateAll)
215 updateMenu();
Boris Barbulovski59e56442015-09-22 11:36:18 -0700216}
217
218
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700219/*
220 * construct a menu entry
221 */
222void ConfigItem::init(void)
223{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700224 if (menu) {
225 ConfigList* list = listView();
226 nextItem = (ConfigItem*)menu->data;
227 menu->data = this;
228
229 if (list->mode != fullMode)
230 setExpanded(true);
231 sym_calc_value(menu->sym);
232 }
233 updateMenu();
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700234}
235
236/*
237 * destruct a menu entry
238 */
239ConfigItem::~ConfigItem(void)
240{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700241 if (menu) {
242 ConfigItem** ip = (ConfigItem**)&menu->data;
243 for (; *ip; ip = &(*ip)->nextItem) {
244 if (*ip == this) {
245 *ip = nextItem;
246 break;
247 }
248 }
249 }
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700250}
251
Roman Zippel43bf6122006-06-08 22:12:45 -0700252ConfigLineEdit::ConfigLineEdit(ConfigView* parent)
253 : Parent(parent)
254{
Boris Barbulovskic14fa5e2015-09-22 11:36:21 -0700255 connect(this, SIGNAL(editingFinished()), SLOT(hide()));
Roman Zippel43bf6122006-06-08 22:12:45 -0700256}
257
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700258void ConfigLineEdit::show(ConfigItem* i)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700259{
260 item = i;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700261 if (sym_get_string_value(item->menu->sym))
Masahiro Yamada3c73ff02020-08-07 18:19:02 +0900262 setText(sym_get_string_value(item->menu->sym));
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700263 else
Mauro Carvalho Chehabcf497b92020-04-02 11:27:58 +0200264 setText(QString());
Linus Torvalds1da177e2005-04-16 15:20:36 -0700265 Parent::show();
266 setFocus();
267}
268
269void ConfigLineEdit::keyPressEvent(QKeyEvent* e)
270{
271 switch (e->key()) {
Markus Heidelbergfbb86372009-05-18 01:36:51 +0200272 case Qt::Key_Escape:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700273 break;
Markus Heidelbergfbb86372009-05-18 01:36:51 +0200274 case Qt::Key_Return:
275 case Qt::Key_Enter:
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700276 sym_set_string_value(item->menu->sym, text().toLatin1());
Masahiro Yamadaf9b918f2020-08-29 17:14:10 +0900277 ConfigList::updateListForAll();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700278 break;
279 default:
280 Parent::keyPressEvent(e);
281 return;
282 }
283 e->accept();
284 parent()->list->setFocus();
285 hide();
286}
287
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700288ConfigList::ConfigList(ConfigView* p, const char *name)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700289 : Parent(p),
290 updateAll(false),
Masahiro Yamada669a1ee2020-08-29 17:14:11 +0900291 showName(false), showRange(false), mode(singleMode), optMode(normalOpt),
Boris Barbulovski59e56442015-09-22 11:36:18 -0700292 rootEntry(0), headerPopup(0)
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700293{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700294 setObjectName(name);
Boris Barbulovskia5225e92015-09-22 11:36:29 -0700295 setSortingEnabled(false);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700296 setRootIsDecorated(true);
297
Boris Barbulovskif999cc02015-09-22 11:36:31 -0700298 setVerticalScrollMode(ScrollPerPixel);
299 setHorizontalScrollMode(ScrollPerPixel);
300
Masahiro Yamada97bebbc2020-07-30 02:46:17 +0900301 setHeaderLabels(QStringList() << "Option" << "Name" << "N" << "M" << "Y" << "Value");
Boris Barbulovskia52cb322015-09-22 11:36:24 -0700302
Boris Barbulovskic14fa5e2015-09-22 11:36:21 -0700303 connect(this, SIGNAL(itemSelectionChanged(void)),
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700304 SLOT(updateSelection(void)));
305
306 if (name) {
307 configSettings->beginGroup(name);
308 showName = configSettings->value("/showName", false).toBool();
309 showRange = configSettings->value("/showRange", false).toBool();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700310 optMode = (enum optionMode)configSettings->value("/optionMode", 0).toInt();
311 configSettings->endGroup();
312 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
313 }
314
Masahiro Yamadaabf741a2020-08-07 18:19:04 +0900315 showColumn(promptColIdx);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700316
Masahiro Yamadaf9b918f2020-08-29 17:14:10 +0900317 allLists.append(this);
318
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700319 reinit();
320}
321
Masahiro Yamadaf9b918f2020-08-29 17:14:10 +0900322ConfigList::~ConfigList()
323{
324 allLists.removeOne(this);
325}
326
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700327bool ConfigList::menuSkip(struct menu *menu)
328{
329 if (optMode == normalOpt && menu_is_visible(menu))
330 return false;
331 if (optMode == promptOpt && menu_has_prompt(menu))
332 return false;
333 if (optMode == allOpt)
334 return false;
335 return true;
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700336}
Boris Barbulovski59e56442015-09-22 11:36:18 -0700337
338void ConfigList::reinit(void)
339{
Masahiro Yamadaabf741a2020-08-07 18:19:04 +0900340 hideColumn(yesColIdx);
341 hideColumn(modColIdx);
342 hideColumn(noColIdx);
343 hideColumn(nameColIdx);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700344
345 if (showName)
Masahiro Yamadaabf741a2020-08-07 18:19:04 +0900346 showColumn(nameColIdx);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700347 if (showRange) {
Masahiro Yamadaabf741a2020-08-07 18:19:04 +0900348 showColumn(noColIdx);
349 showColumn(modColIdx);
350 showColumn(yesColIdx);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700351 }
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700352
353 updateListAll();
Boris Barbulovski59e56442015-09-22 11:36:18 -0700354}
355
Masahiro Yamadad4bbe8a2020-08-07 18:19:09 +0900356void ConfigList::setOptionMode(QAction *action)
357{
358 if (action == showNormalAction)
359 optMode = normalOpt;
360 else if (action == showAllAction)
361 optMode = allOpt;
362 else
363 optMode = promptOpt;
364
365 updateListAll();
366}
367
Boris Barbulovski59e56442015-09-22 11:36:18 -0700368void ConfigList::saveSettings(void)
369{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700370 if (!objectName().isEmpty()) {
371 configSettings->beginGroup(objectName());
372 configSettings->setValue("/showName", showName);
373 configSettings->setValue("/showRange", showRange);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700374 configSettings->setValue("/optionMode", (int)optMode);
375 configSettings->endGroup();
376 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700377}
378
379ConfigItem* ConfigList::findConfigItem(struct menu *menu)
380{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700381 ConfigItem* item = (ConfigItem*)menu->data;
382
383 for (; item; item = item->nextItem) {
384 if (this == item->listView())
385 break;
386 }
387
388 return item;
Boris Barbulovski59e56442015-09-22 11:36:18 -0700389}
390
391void ConfigList::updateSelection(void)
392{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700393 struct menu *menu;
394 enum prop_type type;
395
Boris Barbulovskibe596aa2015-09-22 11:36:28 -0700396 if (selectedItems().count() == 0)
397 return;
398
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700399 ConfigItem* item = (ConfigItem*)selectedItems().first();
400 if (!item)
401 return;
402
403 menu = item->menu;
404 emit menuChanged(menu);
405 if (!menu)
406 return;
407 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
408 if (mode == menuMode && type == P_MENU)
409 emit menuSelected(menu);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700410}
411
Masahiro Yamadacb770432020-08-07 18:18:59 +0900412void ConfigList::updateList()
Boris Barbulovski59e56442015-09-22 11:36:18 -0700413{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700414 ConfigItem* last = 0;
Masahiro Yamadacb770432020-08-07 18:18:59 +0900415 ConfigItem *item;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700416
417 if (!rootEntry) {
418 if (mode != listMode)
419 goto update;
420 QTreeWidgetItemIterator it(this);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700421
422 while (*it) {
423 item = (ConfigItem*)(*it);
424 if (!item->menu)
425 continue;
426 item->testUpdateMenu(menu_is_visible(item->menu));
427
428 ++it;
429 }
430 return;
431 }
432
433 if (rootEntry != &rootmenu && (mode == singleMode ||
434 (mode == symbolMode && rootEntry->parent != &rootmenu))) {
Boris Barbulovskiee7298f2015-09-22 11:36:37 -0700435 item = (ConfigItem *)topLevelItem(0);
Masahiro Yamada4b20e102020-08-01 16:08:49 +0900436 if (!item)
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700437 item = new ConfigItem(this, 0, true);
Masahiro Yamada4b20e102020-08-01 16:08:49 +0900438 last = item;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700439 }
440 if ((mode == singleMode || (mode == symbolMode && !(rootEntry->flags & MENU_ROOT))) &&
441 rootEntry->sym && rootEntry->prompt) {
Masahiro Yamadaccf56e52020-08-01 16:08:50 +0900442 item = last ? last->nextSibling() : nullptr;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700443 if (!item)
444 item = new ConfigItem(this, last, rootEntry, true);
445 else
446 item->testUpdateMenu(true);
447
448 updateMenuList(item, rootEntry);
449 update();
Boris Barbulovskif999cc02015-09-22 11:36:31 -0700450 resizeColumnToContents(0);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700451 return;
452 }
453update:
Masahiro Yamada5b75a6c2020-08-07 18:19:01 +0900454 updateMenuList(rootEntry);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700455 update();
Boris Barbulovskif999cc02015-09-22 11:36:31 -0700456 resizeColumnToContents(0);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700457}
458
Masahiro Yamadaf9b918f2020-08-29 17:14:10 +0900459void ConfigList::updateListForAll()
460{
461 QListIterator<ConfigList *> it(allLists);
462
463 while (it.hasNext()) {
464 ConfigList *list = it.next();
465
466 list->updateList();
467 }
468}
469
470void ConfigList::updateListAllForAll()
471{
472 QListIterator<ConfigList *> it(allLists);
473
474 while (it.hasNext()) {
475 ConfigList *list = it.next();
476
477 list->updateList();
478 }
479}
480
Boris Barbulovski59e56442015-09-22 11:36:18 -0700481void ConfigList::setValue(ConfigItem* item, tristate val)
482{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700483 struct symbol* sym;
484 int type;
485 tristate oldval;
486
487 sym = item->menu ? item->menu->sym : 0;
488 if (!sym)
489 return;
490
491 type = sym_get_type(sym);
492 switch (type) {
493 case S_BOOLEAN:
494 case S_TRISTATE:
495 oldval = sym_get_tristate_value(sym);
496
497 if (!sym_set_tristate_value(sym, val))
498 return;
499 if (oldval == no && item->menu->list)
500 item->setExpanded(true);
Masahiro Yamadaf9b918f2020-08-29 17:14:10 +0900501 ConfigList::updateListForAll();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700502 break;
503 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700504}
505
506void ConfigList::changeValue(ConfigItem* item)
507{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700508 struct symbol* sym;
509 struct menu* menu;
510 int type, oldexpr, newexpr;
511
512 menu = item->menu;
513 if (!menu)
514 return;
515 sym = menu->sym;
516 if (!sym) {
517 if (item->menu->list)
518 item->setExpanded(!item->isExpanded());
519 return;
520 }
521
522 type = sym_get_type(sym);
523 switch (type) {
524 case S_BOOLEAN:
525 case S_TRISTATE:
526 oldexpr = sym_get_tristate_value(sym);
527 newexpr = sym_toggle_tristate_value(sym);
528 if (item->menu->list) {
529 if (oldexpr == newexpr)
530 item->setExpanded(!item->isExpanded());
531 else if (oldexpr == no)
532 item->setExpanded(true);
533 }
534 if (oldexpr != newexpr)
Masahiro Yamadaf9b918f2020-08-29 17:14:10 +0900535 ConfigList::updateListForAll();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700536 break;
537 case S_INT:
538 case S_HEX:
539 case S_STRING:
Boris Barbulovskie336b9f2015-09-22 11:36:34 -0700540 parent()->lineEdit->show(item);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700541 break;
542 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700543}
544
545void ConfigList::setRootMenu(struct menu *menu)
546{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700547 enum prop_type type;
548
549 if (rootEntry == menu)
550 return;
551 type = menu && menu->prompt ? menu->prompt->type : P_UNKNOWN;
552 if (type != P_MENU)
553 return;
Masahiro Yamada5b75a6c2020-08-07 18:19:01 +0900554 updateMenuList(0);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700555 rootEntry = menu;
556 updateListAll();
557 if (currentItem()) {
Mauro Carvalho Chehabb06c3ec2020-06-30 08:26:38 +0200558 setSelected(currentItem(), hasFocus());
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700559 scrollToItem(currentItem());
560 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700561}
562
563void ConfigList::setParentMenu(void)
564{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700565 ConfigItem* item;
566 struct menu *oldroot;
567
568 oldroot = rootEntry;
569 if (rootEntry == &rootmenu)
570 return;
571 setRootMenu(menu_get_parent_menu(rootEntry->parent));
572
573 QTreeWidgetItemIterator it(this);
574 while (*it) {
575 item = (ConfigItem *)(*it);
576 if (item->menu == oldroot) {
577 setCurrentItem(item);
578 scrollToItem(item);
579 break;
580 }
581
582 ++it;
583 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700584}
585
586/*
587 * update all the children of a menu entry
588 * removes/adds the entries from the parent widget as necessary
589 *
590 * parent: either the menu list widget or a menu entry widget
591 * menu: entry to be updated
592 */
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700593void ConfigList::updateMenuList(ConfigItem *parent, struct menu* menu)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700594{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700595 struct menu* child;
596 ConfigItem* item;
597 ConfigItem* last;
598 bool visible;
599 enum prop_type type;
600
601 if (!menu) {
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700602 while (parent->childCount() > 0)
603 {
604 delete parent->takeChild(0);
605 }
606
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700607 return;
608 }
609
610 last = parent->firstChild();
611 if (last && !last->goParent)
612 last = 0;
613 for (child = menu->list; child; child = child->next) {
614 item = last ? last->nextSibling() : parent->firstChild();
615 type = child->prompt ? child->prompt->type : P_UNKNOWN;
616
617 switch (mode) {
618 case menuMode:
619 if (!(child->flags & MENU_ROOT))
620 goto hide;
621 break;
622 case symbolMode:
623 if (child->flags & MENU_ROOT)
624 goto hide;
625 break;
626 default:
627 break;
628 }
629
630 visible = menu_is_visible(child);
631 if (!menuSkip(child)) {
632 if (!child->sym && !child->list && !child->prompt)
633 continue;
634 if (!item || item->menu != child)
635 item = new ConfigItem(parent, last, child, visible);
636 else
637 item->testUpdateMenu(visible);
638
639 if (mode == fullMode || mode == menuMode || type != P_MENU)
640 updateMenuList(item, child);
641 else
642 updateMenuList(item, 0);
643 last = item;
644 continue;
645 }
Mauro Carvalho Chehab60969f02020-04-02 11:28:03 +0200646hide:
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700647 if (item && item->menu == child) {
648 last = parent->firstChild();
649 if (last == item)
650 last = 0;
651 else while (last->nextSibling() != item)
652 last = last->nextSibling();
653 delete item;
654 }
655 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700656}
657
Masahiro Yamada5b75a6c2020-08-07 18:19:01 +0900658void ConfigList::updateMenuList(struct menu *menu)
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700659{
660 struct menu* child;
661 ConfigItem* item;
662 ConfigItem* last;
663 bool visible;
664 enum prop_type type;
665
666 if (!menu) {
Masahiro Yamada5b75a6c2020-08-07 18:19:01 +0900667 while (topLevelItemCount() > 0)
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700668 {
Masahiro Yamada5b75a6c2020-08-07 18:19:01 +0900669 delete takeTopLevelItem(0);
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700670 }
671
672 return;
673 }
674
Masahiro Yamada5b75a6c2020-08-07 18:19:01 +0900675 last = (ConfigItem *)topLevelItem(0);
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700676 if (last && !last->goParent)
677 last = 0;
678 for (child = menu->list; child; child = child->next) {
Masahiro Yamada5b75a6c2020-08-07 18:19:01 +0900679 item = last ? last->nextSibling() : (ConfigItem *)topLevelItem(0);
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700680 type = child->prompt ? child->prompt->type : P_UNKNOWN;
681
682 switch (mode) {
683 case menuMode:
684 if (!(child->flags & MENU_ROOT))
685 goto hide;
686 break;
687 case symbolMode:
688 if (child->flags & MENU_ROOT)
689 goto hide;
690 break;
691 default:
692 break;
693 }
694
695 visible = menu_is_visible(child);
696 if (!menuSkip(child)) {
697 if (!child->sym && !child->list && !child->prompt)
698 continue;
699 if (!item || item->menu != child)
Masahiro Yamada5b75a6c2020-08-07 18:19:01 +0900700 item = new ConfigItem(this, last, child, visible);
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700701 else
702 item->testUpdateMenu(visible);
703
704 if (mode == fullMode || mode == menuMode || type != P_MENU)
705 updateMenuList(item, child);
706 else
707 updateMenuList(item, 0);
708 last = item;
709 continue;
710 }
Mauro Carvalho Chehab60969f02020-04-02 11:28:03 +0200711hide:
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700712 if (item && item->menu == child) {
Masahiro Yamada5b75a6c2020-08-07 18:19:01 +0900713 last = (ConfigItem *)topLevelItem(0);
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700714 if (last == item)
715 last = 0;
716 else while (last->nextSibling() != item)
717 last = last->nextSibling();
718 delete item;
719 }
720 }
721}
722
Boris Barbulovski59e56442015-09-22 11:36:18 -0700723void ConfigList::keyPressEvent(QKeyEvent* ev)
724{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700725 QTreeWidgetItem* i = currentItem();
726 ConfigItem* item;
727 struct menu *menu;
728 enum prop_type type;
729
730 if (ev->key() == Qt::Key_Escape && mode != fullMode && mode != listMode) {
731 emit parentSelected();
732 ev->accept();
733 return;
734 }
735
736 if (!i) {
737 Parent::keyPressEvent(ev);
738 return;
739 }
740 item = (ConfigItem*)i;
741
742 switch (ev->key()) {
743 case Qt::Key_Return:
744 case Qt::Key_Enter:
745 if (item->goParent) {
746 emit parentSelected();
747 break;
748 }
749 menu = item->menu;
750 if (!menu)
751 break;
752 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
753 if (type == P_MENU && rootEntry != menu &&
754 mode != fullMode && mode != menuMode) {
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +0200755 if (mode == menuMode)
756 emit menuSelected(menu);
757 else
758 emit itemSelected(menu);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700759 break;
760 }
761 case Qt::Key_Space:
762 changeValue(item);
763 break;
764 case Qt::Key_N:
765 setValue(item, no);
766 break;
767 case Qt::Key_M:
768 setValue(item, mod);
769 break;
770 case Qt::Key_Y:
771 setValue(item, yes);
772 break;
773 default:
774 Parent::keyPressEvent(ev);
775 return;
776 }
777 ev->accept();
Boris Barbulovski59e56442015-09-22 11:36:18 -0700778}
779
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700780void ConfigList::mousePressEvent(QMouseEvent* e)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700781{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700782 //QPoint p(contentsToViewport(e->pos()));
783 //printf("contentsMousePressEvent: %d,%d\n", p.x(), p.y());
784 Parent::mousePressEvent(e);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700785}
786
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700787void ConfigList::mouseReleaseEvent(QMouseEvent* e)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700788{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700789 QPoint p = e->pos();
790 ConfigItem* item = (ConfigItem*)itemAt(p);
791 struct menu *menu;
792 enum prop_type ptype;
793 QIcon icon;
794 int idx, x;
795
796 if (!item)
797 goto skip;
798
799 menu = item->menu;
800 x = header()->offset() + p.x();
Boris Barbulovski76d53cb2015-09-22 11:36:35 -0700801 idx = header()->logicalIndexAt(x);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700802 switch (idx) {
803 case promptColIdx:
Masahiro Yamada711b8752020-08-07 18:19:03 +0900804 icon = item->icon(promptColIdx);
Boris Barbulovski76d53cb2015-09-22 11:36:35 -0700805 if (!icon.isNull()) {
806 int off = header()->sectionPosition(0) + visualRect(indexAt(p)).x() + 4; // 4 is Hardcoded image offset. There might be a way to do it properly.
807 if (x >= off && x < off + icon.availableSizes().first().width()) {
808 if (item->goParent) {
809 emit parentSelected();
810 break;
811 } else if (!menu)
812 break;
813 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
814 if (ptype == P_MENU && rootEntry != menu &&
Maxime Chretien7eb7c106f2020-07-08 15:32:15 +0200815 mode != fullMode && mode != menuMode &&
816 mode != listMode)
Boris Barbulovski76d53cb2015-09-22 11:36:35 -0700817 emit menuSelected(menu);
818 else
819 changeValue(item);
820 }
821 }
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700822 break;
823 case noColIdx:
824 setValue(item, no);
825 break;
826 case modColIdx:
827 setValue(item, mod);
828 break;
829 case yesColIdx:
830 setValue(item, yes);
831 break;
832 case dataColIdx:
833 changeValue(item);
834 break;
835 }
836
837skip:
838 //printf("contentsMouseReleaseEvent: %d,%d\n", p.x(), p.y());
839 Parent::mouseReleaseEvent(e);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700840}
841
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700842void ConfigList::mouseMoveEvent(QMouseEvent* e)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700843{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700844 //QPoint p(contentsToViewport(e->pos()));
845 //printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y());
846 Parent::mouseMoveEvent(e);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700847}
848
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700849void ConfigList::mouseDoubleClickEvent(QMouseEvent* e)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700850{
Mauro Carvalho Chehabe1f77692020-04-02 11:28:02 +0200851 QPoint p = e->pos();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700852 ConfigItem* item = (ConfigItem*)itemAt(p);
853 struct menu *menu;
854 enum prop_type ptype;
855
856 if (!item)
857 goto skip;
858 if (item->goParent) {
859 emit parentSelected();
860 goto skip;
861 }
862 menu = item->menu;
863 if (!menu)
864 goto skip;
865 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
Maxime Chretien7eb7c106f2020-07-08 15:32:15 +0200866 if (ptype == P_MENU && mode != listMode) {
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +0200867 if (mode == singleMode)
868 emit itemSelected(menu);
869 else if (mode == symbolMode)
870 emit menuSelected(menu);
871 } else if (menu->sym)
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700872 changeValue(item);
873
874skip:
875 //printf("contentsMouseDoubleClickEvent: %d,%d\n", p.x(), p.y());
876 Parent::mouseDoubleClickEvent(e);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700877}
878
879void ConfigList::focusInEvent(QFocusEvent *e)
880{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700881 struct menu *menu = NULL;
882
883 Parent::focusInEvent(e);
884
885 ConfigItem* item = (ConfigItem *)currentItem();
886 if (item) {
Mauro Carvalho Chehabb06c3ec2020-06-30 08:26:38 +0200887 setSelected(item, true);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700888 menu = item->menu;
889 }
890 emit gotFocus(menu);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700891}
892
893void ConfigList::contextMenuEvent(QContextMenuEvent *e)
894{
Masahiro Yamadafa8de0a2020-08-07 18:19:08 +0900895 if (!headerPopup) {
896 QAction *action;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700897
Masahiro Yamadafa8de0a2020-08-07 18:19:08 +0900898 headerPopup = new QMenu(this);
899 action = new QAction("Show Name", this);
900 action->setCheckable(true);
901 connect(action, SIGNAL(toggled(bool)),
902 parent(), SLOT(setShowName(bool)));
903 connect(parent(), SIGNAL(showNameChanged(bool)),
Masahiro Yamadad85de332020-08-18 01:36:29 +0900904 action, SLOT(setChecked(bool)));
Masahiro Yamadafa8de0a2020-08-07 18:19:08 +0900905 action->setChecked(showName);
906 headerPopup->addAction(action);
907
908 action = new QAction("Show Range", this);
909 action->setCheckable(true);
910 connect(action, SIGNAL(toggled(bool)),
911 parent(), SLOT(setShowRange(bool)));
912 connect(parent(), SIGNAL(showRangeChanged(bool)),
Masahiro Yamadad85de332020-08-18 01:36:29 +0900913 action, SLOT(setChecked(bool)));
Masahiro Yamadafa8de0a2020-08-07 18:19:08 +0900914 action->setChecked(showRange);
915 headerPopup->addAction(action);
Masahiro Yamadafa8de0a2020-08-07 18:19:08 +0900916 }
917
918 headerPopup->exec(e->globalPos());
919 e->accept();
Boris Barbulovski59e56442015-09-22 11:36:18 -0700920}
921
Masahiro Yamadaf9b918f2020-08-29 17:14:10 +0900922QList<ConfigList *> ConfigList::allLists;
Masahiro Yamadad4bbe8a2020-08-07 18:19:09 +0900923QAction *ConfigList::showNormalAction;
924QAction *ConfigList::showAllAction;
925QAction *ConfigList::showPromptAction;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700926
Roman Zippel7fc925f2006-06-08 22:12:46 -0700927ConfigView::ConfigView(QWidget* parent, const char *name)
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -0700928 : Parent(parent)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700929{
Boris Barbulovski9bd36ed2015-09-22 11:36:22 -0700930 setObjectName(name);
Boris Barbulovski29a70162015-09-22 11:36:10 -0700931 QVBoxLayout *verticalLayout = new QVBoxLayout(this);
Boris Barbulovski92298b42015-09-22 11:36:11 -0700932 verticalLayout->setContentsMargins(0, 0, 0, 0);
Boris Barbulovski29a70162015-09-22 11:36:10 -0700933
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700934 list = new ConfigList(this);
Boris Barbulovski29a70162015-09-22 11:36:10 -0700935 verticalLayout->addWidget(list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700936 lineEdit = new ConfigLineEdit(this);
937 lineEdit->hide();
Boris Barbulovski29a70162015-09-22 11:36:10 -0700938 verticalLayout->addWidget(lineEdit);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700939}
940
Roman Zippel7fc925f2006-06-08 22:12:46 -0700941void ConfigView::setShowName(bool b)
942{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700943 if (list->showName != b) {
944 list->showName = b;
945 list->reinit();
946 emit showNameChanged(b);
947 }
Roman Zippel7fc925f2006-06-08 22:12:46 -0700948}
949
950void ConfigView::setShowRange(bool b)
951{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700952 if (list->showRange != b) {
953 list->showRange = b;
954 list->reinit();
955 emit showRangeChanged(b);
956 }
Roman Zippel7fc925f2006-06-08 22:12:46 -0700957}
958
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700959void ConfigList::setAllOpen(bool open)
960{
961 QTreeWidgetItemIterator it(this);
962
963 while (*it) {
964 (*it)->setExpanded(open);
965
966 ++it;
967 }
Roman Zippel7fc925f2006-06-08 22:12:46 -0700968}
969
Roman Zippel43bf6122006-06-08 22:12:45 -0700970ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name)
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -0700971 : Parent(parent), sym(0), _menu(0)
Roman Zippel43bf6122006-06-08 22:12:45 -0700972{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700973 setObjectName(name);
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +0200974 setOpenLinks(false);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700975
976 if (!objectName().isEmpty()) {
977 configSettings->beginGroup(objectName());
Boris Barbulovskie0393032016-11-30 14:57:52 -0800978 setShowDebug(configSettings->value("/showDebug", false).toBool());
Roman Zippel7fc925f2006-06-08 22:12:46 -0700979 configSettings->endGroup();
980 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
981 }
Masahiro Yamada7d1300e2020-08-18 01:36:30 +0900982
983 contextMenu = createStandardContextMenu();
984 QAction *action = new QAction("Show Debug Info", contextMenu);
985
986 action->setCheckable(true);
987 connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
988 connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setChecked(bool)));
989 action->setChecked(showDebug());
990 contextMenu->addSeparator();
991 contextMenu->addAction(action);
Roman Zippel7fc925f2006-06-08 22:12:46 -0700992}
993
994void ConfigInfoView::saveSettings(void)
995{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700996 if (!objectName().isEmpty()) {
997 configSettings->beginGroup(objectName());
998 configSettings->setValue("/showDebug", showDebug());
999 configSettings->endGroup();
1000 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001001}
1002
1003void ConfigInfoView::setShowDebug(bool b)
1004{
1005 if (_showDebug != b) {
1006 _showDebug = b;
Alexander Stein133c5f72010-08-31 17:34:37 +02001007 if (_menu)
Roman Zippel43bf6122006-06-08 22:12:45 -07001008 menuInfo();
Roman Zippelab45d192006-06-08 22:12:47 -07001009 else if (sym)
1010 symbolInfo();
Roman Zippel43bf6122006-06-08 22:12:45 -07001011 emit showDebugChanged(b);
1012 }
1013}
1014
1015void ConfigInfoView::setInfo(struct menu *m)
1016{
Alexander Stein133c5f72010-08-31 17:34:37 +02001017 if (_menu == m)
Roman Zippelb65a47e2006-06-08 22:12:47 -07001018 return;
Alexander Stein133c5f72010-08-31 17:34:37 +02001019 _menu = m;
Roman Zippel6fa1da82007-01-10 23:15:31 -08001020 sym = NULL;
Alexander Stein133c5f72010-08-31 17:34:37 +02001021 if (!_menu)
Roman Zippel43bf6122006-06-08 22:12:45 -07001022 clear();
Roman Zippel6fa1da82007-01-10 23:15:31 -08001023 else
Roman Zippel43bf6122006-06-08 22:12:45 -07001024 menuInfo();
1025}
1026
Roman Zippelab45d192006-06-08 22:12:47 -07001027void ConfigInfoView::symbolInfo(void)
1028{
1029 QString str;
1030
1031 str += "<big>Symbol: <b>";
1032 str += print_filter(sym->name);
1033 str += "</b></big><br><br>value: ";
1034 str += print_filter(sym_get_string_value(sym));
1035 str += "<br>visibility: ";
1036 str += sym->visible == yes ? "y" : sym->visible == mod ? "m" : "n";
1037 str += "<br>";
1038 str += debug_info(sym);
1039
1040 setText(str);
1041}
1042
Roman Zippel43bf6122006-06-08 22:12:45 -07001043void ConfigInfoView::menuInfo(void)
1044{
1045 struct symbol* sym;
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001046 QString info;
1047 QTextStream stream(&info);
Roman Zippel43bf6122006-06-08 22:12:45 -07001048
Alexander Stein133c5f72010-08-31 17:34:37 +02001049 sym = _menu->sym;
Roman Zippel43bf6122006-06-08 22:12:45 -07001050 if (sym) {
Alexander Stein133c5f72010-08-31 17:34:37 +02001051 if (_menu->prompt) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001052 stream << "<big><b>";
1053 stream << print_filter(_menu->prompt->text);
1054 stream << "</b></big>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001055 if (sym->name) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001056 stream << " (";
Roman Zippelab45d192006-06-08 22:12:47 -07001057 if (showDebug())
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001058 stream << "<a href=\"s" << sym->name << "\">";
1059 stream << print_filter(sym->name);
Roman Zippelab45d192006-06-08 22:12:47 -07001060 if (showDebug())
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001061 stream << "</a>";
1062 stream << ")";
Roman Zippel43bf6122006-06-08 22:12:45 -07001063 }
1064 } else if (sym->name) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001065 stream << "<big><b>";
Roman Zippelab45d192006-06-08 22:12:47 -07001066 if (showDebug())
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001067 stream << "<a href=\"s" << sym->name << "\">";
1068 stream << print_filter(sym->name);
Roman Zippelab45d192006-06-08 22:12:47 -07001069 if (showDebug())
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001070 stream << "</a>";
1071 stream << "</b></big>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001072 }
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001073 stream << "<br><br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001074
1075 if (showDebug())
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001076 stream << debug_info(sym);
1077
Masahiro Yamadaa46afd12020-09-14 23:59:48 +09001078 struct gstr help_gstr = str_new();
1079
1080 menu_get_ext_help(_menu, &help_gstr);
1081 stream << print_filter(str_get(&help_gstr));
1082 str_free(&help_gstr);
Alexander Stein133c5f72010-08-31 17:34:37 +02001083 } else if (_menu->prompt) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001084 stream << "<big><b>";
1085 stream << print_filter(_menu->prompt->text);
1086 stream << "</b></big><br><br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001087 if (showDebug()) {
Alexander Stein133c5f72010-08-31 17:34:37 +02001088 if (_menu->prompt->visible.expr) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001089 stream << "&nbsp;&nbsp;dep: ";
1090 expr_print(_menu->prompt->visible.expr,
1091 expr_print_help, &stream, E_NONE);
1092 stream << "<br><br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001093 }
Masahiro Yamadaa46afd12020-09-14 23:59:48 +09001094
1095 stream << "defined at " << _menu->file->name << ":"
1096 << _menu->lineno << "<br><br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001097 }
1098 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001099
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001100 setText(info);
Roman Zippel43bf6122006-06-08 22:12:45 -07001101}
1102
1103QString ConfigInfoView::debug_info(struct symbol *sym)
1104{
1105 QString debug;
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001106 QTextStream stream(&debug);
Roman Zippel43bf6122006-06-08 22:12:45 -07001107
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001108 stream << "type: ";
1109 stream << print_filter(sym_type_name(sym->type));
Roman Zippel43bf6122006-06-08 22:12:45 -07001110 if (sym_is_choice(sym))
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001111 stream << " (choice)";
Roman Zippel43bf6122006-06-08 22:12:45 -07001112 debug += "<br>";
1113 if (sym->rev_dep.expr) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001114 stream << "reverse dep: ";
1115 expr_print(sym->rev_dep.expr, expr_print_help, &stream, E_NONE);
1116 stream << "<br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001117 }
1118 for (struct property *prop = sym->prop; prop; prop = prop->next) {
1119 switch (prop->type) {
1120 case P_PROMPT:
1121 case P_MENU:
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001122 stream << "prompt: <a href=\"m" << sym->name << "\">";
1123 stream << print_filter(prop->text);
1124 stream << "</a><br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001125 break;
1126 case P_DEFAULT:
Roman Zippel93449082008-01-14 04:50:54 +01001127 case P_SELECT:
1128 case P_RANGE:
Mauro Carvalho Chehab8f8499a2020-06-30 08:48:53 +02001129 case P_COMMENT:
1130 case P_IMPLY:
1131 case P_SYMBOL:
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001132 stream << prop_get_type_name(prop->type);
1133 stream << ": ";
1134 expr_print(prop->expr, expr_print_help,
1135 &stream, E_NONE);
1136 stream << "<br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001137 break;
1138 case P_CHOICE:
1139 if (sym_is_choice(sym)) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001140 stream << "choice: ";
1141 expr_print(prop->expr, expr_print_help,
1142 &stream, E_NONE);
1143 stream << "<br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001144 }
1145 break;
Roman Zippel43bf6122006-06-08 22:12:45 -07001146 default:
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001147 stream << "unknown property: ";
1148 stream << prop_get_type_name(prop->type);
1149 stream << "<br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001150 }
1151 if (prop->visible.expr) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001152 stream << "&nbsp;&nbsp;&nbsp;&nbsp;dep: ";
1153 expr_print(prop->visible.expr, expr_print_help,
1154 &stream, E_NONE);
1155 stream << "<br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001156 }
1157 }
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001158 stream << "<br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001159
1160 return debug;
1161}
1162
1163QString ConfigInfoView::print_filter(const QString &str)
1164{
1165 QRegExp re("[<>&\"\\n]");
1166 QString res = str;
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001167 for (int i = 0; (i = res.indexOf(re, i)) >= 0;) {
1168 switch (res[i].toLatin1()) {
Roman Zippel43bf6122006-06-08 22:12:45 -07001169 case '<':
1170 res.replace(i, 1, "&lt;");
1171 i += 4;
1172 break;
1173 case '>':
1174 res.replace(i, 1, "&gt;");
1175 i += 4;
1176 break;
1177 case '&':
1178 res.replace(i, 1, "&amp;");
1179 i += 5;
1180 break;
1181 case '"':
1182 res.replace(i, 1, "&quot;");
1183 i += 6;
1184 break;
1185 case '\n':
1186 res.replace(i, 1, "<br>");
1187 i += 4;
1188 break;
1189 }
1190 }
1191 return res;
1192}
1193
Roman Zippelab45d192006-06-08 22:12:47 -07001194void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char *str)
Roman Zippel43bf6122006-06-08 22:12:45 -07001195{
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001196 QTextStream *stream = reinterpret_cast<QTextStream *>(data);
Roman Zippelab45d192006-06-08 22:12:47 -07001197
1198 if (sym && sym->name && !(sym->flags & SYMBOL_CONST)) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001199 *stream << "<a href=\"s" << sym->name << "\">";
1200 *stream << print_filter(str);
1201 *stream << "</a>";
1202 } else {
1203 *stream << print_filter(str);
1204 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001205}
1206
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001207void ConfigInfoView::clicked(const QUrl &url)
1208{
1209 QByteArray str = url.toEncoded();
1210 const std::size_t count = str.size();
1211 char *data = new char[count + 1];
1212 struct symbol **result;
1213 struct menu *m = NULL;
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001214
1215 if (count < 1) {
Masahiro Yamadac9b09a922020-07-30 02:02:39 +09001216 delete[] data;
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001217 return;
1218 }
1219
1220 memcpy(data, str.constData(), count);
1221 data[count] = '\0';
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001222
1223 /* Seek for exact match */
1224 data[0] = '^';
1225 strcat(data, "$");
1226 result = sym_re_search(data);
1227 if (!result) {
Masahiro Yamadac9b09a922020-07-30 02:02:39 +09001228 delete[] data;
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001229 return;
1230 }
1231
1232 sym = *result;
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001233
Mauro Carvalho Chehab8a3b6e52020-06-30 08:48:35 +02001234 /* Seek for the menu which holds the symbol */
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001235 for (struct property *prop = sym->prop; prop; prop = prop->next) {
1236 if (prop->type != P_PROMPT && prop->type != P_MENU)
1237 continue;
1238 m = prop->menu;
1239 break;
1240 }
1241
1242 if (!m) {
Mauro Carvalho Chehab8a3b6e52020-06-30 08:48:35 +02001243 /* Symbol is not visible as a menu */
1244 symbolInfo();
1245 emit showDebugChanged(true);
1246 } else {
1247 emit menuSelected(m);
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001248 }
1249
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001250 free(result);
Masahiro Yamadaa608b6a2020-09-09 07:16:37 +09001251 delete[] data;
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001252}
1253
Masahiro Yamada7d1300e2020-08-18 01:36:30 +09001254void ConfigInfoView::contextMenuEvent(QContextMenuEvent *event)
Roman Zippel7fc925f2006-06-08 22:12:46 -07001255{
Masahiro Yamada7d1300e2020-08-18 01:36:30 +09001256 contextMenu->popup(event->globalPos());
1257 event->accept();
Roman Zippel7fc925f2006-06-08 22:12:46 -07001258}
1259
Masahiro Yamada740fdef2020-08-07 18:18:57 +09001260ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow *parent)
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001261 : Parent(parent), result(NULL)
Roman Zippel43bf6122006-06-08 22:12:45 -07001262{
Masahiro Yamada740fdef2020-08-07 18:18:57 +09001263 setObjectName("search");
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001264 setWindowTitle("Search Config");
Roman Zippel43bf6122006-06-08 22:12:45 -07001265
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001266 QVBoxLayout* layout1 = new QVBoxLayout(this);
1267 layout1->setContentsMargins(11, 11, 11, 11);
1268 layout1->setSpacing(6);
Masahiro Yamada92641152020-08-07 18:18:58 +09001269
1270 QHBoxLayout* layout2 = new QHBoxLayout();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001271 layout2->setContentsMargins(0, 0, 0, 0);
1272 layout2->setSpacing(6);
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001273 layout2->addWidget(new QLabel("Find:", this));
Roman Zippel43bf6122006-06-08 22:12:45 -07001274 editField = new QLineEdit(this);
1275 connect(editField, SIGNAL(returnPressed()), SLOT(search()));
1276 layout2->addWidget(editField);
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001277 searchButton = new QPushButton("Search", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001278 searchButton->setAutoDefault(false);
Roman Zippel43bf6122006-06-08 22:12:45 -07001279 connect(searchButton, SIGNAL(clicked()), SLOT(search()));
1280 layout2->addWidget(searchButton);
1281 layout1->addLayout(layout2);
1282
Roman Zippel7fc925f2006-06-08 22:12:46 -07001283 split = new QSplitter(this);
Markus Heidelberg7298b932009-05-18 01:36:50 +02001284 split->setOrientation(Qt::Vertical);
Masahiro Yamada740fdef2020-08-07 18:18:57 +09001285 list = new ConfigView(split, "search");
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001286 list->list->mode = listMode;
Masahiro Yamada740fdef2020-08-07 18:18:57 +09001287 info = new ConfigInfoView(split, "search");
Roman Zippel43bf6122006-06-08 22:12:45 -07001288 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1289 info, SLOT(setInfo(struct menu *)));
Marco Costalba63431e72006-10-05 19:12:59 +02001290 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1291 parent, SLOT(setMenuLink(struct menu *)));
1292
Roman Zippel43bf6122006-06-08 22:12:45 -07001293 layout1->addWidget(split);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001294
Masahiro Yamada740fdef2020-08-07 18:18:57 +09001295 QVariant x, y;
1296 int width, height;
1297 bool ok;
Roman Zippel7fc925f2006-06-08 22:12:46 -07001298
Masahiro Yamada740fdef2020-08-07 18:18:57 +09001299 configSettings->beginGroup("search");
1300 width = configSettings->value("/window width", parent->width() / 2).toInt();
1301 height = configSettings->value("/window height", parent->height() / 2).toInt();
1302 resize(width, height);
1303 x = configSettings->value("/window x");
1304 y = configSettings->value("/window y");
1305 if (x.isValid() && y.isValid())
1306 move(x.toInt(), y.toInt());
1307 QList<int> sizes = configSettings->readSizes("/split", &ok);
1308 if (ok)
1309 split->setSizes(sizes);
1310 configSettings->endGroup();
1311 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
Roman Zippel7fc925f2006-06-08 22:12:46 -07001312}
1313
1314void ConfigSearchWindow::saveSettings(void)
1315{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001316 if (!objectName().isEmpty()) {
1317 configSettings->beginGroup(objectName());
1318 configSettings->setValue("/window x", pos().x());
1319 configSettings->setValue("/window y", pos().y());
1320 configSettings->setValue("/window width", size().width());
1321 configSettings->setValue("/window height", size().height());
1322 configSettings->writeSizes("/split", split->sizes());
1323 configSettings->endGroup();
1324 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001325}
1326
1327void ConfigSearchWindow::search(void)
1328{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001329 struct symbol **p;
1330 struct property *prop;
1331 ConfigItem *lastItem = NULL;
1332
1333 free(result);
1334 list->list->clear();
1335 info->clear();
1336
1337 result = sym_re_search(editField->text().toLatin1());
1338 if (!result)
1339 return;
1340 for (p = result; *p; p++) {
1341 for_all_prompts((*p), prop)
1342 lastItem = new ConfigItem(list->list, lastItem, prop->menu,
1343 menu_is_visible(prop->menu));
1344 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001345}
1346
Linus Torvalds1da177e2005-04-16 15:20:36 -07001347/*
1348 * Construct the complete config widget
1349 */
1350ConfigMainWindow::ConfigMainWindow(void)
Roman Zippelf12aa702006-11-25 11:09:31 -08001351 : searchWindow(0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001352{
Boris Barbulovski92119932015-09-22 11:36:16 -07001353 bool ok = true;
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001354 QVariant x, y;
1355 int width, height;
Randy Dunlapa54bb702007-10-20 11:18:47 -07001356 char title[256];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001357
Markus Heidelberg8d90c972009-05-18 01:36:52 +02001358 QDesktopWidget *d = configApp->desktop();
Arnaud Lacombe09548282010-08-18 01:57:13 -04001359 snprintf(title, sizeof(title), "%s%s",
1360 rootmenu.prompt->text,
Michal Marek76a136c2010-09-01 17:39:27 +02001361 ""
Michal Marek76a136c2010-09-01 17:39:27 +02001362 );
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001363 setWindowTitle(title);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001364
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001365 width = configSettings->value("/window width", d->width() - 64).toInt();
1366 height = configSettings->value("/window height", d->height() - 64).toInt();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001367 resize(width, height);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001368 x = configSettings->value("/window x");
1369 y = configSettings->value("/window y");
1370 if ((x.isValid())&&(y.isValid()))
1371 move(x.toInt(), y.toInt());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001372
Masahiro Yamada5cb255f2020-08-07 18:19:07 +09001373 // set up icons
1374 ConfigItem::symbolYesIcon = QIcon(QPixmap(xpm_symbol_yes));
1375 ConfigItem::symbolModIcon = QIcon(QPixmap(xpm_symbol_mod));
1376 ConfigItem::symbolNoIcon = QIcon(QPixmap(xpm_symbol_no));
1377 ConfigItem::choiceYesIcon = QIcon(QPixmap(xpm_choice_yes));
1378 ConfigItem::choiceNoIcon = QIcon(QPixmap(xpm_choice_no));
1379 ConfigItem::menuIcon = QIcon(QPixmap(xpm_menu));
1380 ConfigItem::menubackIcon = QIcon(QPixmap(xpm_menuback));
1381
Mauro Carvalho Chehabcce1fab2020-04-02 11:28:00 +02001382 QWidget *widget = new QWidget(this);
1383 QVBoxLayout *layout = new QVBoxLayout(widget);
1384 setCentralWidget(widget);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001385
Mauro Carvalho Chehabcce1fab2020-04-02 11:28:00 +02001386 split1 = new QSplitter(widget);
1387 split1->setOrientation(Qt::Horizontal);
1388 split1->setChildrenCollapsible(false);
1389
1390 menuView = new ConfigView(widget, "menu");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001391 menuList = menuView->list;
1392
Mauro Carvalho Chehabcce1fab2020-04-02 11:28:00 +02001393 split2 = new QSplitter(widget);
1394 split2->setChildrenCollapsible(false);
Markus Heidelberg7298b932009-05-18 01:36:50 +02001395 split2->setOrientation(Qt::Vertical);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001396
1397 // create config tree
Mauro Carvalho Chehabcce1fab2020-04-02 11:28:00 +02001398 configView = new ConfigView(widget, "config");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001399 configList = configView->list;
1400
Mauro Carvalho Chehabcce1fab2020-04-02 11:28:00 +02001401 helpText = new ConfigInfoView(widget, "help");
1402
1403 layout->addWidget(split2);
1404 split2->addWidget(split1);
1405 split1->addWidget(configView);
1406 split1->addWidget(menuView);
1407 split2->addWidget(helpText);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001408
1409 setTabOrder(configList, helpText);
1410 configList->setFocus();
1411
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001412 backAction = new QAction(QPixmap(xpm_back), "Back", this);
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001413 connect(backAction, SIGNAL(triggered(bool)), SLOT(goBack()));
1414
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001415 QAction *quitAction = new QAction("&Quit", this);
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001416 quitAction->setShortcut(Qt::CTRL + Qt::Key_Q);
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001417 connect(quitAction, SIGNAL(triggered(bool)), SLOT(close()));
1418
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001419 QAction *loadAction = new QAction(QPixmap(xpm_load), "&Load", this);
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001420 loadAction->setShortcut(Qt::CTRL + Qt::Key_L);
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001421 connect(loadAction, SIGNAL(triggered(bool)), SLOT(loadConfig()));
1422
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001423 saveAction = new QAction(QPixmap(xpm_save), "&Save", this);
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001424 saveAction->setShortcut(Qt::CTRL + Qt::Key_S);
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001425 connect(saveAction, SIGNAL(triggered(bool)), SLOT(saveConfig()));
1426
Karsten Wiese3b354c52006-12-13 00:34:08 -08001427 conf_set_changed_callback(conf_changed);
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001428
Karsten Wiese3b354c52006-12-13 00:34:08 -08001429 // Set saveAction's initial state
1430 conf_changed();
Masahiro Yamada87419082019-03-11 01:13:15 +09001431 configname = xstrdup(conf_get_configname());
1432
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001433 QAction *saveAsAction = new QAction("Save &As...", this);
Boris Barbulovski92119932015-09-22 11:36:16 -07001434 connect(saveAsAction, SIGNAL(triggered(bool)), SLOT(saveConfigAs()));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001435 QAction *searchAction = new QAction("&Find", this);
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001436 searchAction->setShortcut(Qt::CTRL + Qt::Key_F);
Boris Barbulovski92119932015-09-22 11:36:16 -07001437 connect(searchAction, SIGNAL(triggered(bool)), SLOT(searchConfig()));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001438 singleViewAction = new QAction(QPixmap(xpm_single_view), "Single View", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001439 singleViewAction->setCheckable(true);
Boris Barbulovski92119932015-09-22 11:36:16 -07001440 connect(singleViewAction, SIGNAL(triggered(bool)), SLOT(showSingleView()));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001441 splitViewAction = new QAction(QPixmap(xpm_split_view), "Split View", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001442 splitViewAction->setCheckable(true);
Boris Barbulovski92119932015-09-22 11:36:16 -07001443 connect(splitViewAction, SIGNAL(triggered(bool)), SLOT(showSplitView()));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001444 fullViewAction = new QAction(QPixmap(xpm_tree_view), "Full View", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001445 fullViewAction->setCheckable(true);
Boris Barbulovski92119932015-09-22 11:36:16 -07001446 connect(fullViewAction, SIGNAL(triggered(bool)), SLOT(showFullView()));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001447
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001448 QAction *showNameAction = new QAction("Show Name", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001449 showNameAction->setCheckable(true);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001450 connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool)));
Boris Barbulovski9c862352015-09-22 11:36:12 -07001451 showNameAction->setChecked(configView->showName());
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001452 QAction *showRangeAction = new QAction("Show Range", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001453 showRangeAction->setCheckable(true);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001454 connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool)));
Li Zefan39a48972010-05-10 16:33:41 +08001455
1456 QActionGroup *optGroup = new QActionGroup(this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001457 optGroup->setExclusive(true);
Masahiro Yamadad4bbe8a2020-08-07 18:19:09 +09001458 connect(optGroup, SIGNAL(triggered(QAction*)), configList,
Li Zefan39a48972010-05-10 16:33:41 +08001459 SLOT(setOptionMode(QAction *)));
Masahiro Yamadad4bbe8a2020-08-07 18:19:09 +09001460 connect(optGroup, SIGNAL(triggered(QAction *)), menuList,
Li Zefan39a48972010-05-10 16:33:41 +08001461 SLOT(setOptionMode(QAction *)));
1462
Masahiro Yamadad4bbe8a2020-08-07 18:19:09 +09001463 ConfigList::showNormalAction = new QAction("Show Normal Options", optGroup);
1464 ConfigList::showNormalAction->setCheckable(true);
1465 ConfigList::showAllAction = new QAction("Show All Options", optGroup);
1466 ConfigList::showAllAction->setCheckable(true);
1467 ConfigList::showPromptAction = new QAction("Show Prompt Options", optGroup);
1468 ConfigList::showPromptAction->setCheckable(true);
Li Zefan39a48972010-05-10 16:33:41 +08001469
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001470 QAction *showDebugAction = new QAction("Show Debug Info", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001471 showDebugAction->setCheckable(true);
Roman Zippel43bf6122006-06-08 22:12:45 -07001472 connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
Boris Barbulovski9c862352015-09-22 11:36:12 -07001473 showDebugAction->setChecked(helpText->showDebug());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001474
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001475 QAction *showIntroAction = new QAction("Introduction", this);
Boris Barbulovski92119932015-09-22 11:36:16 -07001476 connect(showIntroAction, SIGNAL(triggered(bool)), SLOT(showIntro()));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001477 QAction *showAboutAction = new QAction("About", this);
Boris Barbulovski92119932015-09-22 11:36:16 -07001478 connect(showAboutAction, SIGNAL(triggered(bool)), SLOT(showAbout()));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001479
1480 // init tool bar
Masahiro Yamada860ec3f2020-08-07 18:18:55 +09001481 QToolBar *toolBar = addToolBar("Tools");
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001482 toolBar->addAction(backAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001483 toolBar->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001484 toolBar->addAction(loadAction);
1485 toolBar->addAction(saveAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001486 toolBar->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001487 toolBar->addAction(singleViewAction);
1488 toolBar->addAction(splitViewAction);
1489 toolBar->addAction(fullViewAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001490
Masahiro Yamada93ebaac2020-08-07 18:18:53 +09001491 // create file menu
1492 QMenu *menu = menuBar()->addMenu("&File");
1493 menu->addAction(loadAction);
1494 menu->addAction(saveAction);
1495 menu->addAction(saveAsAction);
1496 menu->addSeparator();
1497 menu->addAction(quitAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001498
Shlomi Fish66e7c722007-02-14 00:32:58 -08001499 // create edit menu
Masahiro Yamada93ebaac2020-08-07 18:18:53 +09001500 menu = menuBar()->addMenu("&Edit");
1501 menu->addAction(searchAction);
Shlomi Fish66e7c722007-02-14 00:32:58 -08001502
Linus Torvalds1da177e2005-04-16 15:20:36 -07001503 // create options menu
Masahiro Yamada93ebaac2020-08-07 18:18:53 +09001504 menu = menuBar()->addMenu("&Option");
1505 menu->addAction(showNameAction);
1506 menu->addAction(showRangeAction);
Masahiro Yamada93ebaac2020-08-07 18:18:53 +09001507 menu->addSeparator();
1508 menu->addActions(optGroup->actions());
1509 menu->addSeparator();
1510 menu->addAction(showDebugAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001511
1512 // create help menu
Masahiro Yamada93ebaac2020-08-07 18:18:53 +09001513 menu = menuBar()->addMenu("&Help");
1514 menu->addAction(showIntroAction);
1515 menu->addAction(showAboutAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001516
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001517 connect (helpText, SIGNAL (anchorClicked (const QUrl &)),
1518 helpText, SLOT (clicked (const QUrl &)) );
1519
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001520 connect(configList, SIGNAL(menuChanged(struct menu *)),
1521 helpText, SLOT(setInfo(struct menu *)));
1522 connect(configList, SIGNAL(menuSelected(struct menu *)),
1523 SLOT(changeMenu(struct menu *)));
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +02001524 connect(configList, SIGNAL(itemSelected(struct menu *)),
1525 SLOT(changeItens(struct menu *)));
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001526 connect(configList, SIGNAL(parentSelected()),
1527 SLOT(goBack()));
1528 connect(menuList, SIGNAL(menuChanged(struct menu *)),
1529 helpText, SLOT(setInfo(struct menu *)));
1530 connect(menuList, SIGNAL(menuSelected(struct menu *)),
1531 SLOT(changeMenu(struct menu *)));
1532
1533 connect(configList, SIGNAL(gotFocus(struct menu *)),
1534 helpText, SLOT(setInfo(struct menu *)));
1535 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1536 helpText, SLOT(setInfo(struct menu *)));
1537 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1538 SLOT(listFocusChanged(void)));
Roman Zippelb65a47e2006-06-08 22:12:47 -07001539 connect(helpText, SIGNAL(menuSelected(struct menu *)),
1540 SLOT(setMenuLink(struct menu *)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001541
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001542 QString listMode = configSettings->value("/listMode", "symbol").toString();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001543 if (listMode == "single")
1544 showSingleView();
1545 else if (listMode == "full")
1546 showFullView();
1547 else /*if (listMode == "split")*/
1548 showSplitView();
1549
1550 // UI setup done, restore splitter positions
Boris Barbulovski041fbdc2015-09-22 11:36:05 -07001551 QList<int> sizes = configSettings->readSizes("/split1", &ok);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001552 if (ok)
1553 split1->setSizes(sizes);
1554
Roman Zippel7fc925f2006-06-08 22:12:46 -07001555 sizes = configSettings->readSizes("/split2", &ok);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001556 if (ok)
1557 split2->setSizes(sizes);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001558}
1559
Linus Torvalds1da177e2005-04-16 15:20:36 -07001560void ConfigMainWindow::loadConfig(void)
1561{
Masahiro Yamada87419082019-03-11 01:13:15 +09001562 QString str;
1563 QByteArray ba;
1564 const char *name;
1565
1566 str = QFileDialog::getOpenFileName(this, "", configname);
1567 if (str.isNull())
Linus Torvalds1da177e2005-04-16 15:20:36 -07001568 return;
Masahiro Yamada87419082019-03-11 01:13:15 +09001569
1570 ba = str.toLocal8Bit();
1571 name = ba.data();
1572
1573 if (conf_read(name))
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001574 QMessageBox::information(this, "qconf", "Unable to load configuration!");
Masahiro Yamada87419082019-03-11 01:13:15 +09001575
1576 free(configname);
1577 configname = xstrdup(name);
1578
Masahiro Yamadaf9b918f2020-08-29 17:14:10 +09001579 ConfigList::updateListAllForAll();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001580}
1581
Michal Marekbac6aa82011-05-25 15:10:25 +02001582bool ConfigMainWindow::saveConfig(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001583{
Masahiro Yamada87419082019-03-11 01:13:15 +09001584 if (conf_write(configname)) {
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001585 QMessageBox::information(this, "qconf", "Unable to save configuration!");
Michal Marekbac6aa82011-05-25 15:10:25 +02001586 return false;
1587 }
Masahiro Yamada00c864f2018-07-20 16:46:31 +09001588 conf_write_autoconf(0);
1589
Michal Marekbac6aa82011-05-25 15:10:25 +02001590 return true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001591}
1592
1593void ConfigMainWindow::saveConfigAs(void)
1594{
Masahiro Yamada87419082019-03-11 01:13:15 +09001595 QString str;
1596 QByteArray ba;
1597 const char *name;
1598
1599 str = QFileDialog::getSaveFileName(this, "", configname);
1600 if (str.isNull())
Linus Torvalds1da177e2005-04-16 15:20:36 -07001601 return;
Masahiro Yamada87419082019-03-11 01:13:15 +09001602
1603 ba = str.toLocal8Bit();
1604 name = ba.data();
1605
1606 if (conf_write(name)) {
1607 QMessageBox::information(this, "qconf", "Unable to save configuration!");
1608 }
1609 conf_write_autoconf(0);
1610
1611 free(configname);
1612 configname = xstrdup(name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001613}
1614
Roman Zippel43bf6122006-06-08 22:12:45 -07001615void ConfigMainWindow::searchConfig(void)
1616{
1617 if (!searchWindow)
Masahiro Yamada740fdef2020-08-07 18:18:57 +09001618 searchWindow = new ConfigSearchWindow(this);
Roman Zippel43bf6122006-06-08 22:12:45 -07001619 searchWindow->show();
1620}
1621
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +02001622void ConfigMainWindow::changeItens(struct menu *menu)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001623{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001624 configList->setRootMenu(menu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001625}
1626
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +02001627void ConfigMainWindow::changeMenu(struct menu *menu)
1628{
1629 menuList->setRootMenu(menu);
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +02001630}
1631
Roman Zippelb65a47e2006-06-08 22:12:47 -07001632void ConfigMainWindow::setMenuLink(struct menu *menu)
1633{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001634 struct menu *parent;
1635 ConfigList* list = NULL;
1636 ConfigItem* item;
1637
1638 if (configList->menuSkip(menu))
1639 return;
1640
1641 switch (configList->mode) {
1642 case singleMode:
1643 list = configList;
1644 parent = menu_get_parent_menu(menu);
1645 if (!parent)
1646 return;
1647 list->setRootMenu(parent);
1648 break;
Mauro Carvalho Chehabc699eaa2020-06-30 08:26:36 +02001649 case menuMode:
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001650 if (menu->flags & MENU_ROOT) {
Mauro Carvalho Chehabc699eaa2020-06-30 08:26:36 +02001651 menuList->setRootMenu(menu);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001652 configList->clearSelection();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001653 list = configList;
Mauro Carvalho Chehabc699eaa2020-06-30 08:26:36 +02001654 } else {
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001655 parent = menu_get_parent_menu(menu->parent);
1656 if (!parent)
1657 return;
Mauro Carvalho Chehabc699eaa2020-06-30 08:26:36 +02001658
Mauro Carvalho Chehabc699eaa2020-06-30 08:26:36 +02001659 /* Select the config view */
1660 item = configList->findConfigItem(parent);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001661 if (item) {
Mauro Carvalho Chehabb06c3ec2020-06-30 08:26:38 +02001662 configList->setSelected(item, true);
Mauro Carvalho Chehabc699eaa2020-06-30 08:26:36 +02001663 configList->scrollToItem(item);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001664 }
Mauro Carvalho Chehabc699eaa2020-06-30 08:26:36 +02001665
1666 menuList->setRootMenu(parent);
1667 menuList->clearSelection();
1668 list = menuList;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001669 }
1670 break;
1671 case fullMode:
1672 list = configList;
1673 break;
1674 default:
1675 break;
1676 }
1677
1678 if (list) {
1679 item = list->findConfigItem(menu);
1680 if (item) {
Mauro Carvalho Chehabb06c3ec2020-06-30 08:26:38 +02001681 list->setSelected(item, true);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001682 list->scrollToItem(item);
1683 list->setFocus();
Mauro Carvalho Chehab8a3b6e52020-06-30 08:48:35 +02001684 helpText->setInfo(menu);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001685 }
1686 }
Roman Zippelb65a47e2006-06-08 22:12:47 -07001687}
1688
Linus Torvalds1da177e2005-04-16 15:20:36 -07001689void ConfigMainWindow::listFocusChanged(void)
1690{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001691 if (menuList->mode == menuMode)
1692 configList->clearSelection();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001693}
1694
1695void ConfigMainWindow::goBack(void)
1696{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001697 if (configList->rootEntry == &rootmenu)
Boris Barbulovskibe596aa2015-09-22 11:36:28 -07001698 return;
1699
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001700 configList->setParentMenu();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001701}
1702
1703void ConfigMainWindow::showSingleView(void)
1704{
Boris Barbulovski780505e2015-09-22 11:36:13 -07001705 singleViewAction->setEnabled(false);
1706 singleViewAction->setChecked(true);
1707 splitViewAction->setEnabled(true);
1708 splitViewAction->setChecked(false);
1709 fullViewAction->setEnabled(true);
1710 fullViewAction->setChecked(false);
1711
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001712 backAction->setEnabled(true);
1713
Linus Torvalds1da177e2005-04-16 15:20:36 -07001714 menuView->hide();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001715 menuList->setRootMenu(0);
1716 configList->mode = singleMode;
1717 if (configList->rootEntry == &rootmenu)
1718 configList->updateListAll();
1719 else
1720 configList->setRootMenu(&rootmenu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001721 configList->setFocus();
1722}
1723
1724void ConfigMainWindow::showSplitView(void)
1725{
Boris Barbulovski780505e2015-09-22 11:36:13 -07001726 singleViewAction->setEnabled(true);
1727 singleViewAction->setChecked(false);
1728 splitViewAction->setEnabled(false);
1729 splitViewAction->setChecked(true);
1730 fullViewAction->setEnabled(true);
1731 fullViewAction->setChecked(false);
1732
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001733 backAction->setEnabled(false);
1734
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +02001735 configList->mode = menuMode;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001736 if (configList->rootEntry == &rootmenu)
1737 configList->updateListAll();
1738 else
1739 configList->setRootMenu(&rootmenu);
1740 configList->setAllOpen(true);
1741 configApp->processEvents();
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +02001742 menuList->mode = symbolMode;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001743 menuList->setRootMenu(&rootmenu);
1744 menuList->setAllOpen(true);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001745 menuView->show();
1746 menuList->setFocus();
1747}
1748
1749void ConfigMainWindow::showFullView(void)
1750{
Boris Barbulovski780505e2015-09-22 11:36:13 -07001751 singleViewAction->setEnabled(true);
1752 singleViewAction->setChecked(false);
1753 splitViewAction->setEnabled(true);
1754 splitViewAction->setChecked(false);
1755 fullViewAction->setEnabled(false);
1756 fullViewAction->setChecked(true);
1757
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001758 backAction->setEnabled(false);
1759
Linus Torvalds1da177e2005-04-16 15:20:36 -07001760 menuView->hide();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001761 menuList->setRootMenu(0);
1762 configList->mode = fullMode;
1763 if (configList->rootEntry == &rootmenu)
1764 configList->updateListAll();
1765 else
1766 configList->setRootMenu(&rootmenu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001767 configList->setFocus();
1768}
1769
Linus Torvalds1da177e2005-04-16 15:20:36 -07001770/*
1771 * ask for saving configuration before quitting
Linus Torvalds1da177e2005-04-16 15:20:36 -07001772 */
1773void ConfigMainWindow::closeEvent(QCloseEvent* e)
1774{
Karsten Wieseb3214292006-12-13 00:34:06 -08001775 if (!conf_get_changed()) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001776 e->accept();
1777 return;
1778 }
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001779 QMessageBox mb("qconf", "Save configuration?", QMessageBox::Warning,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001780 QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape);
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001781 mb.setButtonText(QMessageBox::Yes, "&Save Changes");
1782 mb.setButtonText(QMessageBox::No, "&Discard Changes");
1783 mb.setButtonText(QMessageBox::Cancel, "Cancel Exit");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001784 switch (mb.exec()) {
1785 case QMessageBox::Yes:
Michal Marekbac6aa82011-05-25 15:10:25 +02001786 if (saveConfig())
1787 e->accept();
1788 else
1789 e->ignore();
1790 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001791 case QMessageBox::No:
1792 e->accept();
1793 break;
1794 case QMessageBox::Cancel:
1795 e->ignore();
1796 break;
1797 }
1798}
1799
1800void ConfigMainWindow::showIntro(void)
1801{
Masahiro Yamada8c30e7e2020-08-29 17:14:07 +09001802 static const QString str =
1803 "Welcome to the qconf graphical configuration tool.\n"
1804 "\n"
1805 "For each option, a blank box indicates the feature is "
1806 "disabled, a check indicates it is enabled, and a dot "
1807 "indicates that it is to be compiled as a module. Clicking on "
1808 "the box will cycle through the three states.\n"
1809 "\n"
1810 "If you do not see an option (e.g., a device driver) that you "
1811 "believe should be present, try turning on Show All Options "
Masahiro Yamada1fb75242020-08-29 17:14:08 +09001812 "under the Options menu. Enabling Show Debug Info will help you"
1813 "figure out what other options must be enabled to support the "
1814 "option you are interested in, and hyperlinks will navigate to "
1815 "them.\n"
Masahiro Yamada8c30e7e2020-08-29 17:14:07 +09001816 "\n"
1817 "Toggling Show Debug Info under the Options menu will show the "
1818 "dependencies, which you can then match by examining other "
1819 "options.\n";
Linus Torvalds1da177e2005-04-16 15:20:36 -07001820
1821 QMessageBox::information(this, "qconf", str);
1822}
1823
1824void ConfigMainWindow::showAbout(void)
1825{
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001826 static const QString str = "qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n"
Boris Barbulovskib4ff1de2015-09-22 11:36:38 -07001827 "Copyright (C) 2015 Boris Barbulovski <bbarbulovski@gmail.com>.\n\n"
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001828 "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n";
Linus Torvalds1da177e2005-04-16 15:20:36 -07001829
1830 QMessageBox::information(this, "qconf", str);
1831}
1832
1833void ConfigMainWindow::saveSettings(void)
1834{
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001835 configSettings->setValue("/window x", pos().x());
1836 configSettings->setValue("/window y", pos().y());
1837 configSettings->setValue("/window width", size().width());
1838 configSettings->setValue("/window height", size().height());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001839
1840 QString entry;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001841 switch(configList->mode) {
1842 case singleMode :
1843 entry = "single";
1844 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001845
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001846 case symbolMode :
1847 entry = "split";
1848 break;
1849
1850 case fullMode :
1851 entry = "full";
1852 break;
1853
1854 default:
1855 break;
1856 }
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001857 configSettings->setValue("/listMode", entry);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001858
Roman Zippel7fc925f2006-06-08 22:12:46 -07001859 configSettings->writeSizes("/split1", split1->sizes());
1860 configSettings->writeSizes("/split2", split2->sizes());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001861}
1862
Karsten Wiese3b354c52006-12-13 00:34:08 -08001863void ConfigMainWindow::conf_changed(void)
1864{
1865 if (saveAction)
1866 saveAction->setEnabled(conf_get_changed());
1867}
1868
Linus Torvalds1da177e2005-04-16 15:20:36 -07001869void fixup_rootmenu(struct menu *menu)
1870{
1871 struct menu *child;
1872 static int menu_cnt = 0;
1873
1874 menu->flags |= MENU_ROOT;
1875 for (child = menu->list; child; child = child->next) {
1876 if (child->prompt && child->prompt->type == P_MENU) {
1877 menu_cnt++;
1878 fixup_rootmenu(child);
1879 menu_cnt--;
1880 } else if (!menu_cnt)
1881 fixup_rootmenu(child);
1882 }
1883}
1884
1885static const char *progname;
1886
1887static void usage(void)
1888{
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001889 printf("%s [-s] <config>\n", progname);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001890 exit(0);
1891}
1892
1893int main(int ac, char** av)
1894{
1895 ConfigMainWindow* v;
1896 const char *name;
1897
Linus Torvalds1da177e2005-04-16 15:20:36 -07001898 progname = av[0];
1899 configApp = new QApplication(ac, av);
1900 if (ac > 1 && av[1][0] == '-') {
1901 switch (av[1][1]) {
Michal Marek0a1f00a2015-04-08 13:30:42 +02001902 case 's':
1903 conf_set_message_callback(NULL);
1904 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001905 case 'h':
1906 case '?':
1907 usage();
1908 }
1909 name = av[2];
1910 } else
1911 name = av[1];
1912 if (!name)
1913 usage();
1914
1915 conf_parse(name);
1916 fixup_rootmenu(&rootmenu);
1917 conf_read(NULL);
1918 //zconfdump(stdout);
1919
Roman Zippel7fc925f2006-06-08 22:12:46 -07001920 configSettings = new ConfigSettings();
1921 configSettings->beginGroup("/kconfig/qconf");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001922 v = new ConfigMainWindow();
1923
1924 //zconfdump(stdout);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001925 configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit()));
1926 configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings()));
Roman Zippel43bf6122006-06-08 22:12:45 -07001927 v->show();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001928 configApp->exec();
1929
Roman Zippel7fc925f2006-06-08 22:12:46 -07001930 configSettings->endGroup();
1931 delete configSettings;
Chris Bainbridge5b61c7b2016-01-08 20:44:04 +00001932 delete v;
1933 delete configApp;
Roman Zippel7fc925f2006-06-08 22:12:46 -07001934
Linus Torvalds1da177e2005-04-16 15:20:36 -07001935 return 0;
1936}