blob: 4ece85ae7dfa90ac4b5d2c5f20fde7d4510aeae1 [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
Masahiro Yamada62ed1652020-08-29 17:14:15 +0900310ConfigList::ConfigList(QWidget *parent, const char *name)
311 : QTreeWidget(parent),
Boris Barbulovski59e56442015-09-22 11:36:18 -0700312 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
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700968void ConfigList::setAllOpen(bool open)
969{
970 QTreeWidgetItemIterator it(this);
971
972 while (*it) {
973 (*it)->setExpanded(open);
974
975 ++it;
976 }
Roman Zippel7fc925f2006-06-08 22:12:46 -0700977}
978
Roman Zippel43bf6122006-06-08 22:12:45 -0700979ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name)
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -0700980 : Parent(parent), sym(0), _menu(0)
Roman Zippel43bf6122006-06-08 22:12:45 -0700981{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700982 setObjectName(name);
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +0200983 setOpenLinks(false);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700984
985 if (!objectName().isEmpty()) {
986 configSettings->beginGroup(objectName());
Boris Barbulovskie0393032016-11-30 14:57:52 -0800987 setShowDebug(configSettings->value("/showDebug", false).toBool());
Roman Zippel7fc925f2006-06-08 22:12:46 -0700988 configSettings->endGroup();
989 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
990 }
Masahiro Yamada7d1300e2020-08-18 01:36:30 +0900991
992 contextMenu = createStandardContextMenu();
993 QAction *action = new QAction("Show Debug Info", contextMenu);
994
995 action->setCheckable(true);
996 connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
997 connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setChecked(bool)));
998 action->setChecked(showDebug());
999 contextMenu->addSeparator();
1000 contextMenu->addAction(action);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001001}
1002
1003void ConfigInfoView::saveSettings(void)
1004{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001005 if (!objectName().isEmpty()) {
1006 configSettings->beginGroup(objectName());
1007 configSettings->setValue("/showDebug", showDebug());
1008 configSettings->endGroup();
1009 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001010}
1011
1012void ConfigInfoView::setShowDebug(bool b)
1013{
1014 if (_showDebug != b) {
1015 _showDebug = b;
Alexander Stein133c5f72010-08-31 17:34:37 +02001016 if (_menu)
Roman Zippel43bf6122006-06-08 22:12:45 -07001017 menuInfo();
Roman Zippelab45d192006-06-08 22:12:47 -07001018 else if (sym)
1019 symbolInfo();
Roman Zippel43bf6122006-06-08 22:12:45 -07001020 emit showDebugChanged(b);
1021 }
1022}
1023
1024void ConfigInfoView::setInfo(struct menu *m)
1025{
Alexander Stein133c5f72010-08-31 17:34:37 +02001026 if (_menu == m)
Roman Zippelb65a47e2006-06-08 22:12:47 -07001027 return;
Alexander Stein133c5f72010-08-31 17:34:37 +02001028 _menu = m;
Roman Zippel6fa1da82007-01-10 23:15:31 -08001029 sym = NULL;
Alexander Stein133c5f72010-08-31 17:34:37 +02001030 if (!_menu)
Roman Zippel43bf6122006-06-08 22:12:45 -07001031 clear();
Roman Zippel6fa1da82007-01-10 23:15:31 -08001032 else
Roman Zippel43bf6122006-06-08 22:12:45 -07001033 menuInfo();
1034}
1035
Roman Zippelab45d192006-06-08 22:12:47 -07001036void ConfigInfoView::symbolInfo(void)
1037{
1038 QString str;
1039
1040 str += "<big>Symbol: <b>";
1041 str += print_filter(sym->name);
1042 str += "</b></big><br><br>value: ";
1043 str += print_filter(sym_get_string_value(sym));
1044 str += "<br>visibility: ";
1045 str += sym->visible == yes ? "y" : sym->visible == mod ? "m" : "n";
1046 str += "<br>";
1047 str += debug_info(sym);
1048
1049 setText(str);
1050}
1051
Roman Zippel43bf6122006-06-08 22:12:45 -07001052void ConfigInfoView::menuInfo(void)
1053{
1054 struct symbol* sym;
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001055 QString info;
1056 QTextStream stream(&info);
Roman Zippel43bf6122006-06-08 22:12:45 -07001057
Alexander Stein133c5f72010-08-31 17:34:37 +02001058 sym = _menu->sym;
Roman Zippel43bf6122006-06-08 22:12:45 -07001059 if (sym) {
Alexander Stein133c5f72010-08-31 17:34:37 +02001060 if (_menu->prompt) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001061 stream << "<big><b>";
1062 stream << print_filter(_menu->prompt->text);
1063 stream << "</b></big>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001064 if (sym->name) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001065 stream << " (";
Roman Zippelab45d192006-06-08 22:12:47 -07001066 if (showDebug())
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001067 stream << "<a href=\"s" << sym->name << "\">";
1068 stream << print_filter(sym->name);
Roman Zippelab45d192006-06-08 22:12:47 -07001069 if (showDebug())
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001070 stream << "</a>";
1071 stream << ")";
Roman Zippel43bf6122006-06-08 22:12:45 -07001072 }
1073 } else if (sym->name) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001074 stream << "<big><b>";
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 << "</b></big>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001081 }
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001082 stream << "<br><br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001083
1084 if (showDebug())
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001085 stream << debug_info(sym);
1086
Masahiro Yamadaa46afd12020-09-14 23:59:48 +09001087 struct gstr help_gstr = str_new();
1088
1089 menu_get_ext_help(_menu, &help_gstr);
1090 stream << print_filter(str_get(&help_gstr));
1091 str_free(&help_gstr);
Alexander Stein133c5f72010-08-31 17:34:37 +02001092 } else if (_menu->prompt) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001093 stream << "<big><b>";
1094 stream << print_filter(_menu->prompt->text);
1095 stream << "</b></big><br><br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001096 if (showDebug()) {
Alexander Stein133c5f72010-08-31 17:34:37 +02001097 if (_menu->prompt->visible.expr) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001098 stream << "&nbsp;&nbsp;dep: ";
1099 expr_print(_menu->prompt->visible.expr,
1100 expr_print_help, &stream, E_NONE);
1101 stream << "<br><br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001102 }
Masahiro Yamadaa46afd12020-09-14 23:59:48 +09001103
1104 stream << "defined at " << _menu->file->name << ":"
1105 << _menu->lineno << "<br><br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001106 }
1107 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001108
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001109 setText(info);
Roman Zippel43bf6122006-06-08 22:12:45 -07001110}
1111
1112QString ConfigInfoView::debug_info(struct symbol *sym)
1113{
1114 QString debug;
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001115 QTextStream stream(&debug);
Roman Zippel43bf6122006-06-08 22:12:45 -07001116
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001117 stream << "type: ";
1118 stream << print_filter(sym_type_name(sym->type));
Roman Zippel43bf6122006-06-08 22:12:45 -07001119 if (sym_is_choice(sym))
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001120 stream << " (choice)";
Roman Zippel43bf6122006-06-08 22:12:45 -07001121 debug += "<br>";
1122 if (sym->rev_dep.expr) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001123 stream << "reverse dep: ";
1124 expr_print(sym->rev_dep.expr, expr_print_help, &stream, E_NONE);
1125 stream << "<br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001126 }
1127 for (struct property *prop = sym->prop; prop; prop = prop->next) {
1128 switch (prop->type) {
1129 case P_PROMPT:
1130 case P_MENU:
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001131 stream << "prompt: <a href=\"m" << sym->name << "\">";
1132 stream << print_filter(prop->text);
1133 stream << "</a><br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001134 break;
1135 case P_DEFAULT:
Roman Zippel93449082008-01-14 04:50:54 +01001136 case P_SELECT:
1137 case P_RANGE:
Mauro Carvalho Chehab8f8499a2020-06-30 08:48:53 +02001138 case P_COMMENT:
1139 case P_IMPLY:
1140 case P_SYMBOL:
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001141 stream << prop_get_type_name(prop->type);
1142 stream << ": ";
1143 expr_print(prop->expr, expr_print_help,
1144 &stream, E_NONE);
1145 stream << "<br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001146 break;
1147 case P_CHOICE:
1148 if (sym_is_choice(sym)) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001149 stream << "choice: ";
1150 expr_print(prop->expr, expr_print_help,
1151 &stream, E_NONE);
1152 stream << "<br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001153 }
1154 break;
Roman Zippel43bf6122006-06-08 22:12:45 -07001155 default:
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001156 stream << "unknown property: ";
1157 stream << prop_get_type_name(prop->type);
1158 stream << "<br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001159 }
1160 if (prop->visible.expr) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001161 stream << "&nbsp;&nbsp;&nbsp;&nbsp;dep: ";
1162 expr_print(prop->visible.expr, expr_print_help,
1163 &stream, E_NONE);
1164 stream << "<br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001165 }
1166 }
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001167 stream << "<br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001168
1169 return debug;
1170}
1171
1172QString ConfigInfoView::print_filter(const QString &str)
1173{
1174 QRegExp re("[<>&\"\\n]");
1175 QString res = str;
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001176 for (int i = 0; (i = res.indexOf(re, i)) >= 0;) {
1177 switch (res[i].toLatin1()) {
Roman Zippel43bf6122006-06-08 22:12:45 -07001178 case '<':
1179 res.replace(i, 1, "&lt;");
1180 i += 4;
1181 break;
1182 case '>':
1183 res.replace(i, 1, "&gt;");
1184 i += 4;
1185 break;
1186 case '&':
1187 res.replace(i, 1, "&amp;");
1188 i += 5;
1189 break;
1190 case '"':
1191 res.replace(i, 1, "&quot;");
1192 i += 6;
1193 break;
1194 case '\n':
1195 res.replace(i, 1, "<br>");
1196 i += 4;
1197 break;
1198 }
1199 }
1200 return res;
1201}
1202
Roman Zippelab45d192006-06-08 22:12:47 -07001203void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char *str)
Roman Zippel43bf6122006-06-08 22:12:45 -07001204{
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001205 QTextStream *stream = reinterpret_cast<QTextStream *>(data);
Roman Zippelab45d192006-06-08 22:12:47 -07001206
1207 if (sym && sym->name && !(sym->flags & SYMBOL_CONST)) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001208 *stream << "<a href=\"s" << sym->name << "\">";
1209 *stream << print_filter(str);
1210 *stream << "</a>";
1211 } else {
1212 *stream << print_filter(str);
1213 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001214}
1215
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001216void ConfigInfoView::clicked(const QUrl &url)
1217{
1218 QByteArray str = url.toEncoded();
1219 const std::size_t count = str.size();
1220 char *data = new char[count + 1];
1221 struct symbol **result;
1222 struct menu *m = NULL;
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001223
1224 if (count < 1) {
Masahiro Yamadac9b09a922020-07-30 02:02:39 +09001225 delete[] data;
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001226 return;
1227 }
1228
1229 memcpy(data, str.constData(), count);
1230 data[count] = '\0';
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001231
1232 /* Seek for exact match */
1233 data[0] = '^';
1234 strcat(data, "$");
1235 result = sym_re_search(data);
1236 if (!result) {
Masahiro Yamadac9b09a922020-07-30 02:02:39 +09001237 delete[] data;
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001238 return;
1239 }
1240
1241 sym = *result;
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001242
Mauro Carvalho Chehab8a3b6e52020-06-30 08:48:35 +02001243 /* Seek for the menu which holds the symbol */
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001244 for (struct property *prop = sym->prop; prop; prop = prop->next) {
1245 if (prop->type != P_PROMPT && prop->type != P_MENU)
1246 continue;
1247 m = prop->menu;
1248 break;
1249 }
1250
1251 if (!m) {
Mauro Carvalho Chehab8a3b6e52020-06-30 08:48:35 +02001252 /* Symbol is not visible as a menu */
1253 symbolInfo();
1254 emit showDebugChanged(true);
1255 } else {
1256 emit menuSelected(m);
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001257 }
1258
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001259 free(result);
Masahiro Yamadaa608b6a2020-09-09 07:16:37 +09001260 delete[] data;
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001261}
1262
Masahiro Yamada7d1300e2020-08-18 01:36:30 +09001263void ConfigInfoView::contextMenuEvent(QContextMenuEvent *event)
Roman Zippel7fc925f2006-06-08 22:12:46 -07001264{
Masahiro Yamada7d1300e2020-08-18 01:36:30 +09001265 contextMenu->popup(event->globalPos());
1266 event->accept();
Roman Zippel7fc925f2006-06-08 22:12:46 -07001267}
1268
Masahiro Yamada740fdef2020-08-07 18:18:57 +09001269ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow *parent)
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001270 : Parent(parent), result(NULL)
Roman Zippel43bf6122006-06-08 22:12:45 -07001271{
Masahiro Yamada740fdef2020-08-07 18:18:57 +09001272 setObjectName("search");
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001273 setWindowTitle("Search Config");
Roman Zippel43bf6122006-06-08 22:12:45 -07001274
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001275 QVBoxLayout* layout1 = new QVBoxLayout(this);
1276 layout1->setContentsMargins(11, 11, 11, 11);
1277 layout1->setSpacing(6);
Masahiro Yamada92641152020-08-07 18:18:58 +09001278
1279 QHBoxLayout* layout2 = new QHBoxLayout();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001280 layout2->setContentsMargins(0, 0, 0, 0);
1281 layout2->setSpacing(6);
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001282 layout2->addWidget(new QLabel("Find:", this));
Roman Zippel43bf6122006-06-08 22:12:45 -07001283 editField = new QLineEdit(this);
1284 connect(editField, SIGNAL(returnPressed()), SLOT(search()));
1285 layout2->addWidget(editField);
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001286 searchButton = new QPushButton("Search", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001287 searchButton->setAutoDefault(false);
Roman Zippel43bf6122006-06-08 22:12:45 -07001288 connect(searchButton, SIGNAL(clicked()), SLOT(search()));
1289 layout2->addWidget(searchButton);
1290 layout1->addLayout(layout2);
1291
Roman Zippel7fc925f2006-06-08 22:12:46 -07001292 split = new QSplitter(this);
Markus Heidelberg7298b932009-05-18 01:36:50 +02001293 split->setOrientation(Qt::Vertical);
Masahiro Yamada62ed1652020-08-29 17:14:15 +09001294 list = new ConfigList(split, "search");
1295 list->mode = listMode;
Masahiro Yamada740fdef2020-08-07 18:18:57 +09001296 info = new ConfigInfoView(split, "search");
Masahiro Yamada62ed1652020-08-29 17:14:15 +09001297 connect(list, SIGNAL(menuChanged(struct menu *)),
Roman Zippel43bf6122006-06-08 22:12:45 -07001298 info, SLOT(setInfo(struct menu *)));
Masahiro Yamada62ed1652020-08-29 17:14:15 +09001299 connect(list, SIGNAL(menuChanged(struct menu *)),
Marco Costalba63431e72006-10-05 19:12:59 +02001300 parent, SLOT(setMenuLink(struct menu *)));
1301
Roman Zippel43bf6122006-06-08 22:12:45 -07001302 layout1->addWidget(split);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001303
Masahiro Yamada740fdef2020-08-07 18:18:57 +09001304 QVariant x, y;
1305 int width, height;
1306 bool ok;
Roman Zippel7fc925f2006-06-08 22:12:46 -07001307
Masahiro Yamada740fdef2020-08-07 18:18:57 +09001308 configSettings->beginGroup("search");
1309 width = configSettings->value("/window width", parent->width() / 2).toInt();
1310 height = configSettings->value("/window height", parent->height() / 2).toInt();
1311 resize(width, height);
1312 x = configSettings->value("/window x");
1313 y = configSettings->value("/window y");
1314 if (x.isValid() && y.isValid())
1315 move(x.toInt(), y.toInt());
1316 QList<int> sizes = configSettings->readSizes("/split", &ok);
1317 if (ok)
1318 split->setSizes(sizes);
1319 configSettings->endGroup();
1320 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
Roman Zippel7fc925f2006-06-08 22:12:46 -07001321}
1322
1323void ConfigSearchWindow::saveSettings(void)
1324{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001325 if (!objectName().isEmpty()) {
1326 configSettings->beginGroup(objectName());
1327 configSettings->setValue("/window x", pos().x());
1328 configSettings->setValue("/window y", pos().y());
1329 configSettings->setValue("/window width", size().width());
1330 configSettings->setValue("/window height", size().height());
1331 configSettings->writeSizes("/split", split->sizes());
1332 configSettings->endGroup();
1333 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001334}
1335
1336void ConfigSearchWindow::search(void)
1337{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001338 struct symbol **p;
1339 struct property *prop;
1340 ConfigItem *lastItem = NULL;
1341
1342 free(result);
Masahiro Yamada62ed1652020-08-29 17:14:15 +09001343 list->clear();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001344 info->clear();
1345
1346 result = sym_re_search(editField->text().toLatin1());
1347 if (!result)
1348 return;
1349 for (p = result; *p; p++) {
1350 for_all_prompts((*p), prop)
Masahiro Yamada62ed1652020-08-29 17:14:15 +09001351 lastItem = new ConfigItem(list, lastItem, prop->menu,
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001352 menu_is_visible(prop->menu));
1353 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001354}
1355
Linus Torvalds1da177e2005-04-16 15:20:36 -07001356/*
1357 * Construct the complete config widget
1358 */
1359ConfigMainWindow::ConfigMainWindow(void)
Roman Zippelf12aa702006-11-25 11:09:31 -08001360 : searchWindow(0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001361{
Boris Barbulovski92119932015-09-22 11:36:16 -07001362 bool ok = true;
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001363 QVariant x, y;
1364 int width, height;
Randy Dunlapa54bb702007-10-20 11:18:47 -07001365 char title[256];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001366
Markus Heidelberg8d90c972009-05-18 01:36:52 +02001367 QDesktopWidget *d = configApp->desktop();
Arnaud Lacombe09548282010-08-18 01:57:13 -04001368 snprintf(title, sizeof(title), "%s%s",
1369 rootmenu.prompt->text,
Michal Marek76a136c2010-09-01 17:39:27 +02001370 ""
Michal Marek76a136c2010-09-01 17:39:27 +02001371 );
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001372 setWindowTitle(title);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001373
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001374 width = configSettings->value("/window width", d->width() - 64).toInt();
1375 height = configSettings->value("/window height", d->height() - 64).toInt();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001376 resize(width, height);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001377 x = configSettings->value("/window x");
1378 y = configSettings->value("/window y");
1379 if ((x.isValid())&&(y.isValid()))
1380 move(x.toInt(), y.toInt());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001381
Masahiro Yamada5cb255f2020-08-07 18:19:07 +09001382 // set up icons
1383 ConfigItem::symbolYesIcon = QIcon(QPixmap(xpm_symbol_yes));
1384 ConfigItem::symbolModIcon = QIcon(QPixmap(xpm_symbol_mod));
1385 ConfigItem::symbolNoIcon = QIcon(QPixmap(xpm_symbol_no));
1386 ConfigItem::choiceYesIcon = QIcon(QPixmap(xpm_choice_yes));
1387 ConfigItem::choiceNoIcon = QIcon(QPixmap(xpm_choice_no));
1388 ConfigItem::menuIcon = QIcon(QPixmap(xpm_menu));
1389 ConfigItem::menubackIcon = QIcon(QPixmap(xpm_menuback));
1390
Mauro Carvalho Chehabcce1fab2020-04-02 11:28:00 +02001391 QWidget *widget = new QWidget(this);
1392 QVBoxLayout *layout = new QVBoxLayout(widget);
1393 setCentralWidget(widget);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001394
Mauro Carvalho Chehabcce1fab2020-04-02 11:28:00 +02001395 split1 = new QSplitter(widget);
1396 split1->setOrientation(Qt::Horizontal);
1397 split1->setChildrenCollapsible(false);
1398
Masahiro Yamada62ed1652020-08-29 17:14:15 +09001399 menuList = new ConfigList(widget, "menu");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001400
Mauro Carvalho Chehabcce1fab2020-04-02 11:28:00 +02001401 split2 = new QSplitter(widget);
1402 split2->setChildrenCollapsible(false);
Markus Heidelberg7298b932009-05-18 01:36:50 +02001403 split2->setOrientation(Qt::Vertical);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001404
1405 // create config tree
Masahiro Yamada62ed1652020-08-29 17:14:15 +09001406 configList = new ConfigList(widget, "config");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001407
Mauro Carvalho Chehabcce1fab2020-04-02 11:28:00 +02001408 helpText = new ConfigInfoView(widget, "help");
1409
1410 layout->addWidget(split2);
1411 split2->addWidget(split1);
Masahiro Yamada62ed1652020-08-29 17:14:15 +09001412 split1->addWidget(configList);
1413 split1->addWidget(menuList);
Mauro Carvalho Chehabcce1fab2020-04-02 11:28:00 +02001414 split2->addWidget(helpText);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001415
1416 setTabOrder(configList, helpText);
1417 configList->setFocus();
1418
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001419 backAction = new QAction(QPixmap(xpm_back), "Back", this);
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001420 connect(backAction, SIGNAL(triggered(bool)), SLOT(goBack()));
1421
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001422 QAction *quitAction = new QAction("&Quit", this);
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001423 quitAction->setShortcut(Qt::CTRL + Qt::Key_Q);
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001424 connect(quitAction, SIGNAL(triggered(bool)), SLOT(close()));
1425
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001426 QAction *loadAction = new QAction(QPixmap(xpm_load), "&Load", this);
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001427 loadAction->setShortcut(Qt::CTRL + Qt::Key_L);
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001428 connect(loadAction, SIGNAL(triggered(bool)), SLOT(loadConfig()));
1429
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001430 saveAction = new QAction(QPixmap(xpm_save), "&Save", this);
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001431 saveAction->setShortcut(Qt::CTRL + Qt::Key_S);
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001432 connect(saveAction, SIGNAL(triggered(bool)), SLOT(saveConfig()));
1433
Karsten Wiese3b354c52006-12-13 00:34:08 -08001434 conf_set_changed_callback(conf_changed);
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001435
Karsten Wiese3b354c52006-12-13 00:34:08 -08001436 // Set saveAction's initial state
1437 conf_changed();
Masahiro Yamada87419082019-03-11 01:13:15 +09001438 configname = xstrdup(conf_get_configname());
1439
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001440 QAction *saveAsAction = new QAction("Save &As...", this);
Boris Barbulovski92119932015-09-22 11:36:16 -07001441 connect(saveAsAction, SIGNAL(triggered(bool)), SLOT(saveConfigAs()));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001442 QAction *searchAction = new QAction("&Find", this);
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001443 searchAction->setShortcut(Qt::CTRL + Qt::Key_F);
Boris Barbulovski92119932015-09-22 11:36:16 -07001444 connect(searchAction, SIGNAL(triggered(bool)), SLOT(searchConfig()));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001445 singleViewAction = new QAction(QPixmap(xpm_single_view), "Single View", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001446 singleViewAction->setCheckable(true);
Boris Barbulovski92119932015-09-22 11:36:16 -07001447 connect(singleViewAction, SIGNAL(triggered(bool)), SLOT(showSingleView()));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001448 splitViewAction = new QAction(QPixmap(xpm_split_view), "Split View", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001449 splitViewAction->setCheckable(true);
Boris Barbulovski92119932015-09-22 11:36:16 -07001450 connect(splitViewAction, SIGNAL(triggered(bool)), SLOT(showSplitView()));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001451 fullViewAction = new QAction(QPixmap(xpm_tree_view), "Full View", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001452 fullViewAction->setCheckable(true);
Boris Barbulovski92119932015-09-22 11:36:16 -07001453 connect(fullViewAction, SIGNAL(triggered(bool)), SLOT(showFullView()));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001454
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001455 QAction *showNameAction = new QAction("Show Name", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001456 showNameAction->setCheckable(true);
Masahiro Yamada7930dd92020-08-29 17:14:14 +09001457 connect(showNameAction, SIGNAL(toggled(bool)), configList, SLOT(setShowName(bool)));
1458 showNameAction->setChecked(configList->showName);
1459
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001460 QAction *showRangeAction = new QAction("Show Range", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001461 showRangeAction->setCheckable(true);
Masahiro Yamada7930dd92020-08-29 17:14:14 +09001462 connect(showRangeAction, SIGNAL(toggled(bool)), configList, SLOT(setShowRange(bool)));
Li Zefan39a48972010-05-10 16:33:41 +08001463
1464 QActionGroup *optGroup = new QActionGroup(this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001465 optGroup->setExclusive(true);
Masahiro Yamadad4bbe8a2020-08-07 18:19:09 +09001466 connect(optGroup, SIGNAL(triggered(QAction*)), configList,
Li Zefan39a48972010-05-10 16:33:41 +08001467 SLOT(setOptionMode(QAction *)));
Masahiro Yamadad4bbe8a2020-08-07 18:19:09 +09001468 connect(optGroup, SIGNAL(triggered(QAction *)), menuList,
Li Zefan39a48972010-05-10 16:33:41 +08001469 SLOT(setOptionMode(QAction *)));
1470
Masahiro Yamadad4bbe8a2020-08-07 18:19:09 +09001471 ConfigList::showNormalAction = new QAction("Show Normal Options", optGroup);
1472 ConfigList::showNormalAction->setCheckable(true);
1473 ConfigList::showAllAction = new QAction("Show All Options", optGroup);
1474 ConfigList::showAllAction->setCheckable(true);
1475 ConfigList::showPromptAction = new QAction("Show Prompt Options", optGroup);
1476 ConfigList::showPromptAction->setCheckable(true);
Li Zefan39a48972010-05-10 16:33:41 +08001477
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001478 QAction *showDebugAction = new QAction("Show Debug Info", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001479 showDebugAction->setCheckable(true);
Roman Zippel43bf6122006-06-08 22:12:45 -07001480 connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
Boris Barbulovski9c862352015-09-22 11:36:12 -07001481 showDebugAction->setChecked(helpText->showDebug());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001482
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001483 QAction *showIntroAction = new QAction("Introduction", this);
Boris Barbulovski92119932015-09-22 11:36:16 -07001484 connect(showIntroAction, SIGNAL(triggered(bool)), SLOT(showIntro()));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001485 QAction *showAboutAction = new QAction("About", this);
Boris Barbulovski92119932015-09-22 11:36:16 -07001486 connect(showAboutAction, SIGNAL(triggered(bool)), SLOT(showAbout()));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001487
1488 // init tool bar
Masahiro Yamada860ec3f2020-08-07 18:18:55 +09001489 QToolBar *toolBar = addToolBar("Tools");
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001490 toolBar->addAction(backAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001491 toolBar->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001492 toolBar->addAction(loadAction);
1493 toolBar->addAction(saveAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001494 toolBar->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001495 toolBar->addAction(singleViewAction);
1496 toolBar->addAction(splitViewAction);
1497 toolBar->addAction(fullViewAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001498
Masahiro Yamada93ebaac2020-08-07 18:18:53 +09001499 // create file menu
1500 QMenu *menu = menuBar()->addMenu("&File");
1501 menu->addAction(loadAction);
1502 menu->addAction(saveAction);
1503 menu->addAction(saveAsAction);
1504 menu->addSeparator();
1505 menu->addAction(quitAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001506
Shlomi Fish66e7c722007-02-14 00:32:58 -08001507 // create edit menu
Masahiro Yamada93ebaac2020-08-07 18:18:53 +09001508 menu = menuBar()->addMenu("&Edit");
1509 menu->addAction(searchAction);
Shlomi Fish66e7c722007-02-14 00:32:58 -08001510
Linus Torvalds1da177e2005-04-16 15:20:36 -07001511 // create options menu
Masahiro Yamada93ebaac2020-08-07 18:18:53 +09001512 menu = menuBar()->addMenu("&Option");
1513 menu->addAction(showNameAction);
1514 menu->addAction(showRangeAction);
Masahiro Yamada93ebaac2020-08-07 18:18:53 +09001515 menu->addSeparator();
1516 menu->addActions(optGroup->actions());
1517 menu->addSeparator();
1518 menu->addAction(showDebugAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001519
1520 // create help menu
Masahiro Yamada93ebaac2020-08-07 18:18:53 +09001521 menu = menuBar()->addMenu("&Help");
1522 menu->addAction(showIntroAction);
1523 menu->addAction(showAboutAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001524
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001525 connect (helpText, SIGNAL (anchorClicked (const QUrl &)),
1526 helpText, SLOT (clicked (const QUrl &)) );
1527
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001528 connect(configList, SIGNAL(menuChanged(struct menu *)),
1529 helpText, SLOT(setInfo(struct menu *)));
1530 connect(configList, SIGNAL(menuSelected(struct menu *)),
1531 SLOT(changeMenu(struct menu *)));
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +02001532 connect(configList, SIGNAL(itemSelected(struct menu *)),
1533 SLOT(changeItens(struct menu *)));
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001534 connect(configList, SIGNAL(parentSelected()),
1535 SLOT(goBack()));
1536 connect(menuList, SIGNAL(menuChanged(struct menu *)),
1537 helpText, SLOT(setInfo(struct menu *)));
1538 connect(menuList, SIGNAL(menuSelected(struct menu *)),
1539 SLOT(changeMenu(struct menu *)));
1540
1541 connect(configList, SIGNAL(gotFocus(struct menu *)),
1542 helpText, SLOT(setInfo(struct menu *)));
1543 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1544 helpText, SLOT(setInfo(struct menu *)));
1545 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1546 SLOT(listFocusChanged(void)));
Roman Zippelb65a47e2006-06-08 22:12:47 -07001547 connect(helpText, SIGNAL(menuSelected(struct menu *)),
1548 SLOT(setMenuLink(struct menu *)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001549
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001550 QString listMode = configSettings->value("/listMode", "symbol").toString();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001551 if (listMode == "single")
1552 showSingleView();
1553 else if (listMode == "full")
1554 showFullView();
1555 else /*if (listMode == "split")*/
1556 showSplitView();
1557
1558 // UI setup done, restore splitter positions
Boris Barbulovski041fbdc2015-09-22 11:36:05 -07001559 QList<int> sizes = configSettings->readSizes("/split1", &ok);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001560 if (ok)
1561 split1->setSizes(sizes);
1562
Roman Zippel7fc925f2006-06-08 22:12:46 -07001563 sizes = configSettings->readSizes("/split2", &ok);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001564 if (ok)
1565 split2->setSizes(sizes);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001566}
1567
Linus Torvalds1da177e2005-04-16 15:20:36 -07001568void ConfigMainWindow::loadConfig(void)
1569{
Masahiro Yamada87419082019-03-11 01:13:15 +09001570 QString str;
1571 QByteArray ba;
1572 const char *name;
1573
1574 str = QFileDialog::getOpenFileName(this, "", configname);
1575 if (str.isNull())
Linus Torvalds1da177e2005-04-16 15:20:36 -07001576 return;
Masahiro Yamada87419082019-03-11 01:13:15 +09001577
1578 ba = str.toLocal8Bit();
1579 name = ba.data();
1580
1581 if (conf_read(name))
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001582 QMessageBox::information(this, "qconf", "Unable to load configuration!");
Masahiro Yamada87419082019-03-11 01:13:15 +09001583
1584 free(configname);
1585 configname = xstrdup(name);
1586
Masahiro Yamadaf9b918f2020-08-29 17:14:10 +09001587 ConfigList::updateListAllForAll();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001588}
1589
Michal Marekbac6aa82011-05-25 15:10:25 +02001590bool ConfigMainWindow::saveConfig(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001591{
Masahiro Yamada87419082019-03-11 01:13:15 +09001592 if (conf_write(configname)) {
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001593 QMessageBox::information(this, "qconf", "Unable to save configuration!");
Michal Marekbac6aa82011-05-25 15:10:25 +02001594 return false;
1595 }
Masahiro Yamada00c864f2018-07-20 16:46:31 +09001596 conf_write_autoconf(0);
1597
Michal Marekbac6aa82011-05-25 15:10:25 +02001598 return true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001599}
1600
1601void ConfigMainWindow::saveConfigAs(void)
1602{
Masahiro Yamada87419082019-03-11 01:13:15 +09001603 QString str;
1604 QByteArray ba;
1605 const char *name;
1606
1607 str = QFileDialog::getSaveFileName(this, "", configname);
1608 if (str.isNull())
Linus Torvalds1da177e2005-04-16 15:20:36 -07001609 return;
Masahiro Yamada87419082019-03-11 01:13:15 +09001610
1611 ba = str.toLocal8Bit();
1612 name = ba.data();
1613
1614 if (conf_write(name)) {
1615 QMessageBox::information(this, "qconf", "Unable to save configuration!");
1616 }
1617 conf_write_autoconf(0);
1618
1619 free(configname);
1620 configname = xstrdup(name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001621}
1622
Roman Zippel43bf6122006-06-08 22:12:45 -07001623void ConfigMainWindow::searchConfig(void)
1624{
1625 if (!searchWindow)
Masahiro Yamada740fdef2020-08-07 18:18:57 +09001626 searchWindow = new ConfigSearchWindow(this);
Roman Zippel43bf6122006-06-08 22:12:45 -07001627 searchWindow->show();
1628}
1629
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +02001630void ConfigMainWindow::changeItens(struct menu *menu)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001631{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001632 configList->setRootMenu(menu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001633}
1634
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +02001635void ConfigMainWindow::changeMenu(struct menu *menu)
1636{
1637 menuList->setRootMenu(menu);
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +02001638}
1639
Roman Zippelb65a47e2006-06-08 22:12:47 -07001640void ConfigMainWindow::setMenuLink(struct menu *menu)
1641{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001642 struct menu *parent;
1643 ConfigList* list = NULL;
1644 ConfigItem* item;
1645
1646 if (configList->menuSkip(menu))
1647 return;
1648
1649 switch (configList->mode) {
1650 case singleMode:
1651 list = configList;
1652 parent = menu_get_parent_menu(menu);
1653 if (!parent)
1654 return;
1655 list->setRootMenu(parent);
1656 break;
Mauro Carvalho Chehabc699eaa2020-06-30 08:26:36 +02001657 case menuMode:
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001658 if (menu->flags & MENU_ROOT) {
Mauro Carvalho Chehabc699eaa2020-06-30 08:26:36 +02001659 menuList->setRootMenu(menu);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001660 configList->clearSelection();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001661 list = configList;
Mauro Carvalho Chehabc699eaa2020-06-30 08:26:36 +02001662 } else {
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001663 parent = menu_get_parent_menu(menu->parent);
1664 if (!parent)
1665 return;
Mauro Carvalho Chehabc699eaa2020-06-30 08:26:36 +02001666
Mauro Carvalho Chehabc699eaa2020-06-30 08:26:36 +02001667 /* Select the config view */
1668 item = configList->findConfigItem(parent);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001669 if (item) {
Mauro Carvalho Chehabb06c3ec2020-06-30 08:26:38 +02001670 configList->setSelected(item, true);
Mauro Carvalho Chehabc699eaa2020-06-30 08:26:36 +02001671 configList->scrollToItem(item);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001672 }
Mauro Carvalho Chehabc699eaa2020-06-30 08:26:36 +02001673
1674 menuList->setRootMenu(parent);
1675 menuList->clearSelection();
1676 list = menuList;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001677 }
1678 break;
1679 case fullMode:
1680 list = configList;
1681 break;
1682 default:
1683 break;
1684 }
1685
1686 if (list) {
1687 item = list->findConfigItem(menu);
1688 if (item) {
Mauro Carvalho Chehabb06c3ec2020-06-30 08:26:38 +02001689 list->setSelected(item, true);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001690 list->scrollToItem(item);
1691 list->setFocus();
Mauro Carvalho Chehab8a3b6e52020-06-30 08:48:35 +02001692 helpText->setInfo(menu);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001693 }
1694 }
Roman Zippelb65a47e2006-06-08 22:12:47 -07001695}
1696
Linus Torvalds1da177e2005-04-16 15:20:36 -07001697void ConfigMainWindow::listFocusChanged(void)
1698{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001699 if (menuList->mode == menuMode)
1700 configList->clearSelection();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001701}
1702
1703void ConfigMainWindow::goBack(void)
1704{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001705 if (configList->rootEntry == &rootmenu)
Boris Barbulovskibe596aa2015-09-22 11:36:28 -07001706 return;
1707
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001708 configList->setParentMenu();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001709}
1710
1711void ConfigMainWindow::showSingleView(void)
1712{
Boris Barbulovski780505e2015-09-22 11:36:13 -07001713 singleViewAction->setEnabled(false);
1714 singleViewAction->setChecked(true);
1715 splitViewAction->setEnabled(true);
1716 splitViewAction->setChecked(false);
1717 fullViewAction->setEnabled(true);
1718 fullViewAction->setChecked(false);
1719
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001720 backAction->setEnabled(true);
1721
Masahiro Yamada62ed1652020-08-29 17:14:15 +09001722 menuList->hide();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001723 menuList->setRootMenu(0);
1724 configList->mode = singleMode;
1725 if (configList->rootEntry == &rootmenu)
1726 configList->updateListAll();
1727 else
1728 configList->setRootMenu(&rootmenu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001729 configList->setFocus();
1730}
1731
1732void ConfigMainWindow::showSplitView(void)
1733{
Boris Barbulovski780505e2015-09-22 11:36:13 -07001734 singleViewAction->setEnabled(true);
1735 singleViewAction->setChecked(false);
1736 splitViewAction->setEnabled(false);
1737 splitViewAction->setChecked(true);
1738 fullViewAction->setEnabled(true);
1739 fullViewAction->setChecked(false);
1740
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001741 backAction->setEnabled(false);
1742
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +02001743 configList->mode = menuMode;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001744 if (configList->rootEntry == &rootmenu)
1745 configList->updateListAll();
1746 else
1747 configList->setRootMenu(&rootmenu);
1748 configList->setAllOpen(true);
1749 configApp->processEvents();
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +02001750 menuList->mode = symbolMode;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001751 menuList->setRootMenu(&rootmenu);
1752 menuList->setAllOpen(true);
Masahiro Yamada62ed1652020-08-29 17:14:15 +09001753 menuList->show();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001754 menuList->setFocus();
1755}
1756
1757void ConfigMainWindow::showFullView(void)
1758{
Boris Barbulovski780505e2015-09-22 11:36:13 -07001759 singleViewAction->setEnabled(true);
1760 singleViewAction->setChecked(false);
1761 splitViewAction->setEnabled(true);
1762 splitViewAction->setChecked(false);
1763 fullViewAction->setEnabled(false);
1764 fullViewAction->setChecked(true);
1765
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001766 backAction->setEnabled(false);
1767
Masahiro Yamada62ed1652020-08-29 17:14:15 +09001768 menuList->hide();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001769 menuList->setRootMenu(0);
1770 configList->mode = fullMode;
1771 if (configList->rootEntry == &rootmenu)
1772 configList->updateListAll();
1773 else
1774 configList->setRootMenu(&rootmenu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001775 configList->setFocus();
1776}
1777
Linus Torvalds1da177e2005-04-16 15:20:36 -07001778/*
1779 * ask for saving configuration before quitting
Linus Torvalds1da177e2005-04-16 15:20:36 -07001780 */
1781void ConfigMainWindow::closeEvent(QCloseEvent* e)
1782{
Karsten Wieseb3214292006-12-13 00:34:06 -08001783 if (!conf_get_changed()) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001784 e->accept();
1785 return;
1786 }
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001787 QMessageBox mb("qconf", "Save configuration?", QMessageBox::Warning,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001788 QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape);
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001789 mb.setButtonText(QMessageBox::Yes, "&Save Changes");
1790 mb.setButtonText(QMessageBox::No, "&Discard Changes");
1791 mb.setButtonText(QMessageBox::Cancel, "Cancel Exit");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001792 switch (mb.exec()) {
1793 case QMessageBox::Yes:
Michal Marekbac6aa82011-05-25 15:10:25 +02001794 if (saveConfig())
1795 e->accept();
1796 else
1797 e->ignore();
1798 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001799 case QMessageBox::No:
1800 e->accept();
1801 break;
1802 case QMessageBox::Cancel:
1803 e->ignore();
1804 break;
1805 }
1806}
1807
1808void ConfigMainWindow::showIntro(void)
1809{
Masahiro Yamada8c30e7e2020-08-29 17:14:07 +09001810 static const QString str =
1811 "Welcome to the qconf graphical configuration tool.\n"
1812 "\n"
Masahiro Yamada37162a62020-08-29 17:14:12 +09001813 "For bool and tristate options, a blank box indicates the "
1814 "feature is disabled, a check indicates it is enabled, and a "
1815 "dot indicates that it is to be compiled as a module. Clicking "
1816 "on the box will cycle through the three states. For int, hex, "
1817 "and string options, double-clicking or pressing F2 on the "
1818 "Value cell will allow you to edit the value.\n"
Masahiro Yamada8c30e7e2020-08-29 17:14:07 +09001819 "\n"
1820 "If you do not see an option (e.g., a device driver) that you "
1821 "believe should be present, try turning on Show All Options "
Masahiro Yamada1fb75242020-08-29 17:14:08 +09001822 "under the Options menu. Enabling Show Debug Info will help you"
1823 "figure out what other options must be enabled to support the "
1824 "option you are interested in, and hyperlinks will navigate to "
1825 "them.\n"
Masahiro Yamada8c30e7e2020-08-29 17:14:07 +09001826 "\n"
1827 "Toggling Show Debug Info under the Options menu will show the "
1828 "dependencies, which you can then match by examining other "
1829 "options.\n";
Linus Torvalds1da177e2005-04-16 15:20:36 -07001830
1831 QMessageBox::information(this, "qconf", str);
1832}
1833
1834void ConfigMainWindow::showAbout(void)
1835{
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001836 static const QString str = "qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n"
Boris Barbulovskib4ff1de2015-09-22 11:36:38 -07001837 "Copyright (C) 2015 Boris Barbulovski <bbarbulovski@gmail.com>.\n\n"
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001838 "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n";
Linus Torvalds1da177e2005-04-16 15:20:36 -07001839
1840 QMessageBox::information(this, "qconf", str);
1841}
1842
1843void ConfigMainWindow::saveSettings(void)
1844{
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001845 configSettings->setValue("/window x", pos().x());
1846 configSettings->setValue("/window y", pos().y());
1847 configSettings->setValue("/window width", size().width());
1848 configSettings->setValue("/window height", size().height());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001849
1850 QString entry;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001851 switch(configList->mode) {
1852 case singleMode :
1853 entry = "single";
1854 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001855
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001856 case symbolMode :
1857 entry = "split";
1858 break;
1859
1860 case fullMode :
1861 entry = "full";
1862 break;
1863
1864 default:
1865 break;
1866 }
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001867 configSettings->setValue("/listMode", entry);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001868
Roman Zippel7fc925f2006-06-08 22:12:46 -07001869 configSettings->writeSizes("/split1", split1->sizes());
1870 configSettings->writeSizes("/split2", split2->sizes());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001871}
1872
Karsten Wiese3b354c52006-12-13 00:34:08 -08001873void ConfigMainWindow::conf_changed(void)
1874{
1875 if (saveAction)
1876 saveAction->setEnabled(conf_get_changed());
1877}
1878
Linus Torvalds1da177e2005-04-16 15:20:36 -07001879void fixup_rootmenu(struct menu *menu)
1880{
1881 struct menu *child;
1882 static int menu_cnt = 0;
1883
1884 menu->flags |= MENU_ROOT;
1885 for (child = menu->list; child; child = child->next) {
1886 if (child->prompt && child->prompt->type == P_MENU) {
1887 menu_cnt++;
1888 fixup_rootmenu(child);
1889 menu_cnt--;
1890 } else if (!menu_cnt)
1891 fixup_rootmenu(child);
1892 }
1893}
1894
1895static const char *progname;
1896
1897static void usage(void)
1898{
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001899 printf("%s [-s] <config>\n", progname);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001900 exit(0);
1901}
1902
1903int main(int ac, char** av)
1904{
1905 ConfigMainWindow* v;
1906 const char *name;
1907
Linus Torvalds1da177e2005-04-16 15:20:36 -07001908 progname = av[0];
1909 configApp = new QApplication(ac, av);
1910 if (ac > 1 && av[1][0] == '-') {
1911 switch (av[1][1]) {
Michal Marek0a1f00a2015-04-08 13:30:42 +02001912 case 's':
1913 conf_set_message_callback(NULL);
1914 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001915 case 'h':
1916 case '?':
1917 usage();
1918 }
1919 name = av[2];
1920 } else
1921 name = av[1];
1922 if (!name)
1923 usage();
1924
1925 conf_parse(name);
1926 fixup_rootmenu(&rootmenu);
1927 conf_read(NULL);
1928 //zconfdump(stdout);
1929
Roman Zippel7fc925f2006-06-08 22:12:46 -07001930 configSettings = new ConfigSettings();
1931 configSettings->beginGroup("/kconfig/qconf");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001932 v = new ConfigMainWindow();
1933
1934 //zconfdump(stdout);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001935 configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit()));
1936 configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings()));
Roman Zippel43bf6122006-06-08 22:12:45 -07001937 v->show();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001938 configApp->exec();
1939
Roman Zippel7fc925f2006-06-08 22:12:46 -07001940 configSettings->endGroup();
1941 delete configSettings;
Chris Bainbridge5b61c7b2016-01-08 20:44:04 +00001942 delete v;
1943 delete configApp;
Roman Zippel7fc925f2006-06-08 22:12:46 -07001944
Linus Torvalds1da177e2005-04-16 15:20:36 -07001945 return 0;
1946}