blob: 461681aa5b196a29e5393ec00bc47981cfa9d73c [file] [log] [blame]
Masahiro Yamada0c874102018-12-18 21:13:35 +09001// SPDX-License-Identifier: GPL-2.0
Linus Torvalds1da177e2005-04-16 15:20:36 -07002/*
3 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
Boris Barbulovskib4ff1de2015-09-22 11:36:38 -07004 * Copyright (C) 2015 Boris Barbulovski <bbarbulovski@gmail.com>
Linus Torvalds1da177e2005-04-16 15:20:36 -07005 */
6
Boris Barbulovski85eaf282015-09-22 11:36:03 -07007#include <QAction>
Mauro Carvalho Chehabcf81dfa2020-06-30 08:26:35 +02008#include <QApplication>
9#include <QCloseEvent>
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +020010#include <QDebug>
Mauro Carvalho Chehabcf81dfa2020-06-30 08:26:35 +020011#include <QDesktopWidget>
Boris Barbulovskibea00772015-09-22 11:36:04 -070012#include <QFileDialog>
Mauro Carvalho Chehabcf81dfa2020-06-30 08:26:35 +020013#include <QLabel>
14#include <QLayout>
15#include <QList>
Boris Barbulovski76bede82015-09-22 11:36:07 -070016#include <QMenu>
Mauro Carvalho Chehabcf81dfa2020-06-30 08:26:35 +020017#include <QMenuBar>
18#include <QMessageBox>
19#include <QToolBar>
Linus Torvalds1da177e2005-04-16 15:20:36 -070020
21#include <stdlib.h>
22
23#include "lkc.h"
24#include "qconf.h"
25
Masahiro Yamada3b541978562018-12-21 17:33:07 +090026#include "images.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070027
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -070028
Linus Torvalds1da177e2005-04-16 15:20:36 -070029static QApplication *configApp;
Roman Zippel7fc925f2006-06-08 22:12:46 -070030static ConfigSettings *configSettings;
Linus Torvalds1da177e2005-04-16 15:20:36 -070031
Boris Barbulovski85eaf282015-09-22 11:36:03 -070032QAction *ConfigMainWindow::saveAction;
Karsten Wiese3b354c52006-12-13 00:34:08 -080033
Ben Hutchings00d4f8f2013-10-06 19:21:31 +010034ConfigSettings::ConfigSettings()
35 : QSettings("kernel.org", "qconf")
36{
37}
38
Linus Torvalds1da177e2005-04-16 15:20:36 -070039/**
40 * Reads a list of integer values from the application settings.
41 */
Boris Barbulovski041fbdc2015-09-22 11:36:05 -070042QList<int> ConfigSettings::readSizes(const QString& key, bool *ok)
Linus Torvalds1da177e2005-04-16 15:20:36 -070043{
Boris Barbulovski041fbdc2015-09-22 11:36:05 -070044 QList<int> result;
Li Zefanc1f96f02010-05-07 13:58:04 +080045
Boris Barbulovski83c3a1b2016-11-30 14:57:55 -080046 if (contains(key))
47 {
48 QStringList entryList = value(key).toStringList();
49 QStringList::Iterator it;
50
51 for (it = entryList.begin(); it != entryList.end(); ++it)
52 result.push_back((*it).toInt());
53
54 *ok = true;
55 }
56 else
57 *ok = false;
Linus Torvalds1da177e2005-04-16 15:20:36 -070058
59 return result;
60}
61
62/**
63 * Writes a list of integer values to the application settings.
64 */
Boris Barbulovski041fbdc2015-09-22 11:36:05 -070065bool ConfigSettings::writeSizes(const QString& key, const QList<int>& value)
Linus Torvalds1da177e2005-04-16 15:20:36 -070066{
67 QStringList stringList;
Boris Barbulovski041fbdc2015-09-22 11:36:05 -070068 QList<int>::ConstIterator it;
Linus Torvalds1da177e2005-04-16 15:20:36 -070069
70 for (it = value.begin(); it != value.end(); ++it)
71 stringList.push_back(QString::number(*it));
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -070072 setValue(key, stringList);
Boris Barbulovski59e56442015-09-22 11:36:18 -070073
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -070074 return true;
Linus Torvalds1da177e2005-04-16 15:20:36 -070075}
Linus Torvalds1da177e2005-04-16 15:20:36 -070076
Masahiro Yamada5cb255f2020-08-07 18:19:07 +090077QIcon ConfigItem::symbolYesIcon;
78QIcon ConfigItem::symbolModIcon;
79QIcon ConfigItem::symbolNoIcon;
80QIcon ConfigItem::choiceYesIcon;
81QIcon ConfigItem::choiceNoIcon;
82QIcon ConfigItem::menuIcon;
83QIcon ConfigItem::menubackIcon;
Boris Barbulovski59e56442015-09-22 11:36:18 -070084
85/*
Boris Barbulovski59e56442015-09-22 11:36:18 -070086 * update the displayed of a menu entry
87 */
88void ConfigItem::updateMenu(void)
89{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -070090 ConfigList* list;
91 struct symbol* sym;
92 struct property *prop;
93 QString prompt;
94 int type;
95 tristate expr;
96
97 list = listView();
98 if (goParent) {
Masahiro Yamada5cb255f2020-08-07 18:19:07 +090099 setIcon(promptColIdx, menubackIcon);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700100 prompt = "..";
101 goto set_prompt;
102 }
103
104 sym = menu->sym;
105 prop = menu->prompt;
Masahiro Yamada3c73ff02020-08-07 18:19:02 +0900106 prompt = menu_get_prompt(menu);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700107
108 if (prop) switch (prop->type) {
109 case P_MENU:
110 if (list->mode == singleMode || list->mode == symbolMode) {
111 /* a menuconfig entry is displayed differently
112 * depending whether it's at the view root or a child.
113 */
114 if (sym && list->rootEntry == menu)
115 break;
Masahiro Yamada5cb255f2020-08-07 18:19:07 +0900116 setIcon(promptColIdx, menuIcon);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700117 } else {
118 if (sym)
119 break;
Masahiro Yamada711b8752020-08-07 18:19:03 +0900120 setIcon(promptColIdx, QIcon());
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700121 }
122 goto set_prompt;
123 case P_COMMENT:
Masahiro Yamada711b8752020-08-07 18:19:03 +0900124 setIcon(promptColIdx, QIcon());
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700125 goto set_prompt;
126 default:
127 ;
128 }
129 if (!sym)
130 goto set_prompt;
131
Masahiro Yamada3c73ff02020-08-07 18:19:02 +0900132 setText(nameColIdx, sym->name);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700133
134 type = sym_get_type(sym);
135 switch (type) {
136 case S_BOOLEAN:
137 case S_TRISTATE:
138 char ch;
139
Marco Ammonbaa23ec2019-07-04 12:50:41 +0200140 if (!sym_is_changeable(sym) && list->optMode == normalOpt) {
Masahiro Yamada711b8752020-08-07 18:19:03 +0900141 setIcon(promptColIdx, QIcon());
Mauro Carvalho Chehabcf497b92020-04-02 11:27:58 +0200142 setText(noColIdx, QString());
143 setText(modColIdx, QString());
144 setText(yesColIdx, QString());
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700145 break;
146 }
147 expr = sym_get_tristate_value(sym);
148 switch (expr) {
149 case yes:
150 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
Masahiro Yamada5cb255f2020-08-07 18:19:07 +0900151 setIcon(promptColIdx, choiceYesIcon);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700152 else
Masahiro Yamada5cb255f2020-08-07 18:19:07 +0900153 setIcon(promptColIdx, symbolYesIcon);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700154 setText(yesColIdx, "Y");
155 ch = 'Y';
156 break;
157 case mod:
Masahiro Yamada5cb255f2020-08-07 18:19:07 +0900158 setIcon(promptColIdx, symbolModIcon);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700159 setText(modColIdx, "M");
160 ch = 'M';
161 break;
162 default:
163 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
Masahiro Yamada5cb255f2020-08-07 18:19:07 +0900164 setIcon(promptColIdx, choiceNoIcon);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700165 else
Masahiro Yamada5cb255f2020-08-07 18:19:07 +0900166 setIcon(promptColIdx, symbolNoIcon);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700167 setText(noColIdx, "N");
168 ch = 'N';
169 break;
170 }
171 if (expr != no)
172 setText(noColIdx, sym_tristate_within_range(sym, no) ? "_" : 0);
173 if (expr != mod)
174 setText(modColIdx, sym_tristate_within_range(sym, mod) ? "_" : 0);
175 if (expr != yes)
176 setText(yesColIdx, sym_tristate_within_range(sym, yes) ? "_" : 0);
177
178 setText(dataColIdx, QChar(ch));
179 break;
180 case S_INT:
181 case S_HEX:
182 case S_STRING:
Masahiro Yamada37162a62020-08-29 17:14:12 +0900183 setText(dataColIdx, sym_get_string_value(sym));
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700184 break;
185 }
186 if (!sym_has_value(sym) && visible)
Sam Ravnborg694c49a2018-05-22 21:36:12 +0200187 prompt += " (NEW)";
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700188set_prompt:
189 setText(promptColIdx, prompt);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700190}
191
192void ConfigItem::testUpdateMenu(bool v)
193{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700194 ConfigItem* i;
195
196 visible = v;
197 if (!menu)
198 return;
199
200 sym_calc_value(menu->sym);
201 if (menu->flags & MENU_CHANGED) {
202 /* the menu entry changed, so update all list items */
203 menu->flags &= ~MENU_CHANGED;
204 for (i = (ConfigItem*)menu->data; i; i = i->nextItem)
205 i->updateMenu();
206 } else if (listView()->updateAll)
207 updateMenu();
Boris Barbulovski59e56442015-09-22 11:36:18 -0700208}
209
210
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700211/*
212 * construct a menu entry
213 */
214void ConfigItem::init(void)
215{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700216 if (menu) {
217 ConfigList* list = listView();
218 nextItem = (ConfigItem*)menu->data;
219 menu->data = this;
220
221 if (list->mode != fullMode)
222 setExpanded(true);
223 sym_calc_value(menu->sym);
Masahiro Yamada37162a62020-08-29 17:14:12 +0900224
225 if (menu->sym) {
226 enum symbol_type type = menu->sym->type;
227
228 // Allow to edit "int", "hex", and "string" in-place in
229 // the data column. Unfortunately, you cannot specify
230 // the flags per column. Set ItemIsEditable for all
231 // columns here, and check the column in createEditor().
232 if (type == S_INT || type == S_HEX || type == S_STRING)
233 setFlags(flags() | Qt::ItemIsEditable);
234 }
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700235 }
236 updateMenu();
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700237}
238
239/*
240 * destruct a menu entry
241 */
242ConfigItem::~ConfigItem(void)
243{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700244 if (menu) {
245 ConfigItem** ip = (ConfigItem**)&menu->data;
246 for (; *ip; ip = &(*ip)->nextItem) {
247 if (*ip == this) {
248 *ip = nextItem;
249 break;
250 }
251 }
252 }
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700253}
254
Masahiro Yamada37162a62020-08-29 17:14:12 +0900255QWidget *ConfigItemDelegate::createEditor(QWidget *parent,
256 const QStyleOptionViewItem &option,
257 const QModelIndex &index) const
258{
259 ConfigItem *item;
260
261 // Only the data column is editable
262 if (index.column() != dataColIdx)
263 return nullptr;
264
265 // You cannot edit invisible menus
266 item = static_cast<ConfigItem *>(index.internalPointer());
267 if (!item || !item->menu || !menu_is_visible(item->menu))
268 return nullptr;
269
270 return QStyledItemDelegate::createEditor(parent, option, index);
271}
272
273void ConfigItemDelegate::setModelData(QWidget *editor,
274 QAbstractItemModel *model,
275 const QModelIndex &index) const
276{
277 QLineEdit *lineEdit;
278 ConfigItem *item;
279 struct symbol *sym;
280 bool success;
281
282 lineEdit = qobject_cast<QLineEdit *>(editor);
283 // If this is not a QLineEdit, use the parent's default.
284 // (does this happen?)
285 if (!lineEdit)
286 goto parent;
287
288 item = static_cast<ConfigItem *>(index.internalPointer());
289 if (!item || !item->menu)
290 goto parent;
291
292 sym = item->menu->sym;
293 if (!sym)
294 goto parent;
295
296 success = sym_set_string_value(sym, lineEdit->text().toUtf8().data());
297 if (success) {
298 ConfigList::updateListForAll();
299 } else {
300 QMessageBox::information(editor, "qconf",
301 "Cannot set the data (maybe due to out of range).\n"
302 "Setting the old value.");
303 lineEdit->setText(sym_get_string_value(sym));
304 }
305
306parent:
307 QStyledItemDelegate::setModelData(editor, model, index);
308}
309
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700310ConfigList::ConfigList(ConfigView* p, const char *name)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700311 : Parent(p),
312 updateAll(false),
Masahiro Yamada669a1ee2020-08-29 17:14:11 +0900313 showName(false), showRange(false), mode(singleMode), optMode(normalOpt),
Boris Barbulovski59e56442015-09-22 11:36:18 -0700314 rootEntry(0), headerPopup(0)
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700315{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700316 setObjectName(name);
Boris Barbulovskia5225e92015-09-22 11:36:29 -0700317 setSortingEnabled(false);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700318 setRootIsDecorated(true);
319
Boris Barbulovskif999cc02015-09-22 11:36:31 -0700320 setVerticalScrollMode(ScrollPerPixel);
321 setHorizontalScrollMode(ScrollPerPixel);
322
Masahiro Yamada97bebbc2020-07-30 02:46:17 +0900323 setHeaderLabels(QStringList() << "Option" << "Name" << "N" << "M" << "Y" << "Value");
Boris Barbulovskia52cb322015-09-22 11:36:24 -0700324
Boris Barbulovskic14fa5e2015-09-22 11:36:21 -0700325 connect(this, SIGNAL(itemSelectionChanged(void)),
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700326 SLOT(updateSelection(void)));
327
328 if (name) {
329 configSettings->beginGroup(name);
330 showName = configSettings->value("/showName", false).toBool();
331 showRange = configSettings->value("/showRange", false).toBool();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700332 optMode = (enum optionMode)configSettings->value("/optionMode", 0).toInt();
333 configSettings->endGroup();
334 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
335 }
336
Masahiro Yamadaabf741a2020-08-07 18:19:04 +0900337 showColumn(promptColIdx);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700338
Masahiro Yamada37162a62020-08-29 17:14:12 +0900339 setItemDelegate(new ConfigItemDelegate(this));
340
Masahiro Yamadaf9b918f2020-08-29 17:14:10 +0900341 allLists.append(this);
342
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700343 reinit();
344}
345
Masahiro Yamadaf9b918f2020-08-29 17:14:10 +0900346ConfigList::~ConfigList()
347{
348 allLists.removeOne(this);
349}
350
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700351bool ConfigList::menuSkip(struct menu *menu)
352{
353 if (optMode == normalOpt && menu_is_visible(menu))
354 return false;
355 if (optMode == promptOpt && menu_has_prompt(menu))
356 return false;
357 if (optMode == allOpt)
358 return false;
359 return true;
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700360}
Boris Barbulovski59e56442015-09-22 11:36:18 -0700361
362void ConfigList::reinit(void)
363{
Masahiro Yamadaabf741a2020-08-07 18:19:04 +0900364 hideColumn(yesColIdx);
365 hideColumn(modColIdx);
366 hideColumn(noColIdx);
367 hideColumn(nameColIdx);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700368
369 if (showName)
Masahiro Yamadaabf741a2020-08-07 18:19:04 +0900370 showColumn(nameColIdx);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700371 if (showRange) {
Masahiro Yamadaabf741a2020-08-07 18:19:04 +0900372 showColumn(noColIdx);
373 showColumn(modColIdx);
374 showColumn(yesColIdx);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700375 }
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700376
377 updateListAll();
Boris Barbulovski59e56442015-09-22 11:36:18 -0700378}
379
Masahiro Yamadad4bbe8a2020-08-07 18:19:09 +0900380void ConfigList::setOptionMode(QAction *action)
381{
382 if (action == showNormalAction)
383 optMode = normalOpt;
384 else if (action == showAllAction)
385 optMode = allOpt;
386 else
387 optMode = promptOpt;
388
389 updateListAll();
390}
391
Boris Barbulovski59e56442015-09-22 11:36:18 -0700392void ConfigList::saveSettings(void)
393{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700394 if (!objectName().isEmpty()) {
395 configSettings->beginGroup(objectName());
396 configSettings->setValue("/showName", showName);
397 configSettings->setValue("/showRange", showRange);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700398 configSettings->setValue("/optionMode", (int)optMode);
399 configSettings->endGroup();
400 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700401}
402
403ConfigItem* ConfigList::findConfigItem(struct menu *menu)
404{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700405 ConfigItem* item = (ConfigItem*)menu->data;
406
407 for (; item; item = item->nextItem) {
408 if (this == item->listView())
409 break;
410 }
411
412 return item;
Boris Barbulovski59e56442015-09-22 11:36:18 -0700413}
414
415void ConfigList::updateSelection(void)
416{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700417 struct menu *menu;
418 enum prop_type type;
419
Boris Barbulovskibe596aa2015-09-22 11:36:28 -0700420 if (selectedItems().count() == 0)
421 return;
422
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700423 ConfigItem* item = (ConfigItem*)selectedItems().first();
424 if (!item)
425 return;
426
427 menu = item->menu;
428 emit menuChanged(menu);
429 if (!menu)
430 return;
431 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
432 if (mode == menuMode && type == P_MENU)
433 emit menuSelected(menu);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700434}
435
Masahiro Yamadacb770432020-08-07 18:18:59 +0900436void ConfigList::updateList()
Boris Barbulovski59e56442015-09-22 11:36:18 -0700437{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700438 ConfigItem* last = 0;
Masahiro Yamadacb770432020-08-07 18:18:59 +0900439 ConfigItem *item;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700440
441 if (!rootEntry) {
442 if (mode != listMode)
443 goto update;
444 QTreeWidgetItemIterator it(this);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700445
446 while (*it) {
447 item = (ConfigItem*)(*it);
448 if (!item->menu)
449 continue;
450 item->testUpdateMenu(menu_is_visible(item->menu));
451
452 ++it;
453 }
454 return;
455 }
456
457 if (rootEntry != &rootmenu && (mode == singleMode ||
458 (mode == symbolMode && rootEntry->parent != &rootmenu))) {
Boris Barbulovskiee7298f2015-09-22 11:36:37 -0700459 item = (ConfigItem *)topLevelItem(0);
Masahiro Yamada4b20e102020-08-01 16:08:49 +0900460 if (!item)
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700461 item = new ConfigItem(this, 0, true);
Masahiro Yamada4b20e102020-08-01 16:08:49 +0900462 last = item;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700463 }
464 if ((mode == singleMode || (mode == symbolMode && !(rootEntry->flags & MENU_ROOT))) &&
465 rootEntry->sym && rootEntry->prompt) {
Masahiro Yamadaccf56e52020-08-01 16:08:50 +0900466 item = last ? last->nextSibling() : nullptr;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700467 if (!item)
468 item = new ConfigItem(this, last, rootEntry, true);
469 else
470 item->testUpdateMenu(true);
471
472 updateMenuList(item, rootEntry);
473 update();
Boris Barbulovskif999cc02015-09-22 11:36:31 -0700474 resizeColumnToContents(0);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700475 return;
476 }
477update:
Masahiro Yamada5b75a6c2020-08-07 18:19:01 +0900478 updateMenuList(rootEntry);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700479 update();
Boris Barbulovskif999cc02015-09-22 11:36:31 -0700480 resizeColumnToContents(0);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700481}
482
Masahiro Yamadaf9b918f2020-08-29 17:14:10 +0900483void ConfigList::updateListForAll()
484{
485 QListIterator<ConfigList *> it(allLists);
486
487 while (it.hasNext()) {
488 ConfigList *list = it.next();
489
490 list->updateList();
491 }
492}
493
494void ConfigList::updateListAllForAll()
495{
496 QListIterator<ConfigList *> it(allLists);
497
498 while (it.hasNext()) {
499 ConfigList *list = it.next();
500
501 list->updateList();
502 }
503}
504
Boris Barbulovski59e56442015-09-22 11:36:18 -0700505void ConfigList::setValue(ConfigItem* item, tristate val)
506{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700507 struct symbol* sym;
508 int type;
509 tristate oldval;
510
511 sym = item->menu ? item->menu->sym : 0;
512 if (!sym)
513 return;
514
515 type = sym_get_type(sym);
516 switch (type) {
517 case S_BOOLEAN:
518 case S_TRISTATE:
519 oldval = sym_get_tristate_value(sym);
520
521 if (!sym_set_tristate_value(sym, val))
522 return;
523 if (oldval == no && item->menu->list)
524 item->setExpanded(true);
Masahiro Yamadaf9b918f2020-08-29 17:14:10 +0900525 ConfigList::updateListForAll();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700526 break;
527 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700528}
529
530void ConfigList::changeValue(ConfigItem* item)
531{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700532 struct symbol* sym;
533 struct menu* menu;
534 int type, oldexpr, newexpr;
535
536 menu = item->menu;
537 if (!menu)
538 return;
539 sym = menu->sym;
540 if (!sym) {
541 if (item->menu->list)
542 item->setExpanded(!item->isExpanded());
543 return;
544 }
545
546 type = sym_get_type(sym);
547 switch (type) {
548 case S_BOOLEAN:
549 case S_TRISTATE:
550 oldexpr = sym_get_tristate_value(sym);
551 newexpr = sym_toggle_tristate_value(sym);
552 if (item->menu->list) {
553 if (oldexpr == newexpr)
554 item->setExpanded(!item->isExpanded());
555 else if (oldexpr == no)
556 item->setExpanded(true);
557 }
558 if (oldexpr != newexpr)
Masahiro Yamadaf9b918f2020-08-29 17:14:10 +0900559 ConfigList::updateListForAll();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700560 break;
Masahiro Yamada37162a62020-08-29 17:14:12 +0900561 default:
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700562 break;
563 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700564}
565
566void ConfigList::setRootMenu(struct menu *menu)
567{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700568 enum prop_type type;
569
570 if (rootEntry == menu)
571 return;
572 type = menu && menu->prompt ? menu->prompt->type : P_UNKNOWN;
573 if (type != P_MENU)
574 return;
Masahiro Yamada5b75a6c2020-08-07 18:19:01 +0900575 updateMenuList(0);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700576 rootEntry = menu;
577 updateListAll();
578 if (currentItem()) {
Mauro Carvalho Chehabb06c3ec2020-06-30 08:26:38 +0200579 setSelected(currentItem(), hasFocus());
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700580 scrollToItem(currentItem());
581 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700582}
583
584void ConfigList::setParentMenu(void)
585{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700586 ConfigItem* item;
587 struct menu *oldroot;
588
589 oldroot = rootEntry;
590 if (rootEntry == &rootmenu)
591 return;
592 setRootMenu(menu_get_parent_menu(rootEntry->parent));
593
594 QTreeWidgetItemIterator it(this);
595 while (*it) {
596 item = (ConfigItem *)(*it);
597 if (item->menu == oldroot) {
598 setCurrentItem(item);
599 scrollToItem(item);
600 break;
601 }
602
603 ++it;
604 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700605}
606
607/*
608 * update all the children of a menu entry
609 * removes/adds the entries from the parent widget as necessary
610 *
611 * parent: either the menu list widget or a menu entry widget
612 * menu: entry to be updated
613 */
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700614void ConfigList::updateMenuList(ConfigItem *parent, struct menu* menu)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700615{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700616 struct menu* child;
617 ConfigItem* item;
618 ConfigItem* last;
619 bool visible;
620 enum prop_type type;
621
622 if (!menu) {
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700623 while (parent->childCount() > 0)
624 {
625 delete parent->takeChild(0);
626 }
627
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700628 return;
629 }
630
631 last = parent->firstChild();
632 if (last && !last->goParent)
633 last = 0;
634 for (child = menu->list; child; child = child->next) {
635 item = last ? last->nextSibling() : parent->firstChild();
636 type = child->prompt ? child->prompt->type : P_UNKNOWN;
637
638 switch (mode) {
639 case menuMode:
640 if (!(child->flags & MENU_ROOT))
641 goto hide;
642 break;
643 case symbolMode:
644 if (child->flags & MENU_ROOT)
645 goto hide;
646 break;
647 default:
648 break;
649 }
650
651 visible = menu_is_visible(child);
652 if (!menuSkip(child)) {
653 if (!child->sym && !child->list && !child->prompt)
654 continue;
655 if (!item || item->menu != child)
656 item = new ConfigItem(parent, last, child, visible);
657 else
658 item->testUpdateMenu(visible);
659
660 if (mode == fullMode || mode == menuMode || type != P_MENU)
661 updateMenuList(item, child);
662 else
663 updateMenuList(item, 0);
664 last = item;
665 continue;
666 }
Mauro Carvalho Chehab60969f02020-04-02 11:28:03 +0200667hide:
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700668 if (item && item->menu == child) {
669 last = parent->firstChild();
670 if (last == item)
671 last = 0;
672 else while (last->nextSibling() != item)
673 last = last->nextSibling();
674 delete item;
675 }
676 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700677}
678
Masahiro Yamada5b75a6c2020-08-07 18:19:01 +0900679void ConfigList::updateMenuList(struct menu *menu)
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700680{
681 struct menu* child;
682 ConfigItem* item;
683 ConfigItem* last;
684 bool visible;
685 enum prop_type type;
686
687 if (!menu) {
Masahiro Yamada5b75a6c2020-08-07 18:19:01 +0900688 while (topLevelItemCount() > 0)
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700689 {
Masahiro Yamada5b75a6c2020-08-07 18:19:01 +0900690 delete takeTopLevelItem(0);
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700691 }
692
693 return;
694 }
695
Masahiro Yamada5b75a6c2020-08-07 18:19:01 +0900696 last = (ConfigItem *)topLevelItem(0);
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700697 if (last && !last->goParent)
698 last = 0;
699 for (child = menu->list; child; child = child->next) {
Masahiro Yamada5b75a6c2020-08-07 18:19:01 +0900700 item = last ? last->nextSibling() : (ConfigItem *)topLevelItem(0);
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700701 type = child->prompt ? child->prompt->type : P_UNKNOWN;
702
703 switch (mode) {
704 case menuMode:
705 if (!(child->flags & MENU_ROOT))
706 goto hide;
707 break;
708 case symbolMode:
709 if (child->flags & MENU_ROOT)
710 goto hide;
711 break;
712 default:
713 break;
714 }
715
716 visible = menu_is_visible(child);
717 if (!menuSkip(child)) {
718 if (!child->sym && !child->list && !child->prompt)
719 continue;
720 if (!item || item->menu != child)
Masahiro Yamada5b75a6c2020-08-07 18:19:01 +0900721 item = new ConfigItem(this, last, child, visible);
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700722 else
723 item->testUpdateMenu(visible);
724
725 if (mode == fullMode || mode == menuMode || type != P_MENU)
726 updateMenuList(item, child);
727 else
728 updateMenuList(item, 0);
729 last = item;
730 continue;
731 }
Mauro Carvalho Chehab60969f02020-04-02 11:28:03 +0200732hide:
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700733 if (item && item->menu == child) {
Masahiro Yamada5b75a6c2020-08-07 18:19:01 +0900734 last = (ConfigItem *)topLevelItem(0);
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700735 if (last == item)
736 last = 0;
737 else while (last->nextSibling() != item)
738 last = last->nextSibling();
739 delete item;
740 }
741 }
742}
743
Boris Barbulovski59e56442015-09-22 11:36:18 -0700744void ConfigList::keyPressEvent(QKeyEvent* ev)
745{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700746 QTreeWidgetItem* i = currentItem();
747 ConfigItem* item;
748 struct menu *menu;
749 enum prop_type type;
750
751 if (ev->key() == Qt::Key_Escape && mode != fullMode && mode != listMode) {
752 emit parentSelected();
753 ev->accept();
754 return;
755 }
756
757 if (!i) {
758 Parent::keyPressEvent(ev);
759 return;
760 }
761 item = (ConfigItem*)i;
762
763 switch (ev->key()) {
764 case Qt::Key_Return:
765 case Qt::Key_Enter:
766 if (item->goParent) {
767 emit parentSelected();
768 break;
769 }
770 menu = item->menu;
771 if (!menu)
772 break;
773 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
774 if (type == P_MENU && rootEntry != menu &&
775 mode != fullMode && mode != menuMode) {
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +0200776 if (mode == menuMode)
777 emit menuSelected(menu);
778 else
779 emit itemSelected(menu);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700780 break;
781 }
782 case Qt::Key_Space:
783 changeValue(item);
784 break;
785 case Qt::Key_N:
786 setValue(item, no);
787 break;
788 case Qt::Key_M:
789 setValue(item, mod);
790 break;
791 case Qt::Key_Y:
792 setValue(item, yes);
793 break;
794 default:
795 Parent::keyPressEvent(ev);
796 return;
797 }
798 ev->accept();
Boris Barbulovski59e56442015-09-22 11:36:18 -0700799}
800
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700801void ConfigList::mousePressEvent(QMouseEvent* e)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700802{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700803 //QPoint p(contentsToViewport(e->pos()));
804 //printf("contentsMousePressEvent: %d,%d\n", p.x(), p.y());
805 Parent::mousePressEvent(e);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700806}
807
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700808void ConfigList::mouseReleaseEvent(QMouseEvent* e)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700809{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700810 QPoint p = e->pos();
811 ConfigItem* item = (ConfigItem*)itemAt(p);
812 struct menu *menu;
813 enum prop_type ptype;
814 QIcon icon;
815 int idx, x;
816
817 if (!item)
818 goto skip;
819
820 menu = item->menu;
821 x = header()->offset() + p.x();
Boris Barbulovski76d53cb2015-09-22 11:36:35 -0700822 idx = header()->logicalIndexAt(x);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700823 switch (idx) {
824 case promptColIdx:
Masahiro Yamada711b8752020-08-07 18:19:03 +0900825 icon = item->icon(promptColIdx);
Boris Barbulovski76d53cb2015-09-22 11:36:35 -0700826 if (!icon.isNull()) {
827 int off = header()->sectionPosition(0) + visualRect(indexAt(p)).x() + 4; // 4 is Hardcoded image offset. There might be a way to do it properly.
828 if (x >= off && x < off + icon.availableSizes().first().width()) {
829 if (item->goParent) {
830 emit parentSelected();
831 break;
832 } else if (!menu)
833 break;
834 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
835 if (ptype == P_MENU && rootEntry != menu &&
Maxime Chretien7eb7c106f2020-07-08 15:32:15 +0200836 mode != fullMode && mode != menuMode &&
837 mode != listMode)
Boris Barbulovski76d53cb2015-09-22 11:36:35 -0700838 emit menuSelected(menu);
839 else
840 changeValue(item);
841 }
842 }
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700843 break;
844 case noColIdx:
845 setValue(item, no);
846 break;
847 case modColIdx:
848 setValue(item, mod);
849 break;
850 case yesColIdx:
851 setValue(item, yes);
852 break;
853 case dataColIdx:
854 changeValue(item);
855 break;
856 }
857
858skip:
859 //printf("contentsMouseReleaseEvent: %d,%d\n", p.x(), p.y());
860 Parent::mouseReleaseEvent(e);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700861}
862
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700863void ConfigList::mouseMoveEvent(QMouseEvent* e)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700864{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700865 //QPoint p(contentsToViewport(e->pos()));
866 //printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y());
867 Parent::mouseMoveEvent(e);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700868}
869
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700870void ConfigList::mouseDoubleClickEvent(QMouseEvent* e)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700871{
Mauro Carvalho Chehabe1f77692020-04-02 11:28:02 +0200872 QPoint p = e->pos();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700873 ConfigItem* item = (ConfigItem*)itemAt(p);
874 struct menu *menu;
875 enum prop_type ptype;
876
877 if (!item)
878 goto skip;
879 if (item->goParent) {
880 emit parentSelected();
881 goto skip;
882 }
883 menu = item->menu;
884 if (!menu)
885 goto skip;
886 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
Maxime Chretien7eb7c106f2020-07-08 15:32:15 +0200887 if (ptype == P_MENU && mode != listMode) {
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +0200888 if (mode == singleMode)
889 emit itemSelected(menu);
890 else if (mode == symbolMode)
891 emit menuSelected(menu);
892 } else if (menu->sym)
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700893 changeValue(item);
894
895skip:
896 //printf("contentsMouseDoubleClickEvent: %d,%d\n", p.x(), p.y());
897 Parent::mouseDoubleClickEvent(e);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700898}
899
900void ConfigList::focusInEvent(QFocusEvent *e)
901{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700902 struct menu *menu = NULL;
903
904 Parent::focusInEvent(e);
905
906 ConfigItem* item = (ConfigItem *)currentItem();
907 if (item) {
Mauro Carvalho Chehabb06c3ec2020-06-30 08:26:38 +0200908 setSelected(item, true);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700909 menu = item->menu;
910 }
911 emit gotFocus(menu);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700912}
913
914void ConfigList::contextMenuEvent(QContextMenuEvent *e)
915{
Masahiro Yamadafa8de0a2020-08-07 18:19:08 +0900916 if (!headerPopup) {
917 QAction *action;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700918
Masahiro Yamadafa8de0a2020-08-07 18:19:08 +0900919 headerPopup = new QMenu(this);
920 action = new QAction("Show Name", this);
921 action->setCheckable(true);
922 connect(action, SIGNAL(toggled(bool)),
923 parent(), SLOT(setShowName(bool)));
924 connect(parent(), SIGNAL(showNameChanged(bool)),
Masahiro Yamadad85de332020-08-18 01:36:29 +0900925 action, SLOT(setChecked(bool)));
Masahiro Yamadafa8de0a2020-08-07 18:19:08 +0900926 action->setChecked(showName);
927 headerPopup->addAction(action);
928
929 action = new QAction("Show Range", this);
930 action->setCheckable(true);
931 connect(action, SIGNAL(toggled(bool)),
932 parent(), SLOT(setShowRange(bool)));
933 connect(parent(), SIGNAL(showRangeChanged(bool)),
Masahiro Yamadad85de332020-08-18 01:36:29 +0900934 action, SLOT(setChecked(bool)));
Masahiro Yamadafa8de0a2020-08-07 18:19:08 +0900935 action->setChecked(showRange);
936 headerPopup->addAction(action);
Masahiro Yamadafa8de0a2020-08-07 18:19:08 +0900937 }
938
939 headerPopup->exec(e->globalPos());
940 e->accept();
Boris Barbulovski59e56442015-09-22 11:36:18 -0700941}
942
Masahiro Yamadaf9b918f2020-08-29 17:14:10 +0900943QList<ConfigList *> ConfigList::allLists;
Masahiro Yamadad4bbe8a2020-08-07 18:19:09 +0900944QAction *ConfigList::showNormalAction;
945QAction *ConfigList::showAllAction;
946QAction *ConfigList::showPromptAction;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700947
Roman Zippel7fc925f2006-06-08 22:12:46 -0700948ConfigView::ConfigView(QWidget* parent, const char *name)
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -0700949 : Parent(parent)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700950{
Boris Barbulovski9bd36ed2015-09-22 11:36:22 -0700951 setObjectName(name);
Boris Barbulovski29a70162015-09-22 11:36:10 -0700952 QVBoxLayout *verticalLayout = new QVBoxLayout(this);
Boris Barbulovski92298b42015-09-22 11:36:11 -0700953 verticalLayout->setContentsMargins(0, 0, 0, 0);
Boris Barbulovski29a70162015-09-22 11:36:10 -0700954
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700955 list = new ConfigList(this);
Boris Barbulovski29a70162015-09-22 11:36:10 -0700956 verticalLayout->addWidget(list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700957}
958
Roman Zippel7fc925f2006-06-08 22:12:46 -0700959void ConfigView::setShowName(bool b)
960{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700961 if (list->showName != b) {
962 list->showName = b;
963 list->reinit();
964 emit showNameChanged(b);
965 }
Roman Zippel7fc925f2006-06-08 22:12:46 -0700966}
967
968void ConfigView::setShowRange(bool b)
969{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700970 if (list->showRange != b) {
971 list->showRange = b;
972 list->reinit();
973 emit showRangeChanged(b);
974 }
Roman Zippel7fc925f2006-06-08 22:12:46 -0700975}
976
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700977void ConfigList::setAllOpen(bool open)
978{
979 QTreeWidgetItemIterator it(this);
980
981 while (*it) {
982 (*it)->setExpanded(open);
983
984 ++it;
985 }
Roman Zippel7fc925f2006-06-08 22:12:46 -0700986}
987
Roman Zippel43bf6122006-06-08 22:12:45 -0700988ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name)
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -0700989 : Parent(parent), sym(0), _menu(0)
Roman Zippel43bf6122006-06-08 22:12:45 -0700990{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700991 setObjectName(name);
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +0200992 setOpenLinks(false);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700993
994 if (!objectName().isEmpty()) {
995 configSettings->beginGroup(objectName());
Boris Barbulovskie0393032016-11-30 14:57:52 -0800996 setShowDebug(configSettings->value("/showDebug", false).toBool());
Roman Zippel7fc925f2006-06-08 22:12:46 -0700997 configSettings->endGroup();
998 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
999 }
Masahiro Yamada7d1300e2020-08-18 01:36:30 +09001000
1001 contextMenu = createStandardContextMenu();
1002 QAction *action = new QAction("Show Debug Info", contextMenu);
1003
1004 action->setCheckable(true);
1005 connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
1006 connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setChecked(bool)));
1007 action->setChecked(showDebug());
1008 contextMenu->addSeparator();
1009 contextMenu->addAction(action);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001010}
1011
1012void ConfigInfoView::saveSettings(void)
1013{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001014 if (!objectName().isEmpty()) {
1015 configSettings->beginGroup(objectName());
1016 configSettings->setValue("/showDebug", showDebug());
1017 configSettings->endGroup();
1018 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001019}
1020
1021void ConfigInfoView::setShowDebug(bool b)
1022{
1023 if (_showDebug != b) {
1024 _showDebug = b;
Alexander Stein133c5f72010-08-31 17:34:37 +02001025 if (_menu)
Roman Zippel43bf6122006-06-08 22:12:45 -07001026 menuInfo();
Roman Zippelab45d192006-06-08 22:12:47 -07001027 else if (sym)
1028 symbolInfo();
Roman Zippel43bf6122006-06-08 22:12:45 -07001029 emit showDebugChanged(b);
1030 }
1031}
1032
1033void ConfigInfoView::setInfo(struct menu *m)
1034{
Alexander Stein133c5f72010-08-31 17:34:37 +02001035 if (_menu == m)
Roman Zippelb65a47e2006-06-08 22:12:47 -07001036 return;
Alexander Stein133c5f72010-08-31 17:34:37 +02001037 _menu = m;
Roman Zippel6fa1da82007-01-10 23:15:31 -08001038 sym = NULL;
Alexander Stein133c5f72010-08-31 17:34:37 +02001039 if (!_menu)
Roman Zippel43bf6122006-06-08 22:12:45 -07001040 clear();
Roman Zippel6fa1da82007-01-10 23:15:31 -08001041 else
Roman Zippel43bf6122006-06-08 22:12:45 -07001042 menuInfo();
1043}
1044
Roman Zippelab45d192006-06-08 22:12:47 -07001045void ConfigInfoView::symbolInfo(void)
1046{
1047 QString str;
1048
1049 str += "<big>Symbol: <b>";
1050 str += print_filter(sym->name);
1051 str += "</b></big><br><br>value: ";
1052 str += print_filter(sym_get_string_value(sym));
1053 str += "<br>visibility: ";
1054 str += sym->visible == yes ? "y" : sym->visible == mod ? "m" : "n";
1055 str += "<br>";
1056 str += debug_info(sym);
1057
1058 setText(str);
1059}
1060
Roman Zippel43bf6122006-06-08 22:12:45 -07001061void ConfigInfoView::menuInfo(void)
1062{
1063 struct symbol* sym;
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001064 QString info;
1065 QTextStream stream(&info);
Roman Zippel43bf6122006-06-08 22:12:45 -07001066
Alexander Stein133c5f72010-08-31 17:34:37 +02001067 sym = _menu->sym;
Roman Zippel43bf6122006-06-08 22:12:45 -07001068 if (sym) {
Alexander Stein133c5f72010-08-31 17:34:37 +02001069 if (_menu->prompt) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001070 stream << "<big><b>";
1071 stream << print_filter(_menu->prompt->text);
1072 stream << "</b></big>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001073 if (sym->name) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001074 stream << " (";
Roman Zippelab45d192006-06-08 22:12:47 -07001075 if (showDebug())
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001076 stream << "<a href=\"s" << sym->name << "\">";
1077 stream << print_filter(sym->name);
Roman Zippelab45d192006-06-08 22:12:47 -07001078 if (showDebug())
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001079 stream << "</a>";
1080 stream << ")";
Roman Zippel43bf6122006-06-08 22:12:45 -07001081 }
1082 } else if (sym->name) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001083 stream << "<big><b>";
Roman Zippelab45d192006-06-08 22:12:47 -07001084 if (showDebug())
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001085 stream << "<a href=\"s" << sym->name << "\">";
1086 stream << print_filter(sym->name);
Roman Zippelab45d192006-06-08 22:12:47 -07001087 if (showDebug())
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001088 stream << "</a>";
1089 stream << "</b></big>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001090 }
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001091 stream << "<br><br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001092
1093 if (showDebug())
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001094 stream << debug_info(sym);
1095
Masahiro Yamadaa46afd12020-09-14 23:59:48 +09001096 struct gstr help_gstr = str_new();
1097
1098 menu_get_ext_help(_menu, &help_gstr);
1099 stream << print_filter(str_get(&help_gstr));
1100 str_free(&help_gstr);
Alexander Stein133c5f72010-08-31 17:34:37 +02001101 } else if (_menu->prompt) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001102 stream << "<big><b>";
1103 stream << print_filter(_menu->prompt->text);
1104 stream << "</b></big><br><br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001105 if (showDebug()) {
Alexander Stein133c5f72010-08-31 17:34:37 +02001106 if (_menu->prompt->visible.expr) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001107 stream << "&nbsp;&nbsp;dep: ";
1108 expr_print(_menu->prompt->visible.expr,
1109 expr_print_help, &stream, E_NONE);
1110 stream << "<br><br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001111 }
Masahiro Yamadaa46afd12020-09-14 23:59:48 +09001112
1113 stream << "defined at " << _menu->file->name << ":"
1114 << _menu->lineno << "<br><br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001115 }
1116 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001117
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001118 setText(info);
Roman Zippel43bf6122006-06-08 22:12:45 -07001119}
1120
1121QString ConfigInfoView::debug_info(struct symbol *sym)
1122{
1123 QString debug;
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001124 QTextStream stream(&debug);
Roman Zippel43bf6122006-06-08 22:12:45 -07001125
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001126 stream << "type: ";
1127 stream << print_filter(sym_type_name(sym->type));
Roman Zippel43bf6122006-06-08 22:12:45 -07001128 if (sym_is_choice(sym))
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001129 stream << " (choice)";
Roman Zippel43bf6122006-06-08 22:12:45 -07001130 debug += "<br>";
1131 if (sym->rev_dep.expr) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001132 stream << "reverse dep: ";
1133 expr_print(sym->rev_dep.expr, expr_print_help, &stream, E_NONE);
1134 stream << "<br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001135 }
1136 for (struct property *prop = sym->prop; prop; prop = prop->next) {
1137 switch (prop->type) {
1138 case P_PROMPT:
1139 case P_MENU:
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001140 stream << "prompt: <a href=\"m" << sym->name << "\">";
1141 stream << print_filter(prop->text);
1142 stream << "</a><br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001143 break;
1144 case P_DEFAULT:
Roman Zippel93449082008-01-14 04:50:54 +01001145 case P_SELECT:
1146 case P_RANGE:
Mauro Carvalho Chehab8f8499a2020-06-30 08:48:53 +02001147 case P_COMMENT:
1148 case P_IMPLY:
1149 case P_SYMBOL:
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001150 stream << prop_get_type_name(prop->type);
1151 stream << ": ";
1152 expr_print(prop->expr, expr_print_help,
1153 &stream, E_NONE);
1154 stream << "<br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001155 break;
1156 case P_CHOICE:
1157 if (sym_is_choice(sym)) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001158 stream << "choice: ";
1159 expr_print(prop->expr, expr_print_help,
1160 &stream, E_NONE);
1161 stream << "<br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001162 }
1163 break;
Roman Zippel43bf6122006-06-08 22:12:45 -07001164 default:
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001165 stream << "unknown property: ";
1166 stream << prop_get_type_name(prop->type);
1167 stream << "<br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001168 }
1169 if (prop->visible.expr) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001170 stream << "&nbsp;&nbsp;&nbsp;&nbsp;dep: ";
1171 expr_print(prop->visible.expr, expr_print_help,
1172 &stream, E_NONE);
1173 stream << "<br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001174 }
1175 }
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001176 stream << "<br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001177
1178 return debug;
1179}
1180
1181QString ConfigInfoView::print_filter(const QString &str)
1182{
1183 QRegExp re("[<>&\"\\n]");
1184 QString res = str;
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001185 for (int i = 0; (i = res.indexOf(re, i)) >= 0;) {
1186 switch (res[i].toLatin1()) {
Roman Zippel43bf6122006-06-08 22:12:45 -07001187 case '<':
1188 res.replace(i, 1, "&lt;");
1189 i += 4;
1190 break;
1191 case '>':
1192 res.replace(i, 1, "&gt;");
1193 i += 4;
1194 break;
1195 case '&':
1196 res.replace(i, 1, "&amp;");
1197 i += 5;
1198 break;
1199 case '"':
1200 res.replace(i, 1, "&quot;");
1201 i += 6;
1202 break;
1203 case '\n':
1204 res.replace(i, 1, "<br>");
1205 i += 4;
1206 break;
1207 }
1208 }
1209 return res;
1210}
1211
Roman Zippelab45d192006-06-08 22:12:47 -07001212void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char *str)
Roman Zippel43bf6122006-06-08 22:12:45 -07001213{
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001214 QTextStream *stream = reinterpret_cast<QTextStream *>(data);
Roman Zippelab45d192006-06-08 22:12:47 -07001215
1216 if (sym && sym->name && !(sym->flags & SYMBOL_CONST)) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001217 *stream << "<a href=\"s" << sym->name << "\">";
1218 *stream << print_filter(str);
1219 *stream << "</a>";
1220 } else {
1221 *stream << print_filter(str);
1222 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001223}
1224
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001225void ConfigInfoView::clicked(const QUrl &url)
1226{
1227 QByteArray str = url.toEncoded();
1228 const std::size_t count = str.size();
1229 char *data = new char[count + 1];
1230 struct symbol **result;
1231 struct menu *m = NULL;
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001232
1233 if (count < 1) {
Masahiro Yamadac9b09a922020-07-30 02:02:39 +09001234 delete[] data;
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001235 return;
1236 }
1237
1238 memcpy(data, str.constData(), count);
1239 data[count] = '\0';
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001240
1241 /* Seek for exact match */
1242 data[0] = '^';
1243 strcat(data, "$");
1244 result = sym_re_search(data);
1245 if (!result) {
Masahiro Yamadac9b09a922020-07-30 02:02:39 +09001246 delete[] data;
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001247 return;
1248 }
1249
1250 sym = *result;
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001251
Mauro Carvalho Chehab8a3b6e52020-06-30 08:48:35 +02001252 /* Seek for the menu which holds the symbol */
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001253 for (struct property *prop = sym->prop; prop; prop = prop->next) {
1254 if (prop->type != P_PROMPT && prop->type != P_MENU)
1255 continue;
1256 m = prop->menu;
1257 break;
1258 }
1259
1260 if (!m) {
Mauro Carvalho Chehab8a3b6e52020-06-30 08:48:35 +02001261 /* Symbol is not visible as a menu */
1262 symbolInfo();
1263 emit showDebugChanged(true);
1264 } else {
1265 emit menuSelected(m);
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001266 }
1267
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001268 free(result);
Masahiro Yamadaa608b6a2020-09-09 07:16:37 +09001269 delete[] data;
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001270}
1271
Masahiro Yamada7d1300e2020-08-18 01:36:30 +09001272void ConfigInfoView::contextMenuEvent(QContextMenuEvent *event)
Roman Zippel7fc925f2006-06-08 22:12:46 -07001273{
Masahiro Yamada7d1300e2020-08-18 01:36:30 +09001274 contextMenu->popup(event->globalPos());
1275 event->accept();
Roman Zippel7fc925f2006-06-08 22:12:46 -07001276}
1277
Masahiro Yamada740fdef2020-08-07 18:18:57 +09001278ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow *parent)
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001279 : Parent(parent), result(NULL)
Roman Zippel43bf6122006-06-08 22:12:45 -07001280{
Masahiro Yamada740fdef2020-08-07 18:18:57 +09001281 setObjectName("search");
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001282 setWindowTitle("Search Config");
Roman Zippel43bf6122006-06-08 22:12:45 -07001283
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001284 QVBoxLayout* layout1 = new QVBoxLayout(this);
1285 layout1->setContentsMargins(11, 11, 11, 11);
1286 layout1->setSpacing(6);
Masahiro Yamada92641152020-08-07 18:18:58 +09001287
1288 QHBoxLayout* layout2 = new QHBoxLayout();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001289 layout2->setContentsMargins(0, 0, 0, 0);
1290 layout2->setSpacing(6);
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001291 layout2->addWidget(new QLabel("Find:", this));
Roman Zippel43bf6122006-06-08 22:12:45 -07001292 editField = new QLineEdit(this);
1293 connect(editField, SIGNAL(returnPressed()), SLOT(search()));
1294 layout2->addWidget(editField);
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001295 searchButton = new QPushButton("Search", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001296 searchButton->setAutoDefault(false);
Roman Zippel43bf6122006-06-08 22:12:45 -07001297 connect(searchButton, SIGNAL(clicked()), SLOT(search()));
1298 layout2->addWidget(searchButton);
1299 layout1->addLayout(layout2);
1300
Roman Zippel7fc925f2006-06-08 22:12:46 -07001301 split = new QSplitter(this);
Markus Heidelberg7298b932009-05-18 01:36:50 +02001302 split->setOrientation(Qt::Vertical);
Masahiro Yamada740fdef2020-08-07 18:18:57 +09001303 list = new ConfigView(split, "search");
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001304 list->list->mode = listMode;
Masahiro Yamada740fdef2020-08-07 18:18:57 +09001305 info = new ConfigInfoView(split, "search");
Roman Zippel43bf6122006-06-08 22:12:45 -07001306 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1307 info, SLOT(setInfo(struct menu *)));
Marco Costalba63431e72006-10-05 19:12:59 +02001308 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1309 parent, SLOT(setMenuLink(struct menu *)));
1310
Roman Zippel43bf6122006-06-08 22:12:45 -07001311 layout1->addWidget(split);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001312
Masahiro Yamada740fdef2020-08-07 18:18:57 +09001313 QVariant x, y;
1314 int width, height;
1315 bool ok;
Roman Zippel7fc925f2006-06-08 22:12:46 -07001316
Masahiro Yamada740fdef2020-08-07 18:18:57 +09001317 configSettings->beginGroup("search");
1318 width = configSettings->value("/window width", parent->width() / 2).toInt();
1319 height = configSettings->value("/window height", parent->height() / 2).toInt();
1320 resize(width, height);
1321 x = configSettings->value("/window x");
1322 y = configSettings->value("/window y");
1323 if (x.isValid() && y.isValid())
1324 move(x.toInt(), y.toInt());
1325 QList<int> sizes = configSettings->readSizes("/split", &ok);
1326 if (ok)
1327 split->setSizes(sizes);
1328 configSettings->endGroup();
1329 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
Roman Zippel7fc925f2006-06-08 22:12:46 -07001330}
1331
1332void ConfigSearchWindow::saveSettings(void)
1333{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001334 if (!objectName().isEmpty()) {
1335 configSettings->beginGroup(objectName());
1336 configSettings->setValue("/window x", pos().x());
1337 configSettings->setValue("/window y", pos().y());
1338 configSettings->setValue("/window width", size().width());
1339 configSettings->setValue("/window height", size().height());
1340 configSettings->writeSizes("/split", split->sizes());
1341 configSettings->endGroup();
1342 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001343}
1344
1345void ConfigSearchWindow::search(void)
1346{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001347 struct symbol **p;
1348 struct property *prop;
1349 ConfigItem *lastItem = NULL;
1350
1351 free(result);
1352 list->list->clear();
1353 info->clear();
1354
1355 result = sym_re_search(editField->text().toLatin1());
1356 if (!result)
1357 return;
1358 for (p = result; *p; p++) {
1359 for_all_prompts((*p), prop)
1360 lastItem = new ConfigItem(list->list, lastItem, prop->menu,
1361 menu_is_visible(prop->menu));
1362 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001363}
1364
Linus Torvalds1da177e2005-04-16 15:20:36 -07001365/*
1366 * Construct the complete config widget
1367 */
1368ConfigMainWindow::ConfigMainWindow(void)
Roman Zippelf12aa702006-11-25 11:09:31 -08001369 : searchWindow(0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001370{
Boris Barbulovski92119932015-09-22 11:36:16 -07001371 bool ok = true;
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001372 QVariant x, y;
1373 int width, height;
Randy Dunlapa54bb702007-10-20 11:18:47 -07001374 char title[256];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001375
Markus Heidelberg8d90c972009-05-18 01:36:52 +02001376 QDesktopWidget *d = configApp->desktop();
Arnaud Lacombe09548282010-08-18 01:57:13 -04001377 snprintf(title, sizeof(title), "%s%s",
1378 rootmenu.prompt->text,
Michal Marek76a136c2010-09-01 17:39:27 +02001379 ""
Michal Marek76a136c2010-09-01 17:39:27 +02001380 );
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001381 setWindowTitle(title);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001382
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001383 width = configSettings->value("/window width", d->width() - 64).toInt();
1384 height = configSettings->value("/window height", d->height() - 64).toInt();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001385 resize(width, height);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001386 x = configSettings->value("/window x");
1387 y = configSettings->value("/window y");
1388 if ((x.isValid())&&(y.isValid()))
1389 move(x.toInt(), y.toInt());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001390
Masahiro Yamada5cb255f2020-08-07 18:19:07 +09001391 // set up icons
1392 ConfigItem::symbolYesIcon = QIcon(QPixmap(xpm_symbol_yes));
1393 ConfigItem::symbolModIcon = QIcon(QPixmap(xpm_symbol_mod));
1394 ConfigItem::symbolNoIcon = QIcon(QPixmap(xpm_symbol_no));
1395 ConfigItem::choiceYesIcon = QIcon(QPixmap(xpm_choice_yes));
1396 ConfigItem::choiceNoIcon = QIcon(QPixmap(xpm_choice_no));
1397 ConfigItem::menuIcon = QIcon(QPixmap(xpm_menu));
1398 ConfigItem::menubackIcon = QIcon(QPixmap(xpm_menuback));
1399
Mauro Carvalho Chehabcce1fab2020-04-02 11:28:00 +02001400 QWidget *widget = new QWidget(this);
1401 QVBoxLayout *layout = new QVBoxLayout(widget);
1402 setCentralWidget(widget);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001403
Mauro Carvalho Chehabcce1fab2020-04-02 11:28:00 +02001404 split1 = new QSplitter(widget);
1405 split1->setOrientation(Qt::Horizontal);
1406 split1->setChildrenCollapsible(false);
1407
1408 menuView = new ConfigView(widget, "menu");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001409 menuList = menuView->list;
1410
Mauro Carvalho Chehabcce1fab2020-04-02 11:28:00 +02001411 split2 = new QSplitter(widget);
1412 split2->setChildrenCollapsible(false);
Markus Heidelberg7298b932009-05-18 01:36:50 +02001413 split2->setOrientation(Qt::Vertical);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001414
1415 // create config tree
Mauro Carvalho Chehabcce1fab2020-04-02 11:28:00 +02001416 configView = new ConfigView(widget, "config");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001417 configList = configView->list;
1418
Mauro Carvalho Chehabcce1fab2020-04-02 11:28:00 +02001419 helpText = new ConfigInfoView(widget, "help");
1420
1421 layout->addWidget(split2);
1422 split2->addWidget(split1);
1423 split1->addWidget(configView);
1424 split1->addWidget(menuView);
1425 split2->addWidget(helpText);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001426
1427 setTabOrder(configList, helpText);
1428 configList->setFocus();
1429
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001430 backAction = new QAction(QPixmap(xpm_back), "Back", this);
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001431 connect(backAction, SIGNAL(triggered(bool)), SLOT(goBack()));
1432
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001433 QAction *quitAction = new QAction("&Quit", this);
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001434 quitAction->setShortcut(Qt::CTRL + Qt::Key_Q);
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001435 connect(quitAction, SIGNAL(triggered(bool)), SLOT(close()));
1436
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001437 QAction *loadAction = new QAction(QPixmap(xpm_load), "&Load", this);
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001438 loadAction->setShortcut(Qt::CTRL + Qt::Key_L);
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001439 connect(loadAction, SIGNAL(triggered(bool)), SLOT(loadConfig()));
1440
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001441 saveAction = new QAction(QPixmap(xpm_save), "&Save", this);
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001442 saveAction->setShortcut(Qt::CTRL + Qt::Key_S);
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001443 connect(saveAction, SIGNAL(triggered(bool)), SLOT(saveConfig()));
1444
Karsten Wiese3b354c52006-12-13 00:34:08 -08001445 conf_set_changed_callback(conf_changed);
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001446
Karsten Wiese3b354c52006-12-13 00:34:08 -08001447 // Set saveAction's initial state
1448 conf_changed();
Masahiro Yamada87419082019-03-11 01:13:15 +09001449 configname = xstrdup(conf_get_configname());
1450
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001451 QAction *saveAsAction = new QAction("Save &As...", this);
Boris Barbulovski92119932015-09-22 11:36:16 -07001452 connect(saveAsAction, SIGNAL(triggered(bool)), SLOT(saveConfigAs()));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001453 QAction *searchAction = new QAction("&Find", this);
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001454 searchAction->setShortcut(Qt::CTRL + Qt::Key_F);
Boris Barbulovski92119932015-09-22 11:36:16 -07001455 connect(searchAction, SIGNAL(triggered(bool)), SLOT(searchConfig()));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001456 singleViewAction = new QAction(QPixmap(xpm_single_view), "Single View", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001457 singleViewAction->setCheckable(true);
Boris Barbulovski92119932015-09-22 11:36:16 -07001458 connect(singleViewAction, SIGNAL(triggered(bool)), SLOT(showSingleView()));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001459 splitViewAction = new QAction(QPixmap(xpm_split_view), "Split View", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001460 splitViewAction->setCheckable(true);
Boris Barbulovski92119932015-09-22 11:36:16 -07001461 connect(splitViewAction, SIGNAL(triggered(bool)), SLOT(showSplitView()));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001462 fullViewAction = new QAction(QPixmap(xpm_tree_view), "Full View", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001463 fullViewAction->setCheckable(true);
Boris Barbulovski92119932015-09-22 11:36:16 -07001464 connect(fullViewAction, SIGNAL(triggered(bool)), SLOT(showFullView()));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001465
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001466 QAction *showNameAction = new QAction("Show Name", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001467 showNameAction->setCheckable(true);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001468 connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool)));
Boris Barbulovski9c862352015-09-22 11:36:12 -07001469 showNameAction->setChecked(configView->showName());
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001470 QAction *showRangeAction = new QAction("Show Range", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001471 showRangeAction->setCheckable(true);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001472 connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool)));
Li Zefan39a48972010-05-10 16:33:41 +08001473
1474 QActionGroup *optGroup = new QActionGroup(this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001475 optGroup->setExclusive(true);
Masahiro Yamadad4bbe8a2020-08-07 18:19:09 +09001476 connect(optGroup, SIGNAL(triggered(QAction*)), configList,
Li Zefan39a48972010-05-10 16:33:41 +08001477 SLOT(setOptionMode(QAction *)));
Masahiro Yamadad4bbe8a2020-08-07 18:19:09 +09001478 connect(optGroup, SIGNAL(triggered(QAction *)), menuList,
Li Zefan39a48972010-05-10 16:33:41 +08001479 SLOT(setOptionMode(QAction *)));
1480
Masahiro Yamadad4bbe8a2020-08-07 18:19:09 +09001481 ConfigList::showNormalAction = new QAction("Show Normal Options", optGroup);
1482 ConfigList::showNormalAction->setCheckable(true);
1483 ConfigList::showAllAction = new QAction("Show All Options", optGroup);
1484 ConfigList::showAllAction->setCheckable(true);
1485 ConfigList::showPromptAction = new QAction("Show Prompt Options", optGroup);
1486 ConfigList::showPromptAction->setCheckable(true);
Li Zefan39a48972010-05-10 16:33:41 +08001487
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001488 QAction *showDebugAction = new QAction("Show Debug Info", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001489 showDebugAction->setCheckable(true);
Roman Zippel43bf6122006-06-08 22:12:45 -07001490 connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
Boris Barbulovski9c862352015-09-22 11:36:12 -07001491 showDebugAction->setChecked(helpText->showDebug());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001492
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001493 QAction *showIntroAction = new QAction("Introduction", this);
Boris Barbulovski92119932015-09-22 11:36:16 -07001494 connect(showIntroAction, SIGNAL(triggered(bool)), SLOT(showIntro()));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001495 QAction *showAboutAction = new QAction("About", this);
Boris Barbulovski92119932015-09-22 11:36:16 -07001496 connect(showAboutAction, SIGNAL(triggered(bool)), SLOT(showAbout()));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001497
1498 // init tool bar
Masahiro Yamada860ec3f2020-08-07 18:18:55 +09001499 QToolBar *toolBar = addToolBar("Tools");
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001500 toolBar->addAction(backAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001501 toolBar->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001502 toolBar->addAction(loadAction);
1503 toolBar->addAction(saveAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001504 toolBar->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001505 toolBar->addAction(singleViewAction);
1506 toolBar->addAction(splitViewAction);
1507 toolBar->addAction(fullViewAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001508
Masahiro Yamada93ebaac2020-08-07 18:18:53 +09001509 // create file menu
1510 QMenu *menu = menuBar()->addMenu("&File");
1511 menu->addAction(loadAction);
1512 menu->addAction(saveAction);
1513 menu->addAction(saveAsAction);
1514 menu->addSeparator();
1515 menu->addAction(quitAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001516
Shlomi Fish66e7c722007-02-14 00:32:58 -08001517 // create edit menu
Masahiro Yamada93ebaac2020-08-07 18:18:53 +09001518 menu = menuBar()->addMenu("&Edit");
1519 menu->addAction(searchAction);
Shlomi Fish66e7c722007-02-14 00:32:58 -08001520
Linus Torvalds1da177e2005-04-16 15:20:36 -07001521 // create options menu
Masahiro Yamada93ebaac2020-08-07 18:18:53 +09001522 menu = menuBar()->addMenu("&Option");
1523 menu->addAction(showNameAction);
1524 menu->addAction(showRangeAction);
Masahiro Yamada93ebaac2020-08-07 18:18:53 +09001525 menu->addSeparator();
1526 menu->addActions(optGroup->actions());
1527 menu->addSeparator();
1528 menu->addAction(showDebugAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001529
1530 // create help menu
Masahiro Yamada93ebaac2020-08-07 18:18:53 +09001531 menu = menuBar()->addMenu("&Help");
1532 menu->addAction(showIntroAction);
1533 menu->addAction(showAboutAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001534
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001535 connect (helpText, SIGNAL (anchorClicked (const QUrl &)),
1536 helpText, SLOT (clicked (const QUrl &)) );
1537
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001538 connect(configList, SIGNAL(menuChanged(struct menu *)),
1539 helpText, SLOT(setInfo(struct menu *)));
1540 connect(configList, SIGNAL(menuSelected(struct menu *)),
1541 SLOT(changeMenu(struct menu *)));
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +02001542 connect(configList, SIGNAL(itemSelected(struct menu *)),
1543 SLOT(changeItens(struct menu *)));
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001544 connect(configList, SIGNAL(parentSelected()),
1545 SLOT(goBack()));
1546 connect(menuList, SIGNAL(menuChanged(struct menu *)),
1547 helpText, SLOT(setInfo(struct menu *)));
1548 connect(menuList, SIGNAL(menuSelected(struct menu *)),
1549 SLOT(changeMenu(struct menu *)));
1550
1551 connect(configList, SIGNAL(gotFocus(struct menu *)),
1552 helpText, SLOT(setInfo(struct menu *)));
1553 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1554 helpText, SLOT(setInfo(struct menu *)));
1555 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1556 SLOT(listFocusChanged(void)));
Roman Zippelb65a47e2006-06-08 22:12:47 -07001557 connect(helpText, SIGNAL(menuSelected(struct menu *)),
1558 SLOT(setMenuLink(struct menu *)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001559
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001560 QString listMode = configSettings->value("/listMode", "symbol").toString();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001561 if (listMode == "single")
1562 showSingleView();
1563 else if (listMode == "full")
1564 showFullView();
1565 else /*if (listMode == "split")*/
1566 showSplitView();
1567
1568 // UI setup done, restore splitter positions
Boris Barbulovski041fbdc2015-09-22 11:36:05 -07001569 QList<int> sizes = configSettings->readSizes("/split1", &ok);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001570 if (ok)
1571 split1->setSizes(sizes);
1572
Roman Zippel7fc925f2006-06-08 22:12:46 -07001573 sizes = configSettings->readSizes("/split2", &ok);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001574 if (ok)
1575 split2->setSizes(sizes);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001576}
1577
Linus Torvalds1da177e2005-04-16 15:20:36 -07001578void ConfigMainWindow::loadConfig(void)
1579{
Masahiro Yamada87419082019-03-11 01:13:15 +09001580 QString str;
1581 QByteArray ba;
1582 const char *name;
1583
1584 str = QFileDialog::getOpenFileName(this, "", configname);
1585 if (str.isNull())
Linus Torvalds1da177e2005-04-16 15:20:36 -07001586 return;
Masahiro Yamada87419082019-03-11 01:13:15 +09001587
1588 ba = str.toLocal8Bit();
1589 name = ba.data();
1590
1591 if (conf_read(name))
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001592 QMessageBox::information(this, "qconf", "Unable to load configuration!");
Masahiro Yamada87419082019-03-11 01:13:15 +09001593
1594 free(configname);
1595 configname = xstrdup(name);
1596
Masahiro Yamadaf9b918f2020-08-29 17:14:10 +09001597 ConfigList::updateListAllForAll();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001598}
1599
Michal Marekbac6aa82011-05-25 15:10:25 +02001600bool ConfigMainWindow::saveConfig(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001601{
Masahiro Yamada87419082019-03-11 01:13:15 +09001602 if (conf_write(configname)) {
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001603 QMessageBox::information(this, "qconf", "Unable to save configuration!");
Michal Marekbac6aa82011-05-25 15:10:25 +02001604 return false;
1605 }
Masahiro Yamada00c864f2018-07-20 16:46:31 +09001606 conf_write_autoconf(0);
1607
Michal Marekbac6aa82011-05-25 15:10:25 +02001608 return true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001609}
1610
1611void ConfigMainWindow::saveConfigAs(void)
1612{
Masahiro Yamada87419082019-03-11 01:13:15 +09001613 QString str;
1614 QByteArray ba;
1615 const char *name;
1616
1617 str = QFileDialog::getSaveFileName(this, "", configname);
1618 if (str.isNull())
Linus Torvalds1da177e2005-04-16 15:20:36 -07001619 return;
Masahiro Yamada87419082019-03-11 01:13:15 +09001620
1621 ba = str.toLocal8Bit();
1622 name = ba.data();
1623
1624 if (conf_write(name)) {
1625 QMessageBox::information(this, "qconf", "Unable to save configuration!");
1626 }
1627 conf_write_autoconf(0);
1628
1629 free(configname);
1630 configname = xstrdup(name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001631}
1632
Roman Zippel43bf6122006-06-08 22:12:45 -07001633void ConfigMainWindow::searchConfig(void)
1634{
1635 if (!searchWindow)
Masahiro Yamada740fdef2020-08-07 18:18:57 +09001636 searchWindow = new ConfigSearchWindow(this);
Roman Zippel43bf6122006-06-08 22:12:45 -07001637 searchWindow->show();
1638}
1639
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +02001640void ConfigMainWindow::changeItens(struct menu *menu)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001641{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001642 configList->setRootMenu(menu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001643}
1644
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +02001645void ConfigMainWindow::changeMenu(struct menu *menu)
1646{
1647 menuList->setRootMenu(menu);
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +02001648}
1649
Roman Zippelb65a47e2006-06-08 22:12:47 -07001650void ConfigMainWindow::setMenuLink(struct menu *menu)
1651{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001652 struct menu *parent;
1653 ConfigList* list = NULL;
1654 ConfigItem* item;
1655
1656 if (configList->menuSkip(menu))
1657 return;
1658
1659 switch (configList->mode) {
1660 case singleMode:
1661 list = configList;
1662 parent = menu_get_parent_menu(menu);
1663 if (!parent)
1664 return;
1665 list->setRootMenu(parent);
1666 break;
Mauro Carvalho Chehabc699eaa2020-06-30 08:26:36 +02001667 case menuMode:
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001668 if (menu->flags & MENU_ROOT) {
Mauro Carvalho Chehabc699eaa2020-06-30 08:26:36 +02001669 menuList->setRootMenu(menu);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001670 configList->clearSelection();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001671 list = configList;
Mauro Carvalho Chehabc699eaa2020-06-30 08:26:36 +02001672 } else {
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001673 parent = menu_get_parent_menu(menu->parent);
1674 if (!parent)
1675 return;
Mauro Carvalho Chehabc699eaa2020-06-30 08:26:36 +02001676
Mauro Carvalho Chehabc699eaa2020-06-30 08:26:36 +02001677 /* Select the config view */
1678 item = configList->findConfigItem(parent);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001679 if (item) {
Mauro Carvalho Chehabb06c3ec2020-06-30 08:26:38 +02001680 configList->setSelected(item, true);
Mauro Carvalho Chehabc699eaa2020-06-30 08:26:36 +02001681 configList->scrollToItem(item);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001682 }
Mauro Carvalho Chehabc699eaa2020-06-30 08:26:36 +02001683
1684 menuList->setRootMenu(parent);
1685 menuList->clearSelection();
1686 list = menuList;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001687 }
1688 break;
1689 case fullMode:
1690 list = configList;
1691 break;
1692 default:
1693 break;
1694 }
1695
1696 if (list) {
1697 item = list->findConfigItem(menu);
1698 if (item) {
Mauro Carvalho Chehabb06c3ec2020-06-30 08:26:38 +02001699 list->setSelected(item, true);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001700 list->scrollToItem(item);
1701 list->setFocus();
Mauro Carvalho Chehab8a3b6e52020-06-30 08:48:35 +02001702 helpText->setInfo(menu);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001703 }
1704 }
Roman Zippelb65a47e2006-06-08 22:12:47 -07001705}
1706
Linus Torvalds1da177e2005-04-16 15:20:36 -07001707void ConfigMainWindow::listFocusChanged(void)
1708{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001709 if (menuList->mode == menuMode)
1710 configList->clearSelection();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001711}
1712
1713void ConfigMainWindow::goBack(void)
1714{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001715 if (configList->rootEntry == &rootmenu)
Boris Barbulovskibe596aa2015-09-22 11:36:28 -07001716 return;
1717
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001718 configList->setParentMenu();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001719}
1720
1721void ConfigMainWindow::showSingleView(void)
1722{
Boris Barbulovski780505e2015-09-22 11:36:13 -07001723 singleViewAction->setEnabled(false);
1724 singleViewAction->setChecked(true);
1725 splitViewAction->setEnabled(true);
1726 splitViewAction->setChecked(false);
1727 fullViewAction->setEnabled(true);
1728 fullViewAction->setChecked(false);
1729
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001730 backAction->setEnabled(true);
1731
Linus Torvalds1da177e2005-04-16 15:20:36 -07001732 menuView->hide();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001733 menuList->setRootMenu(0);
1734 configList->mode = singleMode;
1735 if (configList->rootEntry == &rootmenu)
1736 configList->updateListAll();
1737 else
1738 configList->setRootMenu(&rootmenu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001739 configList->setFocus();
1740}
1741
1742void ConfigMainWindow::showSplitView(void)
1743{
Boris Barbulovski780505e2015-09-22 11:36:13 -07001744 singleViewAction->setEnabled(true);
1745 singleViewAction->setChecked(false);
1746 splitViewAction->setEnabled(false);
1747 splitViewAction->setChecked(true);
1748 fullViewAction->setEnabled(true);
1749 fullViewAction->setChecked(false);
1750
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001751 backAction->setEnabled(false);
1752
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +02001753 configList->mode = menuMode;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001754 if (configList->rootEntry == &rootmenu)
1755 configList->updateListAll();
1756 else
1757 configList->setRootMenu(&rootmenu);
1758 configList->setAllOpen(true);
1759 configApp->processEvents();
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +02001760 menuList->mode = symbolMode;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001761 menuList->setRootMenu(&rootmenu);
1762 menuList->setAllOpen(true);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001763 menuView->show();
1764 menuList->setFocus();
1765}
1766
1767void ConfigMainWindow::showFullView(void)
1768{
Boris Barbulovski780505e2015-09-22 11:36:13 -07001769 singleViewAction->setEnabled(true);
1770 singleViewAction->setChecked(false);
1771 splitViewAction->setEnabled(true);
1772 splitViewAction->setChecked(false);
1773 fullViewAction->setEnabled(false);
1774 fullViewAction->setChecked(true);
1775
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001776 backAction->setEnabled(false);
1777
Linus Torvalds1da177e2005-04-16 15:20:36 -07001778 menuView->hide();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001779 menuList->setRootMenu(0);
1780 configList->mode = fullMode;
1781 if (configList->rootEntry == &rootmenu)
1782 configList->updateListAll();
1783 else
1784 configList->setRootMenu(&rootmenu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001785 configList->setFocus();
1786}
1787
Linus Torvalds1da177e2005-04-16 15:20:36 -07001788/*
1789 * ask for saving configuration before quitting
Linus Torvalds1da177e2005-04-16 15:20:36 -07001790 */
1791void ConfigMainWindow::closeEvent(QCloseEvent* e)
1792{
Karsten Wieseb3214292006-12-13 00:34:06 -08001793 if (!conf_get_changed()) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001794 e->accept();
1795 return;
1796 }
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001797 QMessageBox mb("qconf", "Save configuration?", QMessageBox::Warning,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001798 QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape);
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001799 mb.setButtonText(QMessageBox::Yes, "&Save Changes");
1800 mb.setButtonText(QMessageBox::No, "&Discard Changes");
1801 mb.setButtonText(QMessageBox::Cancel, "Cancel Exit");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001802 switch (mb.exec()) {
1803 case QMessageBox::Yes:
Michal Marekbac6aa82011-05-25 15:10:25 +02001804 if (saveConfig())
1805 e->accept();
1806 else
1807 e->ignore();
1808 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001809 case QMessageBox::No:
1810 e->accept();
1811 break;
1812 case QMessageBox::Cancel:
1813 e->ignore();
1814 break;
1815 }
1816}
1817
1818void ConfigMainWindow::showIntro(void)
1819{
Masahiro Yamada8c30e7e2020-08-29 17:14:07 +09001820 static const QString str =
1821 "Welcome to the qconf graphical configuration tool.\n"
1822 "\n"
Masahiro Yamada37162a62020-08-29 17:14:12 +09001823 "For bool and tristate options, a blank box indicates the "
1824 "feature is disabled, a check indicates it is enabled, and a "
1825 "dot indicates that it is to be compiled as a module. Clicking "
1826 "on the box will cycle through the three states. For int, hex, "
1827 "and string options, double-clicking or pressing F2 on the "
1828 "Value cell will allow you to edit the value.\n"
Masahiro Yamada8c30e7e2020-08-29 17:14:07 +09001829 "\n"
1830 "If you do not see an option (e.g., a device driver) that you "
1831 "believe should be present, try turning on Show All Options "
Masahiro Yamada1fb75242020-08-29 17:14:08 +09001832 "under the Options menu. Enabling Show Debug Info will help you"
1833 "figure out what other options must be enabled to support the "
1834 "option you are interested in, and hyperlinks will navigate to "
1835 "them.\n"
Masahiro Yamada8c30e7e2020-08-29 17:14:07 +09001836 "\n"
1837 "Toggling Show Debug Info under the Options menu will show the "
1838 "dependencies, which you can then match by examining other "
1839 "options.\n";
Linus Torvalds1da177e2005-04-16 15:20:36 -07001840
1841 QMessageBox::information(this, "qconf", str);
1842}
1843
1844void ConfigMainWindow::showAbout(void)
1845{
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001846 static const QString str = "qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n"
Boris Barbulovskib4ff1de2015-09-22 11:36:38 -07001847 "Copyright (C) 2015 Boris Barbulovski <bbarbulovski@gmail.com>.\n\n"
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001848 "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n";
Linus Torvalds1da177e2005-04-16 15:20:36 -07001849
1850 QMessageBox::information(this, "qconf", str);
1851}
1852
1853void ConfigMainWindow::saveSettings(void)
1854{
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001855 configSettings->setValue("/window x", pos().x());
1856 configSettings->setValue("/window y", pos().y());
1857 configSettings->setValue("/window width", size().width());
1858 configSettings->setValue("/window height", size().height());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001859
1860 QString entry;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001861 switch(configList->mode) {
1862 case singleMode :
1863 entry = "single";
1864 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001865
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001866 case symbolMode :
1867 entry = "split";
1868 break;
1869
1870 case fullMode :
1871 entry = "full";
1872 break;
1873
1874 default:
1875 break;
1876 }
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001877 configSettings->setValue("/listMode", entry);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001878
Roman Zippel7fc925f2006-06-08 22:12:46 -07001879 configSettings->writeSizes("/split1", split1->sizes());
1880 configSettings->writeSizes("/split2", split2->sizes());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001881}
1882
Karsten Wiese3b354c52006-12-13 00:34:08 -08001883void ConfigMainWindow::conf_changed(void)
1884{
1885 if (saveAction)
1886 saveAction->setEnabled(conf_get_changed());
1887}
1888
Linus Torvalds1da177e2005-04-16 15:20:36 -07001889void fixup_rootmenu(struct menu *menu)
1890{
1891 struct menu *child;
1892 static int menu_cnt = 0;
1893
1894 menu->flags |= MENU_ROOT;
1895 for (child = menu->list; child; child = child->next) {
1896 if (child->prompt && child->prompt->type == P_MENU) {
1897 menu_cnt++;
1898 fixup_rootmenu(child);
1899 menu_cnt--;
1900 } else if (!menu_cnt)
1901 fixup_rootmenu(child);
1902 }
1903}
1904
1905static const char *progname;
1906
1907static void usage(void)
1908{
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001909 printf("%s [-s] <config>\n", progname);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001910 exit(0);
1911}
1912
1913int main(int ac, char** av)
1914{
1915 ConfigMainWindow* v;
1916 const char *name;
1917
Linus Torvalds1da177e2005-04-16 15:20:36 -07001918 progname = av[0];
1919 configApp = new QApplication(ac, av);
1920 if (ac > 1 && av[1][0] == '-') {
1921 switch (av[1][1]) {
Michal Marek0a1f00a2015-04-08 13:30:42 +02001922 case 's':
1923 conf_set_message_callback(NULL);
1924 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001925 case 'h':
1926 case '?':
1927 usage();
1928 }
1929 name = av[2];
1930 } else
1931 name = av[1];
1932 if (!name)
1933 usage();
1934
1935 conf_parse(name);
1936 fixup_rootmenu(&rootmenu);
1937 conf_read(NULL);
1938 //zconfdump(stdout);
1939
Roman Zippel7fc925f2006-06-08 22:12:46 -07001940 configSettings = new ConfigSettings();
1941 configSettings->beginGroup("/kconfig/qconf");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001942 v = new ConfigMainWindow();
1943
1944 //zconfdump(stdout);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001945 configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit()));
1946 configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings()));
Roman Zippel43bf6122006-06-08 22:12:45 -07001947 v->show();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001948 configApp->exec();
1949
Roman Zippel7fc925f2006-06-08 22:12:46 -07001950 configSettings->endGroup();
1951 delete configSettings;
Chris Bainbridge5b61c7b2016-01-08 20:44:04 +00001952 delete v;
1953 delete configApp;
Roman Zippel7fc925f2006-06-08 22:12:46 -07001954
Linus Torvalds1da177e2005-04-16 15:20:36 -07001955 return 0;
1956}