blob: d000869b787c87de8540fd289c66d68e2e963f4d [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());
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700142 break;
143 }
144 expr = sym_get_tristate_value(sym);
145 switch (expr) {
146 case yes:
147 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
Masahiro Yamada5cb255f2020-08-07 18:19:07 +0900148 setIcon(promptColIdx, choiceYesIcon);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700149 else
Masahiro Yamada5cb255f2020-08-07 18:19:07 +0900150 setIcon(promptColIdx, symbolYesIcon);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700151 ch = 'Y';
152 break;
153 case mod:
Masahiro Yamada5cb255f2020-08-07 18:19:07 +0900154 setIcon(promptColIdx, symbolModIcon);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700155 ch = 'M';
156 break;
157 default:
158 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
Masahiro Yamada5cb255f2020-08-07 18:19:07 +0900159 setIcon(promptColIdx, choiceNoIcon);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700160 else
Masahiro Yamada5cb255f2020-08-07 18:19:07 +0900161 setIcon(promptColIdx, symbolNoIcon);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700162 ch = 'N';
163 break;
164 }
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700165
166 setText(dataColIdx, QChar(ch));
167 break;
168 case S_INT:
169 case S_HEX:
170 case S_STRING:
Masahiro Yamada37162a62020-08-29 17:14:12 +0900171 setText(dataColIdx, sym_get_string_value(sym));
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700172 break;
173 }
174 if (!sym_has_value(sym) && visible)
Sam Ravnborg694c49a2018-05-22 21:36:12 +0200175 prompt += " (NEW)";
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700176set_prompt:
177 setText(promptColIdx, prompt);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700178}
179
180void ConfigItem::testUpdateMenu(bool v)
181{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700182 ConfigItem* i;
183
184 visible = v;
185 if (!menu)
186 return;
187
188 sym_calc_value(menu->sym);
189 if (menu->flags & MENU_CHANGED) {
190 /* the menu entry changed, so update all list items */
191 menu->flags &= ~MENU_CHANGED;
192 for (i = (ConfigItem*)menu->data; i; i = i->nextItem)
193 i->updateMenu();
194 } else if (listView()->updateAll)
195 updateMenu();
Boris Barbulovski59e56442015-09-22 11:36:18 -0700196}
197
198
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700199/*
200 * construct a menu entry
201 */
202void ConfigItem::init(void)
203{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700204 if (menu) {
205 ConfigList* list = listView();
206 nextItem = (ConfigItem*)menu->data;
207 menu->data = this;
208
209 if (list->mode != fullMode)
210 setExpanded(true);
211 sym_calc_value(menu->sym);
Masahiro Yamada37162a62020-08-29 17:14:12 +0900212
213 if (menu->sym) {
214 enum symbol_type type = menu->sym->type;
215
216 // Allow to edit "int", "hex", and "string" in-place in
217 // the data column. Unfortunately, you cannot specify
218 // the flags per column. Set ItemIsEditable for all
219 // columns here, and check the column in createEditor().
220 if (type == S_INT || type == S_HEX || type == S_STRING)
221 setFlags(flags() | Qt::ItemIsEditable);
222 }
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700223 }
224 updateMenu();
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700225}
226
227/*
228 * destruct a menu entry
229 */
230ConfigItem::~ConfigItem(void)
231{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700232 if (menu) {
233 ConfigItem** ip = (ConfigItem**)&menu->data;
234 for (; *ip; ip = &(*ip)->nextItem) {
235 if (*ip == this) {
236 *ip = nextItem;
237 break;
238 }
239 }
240 }
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700241}
242
Masahiro Yamada37162a62020-08-29 17:14:12 +0900243QWidget *ConfigItemDelegate::createEditor(QWidget *parent,
244 const QStyleOptionViewItem &option,
245 const QModelIndex &index) const
246{
247 ConfigItem *item;
248
249 // Only the data column is editable
250 if (index.column() != dataColIdx)
251 return nullptr;
252
253 // You cannot edit invisible menus
254 item = static_cast<ConfigItem *>(index.internalPointer());
255 if (!item || !item->menu || !menu_is_visible(item->menu))
256 return nullptr;
257
258 return QStyledItemDelegate::createEditor(parent, option, index);
259}
260
261void ConfigItemDelegate::setModelData(QWidget *editor,
262 QAbstractItemModel *model,
263 const QModelIndex &index) const
264{
265 QLineEdit *lineEdit;
266 ConfigItem *item;
267 struct symbol *sym;
268 bool success;
269
270 lineEdit = qobject_cast<QLineEdit *>(editor);
271 // If this is not a QLineEdit, use the parent's default.
272 // (does this happen?)
273 if (!lineEdit)
274 goto parent;
275
276 item = static_cast<ConfigItem *>(index.internalPointer());
277 if (!item || !item->menu)
278 goto parent;
279
280 sym = item->menu->sym;
281 if (!sym)
282 goto parent;
283
284 success = sym_set_string_value(sym, lineEdit->text().toUtf8().data());
285 if (success) {
286 ConfigList::updateListForAll();
287 } else {
288 QMessageBox::information(editor, "qconf",
289 "Cannot set the data (maybe due to out of range).\n"
290 "Setting the old value.");
291 lineEdit->setText(sym_get_string_value(sym));
292 }
293
294parent:
295 QStyledItemDelegate::setModelData(editor, model, index);
296}
297
Masahiro Yamada62ed1652020-08-29 17:14:15 +0900298ConfigList::ConfigList(QWidget *parent, const char *name)
299 : QTreeWidget(parent),
Boris Barbulovski59e56442015-09-22 11:36:18 -0700300 updateAll(false),
Masahiro Yamadaa0fce282020-08-29 17:14:16 +0900301 showName(false), mode(singleMode), optMode(normalOpt),
Boris Barbulovski59e56442015-09-22 11:36:18 -0700302 rootEntry(0), headerPopup(0)
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700303{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700304 setObjectName(name);
Boris Barbulovskia5225e92015-09-22 11:36:29 -0700305 setSortingEnabled(false);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700306 setRootIsDecorated(true);
307
Boris Barbulovskif999cc02015-09-22 11:36:31 -0700308 setVerticalScrollMode(ScrollPerPixel);
309 setHorizontalScrollMode(ScrollPerPixel);
310
Masahiro Yamadaa0fce282020-08-29 17:14:16 +0900311 setHeaderLabels(QStringList() << "Option" << "Name" << "Value");
Boris Barbulovskia52cb322015-09-22 11:36:24 -0700312
Masahiro Yamadaa2574c12020-10-24 21:38:41 +0900313 connect(this, &ConfigList::itemSelectionChanged,
314 this, &ConfigList::updateSelection);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700315
316 if (name) {
317 configSettings->beginGroup(name);
318 showName = configSettings->value("/showName", false).toBool();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700319 optMode = (enum optionMode)configSettings->value("/optionMode", 0).toInt();
320 configSettings->endGroup();
Masahiro Yamadaa2574c12020-10-24 21:38:41 +0900321 connect(configApp, &QApplication::aboutToQuit,
322 this, &ConfigList::saveSettings);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700323 }
324
Masahiro Yamadaabf741a2020-08-07 18:19:04 +0900325 showColumn(promptColIdx);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700326
Masahiro Yamada37162a62020-08-29 17:14:12 +0900327 setItemDelegate(new ConfigItemDelegate(this));
328
Masahiro Yamadaf9b918f2020-08-29 17:14:10 +0900329 allLists.append(this);
330
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700331 reinit();
332}
333
Masahiro Yamadaf9b918f2020-08-29 17:14:10 +0900334ConfigList::~ConfigList()
335{
336 allLists.removeOne(this);
337}
338
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700339bool ConfigList::menuSkip(struct menu *menu)
340{
341 if (optMode == normalOpt && menu_is_visible(menu))
342 return false;
343 if (optMode == promptOpt && menu_has_prompt(menu))
344 return false;
345 if (optMode == allOpt)
346 return false;
347 return true;
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700348}
Boris Barbulovski59e56442015-09-22 11:36:18 -0700349
350void ConfigList::reinit(void)
351{
Masahiro Yamadaabf741a2020-08-07 18:19:04 +0900352 hideColumn(nameColIdx);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700353
354 if (showName)
Masahiro Yamadaabf741a2020-08-07 18:19:04 +0900355 showColumn(nameColIdx);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700356
357 updateListAll();
Boris Barbulovski59e56442015-09-22 11:36:18 -0700358}
359
Masahiro Yamadad4bbe8a2020-08-07 18:19:09 +0900360void ConfigList::setOptionMode(QAction *action)
361{
362 if (action == showNormalAction)
363 optMode = normalOpt;
364 else if (action == showAllAction)
365 optMode = allOpt;
366 else
367 optMode = promptOpt;
368
369 updateListAll();
370}
371
Boris Barbulovski59e56442015-09-22 11:36:18 -0700372void ConfigList::saveSettings(void)
373{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700374 if (!objectName().isEmpty()) {
375 configSettings->beginGroup(objectName());
376 configSettings->setValue("/showName", showName);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700377 configSettings->setValue("/optionMode", (int)optMode);
378 configSettings->endGroup();
379 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700380}
381
382ConfigItem* ConfigList::findConfigItem(struct menu *menu)
383{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700384 ConfigItem* item = (ConfigItem*)menu->data;
385
386 for (; item; item = item->nextItem) {
387 if (this == item->listView())
388 break;
389 }
390
391 return item;
Boris Barbulovski59e56442015-09-22 11:36:18 -0700392}
393
394void ConfigList::updateSelection(void)
395{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700396 struct menu *menu;
397 enum prop_type type;
398
Boris Barbulovskibe596aa2015-09-22 11:36:28 -0700399 if (selectedItems().count() == 0)
400 return;
401
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700402 ConfigItem* item = (ConfigItem*)selectedItems().first();
403 if (!item)
404 return;
405
406 menu = item->menu;
407 emit menuChanged(menu);
408 if (!menu)
409 return;
410 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
411 if (mode == menuMode && type == P_MENU)
412 emit menuSelected(menu);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700413}
414
Masahiro Yamadacb770432020-08-07 18:18:59 +0900415void ConfigList::updateList()
Boris Barbulovski59e56442015-09-22 11:36:18 -0700416{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700417 ConfigItem* last = 0;
Masahiro Yamadacb770432020-08-07 18:18:59 +0900418 ConfigItem *item;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700419
420 if (!rootEntry) {
421 if (mode != listMode)
422 goto update;
423 QTreeWidgetItemIterator it(this);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700424
425 while (*it) {
426 item = (ConfigItem*)(*it);
427 if (!item->menu)
428 continue;
429 item->testUpdateMenu(menu_is_visible(item->menu));
430
431 ++it;
432 }
433 return;
434 }
435
436 if (rootEntry != &rootmenu && (mode == singleMode ||
437 (mode == symbolMode && rootEntry->parent != &rootmenu))) {
Boris Barbulovskiee7298f2015-09-22 11:36:37 -0700438 item = (ConfigItem *)topLevelItem(0);
Masahiro Yamada4b20e102020-08-01 16:08:49 +0900439 if (!item)
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700440 item = new ConfigItem(this, 0, true);
Masahiro Yamada4b20e102020-08-01 16:08:49 +0900441 last = item;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700442 }
443 if ((mode == singleMode || (mode == symbolMode && !(rootEntry->flags & MENU_ROOT))) &&
444 rootEntry->sym && rootEntry->prompt) {
Masahiro Yamadaccf56e52020-08-01 16:08:50 +0900445 item = last ? last->nextSibling() : nullptr;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700446 if (!item)
447 item = new ConfigItem(this, last, rootEntry, true);
448 else
449 item->testUpdateMenu(true);
450
451 updateMenuList(item, rootEntry);
452 update();
Boris Barbulovskif999cc02015-09-22 11:36:31 -0700453 resizeColumnToContents(0);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700454 return;
455 }
456update:
Masahiro Yamada5b75a6c2020-08-07 18:19:01 +0900457 updateMenuList(rootEntry);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700458 update();
Boris Barbulovskif999cc02015-09-22 11:36:31 -0700459 resizeColumnToContents(0);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700460}
461
Masahiro Yamadaf9b918f2020-08-29 17:14:10 +0900462void ConfigList::updateListForAll()
463{
464 QListIterator<ConfigList *> it(allLists);
465
466 while (it.hasNext()) {
467 ConfigList *list = it.next();
468
469 list->updateList();
470 }
471}
472
473void ConfigList::updateListAllForAll()
474{
475 QListIterator<ConfigList *> it(allLists);
476
477 while (it.hasNext()) {
478 ConfigList *list = it.next();
479
480 list->updateList();
481 }
482}
483
Boris Barbulovski59e56442015-09-22 11:36:18 -0700484void ConfigList::setValue(ConfigItem* item, tristate val)
485{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700486 struct symbol* sym;
487 int type;
488 tristate oldval;
489
490 sym = item->menu ? item->menu->sym : 0;
491 if (!sym)
492 return;
493
494 type = sym_get_type(sym);
495 switch (type) {
496 case S_BOOLEAN:
497 case S_TRISTATE:
498 oldval = sym_get_tristate_value(sym);
499
500 if (!sym_set_tristate_value(sym, val))
501 return;
502 if (oldval == no && item->menu->list)
503 item->setExpanded(true);
Masahiro Yamadaf9b918f2020-08-29 17:14:10 +0900504 ConfigList::updateListForAll();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700505 break;
506 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700507}
508
509void ConfigList::changeValue(ConfigItem* item)
510{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700511 struct symbol* sym;
512 struct menu* menu;
513 int type, oldexpr, newexpr;
514
515 menu = item->menu;
516 if (!menu)
517 return;
518 sym = menu->sym;
519 if (!sym) {
520 if (item->menu->list)
521 item->setExpanded(!item->isExpanded());
522 return;
523 }
524
525 type = sym_get_type(sym);
526 switch (type) {
527 case S_BOOLEAN:
528 case S_TRISTATE:
529 oldexpr = sym_get_tristate_value(sym);
530 newexpr = sym_toggle_tristate_value(sym);
531 if (item->menu->list) {
532 if (oldexpr == newexpr)
533 item->setExpanded(!item->isExpanded());
534 else if (oldexpr == no)
535 item->setExpanded(true);
536 }
537 if (oldexpr != newexpr)
Masahiro Yamadaf9b918f2020-08-29 17:14:10 +0900538 ConfigList::updateListForAll();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700539 break;
Masahiro Yamada37162a62020-08-29 17:14:12 +0900540 default:
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;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700823 case dataColIdx:
824 changeValue(item);
825 break;
826 }
827
828skip:
829 //printf("contentsMouseReleaseEvent: %d,%d\n", p.x(), p.y());
830 Parent::mouseReleaseEvent(e);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700831}
832
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700833void ConfigList::mouseMoveEvent(QMouseEvent* e)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700834{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700835 //QPoint p(contentsToViewport(e->pos()));
836 //printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y());
837 Parent::mouseMoveEvent(e);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700838}
839
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700840void ConfigList::mouseDoubleClickEvent(QMouseEvent* e)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700841{
Mauro Carvalho Chehabe1f77692020-04-02 11:28:02 +0200842 QPoint p = e->pos();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700843 ConfigItem* item = (ConfigItem*)itemAt(p);
844 struct menu *menu;
845 enum prop_type ptype;
846
847 if (!item)
848 goto skip;
849 if (item->goParent) {
850 emit parentSelected();
851 goto skip;
852 }
853 menu = item->menu;
854 if (!menu)
855 goto skip;
856 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
Maxime Chretien7eb7c106f2020-07-08 15:32:15 +0200857 if (ptype == P_MENU && mode != listMode) {
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +0200858 if (mode == singleMode)
859 emit itemSelected(menu);
860 else if (mode == symbolMode)
861 emit menuSelected(menu);
862 } else if (menu->sym)
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700863 changeValue(item);
864
865skip:
866 //printf("contentsMouseDoubleClickEvent: %d,%d\n", p.x(), p.y());
867 Parent::mouseDoubleClickEvent(e);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700868}
869
870void ConfigList::focusInEvent(QFocusEvent *e)
871{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700872 struct menu *menu = NULL;
873
874 Parent::focusInEvent(e);
875
876 ConfigItem* item = (ConfigItem *)currentItem();
877 if (item) {
Mauro Carvalho Chehabb06c3ec2020-06-30 08:26:38 +0200878 setSelected(item, true);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700879 menu = item->menu;
880 }
881 emit gotFocus(menu);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700882}
883
884void ConfigList::contextMenuEvent(QContextMenuEvent *e)
885{
Masahiro Yamadafa8de0a2020-08-07 18:19:08 +0900886 if (!headerPopup) {
887 QAction *action;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700888
Masahiro Yamadafa8de0a2020-08-07 18:19:08 +0900889 headerPopup = new QMenu(this);
890 action = new QAction("Show Name", this);
891 action->setCheckable(true);
Masahiro Yamadaa2574c12020-10-24 21:38:41 +0900892 connect(action, &QAction::toggled,
893 this, &ConfigList::setShowName);
894 connect(this, &ConfigList::showNameChanged,
895 action, &QAction::setChecked);
Masahiro Yamadafa8de0a2020-08-07 18:19:08 +0900896 action->setChecked(showName);
897 headerPopup->addAction(action);
Masahiro Yamadafa8de0a2020-08-07 18:19:08 +0900898 }
899
900 headerPopup->exec(e->globalPos());
901 e->accept();
Boris Barbulovski59e56442015-09-22 11:36:18 -0700902}
903
Masahiro Yamada7930dd92020-08-29 17:14:14 +0900904void ConfigList::setShowName(bool on)
905{
906 if (showName == on)
907 return;
908
909 showName = on;
910 reinit();
911 emit showNameChanged(on);
912}
913
Masahiro Yamadaf9b918f2020-08-29 17:14:10 +0900914QList<ConfigList *> ConfigList::allLists;
Masahiro Yamadad4bbe8a2020-08-07 18:19:09 +0900915QAction *ConfigList::showNormalAction;
916QAction *ConfigList::showAllAction;
917QAction *ConfigList::showPromptAction;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700918
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700919void ConfigList::setAllOpen(bool open)
920{
921 QTreeWidgetItemIterator it(this);
922
923 while (*it) {
924 (*it)->setExpanded(open);
925
926 ++it;
927 }
Roman Zippel7fc925f2006-06-08 22:12:46 -0700928}
929
Roman Zippel43bf6122006-06-08 22:12:45 -0700930ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name)
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -0700931 : Parent(parent), sym(0), _menu(0)
Roman Zippel43bf6122006-06-08 22:12:45 -0700932{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700933 setObjectName(name);
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +0200934 setOpenLinks(false);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700935
936 if (!objectName().isEmpty()) {
937 configSettings->beginGroup(objectName());
Boris Barbulovskie0393032016-11-30 14:57:52 -0800938 setShowDebug(configSettings->value("/showDebug", false).toBool());
Roman Zippel7fc925f2006-06-08 22:12:46 -0700939 configSettings->endGroup();
Masahiro Yamadaa2574c12020-10-24 21:38:41 +0900940 connect(configApp, &QApplication::aboutToQuit,
941 this, &ConfigInfoView::saveSettings);
Roman Zippel7fc925f2006-06-08 22:12:46 -0700942 }
Masahiro Yamada7d1300e2020-08-18 01:36:30 +0900943
944 contextMenu = createStandardContextMenu();
945 QAction *action = new QAction("Show Debug Info", contextMenu);
946
947 action->setCheckable(true);
Masahiro Yamadaa2574c12020-10-24 21:38:41 +0900948 connect(action, &QAction::toggled,
949 this, &ConfigInfoView::setShowDebug);
950 connect(this, &ConfigInfoView::showDebugChanged,
951 action, &QAction::setChecked);
Masahiro Yamada7d1300e2020-08-18 01:36:30 +0900952 action->setChecked(showDebug());
953 contextMenu->addSeparator();
954 contextMenu->addAction(action);
Roman Zippel7fc925f2006-06-08 22:12:46 -0700955}
956
957void ConfigInfoView::saveSettings(void)
958{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700959 if (!objectName().isEmpty()) {
960 configSettings->beginGroup(objectName());
961 configSettings->setValue("/showDebug", showDebug());
962 configSettings->endGroup();
963 }
Roman Zippel43bf6122006-06-08 22:12:45 -0700964}
965
966void ConfigInfoView::setShowDebug(bool b)
967{
968 if (_showDebug != b) {
969 _showDebug = b;
Alexander Stein133c5f72010-08-31 17:34:37 +0200970 if (_menu)
Roman Zippel43bf6122006-06-08 22:12:45 -0700971 menuInfo();
Roman Zippelab45d192006-06-08 22:12:47 -0700972 else if (sym)
973 symbolInfo();
Roman Zippel43bf6122006-06-08 22:12:45 -0700974 emit showDebugChanged(b);
975 }
976}
977
978void ConfigInfoView::setInfo(struct menu *m)
979{
Alexander Stein133c5f72010-08-31 17:34:37 +0200980 if (_menu == m)
Roman Zippelb65a47e2006-06-08 22:12:47 -0700981 return;
Alexander Stein133c5f72010-08-31 17:34:37 +0200982 _menu = m;
Roman Zippel6fa1da82007-01-10 23:15:31 -0800983 sym = NULL;
Alexander Stein133c5f72010-08-31 17:34:37 +0200984 if (!_menu)
Roman Zippel43bf6122006-06-08 22:12:45 -0700985 clear();
Roman Zippel6fa1da82007-01-10 23:15:31 -0800986 else
Roman Zippel43bf6122006-06-08 22:12:45 -0700987 menuInfo();
988}
989
Roman Zippelab45d192006-06-08 22:12:47 -0700990void ConfigInfoView::symbolInfo(void)
991{
992 QString str;
993
994 str += "<big>Symbol: <b>";
995 str += print_filter(sym->name);
996 str += "</b></big><br><br>value: ";
997 str += print_filter(sym_get_string_value(sym));
998 str += "<br>visibility: ";
999 str += sym->visible == yes ? "y" : sym->visible == mod ? "m" : "n";
1000 str += "<br>";
1001 str += debug_info(sym);
1002
1003 setText(str);
1004}
1005
Roman Zippel43bf6122006-06-08 22:12:45 -07001006void ConfigInfoView::menuInfo(void)
1007{
1008 struct symbol* sym;
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001009 QString info;
1010 QTextStream stream(&info);
Roman Zippel43bf6122006-06-08 22:12:45 -07001011
Alexander Stein133c5f72010-08-31 17:34:37 +02001012 sym = _menu->sym;
Roman Zippel43bf6122006-06-08 22:12:45 -07001013 if (sym) {
Alexander Stein133c5f72010-08-31 17:34:37 +02001014 if (_menu->prompt) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001015 stream << "<big><b>";
1016 stream << print_filter(_menu->prompt->text);
1017 stream << "</b></big>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001018 if (sym->name) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001019 stream << " (";
Roman Zippelab45d192006-06-08 22:12:47 -07001020 if (showDebug())
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001021 stream << "<a href=\"s" << sym->name << "\">";
1022 stream << print_filter(sym->name);
Roman Zippelab45d192006-06-08 22:12:47 -07001023 if (showDebug())
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001024 stream << "</a>";
1025 stream << ")";
Roman Zippel43bf6122006-06-08 22:12:45 -07001026 }
1027 } else if (sym->name) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001028 stream << "<big><b>";
Roman Zippelab45d192006-06-08 22:12:47 -07001029 if (showDebug())
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001030 stream << "<a href=\"s" << sym->name << "\">";
1031 stream << print_filter(sym->name);
Roman Zippelab45d192006-06-08 22:12:47 -07001032 if (showDebug())
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001033 stream << "</a>";
1034 stream << "</b></big>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001035 }
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001036 stream << "<br><br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001037
1038 if (showDebug())
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001039 stream << debug_info(sym);
1040
Masahiro Yamadaa46afd12020-09-14 23:59:48 +09001041 struct gstr help_gstr = str_new();
1042
1043 menu_get_ext_help(_menu, &help_gstr);
1044 stream << print_filter(str_get(&help_gstr));
1045 str_free(&help_gstr);
Alexander Stein133c5f72010-08-31 17:34:37 +02001046 } else if (_menu->prompt) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001047 stream << "<big><b>";
1048 stream << print_filter(_menu->prompt->text);
1049 stream << "</b></big><br><br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001050 if (showDebug()) {
Alexander Stein133c5f72010-08-31 17:34:37 +02001051 if (_menu->prompt->visible.expr) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001052 stream << "&nbsp;&nbsp;dep: ";
1053 expr_print(_menu->prompt->visible.expr,
1054 expr_print_help, &stream, E_NONE);
1055 stream << "<br><br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001056 }
Masahiro Yamadaa46afd12020-09-14 23:59:48 +09001057
1058 stream << "defined at " << _menu->file->name << ":"
1059 << _menu->lineno << "<br><br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001060 }
1061 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001062
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001063 setText(info);
Roman Zippel43bf6122006-06-08 22:12:45 -07001064}
1065
1066QString ConfigInfoView::debug_info(struct symbol *sym)
1067{
1068 QString debug;
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001069 QTextStream stream(&debug);
Roman Zippel43bf6122006-06-08 22:12:45 -07001070
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001071 stream << "type: ";
1072 stream << print_filter(sym_type_name(sym->type));
Roman Zippel43bf6122006-06-08 22:12:45 -07001073 if (sym_is_choice(sym))
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001074 stream << " (choice)";
Roman Zippel43bf6122006-06-08 22:12:45 -07001075 debug += "<br>";
1076 if (sym->rev_dep.expr) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001077 stream << "reverse dep: ";
1078 expr_print(sym->rev_dep.expr, expr_print_help, &stream, E_NONE);
1079 stream << "<br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001080 }
1081 for (struct property *prop = sym->prop; prop; prop = prop->next) {
1082 switch (prop->type) {
1083 case P_PROMPT:
1084 case P_MENU:
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001085 stream << "prompt: <a href=\"m" << sym->name << "\">";
1086 stream << print_filter(prop->text);
1087 stream << "</a><br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001088 break;
1089 case P_DEFAULT:
Roman Zippel93449082008-01-14 04:50:54 +01001090 case P_SELECT:
1091 case P_RANGE:
Mauro Carvalho Chehab8f8499a2020-06-30 08:48:53 +02001092 case P_COMMENT:
1093 case P_IMPLY:
1094 case P_SYMBOL:
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001095 stream << prop_get_type_name(prop->type);
1096 stream << ": ";
1097 expr_print(prop->expr, expr_print_help,
1098 &stream, E_NONE);
1099 stream << "<br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001100 break;
1101 case P_CHOICE:
1102 if (sym_is_choice(sym)) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001103 stream << "choice: ";
1104 expr_print(prop->expr, expr_print_help,
1105 &stream, E_NONE);
1106 stream << "<br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001107 }
1108 break;
Roman Zippel43bf6122006-06-08 22:12:45 -07001109 default:
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001110 stream << "unknown property: ";
1111 stream << prop_get_type_name(prop->type);
1112 stream << "<br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001113 }
1114 if (prop->visible.expr) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001115 stream << "&nbsp;&nbsp;&nbsp;&nbsp;dep: ";
1116 expr_print(prop->visible.expr, expr_print_help,
1117 &stream, E_NONE);
1118 stream << "<br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001119 }
1120 }
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001121 stream << "<br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001122
1123 return debug;
1124}
1125
1126QString ConfigInfoView::print_filter(const QString &str)
1127{
1128 QRegExp re("[<>&\"\\n]");
1129 QString res = str;
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001130 for (int i = 0; (i = res.indexOf(re, i)) >= 0;) {
1131 switch (res[i].toLatin1()) {
Roman Zippel43bf6122006-06-08 22:12:45 -07001132 case '<':
1133 res.replace(i, 1, "&lt;");
1134 i += 4;
1135 break;
1136 case '>':
1137 res.replace(i, 1, "&gt;");
1138 i += 4;
1139 break;
1140 case '&':
1141 res.replace(i, 1, "&amp;");
1142 i += 5;
1143 break;
1144 case '"':
1145 res.replace(i, 1, "&quot;");
1146 i += 6;
1147 break;
1148 case '\n':
1149 res.replace(i, 1, "<br>");
1150 i += 4;
1151 break;
1152 }
1153 }
1154 return res;
1155}
1156
Roman Zippelab45d192006-06-08 22:12:47 -07001157void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char *str)
Roman Zippel43bf6122006-06-08 22:12:45 -07001158{
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001159 QTextStream *stream = reinterpret_cast<QTextStream *>(data);
Roman Zippelab45d192006-06-08 22:12:47 -07001160
1161 if (sym && sym->name && !(sym->flags & SYMBOL_CONST)) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001162 *stream << "<a href=\"s" << sym->name << "\">";
1163 *stream << print_filter(str);
1164 *stream << "</a>";
1165 } else {
1166 *stream << print_filter(str);
1167 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001168}
1169
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001170void ConfigInfoView::clicked(const QUrl &url)
1171{
1172 QByteArray str = url.toEncoded();
1173 const std::size_t count = str.size();
1174 char *data = new char[count + 1];
1175 struct symbol **result;
1176 struct menu *m = NULL;
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001177
1178 if (count < 1) {
Masahiro Yamadac9b09a922020-07-30 02:02:39 +09001179 delete[] data;
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001180 return;
1181 }
1182
1183 memcpy(data, str.constData(), count);
1184 data[count] = '\0';
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001185
1186 /* Seek for exact match */
1187 data[0] = '^';
1188 strcat(data, "$");
1189 result = sym_re_search(data);
1190 if (!result) {
Masahiro Yamadac9b09a922020-07-30 02:02:39 +09001191 delete[] data;
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001192 return;
1193 }
1194
1195 sym = *result;
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001196
Mauro Carvalho Chehab8a3b6e52020-06-30 08:48:35 +02001197 /* Seek for the menu which holds the symbol */
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001198 for (struct property *prop = sym->prop; prop; prop = prop->next) {
1199 if (prop->type != P_PROMPT && prop->type != P_MENU)
1200 continue;
1201 m = prop->menu;
1202 break;
1203 }
1204
1205 if (!m) {
Mauro Carvalho Chehab8a3b6e52020-06-30 08:48:35 +02001206 /* Symbol is not visible as a menu */
1207 symbolInfo();
1208 emit showDebugChanged(true);
1209 } else {
1210 emit menuSelected(m);
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001211 }
1212
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001213 free(result);
Masahiro Yamadaa608b6a2020-09-09 07:16:37 +09001214 delete[] data;
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001215}
1216
Masahiro Yamada7d1300e2020-08-18 01:36:30 +09001217void ConfigInfoView::contextMenuEvent(QContextMenuEvent *event)
Roman Zippel7fc925f2006-06-08 22:12:46 -07001218{
Masahiro Yamada7d1300e2020-08-18 01:36:30 +09001219 contextMenu->popup(event->globalPos());
1220 event->accept();
Roman Zippel7fc925f2006-06-08 22:12:46 -07001221}
1222
Masahiro Yamada740fdef2020-08-07 18:18:57 +09001223ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow *parent)
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001224 : Parent(parent), result(NULL)
Roman Zippel43bf6122006-06-08 22:12:45 -07001225{
Masahiro Yamada740fdef2020-08-07 18:18:57 +09001226 setObjectName("search");
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001227 setWindowTitle("Search Config");
Roman Zippel43bf6122006-06-08 22:12:45 -07001228
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001229 QVBoxLayout* layout1 = new QVBoxLayout(this);
1230 layout1->setContentsMargins(11, 11, 11, 11);
1231 layout1->setSpacing(6);
Masahiro Yamada92641152020-08-07 18:18:58 +09001232
1233 QHBoxLayout* layout2 = new QHBoxLayout();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001234 layout2->setContentsMargins(0, 0, 0, 0);
1235 layout2->setSpacing(6);
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001236 layout2->addWidget(new QLabel("Find:", this));
Roman Zippel43bf6122006-06-08 22:12:45 -07001237 editField = new QLineEdit(this);
Masahiro Yamadaa2574c12020-10-24 21:38:41 +09001238 connect(editField, &QLineEdit::returnPressed,
1239 this, &ConfigSearchWindow::search);
Roman Zippel43bf6122006-06-08 22:12:45 -07001240 layout2->addWidget(editField);
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001241 searchButton = new QPushButton("Search", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001242 searchButton->setAutoDefault(false);
Masahiro Yamadaa2574c12020-10-24 21:38:41 +09001243 connect(searchButton, &QPushButton::clicked,
1244 this, &ConfigSearchWindow::search);
Roman Zippel43bf6122006-06-08 22:12:45 -07001245 layout2->addWidget(searchButton);
1246 layout1->addLayout(layout2);
1247
Roman Zippel7fc925f2006-06-08 22:12:46 -07001248 split = new QSplitter(this);
Markus Heidelberg7298b932009-05-18 01:36:50 +02001249 split->setOrientation(Qt::Vertical);
Masahiro Yamada62ed1652020-08-29 17:14:15 +09001250 list = new ConfigList(split, "search");
1251 list->mode = listMode;
Masahiro Yamada740fdef2020-08-07 18:18:57 +09001252 info = new ConfigInfoView(split, "search");
Masahiro Yamadaa2574c12020-10-24 21:38:41 +09001253 connect(list, &ConfigList::menuChanged,
1254 info, &ConfigInfoView::setInfo);
1255 connect(list, &ConfigList::menuChanged,
1256 parent, &ConfigMainWindow::setMenuLink);
Marco Costalba63431e72006-10-05 19:12:59 +02001257
Roman Zippel43bf6122006-06-08 22:12:45 -07001258 layout1->addWidget(split);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001259
Masahiro Yamada740fdef2020-08-07 18:18:57 +09001260 QVariant x, y;
1261 int width, height;
1262 bool ok;
Roman Zippel7fc925f2006-06-08 22:12:46 -07001263
Masahiro Yamada740fdef2020-08-07 18:18:57 +09001264 configSettings->beginGroup("search");
1265 width = configSettings->value("/window width", parent->width() / 2).toInt();
1266 height = configSettings->value("/window height", parent->height() / 2).toInt();
1267 resize(width, height);
1268 x = configSettings->value("/window x");
1269 y = configSettings->value("/window y");
1270 if (x.isValid() && y.isValid())
1271 move(x.toInt(), y.toInt());
1272 QList<int> sizes = configSettings->readSizes("/split", &ok);
1273 if (ok)
1274 split->setSizes(sizes);
1275 configSettings->endGroup();
Masahiro Yamadaa2574c12020-10-24 21:38:41 +09001276 connect(configApp, &QApplication::aboutToQuit,
1277 this, &ConfigSearchWindow::saveSettings);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001278}
1279
1280void ConfigSearchWindow::saveSettings(void)
1281{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001282 if (!objectName().isEmpty()) {
1283 configSettings->beginGroup(objectName());
1284 configSettings->setValue("/window x", pos().x());
1285 configSettings->setValue("/window y", pos().y());
1286 configSettings->setValue("/window width", size().width());
1287 configSettings->setValue("/window height", size().height());
1288 configSettings->writeSizes("/split", split->sizes());
1289 configSettings->endGroup();
1290 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001291}
1292
1293void ConfigSearchWindow::search(void)
1294{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001295 struct symbol **p;
1296 struct property *prop;
1297 ConfigItem *lastItem = NULL;
1298
1299 free(result);
Masahiro Yamada62ed1652020-08-29 17:14:15 +09001300 list->clear();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001301 info->clear();
1302
1303 result = sym_re_search(editField->text().toLatin1());
1304 if (!result)
1305 return;
1306 for (p = result; *p; p++) {
1307 for_all_prompts((*p), prop)
Masahiro Yamada62ed1652020-08-29 17:14:15 +09001308 lastItem = new ConfigItem(list, lastItem, prop->menu,
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001309 menu_is_visible(prop->menu));
1310 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001311}
1312
Linus Torvalds1da177e2005-04-16 15:20:36 -07001313/*
1314 * Construct the complete config widget
1315 */
1316ConfigMainWindow::ConfigMainWindow(void)
Roman Zippelf12aa702006-11-25 11:09:31 -08001317 : searchWindow(0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001318{
Boris Barbulovski92119932015-09-22 11:36:16 -07001319 bool ok = true;
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001320 QVariant x, y;
1321 int width, height;
Randy Dunlapa54bb702007-10-20 11:18:47 -07001322 char title[256];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001323
Markus Heidelberg8d90c972009-05-18 01:36:52 +02001324 QDesktopWidget *d = configApp->desktop();
Arnaud Lacombe09548282010-08-18 01:57:13 -04001325 snprintf(title, sizeof(title), "%s%s",
1326 rootmenu.prompt->text,
Michal Marek76a136c2010-09-01 17:39:27 +02001327 ""
Michal Marek76a136c2010-09-01 17:39:27 +02001328 );
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001329 setWindowTitle(title);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001330
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001331 width = configSettings->value("/window width", d->width() - 64).toInt();
1332 height = configSettings->value("/window height", d->height() - 64).toInt();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001333 resize(width, height);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001334 x = configSettings->value("/window x");
1335 y = configSettings->value("/window y");
1336 if ((x.isValid())&&(y.isValid()))
1337 move(x.toInt(), y.toInt());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001338
Masahiro Yamada5cb255f2020-08-07 18:19:07 +09001339 // set up icons
1340 ConfigItem::symbolYesIcon = QIcon(QPixmap(xpm_symbol_yes));
1341 ConfigItem::symbolModIcon = QIcon(QPixmap(xpm_symbol_mod));
1342 ConfigItem::symbolNoIcon = QIcon(QPixmap(xpm_symbol_no));
1343 ConfigItem::choiceYesIcon = QIcon(QPixmap(xpm_choice_yes));
1344 ConfigItem::choiceNoIcon = QIcon(QPixmap(xpm_choice_no));
1345 ConfigItem::menuIcon = QIcon(QPixmap(xpm_menu));
1346 ConfigItem::menubackIcon = QIcon(QPixmap(xpm_menuback));
1347
Mauro Carvalho Chehabcce1fab2020-04-02 11:28:00 +02001348 QWidget *widget = new QWidget(this);
1349 QVBoxLayout *layout = new QVBoxLayout(widget);
1350 setCentralWidget(widget);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001351
Mauro Carvalho Chehabcce1fab2020-04-02 11:28:00 +02001352 split1 = new QSplitter(widget);
1353 split1->setOrientation(Qt::Horizontal);
1354 split1->setChildrenCollapsible(false);
1355
Masahiro Yamada62ed1652020-08-29 17:14:15 +09001356 menuList = new ConfigList(widget, "menu");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001357
Mauro Carvalho Chehabcce1fab2020-04-02 11:28:00 +02001358 split2 = new QSplitter(widget);
1359 split2->setChildrenCollapsible(false);
Markus Heidelberg7298b932009-05-18 01:36:50 +02001360 split2->setOrientation(Qt::Vertical);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001361
1362 // create config tree
Masahiro Yamada62ed1652020-08-29 17:14:15 +09001363 configList = new ConfigList(widget, "config");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001364
Mauro Carvalho Chehabcce1fab2020-04-02 11:28:00 +02001365 helpText = new ConfigInfoView(widget, "help");
1366
1367 layout->addWidget(split2);
1368 split2->addWidget(split1);
Masahiro Yamada62ed1652020-08-29 17:14:15 +09001369 split1->addWidget(configList);
1370 split1->addWidget(menuList);
Mauro Carvalho Chehabcce1fab2020-04-02 11:28:00 +02001371 split2->addWidget(helpText);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001372
1373 setTabOrder(configList, helpText);
1374 configList->setFocus();
1375
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001376 backAction = new QAction(QPixmap(xpm_back), "Back", this);
Masahiro Yamadaa2574c12020-10-24 21:38:41 +09001377 connect(backAction, &QAction::triggered,
1378 this, &ConfigMainWindow::goBack);
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001379
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001380 QAction *quitAction = new QAction("&Quit", this);
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001381 quitAction->setShortcut(Qt::CTRL + Qt::Key_Q);
Masahiro Yamadaa2574c12020-10-24 21:38:41 +09001382 connect(quitAction, &QAction::triggered,
1383 this, &ConfigMainWindow::close);
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001384
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001385 QAction *loadAction = new QAction(QPixmap(xpm_load), "&Load", this);
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001386 loadAction->setShortcut(Qt::CTRL + Qt::Key_L);
Masahiro Yamadaa2574c12020-10-24 21:38:41 +09001387 connect(loadAction, &QAction::triggered,
1388 this, &ConfigMainWindow::loadConfig);
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001389
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001390 saveAction = new QAction(QPixmap(xpm_save), "&Save", this);
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001391 saveAction->setShortcut(Qt::CTRL + Qt::Key_S);
Masahiro Yamadaa2574c12020-10-24 21:38:41 +09001392 connect(saveAction, &QAction::triggered,
1393 this, &ConfigMainWindow::saveConfig);
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001394
Karsten Wiese3b354c52006-12-13 00:34:08 -08001395 conf_set_changed_callback(conf_changed);
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001396
Karsten Wiese3b354c52006-12-13 00:34:08 -08001397 // Set saveAction's initial state
1398 conf_changed();
Masahiro Yamada87419082019-03-11 01:13:15 +09001399 configname = xstrdup(conf_get_configname());
1400
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001401 QAction *saveAsAction = new QAction("Save &As...", this);
Masahiro Yamadaa2574c12020-10-24 21:38:41 +09001402 connect(saveAsAction, &QAction::triggered,
1403 this, &ConfigMainWindow::saveConfigAs);
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001404 QAction *searchAction = new QAction("&Find", this);
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001405 searchAction->setShortcut(Qt::CTRL + Qt::Key_F);
Masahiro Yamadaa2574c12020-10-24 21:38:41 +09001406 connect(searchAction, &QAction::triggered,
1407 this, &ConfigMainWindow::searchConfig);
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001408 singleViewAction = new QAction(QPixmap(xpm_single_view), "Single View", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001409 singleViewAction->setCheckable(true);
Masahiro Yamadaa2574c12020-10-24 21:38:41 +09001410 connect(singleViewAction, &QAction::triggered,
1411 this, &ConfigMainWindow::showSingleView);
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001412 splitViewAction = new QAction(QPixmap(xpm_split_view), "Split View", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001413 splitViewAction->setCheckable(true);
Masahiro Yamadaa2574c12020-10-24 21:38:41 +09001414 connect(splitViewAction, &QAction::triggered,
1415 this, &ConfigMainWindow::showSplitView);
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001416 fullViewAction = new QAction(QPixmap(xpm_tree_view), "Full View", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001417 fullViewAction->setCheckable(true);
Masahiro Yamadaa2574c12020-10-24 21:38:41 +09001418 connect(fullViewAction, &QAction::triggered,
1419 this, &ConfigMainWindow::showFullView);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001420
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001421 QAction *showNameAction = new QAction("Show Name", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001422 showNameAction->setCheckable(true);
Masahiro Yamadaa2574c12020-10-24 21:38:41 +09001423 connect(showNameAction, &QAction::toggled,
1424 configList, &ConfigList::setShowName);
Masahiro Yamada7930dd92020-08-29 17:14:14 +09001425 showNameAction->setChecked(configList->showName);
1426
Li Zefan39a48972010-05-10 16:33:41 +08001427 QActionGroup *optGroup = new QActionGroup(this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001428 optGroup->setExclusive(true);
Masahiro Yamadaa2574c12020-10-24 21:38:41 +09001429 connect(optGroup, &QActionGroup::triggered,
1430 configList, &ConfigList::setOptionMode);
1431 connect(optGroup, &QActionGroup::triggered,
1432 menuList, &ConfigList::setOptionMode);
Li Zefan39a48972010-05-10 16:33:41 +08001433
Masahiro Yamadad4bbe8a2020-08-07 18:19:09 +09001434 ConfigList::showNormalAction = new QAction("Show Normal Options", optGroup);
1435 ConfigList::showNormalAction->setCheckable(true);
1436 ConfigList::showAllAction = new QAction("Show All Options", optGroup);
1437 ConfigList::showAllAction->setCheckable(true);
1438 ConfigList::showPromptAction = new QAction("Show Prompt Options", optGroup);
1439 ConfigList::showPromptAction->setCheckable(true);
Li Zefan39a48972010-05-10 16:33:41 +08001440
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001441 QAction *showDebugAction = new QAction("Show Debug Info", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001442 showDebugAction->setCheckable(true);
Masahiro Yamadaa2574c12020-10-24 21:38:41 +09001443 connect(showDebugAction, &QAction::toggled,
1444 helpText, &ConfigInfoView::setShowDebug);
Boris Barbulovski9c862352015-09-22 11:36:12 -07001445 showDebugAction->setChecked(helpText->showDebug());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001446
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001447 QAction *showIntroAction = new QAction("Introduction", this);
Masahiro Yamadaa2574c12020-10-24 21:38:41 +09001448 connect(showIntroAction, &QAction::triggered,
1449 this, &ConfigMainWindow::showIntro);
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001450 QAction *showAboutAction = new QAction("About", this);
Masahiro Yamadaa2574c12020-10-24 21:38:41 +09001451 connect(showAboutAction, &QAction::triggered,
1452 this, &ConfigMainWindow::showAbout);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001453
1454 // init tool bar
Masahiro Yamada860ec3f2020-08-07 18:18:55 +09001455 QToolBar *toolBar = addToolBar("Tools");
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001456 toolBar->addAction(backAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001457 toolBar->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001458 toolBar->addAction(loadAction);
1459 toolBar->addAction(saveAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001460 toolBar->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001461 toolBar->addAction(singleViewAction);
1462 toolBar->addAction(splitViewAction);
1463 toolBar->addAction(fullViewAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001464
Masahiro Yamada93ebaac2020-08-07 18:18:53 +09001465 // create file menu
1466 QMenu *menu = menuBar()->addMenu("&File");
1467 menu->addAction(loadAction);
1468 menu->addAction(saveAction);
1469 menu->addAction(saveAsAction);
1470 menu->addSeparator();
1471 menu->addAction(quitAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001472
Shlomi Fish66e7c722007-02-14 00:32:58 -08001473 // create edit menu
Masahiro Yamada93ebaac2020-08-07 18:18:53 +09001474 menu = menuBar()->addMenu("&Edit");
1475 menu->addAction(searchAction);
Shlomi Fish66e7c722007-02-14 00:32:58 -08001476
Linus Torvalds1da177e2005-04-16 15:20:36 -07001477 // create options menu
Masahiro Yamada93ebaac2020-08-07 18:18:53 +09001478 menu = menuBar()->addMenu("&Option");
1479 menu->addAction(showNameAction);
Masahiro Yamada93ebaac2020-08-07 18:18:53 +09001480 menu->addSeparator();
1481 menu->addActions(optGroup->actions());
1482 menu->addSeparator();
1483 menu->addAction(showDebugAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001484
1485 // create help menu
Masahiro Yamada93ebaac2020-08-07 18:18:53 +09001486 menu = menuBar()->addMenu("&Help");
1487 menu->addAction(showIntroAction);
1488 menu->addAction(showAboutAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001489
Masahiro Yamadaa2574c12020-10-24 21:38:41 +09001490 connect(helpText, &ConfigInfoView::anchorClicked,
1491 helpText, &ConfigInfoView::clicked);
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001492
Masahiro Yamadaa2574c12020-10-24 21:38:41 +09001493 connect(configList, &ConfigList::menuChanged,
1494 helpText, &ConfigInfoView::setInfo);
1495 connect(configList, &ConfigList::menuSelected,
1496 this, &ConfigMainWindow::changeMenu);
1497 connect(configList, &ConfigList::itemSelected,
1498 this, &ConfigMainWindow::changeItens);
1499 connect(configList, &ConfigList::parentSelected,
1500 this, &ConfigMainWindow::goBack);
1501 connect(menuList, &ConfigList::menuChanged,
1502 helpText, &ConfigInfoView::setInfo);
1503 connect(menuList, &ConfigList::menuSelected,
1504 this, &ConfigMainWindow::changeMenu);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001505
Masahiro Yamadaa2574c12020-10-24 21:38:41 +09001506 connect(configList, &ConfigList::gotFocus,
1507 helpText, &ConfigInfoView::setInfo);
1508 connect(menuList, &ConfigList::gotFocus,
1509 helpText, &ConfigInfoView::setInfo);
1510 connect(menuList, &ConfigList::gotFocus,
1511 this, &ConfigMainWindow::listFocusChanged);
1512 connect(helpText, &ConfigInfoView::menuSelected,
1513 this, &ConfigMainWindow::setMenuLink);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001514
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001515 QString listMode = configSettings->value("/listMode", "symbol").toString();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001516 if (listMode == "single")
1517 showSingleView();
1518 else if (listMode == "full")
1519 showFullView();
1520 else /*if (listMode == "split")*/
1521 showSplitView();
1522
1523 // UI setup done, restore splitter positions
Boris Barbulovski041fbdc2015-09-22 11:36:05 -07001524 QList<int> sizes = configSettings->readSizes("/split1", &ok);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001525 if (ok)
1526 split1->setSizes(sizes);
1527
Roman Zippel7fc925f2006-06-08 22:12:46 -07001528 sizes = configSettings->readSizes("/split2", &ok);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001529 if (ok)
1530 split2->setSizes(sizes);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001531}
1532
Linus Torvalds1da177e2005-04-16 15:20:36 -07001533void ConfigMainWindow::loadConfig(void)
1534{
Masahiro Yamada87419082019-03-11 01:13:15 +09001535 QString str;
1536 QByteArray ba;
1537 const char *name;
1538
1539 str = QFileDialog::getOpenFileName(this, "", configname);
1540 if (str.isNull())
Linus Torvalds1da177e2005-04-16 15:20:36 -07001541 return;
Masahiro Yamada87419082019-03-11 01:13:15 +09001542
1543 ba = str.toLocal8Bit();
1544 name = ba.data();
1545
1546 if (conf_read(name))
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001547 QMessageBox::information(this, "qconf", "Unable to load configuration!");
Masahiro Yamada87419082019-03-11 01:13:15 +09001548
1549 free(configname);
1550 configname = xstrdup(name);
1551
Masahiro Yamadaf9b918f2020-08-29 17:14:10 +09001552 ConfigList::updateListAllForAll();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001553}
1554
Michal Marekbac6aa82011-05-25 15:10:25 +02001555bool ConfigMainWindow::saveConfig(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001556{
Masahiro Yamada87419082019-03-11 01:13:15 +09001557 if (conf_write(configname)) {
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001558 QMessageBox::information(this, "qconf", "Unable to save configuration!");
Michal Marekbac6aa82011-05-25 15:10:25 +02001559 return false;
1560 }
Masahiro Yamada00c864f2018-07-20 16:46:31 +09001561 conf_write_autoconf(0);
1562
Michal Marekbac6aa82011-05-25 15:10:25 +02001563 return true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001564}
1565
1566void ConfigMainWindow::saveConfigAs(void)
1567{
Masahiro Yamada87419082019-03-11 01:13:15 +09001568 QString str;
1569 QByteArray ba;
1570 const char *name;
1571
1572 str = QFileDialog::getSaveFileName(this, "", configname);
1573 if (str.isNull())
Linus Torvalds1da177e2005-04-16 15:20:36 -07001574 return;
Masahiro Yamada87419082019-03-11 01:13:15 +09001575
1576 ba = str.toLocal8Bit();
1577 name = ba.data();
1578
1579 if (conf_write(name)) {
1580 QMessageBox::information(this, "qconf", "Unable to save configuration!");
1581 }
1582 conf_write_autoconf(0);
1583
1584 free(configname);
1585 configname = xstrdup(name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001586}
1587
Roman Zippel43bf6122006-06-08 22:12:45 -07001588void ConfigMainWindow::searchConfig(void)
1589{
1590 if (!searchWindow)
Masahiro Yamada740fdef2020-08-07 18:18:57 +09001591 searchWindow = new ConfigSearchWindow(this);
Roman Zippel43bf6122006-06-08 22:12:45 -07001592 searchWindow->show();
1593}
1594
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +02001595void ConfigMainWindow::changeItens(struct menu *menu)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001596{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001597 configList->setRootMenu(menu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001598}
1599
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +02001600void ConfigMainWindow::changeMenu(struct menu *menu)
1601{
1602 menuList->setRootMenu(menu);
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +02001603}
1604
Roman Zippelb65a47e2006-06-08 22:12:47 -07001605void ConfigMainWindow::setMenuLink(struct menu *menu)
1606{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001607 struct menu *parent;
1608 ConfigList* list = NULL;
1609 ConfigItem* item;
1610
1611 if (configList->menuSkip(menu))
1612 return;
1613
1614 switch (configList->mode) {
1615 case singleMode:
1616 list = configList;
1617 parent = menu_get_parent_menu(menu);
1618 if (!parent)
1619 return;
1620 list->setRootMenu(parent);
1621 break;
Mauro Carvalho Chehabc699eaa2020-06-30 08:26:36 +02001622 case menuMode:
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001623 if (menu->flags & MENU_ROOT) {
Mauro Carvalho Chehabc699eaa2020-06-30 08:26:36 +02001624 menuList->setRootMenu(menu);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001625 configList->clearSelection();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001626 list = configList;
Mauro Carvalho Chehabc699eaa2020-06-30 08:26:36 +02001627 } else {
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001628 parent = menu_get_parent_menu(menu->parent);
1629 if (!parent)
1630 return;
Mauro Carvalho Chehabc699eaa2020-06-30 08:26:36 +02001631
Mauro Carvalho Chehabc699eaa2020-06-30 08:26:36 +02001632 /* Select the config view */
1633 item = configList->findConfigItem(parent);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001634 if (item) {
Mauro Carvalho Chehabb06c3ec2020-06-30 08:26:38 +02001635 configList->setSelected(item, true);
Mauro Carvalho Chehabc699eaa2020-06-30 08:26:36 +02001636 configList->scrollToItem(item);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001637 }
Mauro Carvalho Chehabc699eaa2020-06-30 08:26:36 +02001638
1639 menuList->setRootMenu(parent);
1640 menuList->clearSelection();
1641 list = menuList;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001642 }
1643 break;
1644 case fullMode:
1645 list = configList;
1646 break;
1647 default:
1648 break;
1649 }
1650
1651 if (list) {
1652 item = list->findConfigItem(menu);
1653 if (item) {
Mauro Carvalho Chehabb06c3ec2020-06-30 08:26:38 +02001654 list->setSelected(item, true);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001655 list->scrollToItem(item);
1656 list->setFocus();
Mauro Carvalho Chehab8a3b6e52020-06-30 08:48:35 +02001657 helpText->setInfo(menu);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001658 }
1659 }
Roman Zippelb65a47e2006-06-08 22:12:47 -07001660}
1661
Linus Torvalds1da177e2005-04-16 15:20:36 -07001662void ConfigMainWindow::listFocusChanged(void)
1663{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001664 if (menuList->mode == menuMode)
1665 configList->clearSelection();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001666}
1667
1668void ConfigMainWindow::goBack(void)
1669{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001670 if (configList->rootEntry == &rootmenu)
Boris Barbulovskibe596aa2015-09-22 11:36:28 -07001671 return;
1672
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001673 configList->setParentMenu();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001674}
1675
1676void ConfigMainWindow::showSingleView(void)
1677{
Boris Barbulovski780505e2015-09-22 11:36:13 -07001678 singleViewAction->setEnabled(false);
1679 singleViewAction->setChecked(true);
1680 splitViewAction->setEnabled(true);
1681 splitViewAction->setChecked(false);
1682 fullViewAction->setEnabled(true);
1683 fullViewAction->setChecked(false);
1684
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001685 backAction->setEnabled(true);
1686
Masahiro Yamada62ed1652020-08-29 17:14:15 +09001687 menuList->hide();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001688 menuList->setRootMenu(0);
1689 configList->mode = singleMode;
1690 if (configList->rootEntry == &rootmenu)
1691 configList->updateListAll();
1692 else
1693 configList->setRootMenu(&rootmenu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001694 configList->setFocus();
1695}
1696
1697void ConfigMainWindow::showSplitView(void)
1698{
Boris Barbulovski780505e2015-09-22 11:36:13 -07001699 singleViewAction->setEnabled(true);
1700 singleViewAction->setChecked(false);
1701 splitViewAction->setEnabled(false);
1702 splitViewAction->setChecked(true);
1703 fullViewAction->setEnabled(true);
1704 fullViewAction->setChecked(false);
1705
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001706 backAction->setEnabled(false);
1707
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +02001708 configList->mode = menuMode;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001709 if (configList->rootEntry == &rootmenu)
1710 configList->updateListAll();
1711 else
1712 configList->setRootMenu(&rootmenu);
1713 configList->setAllOpen(true);
1714 configApp->processEvents();
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +02001715 menuList->mode = symbolMode;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001716 menuList->setRootMenu(&rootmenu);
1717 menuList->setAllOpen(true);
Masahiro Yamada62ed1652020-08-29 17:14:15 +09001718 menuList->show();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001719 menuList->setFocus();
1720}
1721
1722void ConfigMainWindow::showFullView(void)
1723{
Boris Barbulovski780505e2015-09-22 11:36:13 -07001724 singleViewAction->setEnabled(true);
1725 singleViewAction->setChecked(false);
1726 splitViewAction->setEnabled(true);
1727 splitViewAction->setChecked(false);
1728 fullViewAction->setEnabled(false);
1729 fullViewAction->setChecked(true);
1730
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001731 backAction->setEnabled(false);
1732
Masahiro Yamada62ed1652020-08-29 17:14:15 +09001733 menuList->hide();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001734 menuList->setRootMenu(0);
1735 configList->mode = fullMode;
1736 if (configList->rootEntry == &rootmenu)
1737 configList->updateListAll();
1738 else
1739 configList->setRootMenu(&rootmenu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001740 configList->setFocus();
1741}
1742
Linus Torvalds1da177e2005-04-16 15:20:36 -07001743/*
1744 * ask for saving configuration before quitting
Linus Torvalds1da177e2005-04-16 15:20:36 -07001745 */
1746void ConfigMainWindow::closeEvent(QCloseEvent* e)
1747{
Karsten Wieseb3214292006-12-13 00:34:06 -08001748 if (!conf_get_changed()) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001749 e->accept();
1750 return;
1751 }
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001752 QMessageBox mb("qconf", "Save configuration?", QMessageBox::Warning,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001753 QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape);
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001754 mb.setButtonText(QMessageBox::Yes, "&Save Changes");
1755 mb.setButtonText(QMessageBox::No, "&Discard Changes");
1756 mb.setButtonText(QMessageBox::Cancel, "Cancel Exit");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001757 switch (mb.exec()) {
1758 case QMessageBox::Yes:
Michal Marekbac6aa82011-05-25 15:10:25 +02001759 if (saveConfig())
1760 e->accept();
1761 else
1762 e->ignore();
1763 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001764 case QMessageBox::No:
1765 e->accept();
1766 break;
1767 case QMessageBox::Cancel:
1768 e->ignore();
1769 break;
1770 }
1771}
1772
1773void ConfigMainWindow::showIntro(void)
1774{
Masahiro Yamada8c30e7e2020-08-29 17:14:07 +09001775 static const QString str =
1776 "Welcome to the qconf graphical configuration tool.\n"
1777 "\n"
Masahiro Yamada37162a62020-08-29 17:14:12 +09001778 "For bool and tristate options, a blank box indicates the "
1779 "feature is disabled, a check indicates it is enabled, and a "
1780 "dot indicates that it is to be compiled as a module. Clicking "
1781 "on the box will cycle through the three states. For int, hex, "
1782 "and string options, double-clicking or pressing F2 on the "
1783 "Value cell will allow you to edit the value.\n"
Masahiro Yamada8c30e7e2020-08-29 17:14:07 +09001784 "\n"
1785 "If you do not see an option (e.g., a device driver) that you "
1786 "believe should be present, try turning on Show All Options "
Masahiro Yamada1fb75242020-08-29 17:14:08 +09001787 "under the Options menu. Enabling Show Debug Info will help you"
1788 "figure out what other options must be enabled to support the "
1789 "option you are interested in, and hyperlinks will navigate to "
1790 "them.\n"
Masahiro Yamada8c30e7e2020-08-29 17:14:07 +09001791 "\n"
1792 "Toggling Show Debug Info under the Options menu will show the "
1793 "dependencies, which you can then match by examining other "
1794 "options.\n";
Linus Torvalds1da177e2005-04-16 15:20:36 -07001795
1796 QMessageBox::information(this, "qconf", str);
1797}
1798
1799void ConfigMainWindow::showAbout(void)
1800{
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001801 static const QString str = "qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n"
Masahiro Yamadaf4632692020-11-02 11:59:57 +09001802 "Copyright (C) 2015 Boris Barbulovski <bbarbulovski@gmail.com>.\n"
1803 "\n"
1804 "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n"
1805 "\n"
1806 "Qt Version: ";
Linus Torvalds1da177e2005-04-16 15:20:36 -07001807
Masahiro Yamadaf4632692020-11-02 11:59:57 +09001808 QMessageBox::information(this, "qconf", str + qVersion());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001809}
1810
1811void ConfigMainWindow::saveSettings(void)
1812{
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001813 configSettings->setValue("/window x", pos().x());
1814 configSettings->setValue("/window y", pos().y());
1815 configSettings->setValue("/window width", size().width());
1816 configSettings->setValue("/window height", size().height());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001817
1818 QString entry;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001819 switch(configList->mode) {
1820 case singleMode :
1821 entry = "single";
1822 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001823
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001824 case symbolMode :
1825 entry = "split";
1826 break;
1827
1828 case fullMode :
1829 entry = "full";
1830 break;
1831
1832 default:
1833 break;
1834 }
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001835 configSettings->setValue("/listMode", entry);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001836
Roman Zippel7fc925f2006-06-08 22:12:46 -07001837 configSettings->writeSizes("/split1", split1->sizes());
1838 configSettings->writeSizes("/split2", split2->sizes());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001839}
1840
Karsten Wiese3b354c52006-12-13 00:34:08 -08001841void ConfigMainWindow::conf_changed(void)
1842{
1843 if (saveAction)
1844 saveAction->setEnabled(conf_get_changed());
1845}
1846
Linus Torvalds1da177e2005-04-16 15:20:36 -07001847void fixup_rootmenu(struct menu *menu)
1848{
1849 struct menu *child;
1850 static int menu_cnt = 0;
1851
1852 menu->flags |= MENU_ROOT;
1853 for (child = menu->list; child; child = child->next) {
1854 if (child->prompt && child->prompt->type == P_MENU) {
1855 menu_cnt++;
1856 fixup_rootmenu(child);
1857 menu_cnt--;
1858 } else if (!menu_cnt)
1859 fixup_rootmenu(child);
1860 }
1861}
1862
1863static const char *progname;
1864
1865static void usage(void)
1866{
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001867 printf("%s [-s] <config>\n", progname);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001868 exit(0);
1869}
1870
1871int main(int ac, char** av)
1872{
1873 ConfigMainWindow* v;
1874 const char *name;
1875
Linus Torvalds1da177e2005-04-16 15:20:36 -07001876 progname = av[0];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001877 if (ac > 1 && av[1][0] == '-') {
1878 switch (av[1][1]) {
Michal Marek0a1f00a2015-04-08 13:30:42 +02001879 case 's':
1880 conf_set_message_callback(NULL);
1881 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001882 case 'h':
1883 case '?':
1884 usage();
1885 }
1886 name = av[2];
1887 } else
1888 name = av[1];
1889 if (!name)
1890 usage();
1891
1892 conf_parse(name);
1893 fixup_rootmenu(&rootmenu);
1894 conf_read(NULL);
1895 //zconfdump(stdout);
1896
Masahiro Yamadaf9a825a2020-08-29 17:14:17 +09001897 configApp = new QApplication(ac, av);
1898
Roman Zippel7fc925f2006-06-08 22:12:46 -07001899 configSettings = new ConfigSettings();
1900 configSettings->beginGroup("/kconfig/qconf");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001901 v = new ConfigMainWindow();
1902
1903 //zconfdump(stdout);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001904 configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit()));
1905 configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings()));
Roman Zippel43bf6122006-06-08 22:12:45 -07001906 v->show();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001907 configApp->exec();
1908
Roman Zippel7fc925f2006-06-08 22:12:46 -07001909 configSettings->endGroup();
1910 delete configSettings;
Chris Bainbridge5b61c7b2016-01-08 20:44:04 +00001911 delete v;
1912 delete configApp;
Roman Zippel7fc925f2006-06-08 22:12:46 -07001913
Linus Torvalds1da177e2005-04-16 15:20:36 -07001914 return 0;
1915}