blob: 78087b2d9ac6728dd573f87a8e55181c8529c159 [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());
Randy Dunlap92f8a922021-04-17 22:51:23 -0700125 prompt = "*** " + prompt + " ***";
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700126 goto set_prompt;
127 default:
128 ;
129 }
130 if (!sym)
131 goto set_prompt;
132
Masahiro Yamada3c73ff02020-08-07 18:19:02 +0900133 setText(nameColIdx, sym->name);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700134
135 type = sym_get_type(sym);
136 switch (type) {
137 case S_BOOLEAN:
138 case S_TRISTATE:
139 char ch;
140
Marco Ammonbaa23ec2019-07-04 12:50:41 +0200141 if (!sym_is_changeable(sym) && list->optMode == normalOpt) {
Masahiro Yamada711b8752020-08-07 18:19:03 +0900142 setIcon(promptColIdx, QIcon());
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700143 break;
144 }
145 expr = sym_get_tristate_value(sym);
146 switch (expr) {
147 case yes:
148 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
Masahiro Yamada5cb255f2020-08-07 18:19:07 +0900149 setIcon(promptColIdx, choiceYesIcon);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700150 else
Masahiro Yamada5cb255f2020-08-07 18:19:07 +0900151 setIcon(promptColIdx, symbolYesIcon);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700152 ch = 'Y';
153 break;
154 case mod:
Masahiro Yamada5cb255f2020-08-07 18:19:07 +0900155 setIcon(promptColIdx, symbolModIcon);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700156 ch = 'M';
157 break;
158 default:
159 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
Masahiro Yamada5cb255f2020-08-07 18:19:07 +0900160 setIcon(promptColIdx, choiceNoIcon);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700161 else
Masahiro Yamada5cb255f2020-08-07 18:19:07 +0900162 setIcon(promptColIdx, symbolNoIcon);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700163 ch = 'N';
164 break;
165 }
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700166
167 setText(dataColIdx, QChar(ch));
168 break;
169 case S_INT:
170 case S_HEX:
171 case S_STRING:
Masahiro Yamada37162a62020-08-29 17:14:12 +0900172 setText(dataColIdx, sym_get_string_value(sym));
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700173 break;
174 }
175 if (!sym_has_value(sym) && visible)
Sam Ravnborg694c49a2018-05-22 21:36:12 +0200176 prompt += " (NEW)";
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700177set_prompt:
178 setText(promptColIdx, prompt);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700179}
180
181void ConfigItem::testUpdateMenu(bool v)
182{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700183 ConfigItem* i;
184
185 visible = v;
186 if (!menu)
187 return;
188
189 sym_calc_value(menu->sym);
190 if (menu->flags & MENU_CHANGED) {
191 /* the menu entry changed, so update all list items */
192 menu->flags &= ~MENU_CHANGED;
193 for (i = (ConfigItem*)menu->data; i; i = i->nextItem)
194 i->updateMenu();
195 } else if (listView()->updateAll)
196 updateMenu();
Boris Barbulovski59e56442015-09-22 11:36:18 -0700197}
198
199
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700200/*
201 * construct a menu entry
202 */
203void ConfigItem::init(void)
204{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700205 if (menu) {
206 ConfigList* list = listView();
207 nextItem = (ConfigItem*)menu->data;
208 menu->data = this;
209
210 if (list->mode != fullMode)
211 setExpanded(true);
212 sym_calc_value(menu->sym);
Masahiro Yamada37162a62020-08-29 17:14:12 +0900213
214 if (menu->sym) {
215 enum symbol_type type = menu->sym->type;
216
217 // Allow to edit "int", "hex", and "string" in-place in
218 // the data column. Unfortunately, you cannot specify
219 // the flags per column. Set ItemIsEditable for all
220 // columns here, and check the column in createEditor().
221 if (type == S_INT || type == S_HEX || type == S_STRING)
222 setFlags(flags() | Qt::ItemIsEditable);
223 }
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700224 }
225 updateMenu();
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700226}
227
228/*
229 * destruct a menu entry
230 */
231ConfigItem::~ConfigItem(void)
232{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700233 if (menu) {
234 ConfigItem** ip = (ConfigItem**)&menu->data;
235 for (; *ip; ip = &(*ip)->nextItem) {
236 if (*ip == this) {
237 *ip = nextItem;
238 break;
239 }
240 }
241 }
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700242}
243
Masahiro Yamada37162a62020-08-29 17:14:12 +0900244QWidget *ConfigItemDelegate::createEditor(QWidget *parent,
245 const QStyleOptionViewItem &option,
246 const QModelIndex &index) const
247{
248 ConfigItem *item;
249
250 // Only the data column is editable
251 if (index.column() != dataColIdx)
252 return nullptr;
253
254 // You cannot edit invisible menus
255 item = static_cast<ConfigItem *>(index.internalPointer());
256 if (!item || !item->menu || !menu_is_visible(item->menu))
257 return nullptr;
258
259 return QStyledItemDelegate::createEditor(parent, option, index);
260}
261
262void ConfigItemDelegate::setModelData(QWidget *editor,
263 QAbstractItemModel *model,
264 const QModelIndex &index) const
265{
266 QLineEdit *lineEdit;
267 ConfigItem *item;
268 struct symbol *sym;
269 bool success;
270
271 lineEdit = qobject_cast<QLineEdit *>(editor);
272 // If this is not a QLineEdit, use the parent's default.
273 // (does this happen?)
274 if (!lineEdit)
275 goto parent;
276
277 item = static_cast<ConfigItem *>(index.internalPointer());
278 if (!item || !item->menu)
279 goto parent;
280
281 sym = item->menu->sym;
282 if (!sym)
283 goto parent;
284
285 success = sym_set_string_value(sym, lineEdit->text().toUtf8().data());
286 if (success) {
287 ConfigList::updateListForAll();
288 } else {
289 QMessageBox::information(editor, "qconf",
290 "Cannot set the data (maybe due to out of range).\n"
291 "Setting the old value.");
292 lineEdit->setText(sym_get_string_value(sym));
293 }
294
295parent:
296 QStyledItemDelegate::setModelData(editor, model, index);
297}
298
Masahiro Yamada62ed1652020-08-29 17:14:15 +0900299ConfigList::ConfigList(QWidget *parent, const char *name)
300 : QTreeWidget(parent),
Boris Barbulovski59e56442015-09-22 11:36:18 -0700301 updateAll(false),
Masahiro Yamadaa0fce282020-08-29 17:14:16 +0900302 showName(false), mode(singleMode), optMode(normalOpt),
Boris Barbulovski59e56442015-09-22 11:36:18 -0700303 rootEntry(0), headerPopup(0)
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700304{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700305 setObjectName(name);
Boris Barbulovskia5225e92015-09-22 11:36:29 -0700306 setSortingEnabled(false);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700307 setRootIsDecorated(true);
308
Boris Barbulovskif999cc02015-09-22 11:36:31 -0700309 setVerticalScrollMode(ScrollPerPixel);
310 setHorizontalScrollMode(ScrollPerPixel);
311
Masahiro Yamadaa0fce282020-08-29 17:14:16 +0900312 setHeaderLabels(QStringList() << "Option" << "Name" << "Value");
Boris Barbulovskia52cb322015-09-22 11:36:24 -0700313
Masahiro Yamadaa2574c12020-10-24 21:38:41 +0900314 connect(this, &ConfigList::itemSelectionChanged,
315 this, &ConfigList::updateSelection);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700316
317 if (name) {
318 configSettings->beginGroup(name);
319 showName = configSettings->value("/showName", false).toBool();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700320 optMode = (enum optionMode)configSettings->value("/optionMode", 0).toInt();
321 configSettings->endGroup();
Masahiro Yamadaa2574c12020-10-24 21:38:41 +0900322 connect(configApp, &QApplication::aboutToQuit,
323 this, &ConfigList::saveSettings);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700324 }
325
Masahiro Yamadaabf741a2020-08-07 18:19:04 +0900326 showColumn(promptColIdx);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700327
Masahiro Yamada37162a62020-08-29 17:14:12 +0900328 setItemDelegate(new ConfigItemDelegate(this));
329
Masahiro Yamadaf9b918f2020-08-29 17:14:10 +0900330 allLists.append(this);
331
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700332 reinit();
333}
334
Masahiro Yamadaf9b918f2020-08-29 17:14:10 +0900335ConfigList::~ConfigList()
336{
337 allLists.removeOne(this);
338}
339
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700340bool ConfigList::menuSkip(struct menu *menu)
341{
342 if (optMode == normalOpt && menu_is_visible(menu))
343 return false;
344 if (optMode == promptOpt && menu_has_prompt(menu))
345 return false;
346 if (optMode == allOpt)
347 return false;
348 return true;
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700349}
Boris Barbulovski59e56442015-09-22 11:36:18 -0700350
351void ConfigList::reinit(void)
352{
Masahiro Yamadaabf741a2020-08-07 18:19:04 +0900353 hideColumn(nameColIdx);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700354
355 if (showName)
Masahiro Yamadaabf741a2020-08-07 18:19:04 +0900356 showColumn(nameColIdx);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700357
358 updateListAll();
Boris Barbulovski59e56442015-09-22 11:36:18 -0700359}
360
Masahiro Yamadad4bbe8a2020-08-07 18:19:09 +0900361void ConfigList::setOptionMode(QAction *action)
362{
363 if (action == showNormalAction)
364 optMode = normalOpt;
365 else if (action == showAllAction)
366 optMode = allOpt;
367 else
368 optMode = promptOpt;
369
370 updateListAll();
371}
372
Boris Barbulovski59e56442015-09-22 11:36:18 -0700373void ConfigList::saveSettings(void)
374{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700375 if (!objectName().isEmpty()) {
376 configSettings->beginGroup(objectName());
377 configSettings->setValue("/showName", showName);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700378 configSettings->setValue("/optionMode", (int)optMode);
379 configSettings->endGroup();
380 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700381}
382
383ConfigItem* ConfigList::findConfigItem(struct menu *menu)
384{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700385 ConfigItem* item = (ConfigItem*)menu->data;
386
387 for (; item; item = item->nextItem) {
388 if (this == item->listView())
389 break;
390 }
391
392 return item;
Boris Barbulovski59e56442015-09-22 11:36:18 -0700393}
394
395void ConfigList::updateSelection(void)
396{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700397 struct menu *menu;
398 enum prop_type type;
399
Boris Barbulovskibe596aa2015-09-22 11:36:28 -0700400 if (selectedItems().count() == 0)
401 return;
402
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700403 ConfigItem* item = (ConfigItem*)selectedItems().first();
404 if (!item)
405 return;
406
407 menu = item->menu;
408 emit menuChanged(menu);
409 if (!menu)
410 return;
411 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
412 if (mode == menuMode && type == P_MENU)
413 emit menuSelected(menu);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700414}
415
Masahiro Yamadacb770432020-08-07 18:18:59 +0900416void ConfigList::updateList()
Boris Barbulovski59e56442015-09-22 11:36:18 -0700417{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700418 ConfigItem* last = 0;
Masahiro Yamadacb770432020-08-07 18:18:59 +0900419 ConfigItem *item;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700420
421 if (!rootEntry) {
422 if (mode != listMode)
423 goto update;
424 QTreeWidgetItemIterator it(this);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700425
426 while (*it) {
427 item = (ConfigItem*)(*it);
428 if (!item->menu)
429 continue;
430 item->testUpdateMenu(menu_is_visible(item->menu));
431
432 ++it;
433 }
434 return;
435 }
436
437 if (rootEntry != &rootmenu && (mode == singleMode ||
438 (mode == symbolMode && rootEntry->parent != &rootmenu))) {
Boris Barbulovskiee7298f2015-09-22 11:36:37 -0700439 item = (ConfigItem *)topLevelItem(0);
Masahiro Yamada4b20e102020-08-01 16:08:49 +0900440 if (!item)
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700441 item = new ConfigItem(this, 0, true);
Masahiro Yamada4b20e102020-08-01 16:08:49 +0900442 last = item;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700443 }
444 if ((mode == singleMode || (mode == symbolMode && !(rootEntry->flags & MENU_ROOT))) &&
445 rootEntry->sym && rootEntry->prompt) {
Masahiro Yamadaccf56e52020-08-01 16:08:50 +0900446 item = last ? last->nextSibling() : nullptr;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700447 if (!item)
448 item = new ConfigItem(this, last, rootEntry, true);
449 else
450 item->testUpdateMenu(true);
451
452 updateMenuList(item, rootEntry);
453 update();
Boris Barbulovskif999cc02015-09-22 11:36:31 -0700454 resizeColumnToContents(0);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700455 return;
456 }
457update:
Masahiro Yamada5b75a6c2020-08-07 18:19:01 +0900458 updateMenuList(rootEntry);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700459 update();
Boris Barbulovskif999cc02015-09-22 11:36:31 -0700460 resizeColumnToContents(0);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700461}
462
Masahiro Yamadaf9b918f2020-08-29 17:14:10 +0900463void ConfigList::updateListForAll()
464{
465 QListIterator<ConfigList *> it(allLists);
466
467 while (it.hasNext()) {
468 ConfigList *list = it.next();
469
470 list->updateList();
471 }
472}
473
474void ConfigList::updateListAllForAll()
475{
476 QListIterator<ConfigList *> it(allLists);
477
478 while (it.hasNext()) {
479 ConfigList *list = it.next();
480
481 list->updateList();
482 }
483}
484
Boris Barbulovski59e56442015-09-22 11:36:18 -0700485void ConfigList::setValue(ConfigItem* item, tristate val)
486{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700487 struct symbol* sym;
488 int type;
489 tristate oldval;
490
491 sym = item->menu ? item->menu->sym : 0;
492 if (!sym)
493 return;
494
495 type = sym_get_type(sym);
496 switch (type) {
497 case S_BOOLEAN:
498 case S_TRISTATE:
499 oldval = sym_get_tristate_value(sym);
500
501 if (!sym_set_tristate_value(sym, val))
502 return;
503 if (oldval == no && item->menu->list)
504 item->setExpanded(true);
Masahiro Yamadaf9b918f2020-08-29 17:14:10 +0900505 ConfigList::updateListForAll();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700506 break;
507 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700508}
509
510void ConfigList::changeValue(ConfigItem* item)
511{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700512 struct symbol* sym;
513 struct menu* menu;
514 int type, oldexpr, newexpr;
515
516 menu = item->menu;
517 if (!menu)
518 return;
519 sym = menu->sym;
520 if (!sym) {
521 if (item->menu->list)
522 item->setExpanded(!item->isExpanded());
523 return;
524 }
525
526 type = sym_get_type(sym);
527 switch (type) {
528 case S_BOOLEAN:
529 case S_TRISTATE:
530 oldexpr = sym_get_tristate_value(sym);
531 newexpr = sym_toggle_tristate_value(sym);
532 if (item->menu->list) {
533 if (oldexpr == newexpr)
534 item->setExpanded(!item->isExpanded());
535 else if (oldexpr == no)
536 item->setExpanded(true);
537 }
538 if (oldexpr != newexpr)
Masahiro Yamadaf9b918f2020-08-29 17:14:10 +0900539 ConfigList::updateListForAll();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700540 break;
Masahiro Yamada37162a62020-08-29 17:14:12 +0900541 default:
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700542 break;
543 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700544}
545
546void ConfigList::setRootMenu(struct menu *menu)
547{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700548 enum prop_type type;
549
550 if (rootEntry == menu)
551 return;
552 type = menu && menu->prompt ? menu->prompt->type : P_UNKNOWN;
553 if (type != P_MENU)
554 return;
Masahiro Yamada5b75a6c2020-08-07 18:19:01 +0900555 updateMenuList(0);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700556 rootEntry = menu;
557 updateListAll();
558 if (currentItem()) {
Mauro Carvalho Chehabb06c3ec2020-06-30 08:26:38 +0200559 setSelected(currentItem(), hasFocus());
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700560 scrollToItem(currentItem());
561 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700562}
563
564void ConfigList::setParentMenu(void)
565{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700566 ConfigItem* item;
567 struct menu *oldroot;
568
569 oldroot = rootEntry;
570 if (rootEntry == &rootmenu)
571 return;
572 setRootMenu(menu_get_parent_menu(rootEntry->parent));
573
574 QTreeWidgetItemIterator it(this);
575 while (*it) {
576 item = (ConfigItem *)(*it);
577 if (item->menu == oldroot) {
578 setCurrentItem(item);
579 scrollToItem(item);
580 break;
581 }
582
583 ++it;
584 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700585}
586
587/*
588 * update all the children of a menu entry
589 * removes/adds the entries from the parent widget as necessary
590 *
591 * parent: either the menu list widget or a menu entry widget
592 * menu: entry to be updated
593 */
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700594void ConfigList::updateMenuList(ConfigItem *parent, struct menu* menu)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700595{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700596 struct menu* child;
597 ConfigItem* item;
598 ConfigItem* last;
599 bool visible;
600 enum prop_type type;
601
602 if (!menu) {
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700603 while (parent->childCount() > 0)
604 {
605 delete parent->takeChild(0);
606 }
607
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700608 return;
609 }
610
611 last = parent->firstChild();
612 if (last && !last->goParent)
613 last = 0;
614 for (child = menu->list; child; child = child->next) {
615 item = last ? last->nextSibling() : parent->firstChild();
616 type = child->prompt ? child->prompt->type : P_UNKNOWN;
617
618 switch (mode) {
619 case menuMode:
620 if (!(child->flags & MENU_ROOT))
621 goto hide;
622 break;
623 case symbolMode:
624 if (child->flags & MENU_ROOT)
625 goto hide;
626 break;
627 default:
628 break;
629 }
630
631 visible = menu_is_visible(child);
632 if (!menuSkip(child)) {
633 if (!child->sym && !child->list && !child->prompt)
634 continue;
635 if (!item || item->menu != child)
636 item = new ConfigItem(parent, last, child, visible);
637 else
638 item->testUpdateMenu(visible);
639
640 if (mode == fullMode || mode == menuMode || type != P_MENU)
641 updateMenuList(item, child);
642 else
643 updateMenuList(item, 0);
644 last = item;
645 continue;
646 }
Mauro Carvalho Chehab60969f02020-04-02 11:28:03 +0200647hide:
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700648 if (item && item->menu == child) {
649 last = parent->firstChild();
650 if (last == item)
651 last = 0;
652 else while (last->nextSibling() != item)
653 last = last->nextSibling();
654 delete item;
655 }
656 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700657}
658
Masahiro Yamada5b75a6c2020-08-07 18:19:01 +0900659void ConfigList::updateMenuList(struct menu *menu)
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700660{
661 struct menu* child;
662 ConfigItem* item;
663 ConfigItem* last;
664 bool visible;
665 enum prop_type type;
666
667 if (!menu) {
Masahiro Yamada5b75a6c2020-08-07 18:19:01 +0900668 while (topLevelItemCount() > 0)
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700669 {
Masahiro Yamada5b75a6c2020-08-07 18:19:01 +0900670 delete takeTopLevelItem(0);
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700671 }
672
673 return;
674 }
675
Masahiro Yamada5b75a6c2020-08-07 18:19:01 +0900676 last = (ConfigItem *)topLevelItem(0);
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700677 if (last && !last->goParent)
678 last = 0;
679 for (child = menu->list; child; child = child->next) {
Masahiro Yamada5b75a6c2020-08-07 18:19:01 +0900680 item = last ? last->nextSibling() : (ConfigItem *)topLevelItem(0);
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700681 type = child->prompt ? child->prompt->type : P_UNKNOWN;
682
683 switch (mode) {
684 case menuMode:
685 if (!(child->flags & MENU_ROOT))
686 goto hide;
687 break;
688 case symbolMode:
689 if (child->flags & MENU_ROOT)
690 goto hide;
691 break;
692 default:
693 break;
694 }
695
696 visible = menu_is_visible(child);
697 if (!menuSkip(child)) {
698 if (!child->sym && !child->list && !child->prompt)
699 continue;
700 if (!item || item->menu != child)
Masahiro Yamada5b75a6c2020-08-07 18:19:01 +0900701 item = new ConfigItem(this, last, child, visible);
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700702 else
703 item->testUpdateMenu(visible);
704
705 if (mode == fullMode || mode == menuMode || type != P_MENU)
706 updateMenuList(item, child);
707 else
708 updateMenuList(item, 0);
709 last = item;
710 continue;
711 }
Mauro Carvalho Chehab60969f02020-04-02 11:28:03 +0200712hide:
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700713 if (item && item->menu == child) {
Masahiro Yamada5b75a6c2020-08-07 18:19:01 +0900714 last = (ConfigItem *)topLevelItem(0);
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700715 if (last == item)
716 last = 0;
717 else while (last->nextSibling() != item)
718 last = last->nextSibling();
719 delete item;
720 }
721 }
722}
723
Boris Barbulovski59e56442015-09-22 11:36:18 -0700724void ConfigList::keyPressEvent(QKeyEvent* ev)
725{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700726 QTreeWidgetItem* i = currentItem();
727 ConfigItem* item;
728 struct menu *menu;
729 enum prop_type type;
730
731 if (ev->key() == Qt::Key_Escape && mode != fullMode && mode != listMode) {
732 emit parentSelected();
733 ev->accept();
734 return;
735 }
736
737 if (!i) {
738 Parent::keyPressEvent(ev);
739 return;
740 }
741 item = (ConfigItem*)i;
742
743 switch (ev->key()) {
744 case Qt::Key_Return:
745 case Qt::Key_Enter:
746 if (item->goParent) {
747 emit parentSelected();
748 break;
749 }
750 menu = item->menu;
751 if (!menu)
752 break;
753 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
754 if (type == P_MENU && rootEntry != menu &&
755 mode != fullMode && mode != menuMode) {
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +0200756 if (mode == menuMode)
757 emit menuSelected(menu);
758 else
759 emit itemSelected(menu);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700760 break;
761 }
762 case Qt::Key_Space:
763 changeValue(item);
764 break;
765 case Qt::Key_N:
766 setValue(item, no);
767 break;
768 case Qt::Key_M:
769 setValue(item, mod);
770 break;
771 case Qt::Key_Y:
772 setValue(item, yes);
773 break;
774 default:
775 Parent::keyPressEvent(ev);
776 return;
777 }
778 ev->accept();
Boris Barbulovski59e56442015-09-22 11:36:18 -0700779}
780
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700781void ConfigList::mousePressEvent(QMouseEvent* e)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700782{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700783 //QPoint p(contentsToViewport(e->pos()));
784 //printf("contentsMousePressEvent: %d,%d\n", p.x(), p.y());
785 Parent::mousePressEvent(e);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700786}
787
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700788void ConfigList::mouseReleaseEvent(QMouseEvent* e)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700789{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700790 QPoint p = e->pos();
791 ConfigItem* item = (ConfigItem*)itemAt(p);
792 struct menu *menu;
793 enum prop_type ptype;
794 QIcon icon;
795 int idx, x;
796
797 if (!item)
798 goto skip;
799
800 menu = item->menu;
801 x = header()->offset() + p.x();
Boris Barbulovski76d53cb2015-09-22 11:36:35 -0700802 idx = header()->logicalIndexAt(x);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700803 switch (idx) {
804 case promptColIdx:
Masahiro Yamada711b8752020-08-07 18:19:03 +0900805 icon = item->icon(promptColIdx);
Boris Barbulovski76d53cb2015-09-22 11:36:35 -0700806 if (!icon.isNull()) {
807 int off = header()->sectionPosition(0) + visualRect(indexAt(p)).x() + 4; // 4 is Hardcoded image offset. There might be a way to do it properly.
808 if (x >= off && x < off + icon.availableSizes().first().width()) {
809 if (item->goParent) {
810 emit parentSelected();
811 break;
812 } else if (!menu)
813 break;
814 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
815 if (ptype == P_MENU && rootEntry != menu &&
Maxime Chretien7eb7c106f2020-07-08 15:32:15 +0200816 mode != fullMode && mode != menuMode &&
817 mode != listMode)
Boris Barbulovski76d53cb2015-09-22 11:36:35 -0700818 emit menuSelected(menu);
819 else
820 changeValue(item);
821 }
822 }
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700823 break;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700824 case dataColIdx:
825 changeValue(item);
826 break;
827 }
828
829skip:
830 //printf("contentsMouseReleaseEvent: %d,%d\n", p.x(), p.y());
831 Parent::mouseReleaseEvent(e);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700832}
833
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700834void ConfigList::mouseMoveEvent(QMouseEvent* e)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700835{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700836 //QPoint p(contentsToViewport(e->pos()));
837 //printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y());
838 Parent::mouseMoveEvent(e);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700839}
840
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700841void ConfigList::mouseDoubleClickEvent(QMouseEvent* e)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700842{
Mauro Carvalho Chehabe1f77692020-04-02 11:28:02 +0200843 QPoint p = e->pos();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700844 ConfigItem* item = (ConfigItem*)itemAt(p);
845 struct menu *menu;
846 enum prop_type ptype;
847
848 if (!item)
849 goto skip;
850 if (item->goParent) {
851 emit parentSelected();
852 goto skip;
853 }
854 menu = item->menu;
855 if (!menu)
856 goto skip;
857 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
Maxime Chretien7eb7c106f2020-07-08 15:32:15 +0200858 if (ptype == P_MENU && mode != listMode) {
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +0200859 if (mode == singleMode)
860 emit itemSelected(menu);
861 else if (mode == symbolMode)
862 emit menuSelected(menu);
863 } else if (menu->sym)
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700864 changeValue(item);
865
866skip:
867 //printf("contentsMouseDoubleClickEvent: %d,%d\n", p.x(), p.y());
868 Parent::mouseDoubleClickEvent(e);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700869}
870
871void ConfigList::focusInEvent(QFocusEvent *e)
872{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700873 struct menu *menu = NULL;
874
875 Parent::focusInEvent(e);
876
877 ConfigItem* item = (ConfigItem *)currentItem();
878 if (item) {
Mauro Carvalho Chehabb06c3ec2020-06-30 08:26:38 +0200879 setSelected(item, true);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700880 menu = item->menu;
881 }
882 emit gotFocus(menu);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700883}
884
885void ConfigList::contextMenuEvent(QContextMenuEvent *e)
886{
Masahiro Yamadafa8de0a2020-08-07 18:19:08 +0900887 if (!headerPopup) {
888 QAction *action;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700889
Masahiro Yamadafa8de0a2020-08-07 18:19:08 +0900890 headerPopup = new QMenu(this);
891 action = new QAction("Show Name", this);
892 action->setCheckable(true);
Masahiro Yamadaa2574c12020-10-24 21:38:41 +0900893 connect(action, &QAction::toggled,
894 this, &ConfigList::setShowName);
895 connect(this, &ConfigList::showNameChanged,
896 action, &QAction::setChecked);
Masahiro Yamadafa8de0a2020-08-07 18:19:08 +0900897 action->setChecked(showName);
898 headerPopup->addAction(action);
Masahiro Yamadafa8de0a2020-08-07 18:19:08 +0900899 }
900
901 headerPopup->exec(e->globalPos());
902 e->accept();
Boris Barbulovski59e56442015-09-22 11:36:18 -0700903}
904
Masahiro Yamada7930dd92020-08-29 17:14:14 +0900905void ConfigList::setShowName(bool on)
906{
907 if (showName == on)
908 return;
909
910 showName = on;
911 reinit();
912 emit showNameChanged(on);
913}
914
Masahiro Yamadaf9b918f2020-08-29 17:14:10 +0900915QList<ConfigList *> ConfigList::allLists;
Masahiro Yamadad4bbe8a2020-08-07 18:19:09 +0900916QAction *ConfigList::showNormalAction;
917QAction *ConfigList::showAllAction;
918QAction *ConfigList::showPromptAction;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700919
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700920void ConfigList::setAllOpen(bool open)
921{
922 QTreeWidgetItemIterator it(this);
923
924 while (*it) {
925 (*it)->setExpanded(open);
926
927 ++it;
928 }
Roman Zippel7fc925f2006-06-08 22:12:46 -0700929}
930
Roman Zippel43bf6122006-06-08 22:12:45 -0700931ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name)
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -0700932 : Parent(parent), sym(0), _menu(0)
Roman Zippel43bf6122006-06-08 22:12:45 -0700933{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700934 setObjectName(name);
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +0200935 setOpenLinks(false);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700936
937 if (!objectName().isEmpty()) {
938 configSettings->beginGroup(objectName());
Boris Barbulovskie0393032016-11-30 14:57:52 -0800939 setShowDebug(configSettings->value("/showDebug", false).toBool());
Roman Zippel7fc925f2006-06-08 22:12:46 -0700940 configSettings->endGroup();
Masahiro Yamadaa2574c12020-10-24 21:38:41 +0900941 connect(configApp, &QApplication::aboutToQuit,
942 this, &ConfigInfoView::saveSettings);
Roman Zippel7fc925f2006-06-08 22:12:46 -0700943 }
Masahiro Yamada7d1300e2020-08-18 01:36:30 +0900944
945 contextMenu = createStandardContextMenu();
946 QAction *action = new QAction("Show Debug Info", contextMenu);
947
948 action->setCheckable(true);
Masahiro Yamadaa2574c12020-10-24 21:38:41 +0900949 connect(action, &QAction::toggled,
950 this, &ConfigInfoView::setShowDebug);
951 connect(this, &ConfigInfoView::showDebugChanged,
952 action, &QAction::setChecked);
Masahiro Yamada7d1300e2020-08-18 01:36:30 +0900953 action->setChecked(showDebug());
954 contextMenu->addSeparator();
955 contextMenu->addAction(action);
Roman Zippel7fc925f2006-06-08 22:12:46 -0700956}
957
958void ConfigInfoView::saveSettings(void)
959{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700960 if (!objectName().isEmpty()) {
961 configSettings->beginGroup(objectName());
962 configSettings->setValue("/showDebug", showDebug());
963 configSettings->endGroup();
964 }
Roman Zippel43bf6122006-06-08 22:12:45 -0700965}
966
967void ConfigInfoView::setShowDebug(bool b)
968{
969 if (_showDebug != b) {
970 _showDebug = b;
Alexander Stein133c5f72010-08-31 17:34:37 +0200971 if (_menu)
Roman Zippel43bf6122006-06-08 22:12:45 -0700972 menuInfo();
Roman Zippelab45d192006-06-08 22:12:47 -0700973 else if (sym)
974 symbolInfo();
Roman Zippel43bf6122006-06-08 22:12:45 -0700975 emit showDebugChanged(b);
976 }
977}
978
979void ConfigInfoView::setInfo(struct menu *m)
980{
Alexander Stein133c5f72010-08-31 17:34:37 +0200981 if (_menu == m)
Roman Zippelb65a47e2006-06-08 22:12:47 -0700982 return;
Alexander Stein133c5f72010-08-31 17:34:37 +0200983 _menu = m;
Roman Zippel6fa1da82007-01-10 23:15:31 -0800984 sym = NULL;
Alexander Stein133c5f72010-08-31 17:34:37 +0200985 if (!_menu)
Roman Zippel43bf6122006-06-08 22:12:45 -0700986 clear();
Roman Zippel6fa1da82007-01-10 23:15:31 -0800987 else
Roman Zippel43bf6122006-06-08 22:12:45 -0700988 menuInfo();
989}
990
Roman Zippelab45d192006-06-08 22:12:47 -0700991void ConfigInfoView::symbolInfo(void)
992{
993 QString str;
994
995 str += "<big>Symbol: <b>";
996 str += print_filter(sym->name);
997 str += "</b></big><br><br>value: ";
998 str += print_filter(sym_get_string_value(sym));
999 str += "<br>visibility: ";
1000 str += sym->visible == yes ? "y" : sym->visible == mod ? "m" : "n";
1001 str += "<br>";
1002 str += debug_info(sym);
1003
1004 setText(str);
1005}
1006
Roman Zippel43bf6122006-06-08 22:12:45 -07001007void ConfigInfoView::menuInfo(void)
1008{
1009 struct symbol* sym;
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001010 QString info;
1011 QTextStream stream(&info);
Roman Zippel43bf6122006-06-08 22:12:45 -07001012
Alexander Stein133c5f72010-08-31 17:34:37 +02001013 sym = _menu->sym;
Roman Zippel43bf6122006-06-08 22:12:45 -07001014 if (sym) {
Alexander Stein133c5f72010-08-31 17:34:37 +02001015 if (_menu->prompt) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001016 stream << "<big><b>";
1017 stream << print_filter(_menu->prompt->text);
1018 stream << "</b></big>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001019 if (sym->name) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001020 stream << " (";
Roman Zippelab45d192006-06-08 22:12:47 -07001021 if (showDebug())
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001022 stream << "<a href=\"s" << sym->name << "\">";
1023 stream << print_filter(sym->name);
Roman Zippelab45d192006-06-08 22:12:47 -07001024 if (showDebug())
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001025 stream << "</a>";
1026 stream << ")";
Roman Zippel43bf6122006-06-08 22:12:45 -07001027 }
1028 } else if (sym->name) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001029 stream << "<big><b>";
Roman Zippelab45d192006-06-08 22:12:47 -07001030 if (showDebug())
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001031 stream << "<a href=\"s" << sym->name << "\">";
1032 stream << print_filter(sym->name);
Roman Zippelab45d192006-06-08 22:12:47 -07001033 if (showDebug())
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001034 stream << "</a>";
1035 stream << "</b></big>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001036 }
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001037 stream << "<br><br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001038
1039 if (showDebug())
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001040 stream << debug_info(sym);
1041
Masahiro Yamadaa46afd12020-09-14 23:59:48 +09001042 struct gstr help_gstr = str_new();
1043
1044 menu_get_ext_help(_menu, &help_gstr);
1045 stream << print_filter(str_get(&help_gstr));
1046 str_free(&help_gstr);
Alexander Stein133c5f72010-08-31 17:34:37 +02001047 } else if (_menu->prompt) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001048 stream << "<big><b>";
1049 stream << print_filter(_menu->prompt->text);
1050 stream << "</b></big><br><br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001051 if (showDebug()) {
Alexander Stein133c5f72010-08-31 17:34:37 +02001052 if (_menu->prompt->visible.expr) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001053 stream << "&nbsp;&nbsp;dep: ";
1054 expr_print(_menu->prompt->visible.expr,
1055 expr_print_help, &stream, E_NONE);
1056 stream << "<br><br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001057 }
Masahiro Yamadaa46afd12020-09-14 23:59:48 +09001058
1059 stream << "defined at " << _menu->file->name << ":"
1060 << _menu->lineno << "<br><br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001061 }
1062 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001063
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001064 setText(info);
Roman Zippel43bf6122006-06-08 22:12:45 -07001065}
1066
1067QString ConfigInfoView::debug_info(struct symbol *sym)
1068{
1069 QString debug;
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001070 QTextStream stream(&debug);
Roman Zippel43bf6122006-06-08 22:12:45 -07001071
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001072 stream << "type: ";
1073 stream << print_filter(sym_type_name(sym->type));
Roman Zippel43bf6122006-06-08 22:12:45 -07001074 if (sym_is_choice(sym))
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001075 stream << " (choice)";
Roman Zippel43bf6122006-06-08 22:12:45 -07001076 debug += "<br>";
1077 if (sym->rev_dep.expr) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001078 stream << "reverse dep: ";
1079 expr_print(sym->rev_dep.expr, expr_print_help, &stream, E_NONE);
1080 stream << "<br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001081 }
1082 for (struct property *prop = sym->prop; prop; prop = prop->next) {
1083 switch (prop->type) {
1084 case P_PROMPT:
1085 case P_MENU:
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001086 stream << "prompt: <a href=\"m" << sym->name << "\">";
1087 stream << print_filter(prop->text);
1088 stream << "</a><br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001089 break;
1090 case P_DEFAULT:
Roman Zippel93449082008-01-14 04:50:54 +01001091 case P_SELECT:
1092 case P_RANGE:
Mauro Carvalho Chehab8f8499a2020-06-30 08:48:53 +02001093 case P_COMMENT:
1094 case P_IMPLY:
1095 case P_SYMBOL:
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001096 stream << prop_get_type_name(prop->type);
1097 stream << ": ";
1098 expr_print(prop->expr, expr_print_help,
1099 &stream, E_NONE);
1100 stream << "<br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001101 break;
1102 case P_CHOICE:
1103 if (sym_is_choice(sym)) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001104 stream << "choice: ";
1105 expr_print(prop->expr, expr_print_help,
1106 &stream, E_NONE);
1107 stream << "<br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001108 }
1109 break;
Roman Zippel43bf6122006-06-08 22:12:45 -07001110 default:
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001111 stream << "unknown property: ";
1112 stream << prop_get_type_name(prop->type);
1113 stream << "<br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001114 }
1115 if (prop->visible.expr) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001116 stream << "&nbsp;&nbsp;&nbsp;&nbsp;dep: ";
1117 expr_print(prop->visible.expr, expr_print_help,
1118 &stream, E_NONE);
1119 stream << "<br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001120 }
1121 }
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001122 stream << "<br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001123
1124 return debug;
1125}
1126
1127QString ConfigInfoView::print_filter(const QString &str)
1128{
1129 QRegExp re("[<>&\"\\n]");
1130 QString res = str;
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001131 for (int i = 0; (i = res.indexOf(re, i)) >= 0;) {
1132 switch (res[i].toLatin1()) {
Roman Zippel43bf6122006-06-08 22:12:45 -07001133 case '<':
1134 res.replace(i, 1, "&lt;");
1135 i += 4;
1136 break;
1137 case '>':
1138 res.replace(i, 1, "&gt;");
1139 i += 4;
1140 break;
1141 case '&':
1142 res.replace(i, 1, "&amp;");
1143 i += 5;
1144 break;
1145 case '"':
1146 res.replace(i, 1, "&quot;");
1147 i += 6;
1148 break;
1149 case '\n':
1150 res.replace(i, 1, "<br>");
1151 i += 4;
1152 break;
1153 }
1154 }
1155 return res;
1156}
1157
Roman Zippelab45d192006-06-08 22:12:47 -07001158void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char *str)
Roman Zippel43bf6122006-06-08 22:12:45 -07001159{
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001160 QTextStream *stream = reinterpret_cast<QTextStream *>(data);
Roman Zippelab45d192006-06-08 22:12:47 -07001161
1162 if (sym && sym->name && !(sym->flags & SYMBOL_CONST)) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001163 *stream << "<a href=\"s" << sym->name << "\">";
1164 *stream << print_filter(str);
1165 *stream << "</a>";
1166 } else {
1167 *stream << print_filter(str);
1168 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001169}
1170
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001171void ConfigInfoView::clicked(const QUrl &url)
1172{
1173 QByteArray str = url.toEncoded();
1174 const std::size_t count = str.size();
1175 char *data = new char[count + 1];
1176 struct symbol **result;
1177 struct menu *m = NULL;
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001178
1179 if (count < 1) {
Masahiro Yamadac9b09a922020-07-30 02:02:39 +09001180 delete[] data;
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001181 return;
1182 }
1183
1184 memcpy(data, str.constData(), count);
1185 data[count] = '\0';
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001186
1187 /* Seek for exact match */
1188 data[0] = '^';
1189 strcat(data, "$");
1190 result = sym_re_search(data);
1191 if (!result) {
Masahiro Yamadac9b09a922020-07-30 02:02:39 +09001192 delete[] data;
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001193 return;
1194 }
1195
1196 sym = *result;
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001197
Mauro Carvalho Chehab8a3b6e52020-06-30 08:48:35 +02001198 /* Seek for the menu which holds the symbol */
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001199 for (struct property *prop = sym->prop; prop; prop = prop->next) {
1200 if (prop->type != P_PROMPT && prop->type != P_MENU)
1201 continue;
1202 m = prop->menu;
1203 break;
1204 }
1205
1206 if (!m) {
Mauro Carvalho Chehab8a3b6e52020-06-30 08:48:35 +02001207 /* Symbol is not visible as a menu */
1208 symbolInfo();
1209 emit showDebugChanged(true);
1210 } else {
1211 emit menuSelected(m);
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001212 }
1213
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001214 free(result);
Masahiro Yamadaa608b6a2020-09-09 07:16:37 +09001215 delete[] data;
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001216}
1217
Masahiro Yamada7d1300e2020-08-18 01:36:30 +09001218void ConfigInfoView::contextMenuEvent(QContextMenuEvent *event)
Roman Zippel7fc925f2006-06-08 22:12:46 -07001219{
Masahiro Yamada7d1300e2020-08-18 01:36:30 +09001220 contextMenu->popup(event->globalPos());
1221 event->accept();
Roman Zippel7fc925f2006-06-08 22:12:46 -07001222}
1223
Masahiro Yamada740fdef2020-08-07 18:18:57 +09001224ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow *parent)
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001225 : Parent(parent), result(NULL)
Roman Zippel43bf6122006-06-08 22:12:45 -07001226{
Masahiro Yamada740fdef2020-08-07 18:18:57 +09001227 setObjectName("search");
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001228 setWindowTitle("Search Config");
Roman Zippel43bf6122006-06-08 22:12:45 -07001229
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001230 QVBoxLayout* layout1 = new QVBoxLayout(this);
1231 layout1->setContentsMargins(11, 11, 11, 11);
1232 layout1->setSpacing(6);
Masahiro Yamada92641152020-08-07 18:18:58 +09001233
1234 QHBoxLayout* layout2 = new QHBoxLayout();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001235 layout2->setContentsMargins(0, 0, 0, 0);
1236 layout2->setSpacing(6);
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001237 layout2->addWidget(new QLabel("Find:", this));
Roman Zippel43bf6122006-06-08 22:12:45 -07001238 editField = new QLineEdit(this);
Masahiro Yamadaa2574c12020-10-24 21:38:41 +09001239 connect(editField, &QLineEdit::returnPressed,
1240 this, &ConfigSearchWindow::search);
Roman Zippel43bf6122006-06-08 22:12:45 -07001241 layout2->addWidget(editField);
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001242 searchButton = new QPushButton("Search", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001243 searchButton->setAutoDefault(false);
Masahiro Yamadaa2574c12020-10-24 21:38:41 +09001244 connect(searchButton, &QPushButton::clicked,
1245 this, &ConfigSearchWindow::search);
Roman Zippel43bf6122006-06-08 22:12:45 -07001246 layout2->addWidget(searchButton);
1247 layout1->addLayout(layout2);
1248
Roman Zippel7fc925f2006-06-08 22:12:46 -07001249 split = new QSplitter(this);
Markus Heidelberg7298b932009-05-18 01:36:50 +02001250 split->setOrientation(Qt::Vertical);
Masahiro Yamada62ed1652020-08-29 17:14:15 +09001251 list = new ConfigList(split, "search");
1252 list->mode = listMode;
Masahiro Yamada740fdef2020-08-07 18:18:57 +09001253 info = new ConfigInfoView(split, "search");
Masahiro Yamadaa2574c12020-10-24 21:38:41 +09001254 connect(list, &ConfigList::menuChanged,
1255 info, &ConfigInfoView::setInfo);
1256 connect(list, &ConfigList::menuChanged,
1257 parent, &ConfigMainWindow::setMenuLink);
Marco Costalba63431e72006-10-05 19:12:59 +02001258
Roman Zippel43bf6122006-06-08 22:12:45 -07001259 layout1->addWidget(split);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001260
Masahiro Yamada740fdef2020-08-07 18:18:57 +09001261 QVariant x, y;
1262 int width, height;
1263 bool ok;
Roman Zippel7fc925f2006-06-08 22:12:46 -07001264
Masahiro Yamada740fdef2020-08-07 18:18:57 +09001265 configSettings->beginGroup("search");
1266 width = configSettings->value("/window width", parent->width() / 2).toInt();
1267 height = configSettings->value("/window height", parent->height() / 2).toInt();
1268 resize(width, height);
1269 x = configSettings->value("/window x");
1270 y = configSettings->value("/window y");
1271 if (x.isValid() && y.isValid())
1272 move(x.toInt(), y.toInt());
1273 QList<int> sizes = configSettings->readSizes("/split", &ok);
1274 if (ok)
1275 split->setSizes(sizes);
1276 configSettings->endGroup();
Masahiro Yamadaa2574c12020-10-24 21:38:41 +09001277 connect(configApp, &QApplication::aboutToQuit,
1278 this, &ConfigSearchWindow::saveSettings);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001279}
1280
1281void ConfigSearchWindow::saveSettings(void)
1282{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001283 if (!objectName().isEmpty()) {
1284 configSettings->beginGroup(objectName());
1285 configSettings->setValue("/window x", pos().x());
1286 configSettings->setValue("/window y", pos().y());
1287 configSettings->setValue("/window width", size().width());
1288 configSettings->setValue("/window height", size().height());
1289 configSettings->writeSizes("/split", split->sizes());
1290 configSettings->endGroup();
1291 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001292}
1293
1294void ConfigSearchWindow::search(void)
1295{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001296 struct symbol **p;
1297 struct property *prop;
1298 ConfigItem *lastItem = NULL;
1299
1300 free(result);
Masahiro Yamada62ed1652020-08-29 17:14:15 +09001301 list->clear();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001302 info->clear();
1303
1304 result = sym_re_search(editField->text().toLatin1());
1305 if (!result)
1306 return;
1307 for (p = result; *p; p++) {
1308 for_all_prompts((*p), prop)
Masahiro Yamada62ed1652020-08-29 17:14:15 +09001309 lastItem = new ConfigItem(list, lastItem, prop->menu,
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001310 menu_is_visible(prop->menu));
1311 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001312}
1313
Linus Torvalds1da177e2005-04-16 15:20:36 -07001314/*
1315 * Construct the complete config widget
1316 */
1317ConfigMainWindow::ConfigMainWindow(void)
Roman Zippelf12aa702006-11-25 11:09:31 -08001318 : searchWindow(0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001319{
Boris Barbulovski92119932015-09-22 11:36:16 -07001320 bool ok = true;
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001321 QVariant x, y;
1322 int width, height;
Randy Dunlapa54bb702007-10-20 11:18:47 -07001323 char title[256];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001324
Markus Heidelberg8d90c972009-05-18 01:36:52 +02001325 QDesktopWidget *d = configApp->desktop();
Arnaud Lacombe09548282010-08-18 01:57:13 -04001326 snprintf(title, sizeof(title), "%s%s",
1327 rootmenu.prompt->text,
Michal Marek76a136c2010-09-01 17:39:27 +02001328 ""
Michal Marek76a136c2010-09-01 17:39:27 +02001329 );
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001330 setWindowTitle(title);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001331
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001332 width = configSettings->value("/window width", d->width() - 64).toInt();
1333 height = configSettings->value("/window height", d->height() - 64).toInt();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001334 resize(width, height);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001335 x = configSettings->value("/window x");
1336 y = configSettings->value("/window y");
1337 if ((x.isValid())&&(y.isValid()))
1338 move(x.toInt(), y.toInt());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001339
Masahiro Yamada5cb255f2020-08-07 18:19:07 +09001340 // set up icons
1341 ConfigItem::symbolYesIcon = QIcon(QPixmap(xpm_symbol_yes));
1342 ConfigItem::symbolModIcon = QIcon(QPixmap(xpm_symbol_mod));
1343 ConfigItem::symbolNoIcon = QIcon(QPixmap(xpm_symbol_no));
1344 ConfigItem::choiceYesIcon = QIcon(QPixmap(xpm_choice_yes));
1345 ConfigItem::choiceNoIcon = QIcon(QPixmap(xpm_choice_no));
1346 ConfigItem::menuIcon = QIcon(QPixmap(xpm_menu));
1347 ConfigItem::menubackIcon = QIcon(QPixmap(xpm_menuback));
1348
Mauro Carvalho Chehabcce1fab2020-04-02 11:28:00 +02001349 QWidget *widget = new QWidget(this);
1350 QVBoxLayout *layout = new QVBoxLayout(widget);
1351 setCentralWidget(widget);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001352
Mauro Carvalho Chehabcce1fab2020-04-02 11:28:00 +02001353 split1 = new QSplitter(widget);
1354 split1->setOrientation(Qt::Horizontal);
1355 split1->setChildrenCollapsible(false);
1356
Masahiro Yamada62ed1652020-08-29 17:14:15 +09001357 menuList = new ConfigList(widget, "menu");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001358
Mauro Carvalho Chehabcce1fab2020-04-02 11:28:00 +02001359 split2 = new QSplitter(widget);
1360 split2->setChildrenCollapsible(false);
Markus Heidelberg7298b932009-05-18 01:36:50 +02001361 split2->setOrientation(Qt::Vertical);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001362
1363 // create config tree
Masahiro Yamada62ed1652020-08-29 17:14:15 +09001364 configList = new ConfigList(widget, "config");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001365
Mauro Carvalho Chehabcce1fab2020-04-02 11:28:00 +02001366 helpText = new ConfigInfoView(widget, "help");
1367
1368 layout->addWidget(split2);
1369 split2->addWidget(split1);
Masahiro Yamada62ed1652020-08-29 17:14:15 +09001370 split1->addWidget(configList);
1371 split1->addWidget(menuList);
Mauro Carvalho Chehabcce1fab2020-04-02 11:28:00 +02001372 split2->addWidget(helpText);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001373
1374 setTabOrder(configList, helpText);
1375 configList->setFocus();
1376
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001377 backAction = new QAction(QPixmap(xpm_back), "Back", this);
Masahiro Yamadaa2574c12020-10-24 21:38:41 +09001378 connect(backAction, &QAction::triggered,
1379 this, &ConfigMainWindow::goBack);
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001380
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001381 QAction *quitAction = new QAction("&Quit", this);
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001382 quitAction->setShortcut(Qt::CTRL + Qt::Key_Q);
Masahiro Yamadaa2574c12020-10-24 21:38:41 +09001383 connect(quitAction, &QAction::triggered,
1384 this, &ConfigMainWindow::close);
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001385
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001386 QAction *loadAction = new QAction(QPixmap(xpm_load), "&Load", this);
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001387 loadAction->setShortcut(Qt::CTRL + Qt::Key_L);
Masahiro Yamadaa2574c12020-10-24 21:38:41 +09001388 connect(loadAction, &QAction::triggered,
1389 this, &ConfigMainWindow::loadConfig);
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001390
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001391 saveAction = new QAction(QPixmap(xpm_save), "&Save", this);
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001392 saveAction->setShortcut(Qt::CTRL + Qt::Key_S);
Masahiro Yamadaa2574c12020-10-24 21:38:41 +09001393 connect(saveAction, &QAction::triggered,
1394 this, &ConfigMainWindow::saveConfig);
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001395
Karsten Wiese3b354c52006-12-13 00:34:08 -08001396 conf_set_changed_callback(conf_changed);
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001397
Karsten Wiese3b354c52006-12-13 00:34:08 -08001398 // Set saveAction's initial state
1399 conf_changed();
Masahiro Yamada87419082019-03-11 01:13:15 +09001400 configname = xstrdup(conf_get_configname());
1401
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001402 QAction *saveAsAction = new QAction("Save &As...", this);
Masahiro Yamadaa2574c12020-10-24 21:38:41 +09001403 connect(saveAsAction, &QAction::triggered,
1404 this, &ConfigMainWindow::saveConfigAs);
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001405 QAction *searchAction = new QAction("&Find", this);
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001406 searchAction->setShortcut(Qt::CTRL + Qt::Key_F);
Masahiro Yamadaa2574c12020-10-24 21:38:41 +09001407 connect(searchAction, &QAction::triggered,
1408 this, &ConfigMainWindow::searchConfig);
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001409 singleViewAction = new QAction(QPixmap(xpm_single_view), "Single View", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001410 singleViewAction->setCheckable(true);
Masahiro Yamadaa2574c12020-10-24 21:38:41 +09001411 connect(singleViewAction, &QAction::triggered,
1412 this, &ConfigMainWindow::showSingleView);
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001413 splitViewAction = new QAction(QPixmap(xpm_split_view), "Split View", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001414 splitViewAction->setCheckable(true);
Masahiro Yamadaa2574c12020-10-24 21:38:41 +09001415 connect(splitViewAction, &QAction::triggered,
1416 this, &ConfigMainWindow::showSplitView);
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001417 fullViewAction = new QAction(QPixmap(xpm_tree_view), "Full View", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001418 fullViewAction->setCheckable(true);
Masahiro Yamadaa2574c12020-10-24 21:38:41 +09001419 connect(fullViewAction, &QAction::triggered,
1420 this, &ConfigMainWindow::showFullView);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001421
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001422 QAction *showNameAction = new QAction("Show Name", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001423 showNameAction->setCheckable(true);
Masahiro Yamadaa2574c12020-10-24 21:38:41 +09001424 connect(showNameAction, &QAction::toggled,
1425 configList, &ConfigList::setShowName);
Masahiro Yamada7930dd92020-08-29 17:14:14 +09001426 showNameAction->setChecked(configList->showName);
1427
Li Zefan39a48972010-05-10 16:33:41 +08001428 QActionGroup *optGroup = new QActionGroup(this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001429 optGroup->setExclusive(true);
Masahiro Yamadaa2574c12020-10-24 21:38:41 +09001430 connect(optGroup, &QActionGroup::triggered,
1431 configList, &ConfigList::setOptionMode);
1432 connect(optGroup, &QActionGroup::triggered,
1433 menuList, &ConfigList::setOptionMode);
Li Zefan39a48972010-05-10 16:33:41 +08001434
Masahiro Yamadad4bbe8a2020-08-07 18:19:09 +09001435 ConfigList::showNormalAction = new QAction("Show Normal Options", optGroup);
1436 ConfigList::showNormalAction->setCheckable(true);
1437 ConfigList::showAllAction = new QAction("Show All Options", optGroup);
1438 ConfigList::showAllAction->setCheckable(true);
1439 ConfigList::showPromptAction = new QAction("Show Prompt Options", optGroup);
1440 ConfigList::showPromptAction->setCheckable(true);
Li Zefan39a48972010-05-10 16:33:41 +08001441
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001442 QAction *showDebugAction = new QAction("Show Debug Info", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001443 showDebugAction->setCheckable(true);
Masahiro Yamadaa2574c12020-10-24 21:38:41 +09001444 connect(showDebugAction, &QAction::toggled,
1445 helpText, &ConfigInfoView::setShowDebug);
Boris Barbulovski9c862352015-09-22 11:36:12 -07001446 showDebugAction->setChecked(helpText->showDebug());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001447
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001448 QAction *showIntroAction = new QAction("Introduction", this);
Masahiro Yamadaa2574c12020-10-24 21:38:41 +09001449 connect(showIntroAction, &QAction::triggered,
1450 this, &ConfigMainWindow::showIntro);
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001451 QAction *showAboutAction = new QAction("About", this);
Masahiro Yamadaa2574c12020-10-24 21:38:41 +09001452 connect(showAboutAction, &QAction::triggered,
1453 this, &ConfigMainWindow::showAbout);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001454
1455 // init tool bar
Masahiro Yamada860ec3f2020-08-07 18:18:55 +09001456 QToolBar *toolBar = addToolBar("Tools");
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001457 toolBar->addAction(backAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001458 toolBar->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001459 toolBar->addAction(loadAction);
1460 toolBar->addAction(saveAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001461 toolBar->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001462 toolBar->addAction(singleViewAction);
1463 toolBar->addAction(splitViewAction);
1464 toolBar->addAction(fullViewAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001465
Masahiro Yamada93ebaac2020-08-07 18:18:53 +09001466 // create file menu
1467 QMenu *menu = menuBar()->addMenu("&File");
1468 menu->addAction(loadAction);
1469 menu->addAction(saveAction);
1470 menu->addAction(saveAsAction);
1471 menu->addSeparator();
1472 menu->addAction(quitAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001473
Shlomi Fish66e7c722007-02-14 00:32:58 -08001474 // create edit menu
Masahiro Yamada93ebaac2020-08-07 18:18:53 +09001475 menu = menuBar()->addMenu("&Edit");
1476 menu->addAction(searchAction);
Shlomi Fish66e7c722007-02-14 00:32:58 -08001477
Linus Torvalds1da177e2005-04-16 15:20:36 -07001478 // create options menu
Masahiro Yamada93ebaac2020-08-07 18:18:53 +09001479 menu = menuBar()->addMenu("&Option");
1480 menu->addAction(showNameAction);
Masahiro Yamada93ebaac2020-08-07 18:18:53 +09001481 menu->addSeparator();
1482 menu->addActions(optGroup->actions());
1483 menu->addSeparator();
1484 menu->addAction(showDebugAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001485
1486 // create help menu
Masahiro Yamada93ebaac2020-08-07 18:18:53 +09001487 menu = menuBar()->addMenu("&Help");
1488 menu->addAction(showIntroAction);
1489 menu->addAction(showAboutAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001490
Masahiro Yamadaa2574c12020-10-24 21:38:41 +09001491 connect(helpText, &ConfigInfoView::anchorClicked,
1492 helpText, &ConfigInfoView::clicked);
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001493
Masahiro Yamadaa2574c12020-10-24 21:38:41 +09001494 connect(configList, &ConfigList::menuChanged,
1495 helpText, &ConfigInfoView::setInfo);
1496 connect(configList, &ConfigList::menuSelected,
1497 this, &ConfigMainWindow::changeMenu);
1498 connect(configList, &ConfigList::itemSelected,
1499 this, &ConfigMainWindow::changeItens);
1500 connect(configList, &ConfigList::parentSelected,
1501 this, &ConfigMainWindow::goBack);
1502 connect(menuList, &ConfigList::menuChanged,
1503 helpText, &ConfigInfoView::setInfo);
1504 connect(menuList, &ConfigList::menuSelected,
1505 this, &ConfigMainWindow::changeMenu);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001506
Masahiro Yamadaa2574c12020-10-24 21:38:41 +09001507 connect(configList, &ConfigList::gotFocus,
1508 helpText, &ConfigInfoView::setInfo);
1509 connect(menuList, &ConfigList::gotFocus,
1510 helpText, &ConfigInfoView::setInfo);
1511 connect(menuList, &ConfigList::gotFocus,
1512 this, &ConfigMainWindow::listFocusChanged);
1513 connect(helpText, &ConfigInfoView::menuSelected,
1514 this, &ConfigMainWindow::setMenuLink);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001515
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001516 QString listMode = configSettings->value("/listMode", "symbol").toString();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001517 if (listMode == "single")
1518 showSingleView();
1519 else if (listMode == "full")
1520 showFullView();
1521 else /*if (listMode == "split")*/
1522 showSplitView();
1523
1524 // UI setup done, restore splitter positions
Boris Barbulovski041fbdc2015-09-22 11:36:05 -07001525 QList<int> sizes = configSettings->readSizes("/split1", &ok);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001526 if (ok)
1527 split1->setSizes(sizes);
1528
Roman Zippel7fc925f2006-06-08 22:12:46 -07001529 sizes = configSettings->readSizes("/split2", &ok);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001530 if (ok)
1531 split2->setSizes(sizes);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001532}
1533
Linus Torvalds1da177e2005-04-16 15:20:36 -07001534void ConfigMainWindow::loadConfig(void)
1535{
Masahiro Yamada87419082019-03-11 01:13:15 +09001536 QString str;
1537 QByteArray ba;
1538 const char *name;
1539
1540 str = QFileDialog::getOpenFileName(this, "", configname);
1541 if (str.isNull())
Linus Torvalds1da177e2005-04-16 15:20:36 -07001542 return;
Masahiro Yamada87419082019-03-11 01:13:15 +09001543
1544 ba = str.toLocal8Bit();
1545 name = ba.data();
1546
1547 if (conf_read(name))
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001548 QMessageBox::information(this, "qconf", "Unable to load configuration!");
Masahiro Yamada87419082019-03-11 01:13:15 +09001549
1550 free(configname);
1551 configname = xstrdup(name);
1552
Masahiro Yamadaf9b918f2020-08-29 17:14:10 +09001553 ConfigList::updateListAllForAll();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001554}
1555
Michal Marekbac6aa82011-05-25 15:10:25 +02001556bool ConfigMainWindow::saveConfig(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001557{
Masahiro Yamada87419082019-03-11 01:13:15 +09001558 if (conf_write(configname)) {
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001559 QMessageBox::information(this, "qconf", "Unable to save configuration!");
Michal Marekbac6aa82011-05-25 15:10:25 +02001560 return false;
1561 }
Masahiro Yamada00c864f2018-07-20 16:46:31 +09001562 conf_write_autoconf(0);
1563
Michal Marekbac6aa82011-05-25 15:10:25 +02001564 return true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001565}
1566
1567void ConfigMainWindow::saveConfigAs(void)
1568{
Masahiro Yamada87419082019-03-11 01:13:15 +09001569 QString str;
1570 QByteArray ba;
1571 const char *name;
1572
1573 str = QFileDialog::getSaveFileName(this, "", configname);
1574 if (str.isNull())
Linus Torvalds1da177e2005-04-16 15:20:36 -07001575 return;
Masahiro Yamada87419082019-03-11 01:13:15 +09001576
1577 ba = str.toLocal8Bit();
1578 name = ba.data();
1579
1580 if (conf_write(name)) {
1581 QMessageBox::information(this, "qconf", "Unable to save configuration!");
1582 }
1583 conf_write_autoconf(0);
1584
1585 free(configname);
1586 configname = xstrdup(name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001587}
1588
Roman Zippel43bf6122006-06-08 22:12:45 -07001589void ConfigMainWindow::searchConfig(void)
1590{
1591 if (!searchWindow)
Masahiro Yamada740fdef2020-08-07 18:18:57 +09001592 searchWindow = new ConfigSearchWindow(this);
Roman Zippel43bf6122006-06-08 22:12:45 -07001593 searchWindow->show();
1594}
1595
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +02001596void ConfigMainWindow::changeItens(struct menu *menu)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001597{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001598 configList->setRootMenu(menu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001599}
1600
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +02001601void ConfigMainWindow::changeMenu(struct menu *menu)
1602{
1603 menuList->setRootMenu(menu);
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +02001604}
1605
Roman Zippelb65a47e2006-06-08 22:12:47 -07001606void ConfigMainWindow::setMenuLink(struct menu *menu)
1607{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001608 struct menu *parent;
1609 ConfigList* list = NULL;
1610 ConfigItem* item;
1611
1612 if (configList->menuSkip(menu))
1613 return;
1614
1615 switch (configList->mode) {
1616 case singleMode:
1617 list = configList;
1618 parent = menu_get_parent_menu(menu);
1619 if (!parent)
1620 return;
1621 list->setRootMenu(parent);
1622 break;
Mauro Carvalho Chehabc699eaa2020-06-30 08:26:36 +02001623 case menuMode:
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001624 if (menu->flags & MENU_ROOT) {
Mauro Carvalho Chehabc699eaa2020-06-30 08:26:36 +02001625 menuList->setRootMenu(menu);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001626 configList->clearSelection();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001627 list = configList;
Mauro Carvalho Chehabc699eaa2020-06-30 08:26:36 +02001628 } else {
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001629 parent = menu_get_parent_menu(menu->parent);
1630 if (!parent)
1631 return;
Mauro Carvalho Chehabc699eaa2020-06-30 08:26:36 +02001632
Mauro Carvalho Chehabc699eaa2020-06-30 08:26:36 +02001633 /* Select the config view */
1634 item = configList->findConfigItem(parent);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001635 if (item) {
Mauro Carvalho Chehabb06c3ec2020-06-30 08:26:38 +02001636 configList->setSelected(item, true);
Mauro Carvalho Chehabc699eaa2020-06-30 08:26:36 +02001637 configList->scrollToItem(item);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001638 }
Mauro Carvalho Chehabc699eaa2020-06-30 08:26:36 +02001639
1640 menuList->setRootMenu(parent);
1641 menuList->clearSelection();
1642 list = menuList;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001643 }
1644 break;
1645 case fullMode:
1646 list = configList;
1647 break;
1648 default:
1649 break;
1650 }
1651
1652 if (list) {
1653 item = list->findConfigItem(menu);
1654 if (item) {
Mauro Carvalho Chehabb06c3ec2020-06-30 08:26:38 +02001655 list->setSelected(item, true);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001656 list->scrollToItem(item);
1657 list->setFocus();
Mauro Carvalho Chehab8a3b6e52020-06-30 08:48:35 +02001658 helpText->setInfo(menu);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001659 }
1660 }
Roman Zippelb65a47e2006-06-08 22:12:47 -07001661}
1662
Linus Torvalds1da177e2005-04-16 15:20:36 -07001663void ConfigMainWindow::listFocusChanged(void)
1664{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001665 if (menuList->mode == menuMode)
1666 configList->clearSelection();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001667}
1668
1669void ConfigMainWindow::goBack(void)
1670{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001671 if (configList->rootEntry == &rootmenu)
Boris Barbulovskibe596aa2015-09-22 11:36:28 -07001672 return;
1673
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001674 configList->setParentMenu();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001675}
1676
1677void ConfigMainWindow::showSingleView(void)
1678{
Boris Barbulovski780505e2015-09-22 11:36:13 -07001679 singleViewAction->setEnabled(false);
1680 singleViewAction->setChecked(true);
1681 splitViewAction->setEnabled(true);
1682 splitViewAction->setChecked(false);
1683 fullViewAction->setEnabled(true);
1684 fullViewAction->setChecked(false);
1685
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001686 backAction->setEnabled(true);
1687
Masahiro Yamada62ed1652020-08-29 17:14:15 +09001688 menuList->hide();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001689 menuList->setRootMenu(0);
1690 configList->mode = singleMode;
1691 if (configList->rootEntry == &rootmenu)
1692 configList->updateListAll();
1693 else
1694 configList->setRootMenu(&rootmenu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001695 configList->setFocus();
1696}
1697
1698void ConfigMainWindow::showSplitView(void)
1699{
Boris Barbulovski780505e2015-09-22 11:36:13 -07001700 singleViewAction->setEnabled(true);
1701 singleViewAction->setChecked(false);
1702 splitViewAction->setEnabled(false);
1703 splitViewAction->setChecked(true);
1704 fullViewAction->setEnabled(true);
1705 fullViewAction->setChecked(false);
1706
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001707 backAction->setEnabled(false);
1708
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +02001709 configList->mode = menuMode;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001710 if (configList->rootEntry == &rootmenu)
1711 configList->updateListAll();
1712 else
1713 configList->setRootMenu(&rootmenu);
1714 configList->setAllOpen(true);
1715 configApp->processEvents();
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +02001716 menuList->mode = symbolMode;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001717 menuList->setRootMenu(&rootmenu);
1718 menuList->setAllOpen(true);
Masahiro Yamada62ed1652020-08-29 17:14:15 +09001719 menuList->show();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001720 menuList->setFocus();
1721}
1722
1723void ConfigMainWindow::showFullView(void)
1724{
Boris Barbulovski780505e2015-09-22 11:36:13 -07001725 singleViewAction->setEnabled(true);
1726 singleViewAction->setChecked(false);
1727 splitViewAction->setEnabled(true);
1728 splitViewAction->setChecked(false);
1729 fullViewAction->setEnabled(false);
1730 fullViewAction->setChecked(true);
1731
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001732 backAction->setEnabled(false);
1733
Masahiro Yamada62ed1652020-08-29 17:14:15 +09001734 menuList->hide();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001735 menuList->setRootMenu(0);
1736 configList->mode = fullMode;
1737 if (configList->rootEntry == &rootmenu)
1738 configList->updateListAll();
1739 else
1740 configList->setRootMenu(&rootmenu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001741 configList->setFocus();
1742}
1743
Linus Torvalds1da177e2005-04-16 15:20:36 -07001744/*
1745 * ask for saving configuration before quitting
Linus Torvalds1da177e2005-04-16 15:20:36 -07001746 */
1747void ConfigMainWindow::closeEvent(QCloseEvent* e)
1748{
Karsten Wieseb3214292006-12-13 00:34:06 -08001749 if (!conf_get_changed()) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001750 e->accept();
1751 return;
1752 }
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001753 QMessageBox mb("qconf", "Save configuration?", QMessageBox::Warning,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001754 QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape);
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001755 mb.setButtonText(QMessageBox::Yes, "&Save Changes");
1756 mb.setButtonText(QMessageBox::No, "&Discard Changes");
1757 mb.setButtonText(QMessageBox::Cancel, "Cancel Exit");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001758 switch (mb.exec()) {
1759 case QMessageBox::Yes:
Michal Marekbac6aa82011-05-25 15:10:25 +02001760 if (saveConfig())
1761 e->accept();
1762 else
1763 e->ignore();
1764 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001765 case QMessageBox::No:
1766 e->accept();
1767 break;
1768 case QMessageBox::Cancel:
1769 e->ignore();
1770 break;
1771 }
1772}
1773
1774void ConfigMainWindow::showIntro(void)
1775{
Masahiro Yamada8c30e7e2020-08-29 17:14:07 +09001776 static const QString str =
1777 "Welcome to the qconf graphical configuration tool.\n"
1778 "\n"
Masahiro Yamada37162a62020-08-29 17:14:12 +09001779 "For bool and tristate options, a blank box indicates the "
1780 "feature is disabled, a check indicates it is enabled, and a "
1781 "dot indicates that it is to be compiled as a module. Clicking "
1782 "on the box will cycle through the three states. For int, hex, "
1783 "and string options, double-clicking or pressing F2 on the "
1784 "Value cell will allow you to edit the value.\n"
Masahiro Yamada8c30e7e2020-08-29 17:14:07 +09001785 "\n"
1786 "If you do not see an option (e.g., a device driver) that you "
1787 "believe should be present, try turning on Show All Options "
Masahiro Yamada1fb75242020-08-29 17:14:08 +09001788 "under the Options menu. Enabling Show Debug Info will help you"
1789 "figure out what other options must be enabled to support the "
1790 "option you are interested in, and hyperlinks will navigate to "
1791 "them.\n"
Masahiro Yamada8c30e7e2020-08-29 17:14:07 +09001792 "\n"
1793 "Toggling Show Debug Info under the Options menu will show the "
1794 "dependencies, which you can then match by examining other "
1795 "options.\n";
Linus Torvalds1da177e2005-04-16 15:20:36 -07001796
1797 QMessageBox::information(this, "qconf", str);
1798}
1799
1800void ConfigMainWindow::showAbout(void)
1801{
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001802 static const QString str = "qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n"
Masahiro Yamadaf4632692020-11-02 11:59:57 +09001803 "Copyright (C) 2015 Boris Barbulovski <bbarbulovski@gmail.com>.\n"
1804 "\n"
1805 "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n"
1806 "\n"
1807 "Qt Version: ";
Linus Torvalds1da177e2005-04-16 15:20:36 -07001808
Masahiro Yamadaf4632692020-11-02 11:59:57 +09001809 QMessageBox::information(this, "qconf", str + qVersion());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001810}
1811
1812void ConfigMainWindow::saveSettings(void)
1813{
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001814 configSettings->setValue("/window x", pos().x());
1815 configSettings->setValue("/window y", pos().y());
1816 configSettings->setValue("/window width", size().width());
1817 configSettings->setValue("/window height", size().height());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001818
1819 QString entry;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001820 switch(configList->mode) {
1821 case singleMode :
1822 entry = "single";
1823 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001824
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001825 case symbolMode :
1826 entry = "split";
1827 break;
1828
1829 case fullMode :
1830 entry = "full";
1831 break;
1832
1833 default:
1834 break;
1835 }
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001836 configSettings->setValue("/listMode", entry);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001837
Roman Zippel7fc925f2006-06-08 22:12:46 -07001838 configSettings->writeSizes("/split1", split1->sizes());
1839 configSettings->writeSizes("/split2", split2->sizes());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001840}
1841
Karsten Wiese3b354c52006-12-13 00:34:08 -08001842void ConfigMainWindow::conf_changed(void)
1843{
1844 if (saveAction)
1845 saveAction->setEnabled(conf_get_changed());
1846}
1847
Linus Torvalds1da177e2005-04-16 15:20:36 -07001848void fixup_rootmenu(struct menu *menu)
1849{
1850 struct menu *child;
1851 static int menu_cnt = 0;
1852
1853 menu->flags |= MENU_ROOT;
1854 for (child = menu->list; child; child = child->next) {
1855 if (child->prompt && child->prompt->type == P_MENU) {
1856 menu_cnt++;
1857 fixup_rootmenu(child);
1858 menu_cnt--;
1859 } else if (!menu_cnt)
1860 fixup_rootmenu(child);
1861 }
1862}
1863
1864static const char *progname;
1865
1866static void usage(void)
1867{
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001868 printf("%s [-s] <config>\n", progname);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001869 exit(0);
1870}
1871
1872int main(int ac, char** av)
1873{
1874 ConfigMainWindow* v;
1875 const char *name;
1876
Linus Torvalds1da177e2005-04-16 15:20:36 -07001877 progname = av[0];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001878 if (ac > 1 && av[1][0] == '-') {
1879 switch (av[1][1]) {
Michal Marek0a1f00a2015-04-08 13:30:42 +02001880 case 's':
1881 conf_set_message_callback(NULL);
1882 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001883 case 'h':
1884 case '?':
1885 usage();
1886 }
1887 name = av[2];
1888 } else
1889 name = av[1];
1890 if (!name)
1891 usage();
1892
1893 conf_parse(name);
1894 fixup_rootmenu(&rootmenu);
1895 conf_read(NULL);
1896 //zconfdump(stdout);
1897
Masahiro Yamadaf9a825a2020-08-29 17:14:17 +09001898 configApp = new QApplication(ac, av);
1899
Roman Zippel7fc925f2006-06-08 22:12:46 -07001900 configSettings = new ConfigSettings();
1901 configSettings->beginGroup("/kconfig/qconf");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001902 v = new ConfigMainWindow();
1903
1904 //zconfdump(stdout);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001905 configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit()));
1906 configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings()));
Roman Zippel43bf6122006-06-08 22:12:45 -07001907 v->show();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001908 configApp->exec();
1909
Roman Zippel7fc925f2006-06-08 22:12:46 -07001910 configSettings->endGroup();
1911 delete configSettings;
Chris Bainbridge5b61c7b2016-01-08 20:44:04 +00001912 delete v;
1913 delete configApp;
Roman Zippel7fc925f2006-06-08 22:12:46 -07001914
Linus Torvalds1da177e2005-04-16 15:20:36 -07001915 return 0;
1916}