blob: 5f3e5e145a99edfc99b69b0e2c1e24d27c1629db [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)),
Masahiro Yamada7930dd92020-08-29 17:14:14 +0900923 SLOT(setShowName(bool)));
924 connect(this, 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)),
Masahiro Yamada7930dd92020-08-29 17:14:14 +0900932 SLOT(setShowRange(bool)));
933 connect(this, 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 Yamada7930dd92020-08-29 17:14:14 +0900943void ConfigList::setShowName(bool on)
944{
945 if (showName == on)
946 return;
947
948 showName = on;
949 reinit();
950 emit showNameChanged(on);
951}
952
953void ConfigList::setShowRange(bool on)
954{
955 if (showRange == on)
956 return;
957
958 showRange = on;
959 reinit();
960 emit showRangeChanged(on);
961}
962
Masahiro Yamadaf9b918f2020-08-29 17:14:10 +0900963QList<ConfigList *> ConfigList::allLists;
Masahiro Yamadad4bbe8a2020-08-07 18:19:09 +0900964QAction *ConfigList::showNormalAction;
965QAction *ConfigList::showAllAction;
966QAction *ConfigList::showPromptAction;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700967
Roman Zippel7fc925f2006-06-08 22:12:46 -0700968ConfigView::ConfigView(QWidget* parent, const char *name)
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -0700969 : Parent(parent)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700970{
Boris Barbulovski9bd36ed2015-09-22 11:36:22 -0700971 setObjectName(name);
Boris Barbulovski29a70162015-09-22 11:36:10 -0700972 QVBoxLayout *verticalLayout = new QVBoxLayout(this);
Boris Barbulovski92298b42015-09-22 11:36:11 -0700973 verticalLayout->setContentsMargins(0, 0, 0, 0);
Boris Barbulovski29a70162015-09-22 11:36:10 -0700974
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700975 list = new ConfigList(this);
Boris Barbulovski29a70162015-09-22 11:36:10 -0700976 verticalLayout->addWidget(list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700977}
978
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700979void ConfigList::setAllOpen(bool open)
980{
981 QTreeWidgetItemIterator it(this);
982
983 while (*it) {
984 (*it)->setExpanded(open);
985
986 ++it;
987 }
Roman Zippel7fc925f2006-06-08 22:12:46 -0700988}
989
Roman Zippel43bf6122006-06-08 22:12:45 -0700990ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name)
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -0700991 : Parent(parent), sym(0), _menu(0)
Roman Zippel43bf6122006-06-08 22:12:45 -0700992{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700993 setObjectName(name);
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +0200994 setOpenLinks(false);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700995
996 if (!objectName().isEmpty()) {
997 configSettings->beginGroup(objectName());
Boris Barbulovskie0393032016-11-30 14:57:52 -0800998 setShowDebug(configSettings->value("/showDebug", false).toBool());
Roman Zippel7fc925f2006-06-08 22:12:46 -0700999 configSettings->endGroup();
1000 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
1001 }
Masahiro Yamada7d1300e2020-08-18 01:36:30 +09001002
1003 contextMenu = createStandardContextMenu();
1004 QAction *action = new QAction("Show Debug Info", contextMenu);
1005
1006 action->setCheckable(true);
1007 connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
1008 connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setChecked(bool)));
1009 action->setChecked(showDebug());
1010 contextMenu->addSeparator();
1011 contextMenu->addAction(action);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001012}
1013
1014void ConfigInfoView::saveSettings(void)
1015{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001016 if (!objectName().isEmpty()) {
1017 configSettings->beginGroup(objectName());
1018 configSettings->setValue("/showDebug", showDebug());
1019 configSettings->endGroup();
1020 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001021}
1022
1023void ConfigInfoView::setShowDebug(bool b)
1024{
1025 if (_showDebug != b) {
1026 _showDebug = b;
Alexander Stein133c5f72010-08-31 17:34:37 +02001027 if (_menu)
Roman Zippel43bf6122006-06-08 22:12:45 -07001028 menuInfo();
Roman Zippelab45d192006-06-08 22:12:47 -07001029 else if (sym)
1030 symbolInfo();
Roman Zippel43bf6122006-06-08 22:12:45 -07001031 emit showDebugChanged(b);
1032 }
1033}
1034
1035void ConfigInfoView::setInfo(struct menu *m)
1036{
Alexander Stein133c5f72010-08-31 17:34:37 +02001037 if (_menu == m)
Roman Zippelb65a47e2006-06-08 22:12:47 -07001038 return;
Alexander Stein133c5f72010-08-31 17:34:37 +02001039 _menu = m;
Roman Zippel6fa1da82007-01-10 23:15:31 -08001040 sym = NULL;
Alexander Stein133c5f72010-08-31 17:34:37 +02001041 if (!_menu)
Roman Zippel43bf6122006-06-08 22:12:45 -07001042 clear();
Roman Zippel6fa1da82007-01-10 23:15:31 -08001043 else
Roman Zippel43bf6122006-06-08 22:12:45 -07001044 menuInfo();
1045}
1046
Roman Zippelab45d192006-06-08 22:12:47 -07001047void ConfigInfoView::symbolInfo(void)
1048{
1049 QString str;
1050
1051 str += "<big>Symbol: <b>";
1052 str += print_filter(sym->name);
1053 str += "</b></big><br><br>value: ";
1054 str += print_filter(sym_get_string_value(sym));
1055 str += "<br>visibility: ";
1056 str += sym->visible == yes ? "y" : sym->visible == mod ? "m" : "n";
1057 str += "<br>";
1058 str += debug_info(sym);
1059
1060 setText(str);
1061}
1062
Roman Zippel43bf6122006-06-08 22:12:45 -07001063void ConfigInfoView::menuInfo(void)
1064{
1065 struct symbol* sym;
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001066 QString info;
1067 QTextStream stream(&info);
Roman Zippel43bf6122006-06-08 22:12:45 -07001068
Alexander Stein133c5f72010-08-31 17:34:37 +02001069 sym = _menu->sym;
Roman Zippel43bf6122006-06-08 22:12:45 -07001070 if (sym) {
Alexander Stein133c5f72010-08-31 17:34:37 +02001071 if (_menu->prompt) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001072 stream << "<big><b>";
1073 stream << print_filter(_menu->prompt->text);
1074 stream << "</b></big>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001075 if (sym->name) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001076 stream << " (";
Roman Zippelab45d192006-06-08 22:12:47 -07001077 if (showDebug())
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001078 stream << "<a href=\"s" << sym->name << "\">";
1079 stream << print_filter(sym->name);
Roman Zippelab45d192006-06-08 22:12:47 -07001080 if (showDebug())
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001081 stream << "</a>";
1082 stream << ")";
Roman Zippel43bf6122006-06-08 22:12:45 -07001083 }
1084 } else if (sym->name) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001085 stream << "<big><b>";
Roman Zippelab45d192006-06-08 22:12:47 -07001086 if (showDebug())
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001087 stream << "<a href=\"s" << sym->name << "\">";
1088 stream << print_filter(sym->name);
Roman Zippelab45d192006-06-08 22:12:47 -07001089 if (showDebug())
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001090 stream << "</a>";
1091 stream << "</b></big>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001092 }
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001093 stream << "<br><br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001094
1095 if (showDebug())
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001096 stream << debug_info(sym);
1097
Masahiro Yamadaa46afd12020-09-14 23:59:48 +09001098 struct gstr help_gstr = str_new();
1099
1100 menu_get_ext_help(_menu, &help_gstr);
1101 stream << print_filter(str_get(&help_gstr));
1102 str_free(&help_gstr);
Alexander Stein133c5f72010-08-31 17:34:37 +02001103 } else if (_menu->prompt) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001104 stream << "<big><b>";
1105 stream << print_filter(_menu->prompt->text);
1106 stream << "</b></big><br><br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001107 if (showDebug()) {
Alexander Stein133c5f72010-08-31 17:34:37 +02001108 if (_menu->prompt->visible.expr) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001109 stream << "&nbsp;&nbsp;dep: ";
1110 expr_print(_menu->prompt->visible.expr,
1111 expr_print_help, &stream, E_NONE);
1112 stream << "<br><br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001113 }
Masahiro Yamadaa46afd12020-09-14 23:59:48 +09001114
1115 stream << "defined at " << _menu->file->name << ":"
1116 << _menu->lineno << "<br><br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001117 }
1118 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001119
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001120 setText(info);
Roman Zippel43bf6122006-06-08 22:12:45 -07001121}
1122
1123QString ConfigInfoView::debug_info(struct symbol *sym)
1124{
1125 QString debug;
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001126 QTextStream stream(&debug);
Roman Zippel43bf6122006-06-08 22:12:45 -07001127
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001128 stream << "type: ";
1129 stream << print_filter(sym_type_name(sym->type));
Roman Zippel43bf6122006-06-08 22:12:45 -07001130 if (sym_is_choice(sym))
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001131 stream << " (choice)";
Roman Zippel43bf6122006-06-08 22:12:45 -07001132 debug += "<br>";
1133 if (sym->rev_dep.expr) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001134 stream << "reverse dep: ";
1135 expr_print(sym->rev_dep.expr, expr_print_help, &stream, E_NONE);
1136 stream << "<br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001137 }
1138 for (struct property *prop = sym->prop; prop; prop = prop->next) {
1139 switch (prop->type) {
1140 case P_PROMPT:
1141 case P_MENU:
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001142 stream << "prompt: <a href=\"m" << sym->name << "\">";
1143 stream << print_filter(prop->text);
1144 stream << "</a><br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001145 break;
1146 case P_DEFAULT:
Roman Zippel93449082008-01-14 04:50:54 +01001147 case P_SELECT:
1148 case P_RANGE:
Mauro Carvalho Chehab8f8499a2020-06-30 08:48:53 +02001149 case P_COMMENT:
1150 case P_IMPLY:
1151 case P_SYMBOL:
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001152 stream << prop_get_type_name(prop->type);
1153 stream << ": ";
1154 expr_print(prop->expr, expr_print_help,
1155 &stream, E_NONE);
1156 stream << "<br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001157 break;
1158 case P_CHOICE:
1159 if (sym_is_choice(sym)) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001160 stream << "choice: ";
1161 expr_print(prop->expr, expr_print_help,
1162 &stream, E_NONE);
1163 stream << "<br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001164 }
1165 break;
Roman Zippel43bf6122006-06-08 22:12:45 -07001166 default:
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001167 stream << "unknown property: ";
1168 stream << prop_get_type_name(prop->type);
1169 stream << "<br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001170 }
1171 if (prop->visible.expr) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001172 stream << "&nbsp;&nbsp;&nbsp;&nbsp;dep: ";
1173 expr_print(prop->visible.expr, expr_print_help,
1174 &stream, E_NONE);
1175 stream << "<br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001176 }
1177 }
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001178 stream << "<br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001179
1180 return debug;
1181}
1182
1183QString ConfigInfoView::print_filter(const QString &str)
1184{
1185 QRegExp re("[<>&\"\\n]");
1186 QString res = str;
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001187 for (int i = 0; (i = res.indexOf(re, i)) >= 0;) {
1188 switch (res[i].toLatin1()) {
Roman Zippel43bf6122006-06-08 22:12:45 -07001189 case '<':
1190 res.replace(i, 1, "&lt;");
1191 i += 4;
1192 break;
1193 case '>':
1194 res.replace(i, 1, "&gt;");
1195 i += 4;
1196 break;
1197 case '&':
1198 res.replace(i, 1, "&amp;");
1199 i += 5;
1200 break;
1201 case '"':
1202 res.replace(i, 1, "&quot;");
1203 i += 6;
1204 break;
1205 case '\n':
1206 res.replace(i, 1, "<br>");
1207 i += 4;
1208 break;
1209 }
1210 }
1211 return res;
1212}
1213
Roman Zippelab45d192006-06-08 22:12:47 -07001214void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char *str)
Roman Zippel43bf6122006-06-08 22:12:45 -07001215{
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001216 QTextStream *stream = reinterpret_cast<QTextStream *>(data);
Roman Zippelab45d192006-06-08 22:12:47 -07001217
1218 if (sym && sym->name && !(sym->flags & SYMBOL_CONST)) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001219 *stream << "<a href=\"s" << sym->name << "\">";
1220 *stream << print_filter(str);
1221 *stream << "</a>";
1222 } else {
1223 *stream << print_filter(str);
1224 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001225}
1226
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001227void ConfigInfoView::clicked(const QUrl &url)
1228{
1229 QByteArray str = url.toEncoded();
1230 const std::size_t count = str.size();
1231 char *data = new char[count + 1];
1232 struct symbol **result;
1233 struct menu *m = NULL;
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001234
1235 if (count < 1) {
Masahiro Yamadac9b09a922020-07-30 02:02:39 +09001236 delete[] data;
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001237 return;
1238 }
1239
1240 memcpy(data, str.constData(), count);
1241 data[count] = '\0';
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001242
1243 /* Seek for exact match */
1244 data[0] = '^';
1245 strcat(data, "$");
1246 result = sym_re_search(data);
1247 if (!result) {
Masahiro Yamadac9b09a922020-07-30 02:02:39 +09001248 delete[] data;
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001249 return;
1250 }
1251
1252 sym = *result;
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001253
Mauro Carvalho Chehab8a3b6e52020-06-30 08:48:35 +02001254 /* Seek for the menu which holds the symbol */
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001255 for (struct property *prop = sym->prop; prop; prop = prop->next) {
1256 if (prop->type != P_PROMPT && prop->type != P_MENU)
1257 continue;
1258 m = prop->menu;
1259 break;
1260 }
1261
1262 if (!m) {
Mauro Carvalho Chehab8a3b6e52020-06-30 08:48:35 +02001263 /* Symbol is not visible as a menu */
1264 symbolInfo();
1265 emit showDebugChanged(true);
1266 } else {
1267 emit menuSelected(m);
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001268 }
1269
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001270 free(result);
Masahiro Yamadaa608b6a2020-09-09 07:16:37 +09001271 delete[] data;
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001272}
1273
Masahiro Yamada7d1300e2020-08-18 01:36:30 +09001274void ConfigInfoView::contextMenuEvent(QContextMenuEvent *event)
Roman Zippel7fc925f2006-06-08 22:12:46 -07001275{
Masahiro Yamada7d1300e2020-08-18 01:36:30 +09001276 contextMenu->popup(event->globalPos());
1277 event->accept();
Roman Zippel7fc925f2006-06-08 22:12:46 -07001278}
1279
Masahiro Yamada740fdef2020-08-07 18:18:57 +09001280ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow *parent)
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001281 : Parent(parent), result(NULL)
Roman Zippel43bf6122006-06-08 22:12:45 -07001282{
Masahiro Yamada740fdef2020-08-07 18:18:57 +09001283 setObjectName("search");
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001284 setWindowTitle("Search Config");
Roman Zippel43bf6122006-06-08 22:12:45 -07001285
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001286 QVBoxLayout* layout1 = new QVBoxLayout(this);
1287 layout1->setContentsMargins(11, 11, 11, 11);
1288 layout1->setSpacing(6);
Masahiro Yamada92641152020-08-07 18:18:58 +09001289
1290 QHBoxLayout* layout2 = new QHBoxLayout();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001291 layout2->setContentsMargins(0, 0, 0, 0);
1292 layout2->setSpacing(6);
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001293 layout2->addWidget(new QLabel("Find:", this));
Roman Zippel43bf6122006-06-08 22:12:45 -07001294 editField = new QLineEdit(this);
1295 connect(editField, SIGNAL(returnPressed()), SLOT(search()));
1296 layout2->addWidget(editField);
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001297 searchButton = new QPushButton("Search", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001298 searchButton->setAutoDefault(false);
Roman Zippel43bf6122006-06-08 22:12:45 -07001299 connect(searchButton, SIGNAL(clicked()), SLOT(search()));
1300 layout2->addWidget(searchButton);
1301 layout1->addLayout(layout2);
1302
Roman Zippel7fc925f2006-06-08 22:12:46 -07001303 split = new QSplitter(this);
Markus Heidelberg7298b932009-05-18 01:36:50 +02001304 split->setOrientation(Qt::Vertical);
Masahiro Yamada740fdef2020-08-07 18:18:57 +09001305 list = new ConfigView(split, "search");
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001306 list->list->mode = listMode;
Masahiro Yamada740fdef2020-08-07 18:18:57 +09001307 info = new ConfigInfoView(split, "search");
Roman Zippel43bf6122006-06-08 22:12:45 -07001308 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1309 info, SLOT(setInfo(struct menu *)));
Marco Costalba63431e72006-10-05 19:12:59 +02001310 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1311 parent, SLOT(setMenuLink(struct menu *)));
1312
Roman Zippel43bf6122006-06-08 22:12:45 -07001313 layout1->addWidget(split);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001314
Masahiro Yamada740fdef2020-08-07 18:18:57 +09001315 QVariant x, y;
1316 int width, height;
1317 bool ok;
Roman Zippel7fc925f2006-06-08 22:12:46 -07001318
Masahiro Yamada740fdef2020-08-07 18:18:57 +09001319 configSettings->beginGroup("search");
1320 width = configSettings->value("/window width", parent->width() / 2).toInt();
1321 height = configSettings->value("/window height", parent->height() / 2).toInt();
1322 resize(width, height);
1323 x = configSettings->value("/window x");
1324 y = configSettings->value("/window y");
1325 if (x.isValid() && y.isValid())
1326 move(x.toInt(), y.toInt());
1327 QList<int> sizes = configSettings->readSizes("/split", &ok);
1328 if (ok)
1329 split->setSizes(sizes);
1330 configSettings->endGroup();
1331 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
Roman Zippel7fc925f2006-06-08 22:12:46 -07001332}
1333
1334void ConfigSearchWindow::saveSettings(void)
1335{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001336 if (!objectName().isEmpty()) {
1337 configSettings->beginGroup(objectName());
1338 configSettings->setValue("/window x", pos().x());
1339 configSettings->setValue("/window y", pos().y());
1340 configSettings->setValue("/window width", size().width());
1341 configSettings->setValue("/window height", size().height());
1342 configSettings->writeSizes("/split", split->sizes());
1343 configSettings->endGroup();
1344 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001345}
1346
1347void ConfigSearchWindow::search(void)
1348{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001349 struct symbol **p;
1350 struct property *prop;
1351 ConfigItem *lastItem = NULL;
1352
1353 free(result);
1354 list->list->clear();
1355 info->clear();
1356
1357 result = sym_re_search(editField->text().toLatin1());
1358 if (!result)
1359 return;
1360 for (p = result; *p; p++) {
1361 for_all_prompts((*p), prop)
1362 lastItem = new ConfigItem(list->list, lastItem, prop->menu,
1363 menu_is_visible(prop->menu));
1364 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001365}
1366
Linus Torvalds1da177e2005-04-16 15:20:36 -07001367/*
1368 * Construct the complete config widget
1369 */
1370ConfigMainWindow::ConfigMainWindow(void)
Roman Zippelf12aa702006-11-25 11:09:31 -08001371 : searchWindow(0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001372{
Boris Barbulovski92119932015-09-22 11:36:16 -07001373 bool ok = true;
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001374 QVariant x, y;
1375 int width, height;
Randy Dunlapa54bb702007-10-20 11:18:47 -07001376 char title[256];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001377
Markus Heidelberg8d90c972009-05-18 01:36:52 +02001378 QDesktopWidget *d = configApp->desktop();
Arnaud Lacombe09548282010-08-18 01:57:13 -04001379 snprintf(title, sizeof(title), "%s%s",
1380 rootmenu.prompt->text,
Michal Marek76a136c2010-09-01 17:39:27 +02001381 ""
Michal Marek76a136c2010-09-01 17:39:27 +02001382 );
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001383 setWindowTitle(title);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001384
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001385 width = configSettings->value("/window width", d->width() - 64).toInt();
1386 height = configSettings->value("/window height", d->height() - 64).toInt();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001387 resize(width, height);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001388 x = configSettings->value("/window x");
1389 y = configSettings->value("/window y");
1390 if ((x.isValid())&&(y.isValid()))
1391 move(x.toInt(), y.toInt());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001392
Masahiro Yamada5cb255f2020-08-07 18:19:07 +09001393 // set up icons
1394 ConfigItem::symbolYesIcon = QIcon(QPixmap(xpm_symbol_yes));
1395 ConfigItem::symbolModIcon = QIcon(QPixmap(xpm_symbol_mod));
1396 ConfigItem::symbolNoIcon = QIcon(QPixmap(xpm_symbol_no));
1397 ConfigItem::choiceYesIcon = QIcon(QPixmap(xpm_choice_yes));
1398 ConfigItem::choiceNoIcon = QIcon(QPixmap(xpm_choice_no));
1399 ConfigItem::menuIcon = QIcon(QPixmap(xpm_menu));
1400 ConfigItem::menubackIcon = QIcon(QPixmap(xpm_menuback));
1401
Mauro Carvalho Chehabcce1fab2020-04-02 11:28:00 +02001402 QWidget *widget = new QWidget(this);
1403 QVBoxLayout *layout = new QVBoxLayout(widget);
1404 setCentralWidget(widget);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001405
Mauro Carvalho Chehabcce1fab2020-04-02 11:28:00 +02001406 split1 = new QSplitter(widget);
1407 split1->setOrientation(Qt::Horizontal);
1408 split1->setChildrenCollapsible(false);
1409
1410 menuView = new ConfigView(widget, "menu");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001411 menuList = menuView->list;
1412
Mauro Carvalho Chehabcce1fab2020-04-02 11:28:00 +02001413 split2 = new QSplitter(widget);
1414 split2->setChildrenCollapsible(false);
Markus Heidelberg7298b932009-05-18 01:36:50 +02001415 split2->setOrientation(Qt::Vertical);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001416
1417 // create config tree
Mauro Carvalho Chehabcce1fab2020-04-02 11:28:00 +02001418 configView = new ConfigView(widget, "config");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001419 configList = configView->list;
1420
Mauro Carvalho Chehabcce1fab2020-04-02 11:28:00 +02001421 helpText = new ConfigInfoView(widget, "help");
1422
1423 layout->addWidget(split2);
1424 split2->addWidget(split1);
1425 split1->addWidget(configView);
1426 split1->addWidget(menuView);
1427 split2->addWidget(helpText);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001428
1429 setTabOrder(configList, helpText);
1430 configList->setFocus();
1431
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001432 backAction = new QAction(QPixmap(xpm_back), "Back", this);
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001433 connect(backAction, SIGNAL(triggered(bool)), SLOT(goBack()));
1434
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001435 QAction *quitAction = new QAction("&Quit", this);
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001436 quitAction->setShortcut(Qt::CTRL + Qt::Key_Q);
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001437 connect(quitAction, SIGNAL(triggered(bool)), SLOT(close()));
1438
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001439 QAction *loadAction = new QAction(QPixmap(xpm_load), "&Load", this);
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001440 loadAction->setShortcut(Qt::CTRL + Qt::Key_L);
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001441 connect(loadAction, SIGNAL(triggered(bool)), SLOT(loadConfig()));
1442
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001443 saveAction = new QAction(QPixmap(xpm_save), "&Save", this);
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001444 saveAction->setShortcut(Qt::CTRL + Qt::Key_S);
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001445 connect(saveAction, SIGNAL(triggered(bool)), SLOT(saveConfig()));
1446
Karsten Wiese3b354c52006-12-13 00:34:08 -08001447 conf_set_changed_callback(conf_changed);
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001448
Karsten Wiese3b354c52006-12-13 00:34:08 -08001449 // Set saveAction's initial state
1450 conf_changed();
Masahiro Yamada87419082019-03-11 01:13:15 +09001451 configname = xstrdup(conf_get_configname());
1452
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001453 QAction *saveAsAction = new QAction("Save &As...", this);
Boris Barbulovski92119932015-09-22 11:36:16 -07001454 connect(saveAsAction, SIGNAL(triggered(bool)), SLOT(saveConfigAs()));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001455 QAction *searchAction = new QAction("&Find", this);
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001456 searchAction->setShortcut(Qt::CTRL + Qt::Key_F);
Boris Barbulovski92119932015-09-22 11:36:16 -07001457 connect(searchAction, SIGNAL(triggered(bool)), SLOT(searchConfig()));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001458 singleViewAction = new QAction(QPixmap(xpm_single_view), "Single View", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001459 singleViewAction->setCheckable(true);
Boris Barbulovski92119932015-09-22 11:36:16 -07001460 connect(singleViewAction, SIGNAL(triggered(bool)), SLOT(showSingleView()));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001461 splitViewAction = new QAction(QPixmap(xpm_split_view), "Split View", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001462 splitViewAction->setCheckable(true);
Boris Barbulovski92119932015-09-22 11:36:16 -07001463 connect(splitViewAction, SIGNAL(triggered(bool)), SLOT(showSplitView()));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001464 fullViewAction = new QAction(QPixmap(xpm_tree_view), "Full View", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001465 fullViewAction->setCheckable(true);
Boris Barbulovski92119932015-09-22 11:36:16 -07001466 connect(fullViewAction, SIGNAL(triggered(bool)), SLOT(showFullView()));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001467
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001468 QAction *showNameAction = new QAction("Show Name", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001469 showNameAction->setCheckable(true);
Masahiro Yamada7930dd92020-08-29 17:14:14 +09001470 connect(showNameAction, SIGNAL(toggled(bool)), configList, SLOT(setShowName(bool)));
1471 showNameAction->setChecked(configList->showName);
1472
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001473 QAction *showRangeAction = new QAction("Show Range", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001474 showRangeAction->setCheckable(true);
Masahiro Yamada7930dd92020-08-29 17:14:14 +09001475 connect(showRangeAction, SIGNAL(toggled(bool)), configList, SLOT(setShowRange(bool)));
Li Zefan39a48972010-05-10 16:33:41 +08001476
1477 QActionGroup *optGroup = new QActionGroup(this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001478 optGroup->setExclusive(true);
Masahiro Yamadad4bbe8a2020-08-07 18:19:09 +09001479 connect(optGroup, SIGNAL(triggered(QAction*)), configList,
Li Zefan39a48972010-05-10 16:33:41 +08001480 SLOT(setOptionMode(QAction *)));
Masahiro Yamadad4bbe8a2020-08-07 18:19:09 +09001481 connect(optGroup, SIGNAL(triggered(QAction *)), menuList,
Li Zefan39a48972010-05-10 16:33:41 +08001482 SLOT(setOptionMode(QAction *)));
1483
Masahiro Yamadad4bbe8a2020-08-07 18:19:09 +09001484 ConfigList::showNormalAction = new QAction("Show Normal Options", optGroup);
1485 ConfigList::showNormalAction->setCheckable(true);
1486 ConfigList::showAllAction = new QAction("Show All Options", optGroup);
1487 ConfigList::showAllAction->setCheckable(true);
1488 ConfigList::showPromptAction = new QAction("Show Prompt Options", optGroup);
1489 ConfigList::showPromptAction->setCheckable(true);
Li Zefan39a48972010-05-10 16:33:41 +08001490
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001491 QAction *showDebugAction = new QAction("Show Debug Info", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001492 showDebugAction->setCheckable(true);
Roman Zippel43bf6122006-06-08 22:12:45 -07001493 connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
Boris Barbulovski9c862352015-09-22 11:36:12 -07001494 showDebugAction->setChecked(helpText->showDebug());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001495
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001496 QAction *showIntroAction = new QAction("Introduction", this);
Boris Barbulovski92119932015-09-22 11:36:16 -07001497 connect(showIntroAction, SIGNAL(triggered(bool)), SLOT(showIntro()));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001498 QAction *showAboutAction = new QAction("About", this);
Boris Barbulovski92119932015-09-22 11:36:16 -07001499 connect(showAboutAction, SIGNAL(triggered(bool)), SLOT(showAbout()));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001500
1501 // init tool bar
Masahiro Yamada860ec3f2020-08-07 18:18:55 +09001502 QToolBar *toolBar = addToolBar("Tools");
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001503 toolBar->addAction(backAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001504 toolBar->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001505 toolBar->addAction(loadAction);
1506 toolBar->addAction(saveAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001507 toolBar->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001508 toolBar->addAction(singleViewAction);
1509 toolBar->addAction(splitViewAction);
1510 toolBar->addAction(fullViewAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001511
Masahiro Yamada93ebaac2020-08-07 18:18:53 +09001512 // create file menu
1513 QMenu *menu = menuBar()->addMenu("&File");
1514 menu->addAction(loadAction);
1515 menu->addAction(saveAction);
1516 menu->addAction(saveAsAction);
1517 menu->addSeparator();
1518 menu->addAction(quitAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001519
Shlomi Fish66e7c722007-02-14 00:32:58 -08001520 // create edit menu
Masahiro Yamada93ebaac2020-08-07 18:18:53 +09001521 menu = menuBar()->addMenu("&Edit");
1522 menu->addAction(searchAction);
Shlomi Fish66e7c722007-02-14 00:32:58 -08001523
Linus Torvalds1da177e2005-04-16 15:20:36 -07001524 // create options menu
Masahiro Yamada93ebaac2020-08-07 18:18:53 +09001525 menu = menuBar()->addMenu("&Option");
1526 menu->addAction(showNameAction);
1527 menu->addAction(showRangeAction);
Masahiro Yamada93ebaac2020-08-07 18:18:53 +09001528 menu->addSeparator();
1529 menu->addActions(optGroup->actions());
1530 menu->addSeparator();
1531 menu->addAction(showDebugAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001532
1533 // create help menu
Masahiro Yamada93ebaac2020-08-07 18:18:53 +09001534 menu = menuBar()->addMenu("&Help");
1535 menu->addAction(showIntroAction);
1536 menu->addAction(showAboutAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001537
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001538 connect (helpText, SIGNAL (anchorClicked (const QUrl &)),
1539 helpText, SLOT (clicked (const QUrl &)) );
1540
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001541 connect(configList, SIGNAL(menuChanged(struct menu *)),
1542 helpText, SLOT(setInfo(struct menu *)));
1543 connect(configList, SIGNAL(menuSelected(struct menu *)),
1544 SLOT(changeMenu(struct menu *)));
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +02001545 connect(configList, SIGNAL(itemSelected(struct menu *)),
1546 SLOT(changeItens(struct menu *)));
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001547 connect(configList, SIGNAL(parentSelected()),
1548 SLOT(goBack()));
1549 connect(menuList, SIGNAL(menuChanged(struct menu *)),
1550 helpText, SLOT(setInfo(struct menu *)));
1551 connect(menuList, SIGNAL(menuSelected(struct menu *)),
1552 SLOT(changeMenu(struct menu *)));
1553
1554 connect(configList, SIGNAL(gotFocus(struct menu *)),
1555 helpText, SLOT(setInfo(struct menu *)));
1556 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1557 helpText, SLOT(setInfo(struct menu *)));
1558 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1559 SLOT(listFocusChanged(void)));
Roman Zippelb65a47e2006-06-08 22:12:47 -07001560 connect(helpText, SIGNAL(menuSelected(struct menu *)),
1561 SLOT(setMenuLink(struct menu *)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001562
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001563 QString listMode = configSettings->value("/listMode", "symbol").toString();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001564 if (listMode == "single")
1565 showSingleView();
1566 else if (listMode == "full")
1567 showFullView();
1568 else /*if (listMode == "split")*/
1569 showSplitView();
1570
1571 // UI setup done, restore splitter positions
Boris Barbulovski041fbdc2015-09-22 11:36:05 -07001572 QList<int> sizes = configSettings->readSizes("/split1", &ok);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001573 if (ok)
1574 split1->setSizes(sizes);
1575
Roman Zippel7fc925f2006-06-08 22:12:46 -07001576 sizes = configSettings->readSizes("/split2", &ok);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001577 if (ok)
1578 split2->setSizes(sizes);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001579}
1580
Linus Torvalds1da177e2005-04-16 15:20:36 -07001581void ConfigMainWindow::loadConfig(void)
1582{
Masahiro Yamada87419082019-03-11 01:13:15 +09001583 QString str;
1584 QByteArray ba;
1585 const char *name;
1586
1587 str = QFileDialog::getOpenFileName(this, "", configname);
1588 if (str.isNull())
Linus Torvalds1da177e2005-04-16 15:20:36 -07001589 return;
Masahiro Yamada87419082019-03-11 01:13:15 +09001590
1591 ba = str.toLocal8Bit();
1592 name = ba.data();
1593
1594 if (conf_read(name))
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001595 QMessageBox::information(this, "qconf", "Unable to load configuration!");
Masahiro Yamada87419082019-03-11 01:13:15 +09001596
1597 free(configname);
1598 configname = xstrdup(name);
1599
Masahiro Yamadaf9b918f2020-08-29 17:14:10 +09001600 ConfigList::updateListAllForAll();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001601}
1602
Michal Marekbac6aa82011-05-25 15:10:25 +02001603bool ConfigMainWindow::saveConfig(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001604{
Masahiro Yamada87419082019-03-11 01:13:15 +09001605 if (conf_write(configname)) {
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001606 QMessageBox::information(this, "qconf", "Unable to save configuration!");
Michal Marekbac6aa82011-05-25 15:10:25 +02001607 return false;
1608 }
Masahiro Yamada00c864f2018-07-20 16:46:31 +09001609 conf_write_autoconf(0);
1610
Michal Marekbac6aa82011-05-25 15:10:25 +02001611 return true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001612}
1613
1614void ConfigMainWindow::saveConfigAs(void)
1615{
Masahiro Yamada87419082019-03-11 01:13:15 +09001616 QString str;
1617 QByteArray ba;
1618 const char *name;
1619
1620 str = QFileDialog::getSaveFileName(this, "", configname);
1621 if (str.isNull())
Linus Torvalds1da177e2005-04-16 15:20:36 -07001622 return;
Masahiro Yamada87419082019-03-11 01:13:15 +09001623
1624 ba = str.toLocal8Bit();
1625 name = ba.data();
1626
1627 if (conf_write(name)) {
1628 QMessageBox::information(this, "qconf", "Unable to save configuration!");
1629 }
1630 conf_write_autoconf(0);
1631
1632 free(configname);
1633 configname = xstrdup(name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001634}
1635
Roman Zippel43bf6122006-06-08 22:12:45 -07001636void ConfigMainWindow::searchConfig(void)
1637{
1638 if (!searchWindow)
Masahiro Yamada740fdef2020-08-07 18:18:57 +09001639 searchWindow = new ConfigSearchWindow(this);
Roman Zippel43bf6122006-06-08 22:12:45 -07001640 searchWindow->show();
1641}
1642
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +02001643void ConfigMainWindow::changeItens(struct menu *menu)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001644{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001645 configList->setRootMenu(menu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001646}
1647
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +02001648void ConfigMainWindow::changeMenu(struct menu *menu)
1649{
1650 menuList->setRootMenu(menu);
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +02001651}
1652
Roman Zippelb65a47e2006-06-08 22:12:47 -07001653void ConfigMainWindow::setMenuLink(struct menu *menu)
1654{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001655 struct menu *parent;
1656 ConfigList* list = NULL;
1657 ConfigItem* item;
1658
1659 if (configList->menuSkip(menu))
1660 return;
1661
1662 switch (configList->mode) {
1663 case singleMode:
1664 list = configList;
1665 parent = menu_get_parent_menu(menu);
1666 if (!parent)
1667 return;
1668 list->setRootMenu(parent);
1669 break;
Mauro Carvalho Chehabc699eaa2020-06-30 08:26:36 +02001670 case menuMode:
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001671 if (menu->flags & MENU_ROOT) {
Mauro Carvalho Chehabc699eaa2020-06-30 08:26:36 +02001672 menuList->setRootMenu(menu);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001673 configList->clearSelection();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001674 list = configList;
Mauro Carvalho Chehabc699eaa2020-06-30 08:26:36 +02001675 } else {
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001676 parent = menu_get_parent_menu(menu->parent);
1677 if (!parent)
1678 return;
Mauro Carvalho Chehabc699eaa2020-06-30 08:26:36 +02001679
Mauro Carvalho Chehabc699eaa2020-06-30 08:26:36 +02001680 /* Select the config view */
1681 item = configList->findConfigItem(parent);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001682 if (item) {
Mauro Carvalho Chehabb06c3ec2020-06-30 08:26:38 +02001683 configList->setSelected(item, true);
Mauro Carvalho Chehabc699eaa2020-06-30 08:26:36 +02001684 configList->scrollToItem(item);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001685 }
Mauro Carvalho Chehabc699eaa2020-06-30 08:26:36 +02001686
1687 menuList->setRootMenu(parent);
1688 menuList->clearSelection();
1689 list = menuList;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001690 }
1691 break;
1692 case fullMode:
1693 list = configList;
1694 break;
1695 default:
1696 break;
1697 }
1698
1699 if (list) {
1700 item = list->findConfigItem(menu);
1701 if (item) {
Mauro Carvalho Chehabb06c3ec2020-06-30 08:26:38 +02001702 list->setSelected(item, true);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001703 list->scrollToItem(item);
1704 list->setFocus();
Mauro Carvalho Chehab8a3b6e52020-06-30 08:48:35 +02001705 helpText->setInfo(menu);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001706 }
1707 }
Roman Zippelb65a47e2006-06-08 22:12:47 -07001708}
1709
Linus Torvalds1da177e2005-04-16 15:20:36 -07001710void ConfigMainWindow::listFocusChanged(void)
1711{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001712 if (menuList->mode == menuMode)
1713 configList->clearSelection();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001714}
1715
1716void ConfigMainWindow::goBack(void)
1717{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001718 if (configList->rootEntry == &rootmenu)
Boris Barbulovskibe596aa2015-09-22 11:36:28 -07001719 return;
1720
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001721 configList->setParentMenu();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001722}
1723
1724void ConfigMainWindow::showSingleView(void)
1725{
Boris Barbulovski780505e2015-09-22 11:36:13 -07001726 singleViewAction->setEnabled(false);
1727 singleViewAction->setChecked(true);
1728 splitViewAction->setEnabled(true);
1729 splitViewAction->setChecked(false);
1730 fullViewAction->setEnabled(true);
1731 fullViewAction->setChecked(false);
1732
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001733 backAction->setEnabled(true);
1734
Linus Torvalds1da177e2005-04-16 15:20:36 -07001735 menuView->hide();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001736 menuList->setRootMenu(0);
1737 configList->mode = singleMode;
1738 if (configList->rootEntry == &rootmenu)
1739 configList->updateListAll();
1740 else
1741 configList->setRootMenu(&rootmenu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001742 configList->setFocus();
1743}
1744
1745void ConfigMainWindow::showSplitView(void)
1746{
Boris Barbulovski780505e2015-09-22 11:36:13 -07001747 singleViewAction->setEnabled(true);
1748 singleViewAction->setChecked(false);
1749 splitViewAction->setEnabled(false);
1750 splitViewAction->setChecked(true);
1751 fullViewAction->setEnabled(true);
1752 fullViewAction->setChecked(false);
1753
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001754 backAction->setEnabled(false);
1755
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +02001756 configList->mode = menuMode;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001757 if (configList->rootEntry == &rootmenu)
1758 configList->updateListAll();
1759 else
1760 configList->setRootMenu(&rootmenu);
1761 configList->setAllOpen(true);
1762 configApp->processEvents();
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +02001763 menuList->mode = symbolMode;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001764 menuList->setRootMenu(&rootmenu);
1765 menuList->setAllOpen(true);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001766 menuView->show();
1767 menuList->setFocus();
1768}
1769
1770void ConfigMainWindow::showFullView(void)
1771{
Boris Barbulovski780505e2015-09-22 11:36:13 -07001772 singleViewAction->setEnabled(true);
1773 singleViewAction->setChecked(false);
1774 splitViewAction->setEnabled(true);
1775 splitViewAction->setChecked(false);
1776 fullViewAction->setEnabled(false);
1777 fullViewAction->setChecked(true);
1778
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001779 backAction->setEnabled(false);
1780
Linus Torvalds1da177e2005-04-16 15:20:36 -07001781 menuView->hide();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001782 menuList->setRootMenu(0);
1783 configList->mode = fullMode;
1784 if (configList->rootEntry == &rootmenu)
1785 configList->updateListAll();
1786 else
1787 configList->setRootMenu(&rootmenu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001788 configList->setFocus();
1789}
1790
Linus Torvalds1da177e2005-04-16 15:20:36 -07001791/*
1792 * ask for saving configuration before quitting
Linus Torvalds1da177e2005-04-16 15:20:36 -07001793 */
1794void ConfigMainWindow::closeEvent(QCloseEvent* e)
1795{
Karsten Wieseb3214292006-12-13 00:34:06 -08001796 if (!conf_get_changed()) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001797 e->accept();
1798 return;
1799 }
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001800 QMessageBox mb("qconf", "Save configuration?", QMessageBox::Warning,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001801 QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape);
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001802 mb.setButtonText(QMessageBox::Yes, "&Save Changes");
1803 mb.setButtonText(QMessageBox::No, "&Discard Changes");
1804 mb.setButtonText(QMessageBox::Cancel, "Cancel Exit");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001805 switch (mb.exec()) {
1806 case QMessageBox::Yes:
Michal Marekbac6aa82011-05-25 15:10:25 +02001807 if (saveConfig())
1808 e->accept();
1809 else
1810 e->ignore();
1811 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001812 case QMessageBox::No:
1813 e->accept();
1814 break;
1815 case QMessageBox::Cancel:
1816 e->ignore();
1817 break;
1818 }
1819}
1820
1821void ConfigMainWindow::showIntro(void)
1822{
Masahiro Yamada8c30e7e2020-08-29 17:14:07 +09001823 static const QString str =
1824 "Welcome to the qconf graphical configuration tool.\n"
1825 "\n"
Masahiro Yamada37162a62020-08-29 17:14:12 +09001826 "For bool and tristate options, a blank box indicates the "
1827 "feature is disabled, a check indicates it is enabled, and a "
1828 "dot indicates that it is to be compiled as a module. Clicking "
1829 "on the box will cycle through the three states. For int, hex, "
1830 "and string options, double-clicking or pressing F2 on the "
1831 "Value cell will allow you to edit the value.\n"
Masahiro Yamada8c30e7e2020-08-29 17:14:07 +09001832 "\n"
1833 "If you do not see an option (e.g., a device driver) that you "
1834 "believe should be present, try turning on Show All Options "
Masahiro Yamada1fb75242020-08-29 17:14:08 +09001835 "under the Options menu. Enabling Show Debug Info will help you"
1836 "figure out what other options must be enabled to support the "
1837 "option you are interested in, and hyperlinks will navigate to "
1838 "them.\n"
Masahiro Yamada8c30e7e2020-08-29 17:14:07 +09001839 "\n"
1840 "Toggling Show Debug Info under the Options menu will show the "
1841 "dependencies, which you can then match by examining other "
1842 "options.\n";
Linus Torvalds1da177e2005-04-16 15:20:36 -07001843
1844 QMessageBox::information(this, "qconf", str);
1845}
1846
1847void ConfigMainWindow::showAbout(void)
1848{
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001849 static const QString str = "qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n"
Boris Barbulovskib4ff1de2015-09-22 11:36:38 -07001850 "Copyright (C) 2015 Boris Barbulovski <bbarbulovski@gmail.com>.\n\n"
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001851 "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n";
Linus Torvalds1da177e2005-04-16 15:20:36 -07001852
1853 QMessageBox::information(this, "qconf", str);
1854}
1855
1856void ConfigMainWindow::saveSettings(void)
1857{
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001858 configSettings->setValue("/window x", pos().x());
1859 configSettings->setValue("/window y", pos().y());
1860 configSettings->setValue("/window width", size().width());
1861 configSettings->setValue("/window height", size().height());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001862
1863 QString entry;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001864 switch(configList->mode) {
1865 case singleMode :
1866 entry = "single";
1867 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001868
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001869 case symbolMode :
1870 entry = "split";
1871 break;
1872
1873 case fullMode :
1874 entry = "full";
1875 break;
1876
1877 default:
1878 break;
1879 }
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001880 configSettings->setValue("/listMode", entry);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001881
Roman Zippel7fc925f2006-06-08 22:12:46 -07001882 configSettings->writeSizes("/split1", split1->sizes());
1883 configSettings->writeSizes("/split2", split2->sizes());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001884}
1885
Karsten Wiese3b354c52006-12-13 00:34:08 -08001886void ConfigMainWindow::conf_changed(void)
1887{
1888 if (saveAction)
1889 saveAction->setEnabled(conf_get_changed());
1890}
1891
Linus Torvalds1da177e2005-04-16 15:20:36 -07001892void fixup_rootmenu(struct menu *menu)
1893{
1894 struct menu *child;
1895 static int menu_cnt = 0;
1896
1897 menu->flags |= MENU_ROOT;
1898 for (child = menu->list; child; child = child->next) {
1899 if (child->prompt && child->prompt->type == P_MENU) {
1900 menu_cnt++;
1901 fixup_rootmenu(child);
1902 menu_cnt--;
1903 } else if (!menu_cnt)
1904 fixup_rootmenu(child);
1905 }
1906}
1907
1908static const char *progname;
1909
1910static void usage(void)
1911{
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001912 printf("%s [-s] <config>\n", progname);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001913 exit(0);
1914}
1915
1916int main(int ac, char** av)
1917{
1918 ConfigMainWindow* v;
1919 const char *name;
1920
Linus Torvalds1da177e2005-04-16 15:20:36 -07001921 progname = av[0];
1922 configApp = new QApplication(ac, av);
1923 if (ac > 1 && av[1][0] == '-') {
1924 switch (av[1][1]) {
Michal Marek0a1f00a2015-04-08 13:30:42 +02001925 case 's':
1926 conf_set_message_callback(NULL);
1927 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001928 case 'h':
1929 case '?':
1930 usage();
1931 }
1932 name = av[2];
1933 } else
1934 name = av[1];
1935 if (!name)
1936 usage();
1937
1938 conf_parse(name);
1939 fixup_rootmenu(&rootmenu);
1940 conf_read(NULL);
1941 //zconfdump(stdout);
1942
Roman Zippel7fc925f2006-06-08 22:12:46 -07001943 configSettings = new ConfigSettings();
1944 configSettings->beginGroup("/kconfig/qconf");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001945 v = new ConfigMainWindow();
1946
1947 //zconfdump(stdout);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001948 configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit()));
1949 configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings()));
Roman Zippel43bf6122006-06-08 22:12:45 -07001950 v->show();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001951 configApp->exec();
1952
Roman Zippel7fc925f2006-06-08 22:12:46 -07001953 configSettings->endGroup();
1954 delete configSettings;
Chris Bainbridge5b61c7b2016-01-08 20:44:04 +00001955 delete v;
1956 delete configApp;
Roman Zippel7fc925f2006-06-08 22:12:46 -07001957
Linus Torvalds1da177e2005-04-16 15:20:36 -07001958 return 0;
1959}