blob: cf33e436190e02710eac11ceeb3eb80eee83c029 [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/*
86 * set the new data
87 * TODO check the value
88 */
89void ConfigItem::okRename(int col)
90{
91}
92
93/*
94 * update the displayed of a menu entry
95 */
96void ConfigItem::updateMenu(void)
97{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -070098 ConfigList* list;
99 struct symbol* sym;
100 struct property *prop;
101 QString prompt;
102 int type;
103 tristate expr;
104
105 list = listView();
106 if (goParent) {
Masahiro Yamada5cb255f2020-08-07 18:19:07 +0900107 setIcon(promptColIdx, menubackIcon);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700108 prompt = "..";
109 goto set_prompt;
110 }
111
112 sym = menu->sym;
113 prop = menu->prompt;
Masahiro Yamada3c73ff02020-08-07 18:19:02 +0900114 prompt = menu_get_prompt(menu);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700115
116 if (prop) switch (prop->type) {
117 case P_MENU:
118 if (list->mode == singleMode || list->mode == symbolMode) {
119 /* a menuconfig entry is displayed differently
120 * depending whether it's at the view root or a child.
121 */
122 if (sym && list->rootEntry == menu)
123 break;
Masahiro Yamada5cb255f2020-08-07 18:19:07 +0900124 setIcon(promptColIdx, menuIcon);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700125 } else {
126 if (sym)
127 break;
Masahiro Yamada711b8752020-08-07 18:19:03 +0900128 setIcon(promptColIdx, QIcon());
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700129 }
130 goto set_prompt;
131 case P_COMMENT:
Masahiro Yamada711b8752020-08-07 18:19:03 +0900132 setIcon(promptColIdx, QIcon());
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700133 goto set_prompt;
134 default:
135 ;
136 }
137 if (!sym)
138 goto set_prompt;
139
Masahiro Yamada3c73ff02020-08-07 18:19:02 +0900140 setText(nameColIdx, sym->name);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700141
142 type = sym_get_type(sym);
143 switch (type) {
144 case S_BOOLEAN:
145 case S_TRISTATE:
146 char ch;
147
Marco Ammonbaa23ec2019-07-04 12:50:41 +0200148 if (!sym_is_changeable(sym) && list->optMode == normalOpt) {
Masahiro Yamada711b8752020-08-07 18:19:03 +0900149 setIcon(promptColIdx, QIcon());
Mauro Carvalho Chehabcf497b92020-04-02 11:27:58 +0200150 setText(noColIdx, QString());
151 setText(modColIdx, QString());
152 setText(yesColIdx, QString());
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700153 break;
154 }
155 expr = sym_get_tristate_value(sym);
156 switch (expr) {
157 case yes:
158 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
Masahiro Yamada5cb255f2020-08-07 18:19:07 +0900159 setIcon(promptColIdx, choiceYesIcon);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700160 else
Masahiro Yamada5cb255f2020-08-07 18:19:07 +0900161 setIcon(promptColIdx, symbolYesIcon);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700162 setText(yesColIdx, "Y");
163 ch = 'Y';
164 break;
165 case mod:
Masahiro Yamada5cb255f2020-08-07 18:19:07 +0900166 setIcon(promptColIdx, symbolModIcon);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700167 setText(modColIdx, "M");
168 ch = 'M';
169 break;
170 default:
171 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
Masahiro Yamada5cb255f2020-08-07 18:19:07 +0900172 setIcon(promptColIdx, choiceNoIcon);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700173 else
Masahiro Yamada5cb255f2020-08-07 18:19:07 +0900174 setIcon(promptColIdx, symbolNoIcon);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700175 setText(noColIdx, "N");
176 ch = 'N';
177 break;
178 }
179 if (expr != no)
180 setText(noColIdx, sym_tristate_within_range(sym, no) ? "_" : 0);
181 if (expr != mod)
182 setText(modColIdx, sym_tristate_within_range(sym, mod) ? "_" : 0);
183 if (expr != yes)
184 setText(yesColIdx, sym_tristate_within_range(sym, yes) ? "_" : 0);
185
186 setText(dataColIdx, QChar(ch));
187 break;
188 case S_INT:
189 case S_HEX:
190 case S_STRING:
191 const char* data;
192
193 data = sym_get_string_value(sym);
194
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700195 setText(dataColIdx, data);
196 if (type == S_STRING)
197 prompt = QString("%1: %2").arg(prompt).arg(data);
198 else
199 prompt = QString("(%2) %1").arg(prompt).arg(data);
200 break;
201 }
202 if (!sym_has_value(sym) && visible)
Sam Ravnborg694c49a2018-05-22 21:36:12 +0200203 prompt += " (NEW)";
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700204set_prompt:
205 setText(promptColIdx, prompt);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700206}
207
208void ConfigItem::testUpdateMenu(bool v)
209{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700210 ConfigItem* i;
211
212 visible = v;
213 if (!menu)
214 return;
215
216 sym_calc_value(menu->sym);
217 if (menu->flags & MENU_CHANGED) {
218 /* the menu entry changed, so update all list items */
219 menu->flags &= ~MENU_CHANGED;
220 for (i = (ConfigItem*)menu->data; i; i = i->nextItem)
221 i->updateMenu();
222 } else if (listView()->updateAll)
223 updateMenu();
Boris Barbulovski59e56442015-09-22 11:36:18 -0700224}
225
226
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700227/*
228 * construct a menu entry
229 */
230void ConfigItem::init(void)
231{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700232 if (menu) {
233 ConfigList* list = listView();
234 nextItem = (ConfigItem*)menu->data;
235 menu->data = this;
236
237 if (list->mode != fullMode)
238 setExpanded(true);
239 sym_calc_value(menu->sym);
240 }
241 updateMenu();
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700242}
243
244/*
245 * destruct a menu entry
246 */
247ConfigItem::~ConfigItem(void)
248{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700249 if (menu) {
250 ConfigItem** ip = (ConfigItem**)&menu->data;
251 for (; *ip; ip = &(*ip)->nextItem) {
252 if (*ip == this) {
253 *ip = nextItem;
254 break;
255 }
256 }
257 }
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700258}
259
Roman Zippel43bf6122006-06-08 22:12:45 -0700260ConfigLineEdit::ConfigLineEdit(ConfigView* parent)
261 : Parent(parent)
262{
Boris Barbulovskic14fa5e2015-09-22 11:36:21 -0700263 connect(this, SIGNAL(editingFinished()), SLOT(hide()));
Roman Zippel43bf6122006-06-08 22:12:45 -0700264}
265
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700266void ConfigLineEdit::show(ConfigItem* i)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700267{
268 item = i;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700269 if (sym_get_string_value(item->menu->sym))
Masahiro Yamada3c73ff02020-08-07 18:19:02 +0900270 setText(sym_get_string_value(item->menu->sym));
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700271 else
Mauro Carvalho Chehabcf497b92020-04-02 11:27:58 +0200272 setText(QString());
Linus Torvalds1da177e2005-04-16 15:20:36 -0700273 Parent::show();
274 setFocus();
275}
276
277void ConfigLineEdit::keyPressEvent(QKeyEvent* e)
278{
279 switch (e->key()) {
Markus Heidelbergfbb86372009-05-18 01:36:51 +0200280 case Qt::Key_Escape:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700281 break;
Markus Heidelbergfbb86372009-05-18 01:36:51 +0200282 case Qt::Key_Return:
283 case Qt::Key_Enter:
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700284 sym_set_string_value(item->menu->sym, text().toLatin1());
Masahiro Yamada10316852020-08-07 18:19:00 +0900285 parent()->updateList();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700286 break;
287 default:
288 Parent::keyPressEvent(e);
289 return;
290 }
291 e->accept();
292 parent()->list->setFocus();
293 hide();
294}
295
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700296ConfigList::ConfigList(ConfigView* p, const char *name)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700297 : Parent(p),
298 updateAll(false),
Boris Barbulovskidbf62932015-09-22 11:36:26 -0700299 showName(false), showRange(false), showData(false), mode(singleMode), optMode(normalOpt),
Boris Barbulovski59e56442015-09-22 11:36:18 -0700300 rootEntry(0), headerPopup(0)
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700301{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700302 setObjectName(name);
Boris Barbulovskia5225e92015-09-22 11:36:29 -0700303 setSortingEnabled(false);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700304 setRootIsDecorated(true);
305
Boris Barbulovskif999cc02015-09-22 11:36:31 -0700306 setVerticalScrollMode(ScrollPerPixel);
307 setHorizontalScrollMode(ScrollPerPixel);
308
Masahiro Yamada97bebbc2020-07-30 02:46:17 +0900309 setHeaderLabels(QStringList() << "Option" << "Name" << "N" << "M" << "Y" << "Value");
Boris Barbulovskia52cb322015-09-22 11:36:24 -0700310
Boris Barbulovskic14fa5e2015-09-22 11:36:21 -0700311 connect(this, SIGNAL(itemSelectionChanged(void)),
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700312 SLOT(updateSelection(void)));
313
314 if (name) {
315 configSettings->beginGroup(name);
316 showName = configSettings->value("/showName", false).toBool();
317 showRange = configSettings->value("/showRange", false).toBool();
318 showData = configSettings->value("/showData", false).toBool();
319 optMode = (enum optionMode)configSettings->value("/optionMode", 0).toInt();
320 configSettings->endGroup();
321 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
322 }
323
Masahiro Yamadaabf741a2020-08-07 18:19:04 +0900324 showColumn(promptColIdx);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700325
326 reinit();
327}
328
329bool ConfigList::menuSkip(struct menu *menu)
330{
331 if (optMode == normalOpt && menu_is_visible(menu))
332 return false;
333 if (optMode == promptOpt && menu_has_prompt(menu))
334 return false;
335 if (optMode == allOpt)
336 return false;
337 return true;
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700338}
Boris Barbulovski59e56442015-09-22 11:36:18 -0700339
340void ConfigList::reinit(void)
341{
Masahiro Yamadaabf741a2020-08-07 18:19:04 +0900342 hideColumn(dataColIdx);
343 hideColumn(yesColIdx);
344 hideColumn(modColIdx);
345 hideColumn(noColIdx);
346 hideColumn(nameColIdx);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700347
348 if (showName)
Masahiro Yamadaabf741a2020-08-07 18:19:04 +0900349 showColumn(nameColIdx);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700350 if (showRange) {
Masahiro Yamadaabf741a2020-08-07 18:19:04 +0900351 showColumn(noColIdx);
352 showColumn(modColIdx);
353 showColumn(yesColIdx);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700354 }
355 if (showData)
Masahiro Yamadaabf741a2020-08-07 18:19:04 +0900356 showColumn(dataColIdx);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700357
358 updateListAll();
Boris Barbulovski59e56442015-09-22 11:36:18 -0700359}
360
Masahiro Yamadad4bbe8a2020-08-07 18:19:09 +0900361void ConfigList::setOptionMode(QAction *action)
362{
363 if (action == showNormalAction)
364 optMode = normalOpt;
365 else if (action == showAllAction)
366 optMode = allOpt;
367 else
368 optMode = promptOpt;
369
370 updateListAll();
371}
372
Boris Barbulovski59e56442015-09-22 11:36:18 -0700373void ConfigList::saveSettings(void)
374{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700375 if (!objectName().isEmpty()) {
376 configSettings->beginGroup(objectName());
377 configSettings->setValue("/showName", showName);
378 configSettings->setValue("/showRange", showRange);
379 configSettings->setValue("/showData", showData);
380 configSettings->setValue("/optionMode", (int)optMode);
381 configSettings->endGroup();
382 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700383}
384
385ConfigItem* ConfigList::findConfigItem(struct menu *menu)
386{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700387 ConfigItem* item = (ConfigItem*)menu->data;
388
389 for (; item; item = item->nextItem) {
390 if (this == item->listView())
391 break;
392 }
393
394 return item;
Boris Barbulovski59e56442015-09-22 11:36:18 -0700395}
396
397void ConfigList::updateSelection(void)
398{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700399 struct menu *menu;
400 enum prop_type type;
401
Boris Barbulovskibe596aa2015-09-22 11:36:28 -0700402 if (selectedItems().count() == 0)
403 return;
404
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700405 ConfigItem* item = (ConfigItem*)selectedItems().first();
406 if (!item)
407 return;
408
409 menu = item->menu;
410 emit menuChanged(menu);
411 if (!menu)
412 return;
413 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
414 if (mode == menuMode && type == P_MENU)
415 emit menuSelected(menu);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700416}
417
Masahiro Yamadacb770432020-08-07 18:18:59 +0900418void ConfigList::updateList()
Boris Barbulovski59e56442015-09-22 11:36:18 -0700419{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700420 ConfigItem* last = 0;
Masahiro Yamadacb770432020-08-07 18:18:59 +0900421 ConfigItem *item;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700422
423 if (!rootEntry) {
424 if (mode != listMode)
425 goto update;
426 QTreeWidgetItemIterator it(this);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700427
428 while (*it) {
429 item = (ConfigItem*)(*it);
430 if (!item->menu)
431 continue;
432 item->testUpdateMenu(menu_is_visible(item->menu));
433
434 ++it;
435 }
436 return;
437 }
438
439 if (rootEntry != &rootmenu && (mode == singleMode ||
440 (mode == symbolMode && rootEntry->parent != &rootmenu))) {
Boris Barbulovskiee7298f2015-09-22 11:36:37 -0700441 item = (ConfigItem *)topLevelItem(0);
Masahiro Yamada4b20e102020-08-01 16:08:49 +0900442 if (!item)
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700443 item = new ConfigItem(this, 0, true);
Masahiro Yamada4b20e102020-08-01 16:08:49 +0900444 last = item;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700445 }
446 if ((mode == singleMode || (mode == symbolMode && !(rootEntry->flags & MENU_ROOT))) &&
447 rootEntry->sym && rootEntry->prompt) {
Masahiro Yamadaccf56e52020-08-01 16:08:50 +0900448 item = last ? last->nextSibling() : nullptr;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700449 if (!item)
450 item = new ConfigItem(this, last, rootEntry, true);
451 else
452 item->testUpdateMenu(true);
453
454 updateMenuList(item, rootEntry);
455 update();
Boris Barbulovskif999cc02015-09-22 11:36:31 -0700456 resizeColumnToContents(0);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700457 return;
458 }
459update:
Masahiro Yamada5b75a6c2020-08-07 18:19:01 +0900460 updateMenuList(rootEntry);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700461 update();
Boris Barbulovskif999cc02015-09-22 11:36:31 -0700462 resizeColumnToContents(0);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700463}
464
465void ConfigList::setValue(ConfigItem* item, tristate val)
466{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700467 struct symbol* sym;
468 int type;
469 tristate oldval;
470
471 sym = item->menu ? item->menu->sym : 0;
472 if (!sym)
473 return;
474
475 type = sym_get_type(sym);
476 switch (type) {
477 case S_BOOLEAN:
478 case S_TRISTATE:
479 oldval = sym_get_tristate_value(sym);
480
481 if (!sym_set_tristate_value(sym, val))
482 return;
483 if (oldval == no && item->menu->list)
484 item->setExpanded(true);
Masahiro Yamada10316852020-08-07 18:19:00 +0900485 parent()->updateList();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700486 break;
487 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700488}
489
490void ConfigList::changeValue(ConfigItem* item)
491{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700492 struct symbol* sym;
493 struct menu* menu;
494 int type, oldexpr, newexpr;
495
496 menu = item->menu;
497 if (!menu)
498 return;
499 sym = menu->sym;
500 if (!sym) {
501 if (item->menu->list)
502 item->setExpanded(!item->isExpanded());
503 return;
504 }
505
506 type = sym_get_type(sym);
507 switch (type) {
508 case S_BOOLEAN:
509 case S_TRISTATE:
510 oldexpr = sym_get_tristate_value(sym);
511 newexpr = sym_toggle_tristate_value(sym);
512 if (item->menu->list) {
513 if (oldexpr == newexpr)
514 item->setExpanded(!item->isExpanded());
515 else if (oldexpr == no)
516 item->setExpanded(true);
517 }
518 if (oldexpr != newexpr)
Masahiro Yamada10316852020-08-07 18:19:00 +0900519 parent()->updateList();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700520 break;
521 case S_INT:
522 case S_HEX:
523 case S_STRING:
Boris Barbulovskie336b9f2015-09-22 11:36:34 -0700524 parent()->lineEdit->show(item);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700525 break;
526 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700527}
528
529void ConfigList::setRootMenu(struct menu *menu)
530{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700531 enum prop_type type;
532
533 if (rootEntry == menu)
534 return;
535 type = menu && menu->prompt ? menu->prompt->type : P_UNKNOWN;
536 if (type != P_MENU)
537 return;
Masahiro Yamada5b75a6c2020-08-07 18:19:01 +0900538 updateMenuList(0);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700539 rootEntry = menu;
540 updateListAll();
541 if (currentItem()) {
Mauro Carvalho Chehabb06c3ec2020-06-30 08:26:38 +0200542 setSelected(currentItem(), hasFocus());
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700543 scrollToItem(currentItem());
544 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700545}
546
547void ConfigList::setParentMenu(void)
548{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700549 ConfigItem* item;
550 struct menu *oldroot;
551
552 oldroot = rootEntry;
553 if (rootEntry == &rootmenu)
554 return;
555 setRootMenu(menu_get_parent_menu(rootEntry->parent));
556
557 QTreeWidgetItemIterator it(this);
558 while (*it) {
559 item = (ConfigItem *)(*it);
560 if (item->menu == oldroot) {
561 setCurrentItem(item);
562 scrollToItem(item);
563 break;
564 }
565
566 ++it;
567 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700568}
569
570/*
571 * update all the children of a menu entry
572 * removes/adds the entries from the parent widget as necessary
573 *
574 * parent: either the menu list widget or a menu entry widget
575 * menu: entry to be updated
576 */
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700577void ConfigList::updateMenuList(ConfigItem *parent, struct menu* menu)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700578{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700579 struct menu* child;
580 ConfigItem* item;
581 ConfigItem* last;
582 bool visible;
583 enum prop_type type;
584
585 if (!menu) {
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700586 while (parent->childCount() > 0)
587 {
588 delete parent->takeChild(0);
589 }
590
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700591 return;
592 }
593
594 last = parent->firstChild();
595 if (last && !last->goParent)
596 last = 0;
597 for (child = menu->list; child; child = child->next) {
598 item = last ? last->nextSibling() : parent->firstChild();
599 type = child->prompt ? child->prompt->type : P_UNKNOWN;
600
601 switch (mode) {
602 case menuMode:
603 if (!(child->flags & MENU_ROOT))
604 goto hide;
605 break;
606 case symbolMode:
607 if (child->flags & MENU_ROOT)
608 goto hide;
609 break;
610 default:
611 break;
612 }
613
614 visible = menu_is_visible(child);
615 if (!menuSkip(child)) {
616 if (!child->sym && !child->list && !child->prompt)
617 continue;
618 if (!item || item->menu != child)
619 item = new ConfigItem(parent, last, child, visible);
620 else
621 item->testUpdateMenu(visible);
622
623 if (mode == fullMode || mode == menuMode || type != P_MENU)
624 updateMenuList(item, child);
625 else
626 updateMenuList(item, 0);
627 last = item;
628 continue;
629 }
Mauro Carvalho Chehab60969f02020-04-02 11:28:03 +0200630hide:
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700631 if (item && item->menu == child) {
632 last = parent->firstChild();
633 if (last == item)
634 last = 0;
635 else while (last->nextSibling() != item)
636 last = last->nextSibling();
637 delete item;
638 }
639 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700640}
641
Masahiro Yamada5b75a6c2020-08-07 18:19:01 +0900642void ConfigList::updateMenuList(struct menu *menu)
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700643{
644 struct menu* child;
645 ConfigItem* item;
646 ConfigItem* last;
647 bool visible;
648 enum prop_type type;
649
650 if (!menu) {
Masahiro Yamada5b75a6c2020-08-07 18:19:01 +0900651 while (topLevelItemCount() > 0)
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700652 {
Masahiro Yamada5b75a6c2020-08-07 18:19:01 +0900653 delete takeTopLevelItem(0);
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700654 }
655
656 return;
657 }
658
Masahiro Yamada5b75a6c2020-08-07 18:19:01 +0900659 last = (ConfigItem *)topLevelItem(0);
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700660 if (last && !last->goParent)
661 last = 0;
662 for (child = menu->list; child; child = child->next) {
Masahiro Yamada5b75a6c2020-08-07 18:19:01 +0900663 item = last ? last->nextSibling() : (ConfigItem *)topLevelItem(0);
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700664 type = child->prompt ? child->prompt->type : P_UNKNOWN;
665
666 switch (mode) {
667 case menuMode:
668 if (!(child->flags & MENU_ROOT))
669 goto hide;
670 break;
671 case symbolMode:
672 if (child->flags & MENU_ROOT)
673 goto hide;
674 break;
675 default:
676 break;
677 }
678
679 visible = menu_is_visible(child);
680 if (!menuSkip(child)) {
681 if (!child->sym && !child->list && !child->prompt)
682 continue;
683 if (!item || item->menu != child)
Masahiro Yamada5b75a6c2020-08-07 18:19:01 +0900684 item = new ConfigItem(this, last, child, visible);
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700685 else
686 item->testUpdateMenu(visible);
687
688 if (mode == fullMode || mode == menuMode || type != P_MENU)
689 updateMenuList(item, child);
690 else
691 updateMenuList(item, 0);
692 last = item;
693 continue;
694 }
Mauro Carvalho Chehab60969f02020-04-02 11:28:03 +0200695hide:
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700696 if (item && item->menu == child) {
Masahiro Yamada5b75a6c2020-08-07 18:19:01 +0900697 last = (ConfigItem *)topLevelItem(0);
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700698 if (last == item)
699 last = 0;
700 else while (last->nextSibling() != item)
701 last = last->nextSibling();
702 delete item;
703 }
704 }
705}
706
Boris Barbulovski59e56442015-09-22 11:36:18 -0700707void ConfigList::keyPressEvent(QKeyEvent* ev)
708{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700709 QTreeWidgetItem* i = currentItem();
710 ConfigItem* item;
711 struct menu *menu;
712 enum prop_type type;
713
714 if (ev->key() == Qt::Key_Escape && mode != fullMode && mode != listMode) {
715 emit parentSelected();
716 ev->accept();
717 return;
718 }
719
720 if (!i) {
721 Parent::keyPressEvent(ev);
722 return;
723 }
724 item = (ConfigItem*)i;
725
726 switch (ev->key()) {
727 case Qt::Key_Return:
728 case Qt::Key_Enter:
729 if (item->goParent) {
730 emit parentSelected();
731 break;
732 }
733 menu = item->menu;
734 if (!menu)
735 break;
736 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
737 if (type == P_MENU && rootEntry != menu &&
738 mode != fullMode && mode != menuMode) {
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +0200739 if (mode == menuMode)
740 emit menuSelected(menu);
741 else
742 emit itemSelected(menu);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700743 break;
744 }
745 case Qt::Key_Space:
746 changeValue(item);
747 break;
748 case Qt::Key_N:
749 setValue(item, no);
750 break;
751 case Qt::Key_M:
752 setValue(item, mod);
753 break;
754 case Qt::Key_Y:
755 setValue(item, yes);
756 break;
757 default:
758 Parent::keyPressEvent(ev);
759 return;
760 }
761 ev->accept();
Boris Barbulovski59e56442015-09-22 11:36:18 -0700762}
763
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700764void ConfigList::mousePressEvent(QMouseEvent* e)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700765{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700766 //QPoint p(contentsToViewport(e->pos()));
767 //printf("contentsMousePressEvent: %d,%d\n", p.x(), p.y());
768 Parent::mousePressEvent(e);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700769}
770
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700771void ConfigList::mouseReleaseEvent(QMouseEvent* e)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700772{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700773 QPoint p = e->pos();
774 ConfigItem* item = (ConfigItem*)itemAt(p);
775 struct menu *menu;
776 enum prop_type ptype;
777 QIcon icon;
778 int idx, x;
779
780 if (!item)
781 goto skip;
782
783 menu = item->menu;
784 x = header()->offset() + p.x();
Boris Barbulovski76d53cb2015-09-22 11:36:35 -0700785 idx = header()->logicalIndexAt(x);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700786 switch (idx) {
787 case promptColIdx:
Masahiro Yamada711b8752020-08-07 18:19:03 +0900788 icon = item->icon(promptColIdx);
Boris Barbulovski76d53cb2015-09-22 11:36:35 -0700789 if (!icon.isNull()) {
790 int off = header()->sectionPosition(0) + visualRect(indexAt(p)).x() + 4; // 4 is Hardcoded image offset. There might be a way to do it properly.
791 if (x >= off && x < off + icon.availableSizes().first().width()) {
792 if (item->goParent) {
793 emit parentSelected();
794 break;
795 } else if (!menu)
796 break;
797 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
798 if (ptype == P_MENU && rootEntry != menu &&
Maxime Chretien7eb7c106f2020-07-08 15:32:15 +0200799 mode != fullMode && mode != menuMode &&
800 mode != listMode)
Boris Barbulovski76d53cb2015-09-22 11:36:35 -0700801 emit menuSelected(menu);
802 else
803 changeValue(item);
804 }
805 }
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700806 break;
807 case noColIdx:
808 setValue(item, no);
809 break;
810 case modColIdx:
811 setValue(item, mod);
812 break;
813 case yesColIdx:
814 setValue(item, yes);
815 break;
816 case dataColIdx:
817 changeValue(item);
818 break;
819 }
820
821skip:
822 //printf("contentsMouseReleaseEvent: %d,%d\n", p.x(), p.y());
823 Parent::mouseReleaseEvent(e);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700824}
825
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700826void ConfigList::mouseMoveEvent(QMouseEvent* e)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700827{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700828 //QPoint p(contentsToViewport(e->pos()));
829 //printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y());
830 Parent::mouseMoveEvent(e);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700831}
832
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700833void ConfigList::mouseDoubleClickEvent(QMouseEvent* e)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700834{
Mauro Carvalho Chehabe1f77692020-04-02 11:28:02 +0200835 QPoint p = e->pos();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700836 ConfigItem* item = (ConfigItem*)itemAt(p);
837 struct menu *menu;
838 enum prop_type ptype;
839
840 if (!item)
841 goto skip;
842 if (item->goParent) {
843 emit parentSelected();
844 goto skip;
845 }
846 menu = item->menu;
847 if (!menu)
848 goto skip;
849 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
Maxime Chretien7eb7c106f2020-07-08 15:32:15 +0200850 if (ptype == P_MENU && mode != listMode) {
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +0200851 if (mode == singleMode)
852 emit itemSelected(menu);
853 else if (mode == symbolMode)
854 emit menuSelected(menu);
855 } else if (menu->sym)
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700856 changeValue(item);
857
858skip:
859 //printf("contentsMouseDoubleClickEvent: %d,%d\n", p.x(), p.y());
860 Parent::mouseDoubleClickEvent(e);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700861}
862
863void ConfigList::focusInEvent(QFocusEvent *e)
864{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700865 struct menu *menu = NULL;
866
867 Parent::focusInEvent(e);
868
869 ConfigItem* item = (ConfigItem *)currentItem();
870 if (item) {
Mauro Carvalho Chehabb06c3ec2020-06-30 08:26:38 +0200871 setSelected(item, true);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700872 menu = item->menu;
873 }
874 emit gotFocus(menu);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700875}
876
877void ConfigList::contextMenuEvent(QContextMenuEvent *e)
878{
Masahiro Yamadafa8de0a2020-08-07 18:19:08 +0900879 if (!headerPopup) {
880 QAction *action;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700881
Masahiro Yamadafa8de0a2020-08-07 18:19:08 +0900882 headerPopup = new QMenu(this);
883 action = new QAction("Show Name", this);
884 action->setCheckable(true);
885 connect(action, SIGNAL(toggled(bool)),
886 parent(), SLOT(setShowName(bool)));
887 connect(parent(), SIGNAL(showNameChanged(bool)),
Masahiro Yamadad85de332020-08-18 01:36:29 +0900888 action, SLOT(setChecked(bool)));
Masahiro Yamadafa8de0a2020-08-07 18:19:08 +0900889 action->setChecked(showName);
890 headerPopup->addAction(action);
891
892 action = new QAction("Show Range", this);
893 action->setCheckable(true);
894 connect(action, SIGNAL(toggled(bool)),
895 parent(), SLOT(setShowRange(bool)));
896 connect(parent(), SIGNAL(showRangeChanged(bool)),
Masahiro Yamadad85de332020-08-18 01:36:29 +0900897 action, SLOT(setChecked(bool)));
Masahiro Yamadafa8de0a2020-08-07 18:19:08 +0900898 action->setChecked(showRange);
899 headerPopup->addAction(action);
900
901 action = new QAction("Show Data", this);
902 action->setCheckable(true);
903 connect(action, SIGNAL(toggled(bool)),
904 parent(), SLOT(setShowData(bool)));
905 connect(parent(), SIGNAL(showDataChanged(bool)),
Masahiro Yamadad85de332020-08-18 01:36:29 +0900906 action, SLOT(setChecked(bool)));
Masahiro Yamadafa8de0a2020-08-07 18:19:08 +0900907 action->setChecked(showData);
908 headerPopup->addAction(action);
909 }
910
911 headerPopup->exec(e->globalPos());
912 e->accept();
Boris Barbulovski59e56442015-09-22 11:36:18 -0700913}
914
Li Zefan39a48972010-05-10 16:33:41 +0800915ConfigView*ConfigView::viewList;
Masahiro Yamadad4bbe8a2020-08-07 18:19:09 +0900916QAction *ConfigList::showNormalAction;
917QAction *ConfigList::showAllAction;
918QAction *ConfigList::showPromptAction;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700919
Roman Zippel7fc925f2006-06-08 22:12:46 -0700920ConfigView::ConfigView(QWidget* parent, const char *name)
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -0700921 : Parent(parent)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700922{
Boris Barbulovski9bd36ed2015-09-22 11:36:22 -0700923 setObjectName(name);
Boris Barbulovski29a70162015-09-22 11:36:10 -0700924 QVBoxLayout *verticalLayout = new QVBoxLayout(this);
Boris Barbulovski92298b42015-09-22 11:36:11 -0700925 verticalLayout->setContentsMargins(0, 0, 0, 0);
Boris Barbulovski29a70162015-09-22 11:36:10 -0700926
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700927 list = new ConfigList(this);
Boris Barbulovski29a70162015-09-22 11:36:10 -0700928 verticalLayout->addWidget(list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700929 lineEdit = new ConfigLineEdit(this);
930 lineEdit->hide();
Boris Barbulovski29a70162015-09-22 11:36:10 -0700931 verticalLayout->addWidget(lineEdit);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700932
933 this->nextView = viewList;
934 viewList = this;
935}
936
937ConfigView::~ConfigView(void)
938{
939 ConfigView** vp;
940
941 for (vp = &viewList; *vp; vp = &(*vp)->nextView) {
942 if (*vp == this) {
943 *vp = nextView;
944 break;
945 }
946 }
947}
948
Roman Zippel7fc925f2006-06-08 22:12:46 -0700949void ConfigView::setShowName(bool b)
950{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700951 if (list->showName != b) {
952 list->showName = b;
953 list->reinit();
954 emit showNameChanged(b);
955 }
Roman Zippel7fc925f2006-06-08 22:12:46 -0700956}
957
958void ConfigView::setShowRange(bool b)
959{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700960 if (list->showRange != b) {
961 list->showRange = b;
962 list->reinit();
963 emit showRangeChanged(b);
964 }
Roman Zippel7fc925f2006-06-08 22:12:46 -0700965}
966
967void ConfigView::setShowData(bool b)
968{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700969 if (list->showData != b) {
970 list->showData = b;
971 list->reinit();
972 emit showDataChanged(b);
973 }
974}
975
976void ConfigList::setAllOpen(bool open)
977{
978 QTreeWidgetItemIterator it(this);
979
980 while (*it) {
981 (*it)->setExpanded(open);
982
983 ++it;
984 }
Roman Zippel7fc925f2006-06-08 22:12:46 -0700985}
986
Masahiro Yamada10316852020-08-07 18:19:00 +0900987void ConfigView::updateList()
Roman Zippel7fc925f2006-06-08 22:12:46 -0700988{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700989 ConfigView* v;
990
991 for (v = viewList; v; v = v->nextView)
Masahiro Yamadacb770432020-08-07 18:18:59 +0900992 v->list->updateList();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700993}
994
995void ConfigView::updateListAll(void)
996{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700997 ConfigView* v;
998
999 for (v = viewList; v; v = v->nextView)
1000 v->list->updateListAll();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001001}
1002
Roman Zippel43bf6122006-06-08 22:12:45 -07001003ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name)
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001004 : Parent(parent), sym(0), _menu(0)
Roman Zippel43bf6122006-06-08 22:12:45 -07001005{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001006 setObjectName(name);
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001007 setOpenLinks(false);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001008
1009 if (!objectName().isEmpty()) {
1010 configSettings->beginGroup(objectName());
Boris Barbulovskie0393032016-11-30 14:57:52 -08001011 setShowDebug(configSettings->value("/showDebug", false).toBool());
Roman Zippel7fc925f2006-06-08 22:12:46 -07001012 configSettings->endGroup();
1013 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
1014 }
Masahiro Yamada7d1300e2020-08-18 01:36:30 +09001015
1016 contextMenu = createStandardContextMenu();
1017 QAction *action = new QAction("Show Debug Info", contextMenu);
1018
1019 action->setCheckable(true);
1020 connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
1021 connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setChecked(bool)));
1022 action->setChecked(showDebug());
1023 contextMenu->addSeparator();
1024 contextMenu->addAction(action);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001025}
1026
1027void ConfigInfoView::saveSettings(void)
1028{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001029 if (!objectName().isEmpty()) {
1030 configSettings->beginGroup(objectName());
1031 configSettings->setValue("/showDebug", showDebug());
1032 configSettings->endGroup();
1033 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001034}
1035
1036void ConfigInfoView::setShowDebug(bool b)
1037{
1038 if (_showDebug != b) {
1039 _showDebug = b;
Alexander Stein133c5f72010-08-31 17:34:37 +02001040 if (_menu)
Roman Zippel43bf6122006-06-08 22:12:45 -07001041 menuInfo();
Roman Zippelab45d192006-06-08 22:12:47 -07001042 else if (sym)
1043 symbolInfo();
Roman Zippel43bf6122006-06-08 22:12:45 -07001044 emit showDebugChanged(b);
1045 }
1046}
1047
1048void ConfigInfoView::setInfo(struct menu *m)
1049{
Alexander Stein133c5f72010-08-31 17:34:37 +02001050 if (_menu == m)
Roman Zippelb65a47e2006-06-08 22:12:47 -07001051 return;
Alexander Stein133c5f72010-08-31 17:34:37 +02001052 _menu = m;
Roman Zippel6fa1da82007-01-10 23:15:31 -08001053 sym = NULL;
Alexander Stein133c5f72010-08-31 17:34:37 +02001054 if (!_menu)
Roman Zippel43bf6122006-06-08 22:12:45 -07001055 clear();
Roman Zippel6fa1da82007-01-10 23:15:31 -08001056 else
Roman Zippel43bf6122006-06-08 22:12:45 -07001057 menuInfo();
1058}
1059
Roman Zippelab45d192006-06-08 22:12:47 -07001060void ConfigInfoView::symbolInfo(void)
1061{
1062 QString str;
1063
1064 str += "<big>Symbol: <b>";
1065 str += print_filter(sym->name);
1066 str += "</b></big><br><br>value: ";
1067 str += print_filter(sym_get_string_value(sym));
1068 str += "<br>visibility: ";
1069 str += sym->visible == yes ? "y" : sym->visible == mod ? "m" : "n";
1070 str += "<br>";
1071 str += debug_info(sym);
1072
1073 setText(str);
1074}
1075
Roman Zippel43bf6122006-06-08 22:12:45 -07001076void ConfigInfoView::menuInfo(void)
1077{
1078 struct symbol* sym;
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001079 QString info;
1080 QTextStream stream(&info);
Roman Zippel43bf6122006-06-08 22:12:45 -07001081
Alexander Stein133c5f72010-08-31 17:34:37 +02001082 sym = _menu->sym;
Roman Zippel43bf6122006-06-08 22:12:45 -07001083 if (sym) {
Alexander Stein133c5f72010-08-31 17:34:37 +02001084 if (_menu->prompt) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001085 stream << "<big><b>";
1086 stream << print_filter(_menu->prompt->text);
1087 stream << "</b></big>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001088 if (sym->name) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001089 stream << " (";
Roman Zippelab45d192006-06-08 22:12:47 -07001090 if (showDebug())
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001091 stream << "<a href=\"s" << sym->name << "\">";
1092 stream << print_filter(sym->name);
Roman Zippelab45d192006-06-08 22:12:47 -07001093 if (showDebug())
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001094 stream << "</a>";
1095 stream << ")";
Roman Zippel43bf6122006-06-08 22:12:45 -07001096 }
1097 } else if (sym->name) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001098 stream << "<big><b>";
Roman Zippelab45d192006-06-08 22:12:47 -07001099 if (showDebug())
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001100 stream << "<a href=\"s" << sym->name << "\">";
1101 stream << print_filter(sym->name);
Roman Zippelab45d192006-06-08 22:12:47 -07001102 if (showDebug())
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001103 stream << "</a>";
1104 stream << "</b></big>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001105 }
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001106 stream << "<br><br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001107
1108 if (showDebug())
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001109 stream << debug_info(sym);
1110
Masahiro Yamadaa46afd12020-09-14 23:59:48 +09001111 struct gstr help_gstr = str_new();
1112
1113 menu_get_ext_help(_menu, &help_gstr);
1114 stream << print_filter(str_get(&help_gstr));
1115 str_free(&help_gstr);
Alexander Stein133c5f72010-08-31 17:34:37 +02001116 } else if (_menu->prompt) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001117 stream << "<big><b>";
1118 stream << print_filter(_menu->prompt->text);
1119 stream << "</b></big><br><br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001120 if (showDebug()) {
Alexander Stein133c5f72010-08-31 17:34:37 +02001121 if (_menu->prompt->visible.expr) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001122 stream << "&nbsp;&nbsp;dep: ";
1123 expr_print(_menu->prompt->visible.expr,
1124 expr_print_help, &stream, E_NONE);
1125 stream << "<br><br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001126 }
Masahiro Yamadaa46afd12020-09-14 23:59:48 +09001127
1128 stream << "defined at " << _menu->file->name << ":"
1129 << _menu->lineno << "<br><br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001130 }
1131 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001132
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001133 setText(info);
Roman Zippel43bf6122006-06-08 22:12:45 -07001134}
1135
1136QString ConfigInfoView::debug_info(struct symbol *sym)
1137{
1138 QString debug;
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001139 QTextStream stream(&debug);
Roman Zippel43bf6122006-06-08 22:12:45 -07001140
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001141 stream << "type: ";
1142 stream << print_filter(sym_type_name(sym->type));
Roman Zippel43bf6122006-06-08 22:12:45 -07001143 if (sym_is_choice(sym))
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001144 stream << " (choice)";
Roman Zippel43bf6122006-06-08 22:12:45 -07001145 debug += "<br>";
1146 if (sym->rev_dep.expr) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001147 stream << "reverse dep: ";
1148 expr_print(sym->rev_dep.expr, expr_print_help, &stream, E_NONE);
1149 stream << "<br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001150 }
1151 for (struct property *prop = sym->prop; prop; prop = prop->next) {
1152 switch (prop->type) {
1153 case P_PROMPT:
1154 case P_MENU:
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001155 stream << "prompt: <a href=\"m" << sym->name << "\">";
1156 stream << print_filter(prop->text);
1157 stream << "</a><br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001158 break;
1159 case P_DEFAULT:
Roman Zippel93449082008-01-14 04:50:54 +01001160 case P_SELECT:
1161 case P_RANGE:
Mauro Carvalho Chehab8f8499a2020-06-30 08:48:53 +02001162 case P_COMMENT:
1163 case P_IMPLY:
1164 case P_SYMBOL:
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001165 stream << prop_get_type_name(prop->type);
1166 stream << ": ";
1167 expr_print(prop->expr, expr_print_help,
1168 &stream, E_NONE);
1169 stream << "<br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001170 break;
1171 case P_CHOICE:
1172 if (sym_is_choice(sym)) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001173 stream << "choice: ";
1174 expr_print(prop->expr, expr_print_help,
1175 &stream, E_NONE);
1176 stream << "<br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001177 }
1178 break;
Roman Zippel43bf6122006-06-08 22:12:45 -07001179 default:
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001180 stream << "unknown property: ";
1181 stream << prop_get_type_name(prop->type);
1182 stream << "<br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001183 }
1184 if (prop->visible.expr) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001185 stream << "&nbsp;&nbsp;&nbsp;&nbsp;dep: ";
1186 expr_print(prop->visible.expr, expr_print_help,
1187 &stream, E_NONE);
1188 stream << "<br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001189 }
1190 }
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001191 stream << "<br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001192
1193 return debug;
1194}
1195
1196QString ConfigInfoView::print_filter(const QString &str)
1197{
1198 QRegExp re("[<>&\"\\n]");
1199 QString res = str;
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001200 for (int i = 0; (i = res.indexOf(re, i)) >= 0;) {
1201 switch (res[i].toLatin1()) {
Roman Zippel43bf6122006-06-08 22:12:45 -07001202 case '<':
1203 res.replace(i, 1, "&lt;");
1204 i += 4;
1205 break;
1206 case '>':
1207 res.replace(i, 1, "&gt;");
1208 i += 4;
1209 break;
1210 case '&':
1211 res.replace(i, 1, "&amp;");
1212 i += 5;
1213 break;
1214 case '"':
1215 res.replace(i, 1, "&quot;");
1216 i += 6;
1217 break;
1218 case '\n':
1219 res.replace(i, 1, "<br>");
1220 i += 4;
1221 break;
1222 }
1223 }
1224 return res;
1225}
1226
Roman Zippelab45d192006-06-08 22:12:47 -07001227void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char *str)
Roman Zippel43bf6122006-06-08 22:12:45 -07001228{
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001229 QTextStream *stream = reinterpret_cast<QTextStream *>(data);
Roman Zippelab45d192006-06-08 22:12:47 -07001230
1231 if (sym && sym->name && !(sym->flags & SYMBOL_CONST)) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001232 *stream << "<a href=\"s" << sym->name << "\">";
1233 *stream << print_filter(str);
1234 *stream << "</a>";
1235 } else {
1236 *stream << print_filter(str);
1237 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001238}
1239
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001240void ConfigInfoView::clicked(const QUrl &url)
1241{
1242 QByteArray str = url.toEncoded();
1243 const std::size_t count = str.size();
1244 char *data = new char[count + 1];
1245 struct symbol **result;
1246 struct menu *m = NULL;
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001247
1248 if (count < 1) {
Masahiro Yamadac9b09a922020-07-30 02:02:39 +09001249 delete[] data;
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001250 return;
1251 }
1252
1253 memcpy(data, str.constData(), count);
1254 data[count] = '\0';
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001255
1256 /* Seek for exact match */
1257 data[0] = '^';
1258 strcat(data, "$");
1259 result = sym_re_search(data);
1260 if (!result) {
Masahiro Yamadac9b09a922020-07-30 02:02:39 +09001261 delete[] data;
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001262 return;
1263 }
1264
1265 sym = *result;
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001266
Mauro Carvalho Chehab8a3b6e52020-06-30 08:48:35 +02001267 /* Seek for the menu which holds the symbol */
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001268 for (struct property *prop = sym->prop; prop; prop = prop->next) {
1269 if (prop->type != P_PROMPT && prop->type != P_MENU)
1270 continue;
1271 m = prop->menu;
1272 break;
1273 }
1274
1275 if (!m) {
Mauro Carvalho Chehab8a3b6e52020-06-30 08:48:35 +02001276 /* Symbol is not visible as a menu */
1277 symbolInfo();
1278 emit showDebugChanged(true);
1279 } else {
1280 emit menuSelected(m);
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001281 }
1282
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001283 free(result);
Masahiro Yamadaa608b6a2020-09-09 07:16:37 +09001284 delete[] data;
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001285}
1286
Masahiro Yamada7d1300e2020-08-18 01:36:30 +09001287void ConfigInfoView::contextMenuEvent(QContextMenuEvent *event)
Roman Zippel7fc925f2006-06-08 22:12:46 -07001288{
Masahiro Yamada7d1300e2020-08-18 01:36:30 +09001289 contextMenu->popup(event->globalPos());
1290 event->accept();
Roman Zippel7fc925f2006-06-08 22:12:46 -07001291}
1292
Masahiro Yamada740fdef2020-08-07 18:18:57 +09001293ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow *parent)
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001294 : Parent(parent), result(NULL)
Roman Zippel43bf6122006-06-08 22:12:45 -07001295{
Masahiro Yamada740fdef2020-08-07 18:18:57 +09001296 setObjectName("search");
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001297 setWindowTitle("Search Config");
Roman Zippel43bf6122006-06-08 22:12:45 -07001298
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001299 QVBoxLayout* layout1 = new QVBoxLayout(this);
1300 layout1->setContentsMargins(11, 11, 11, 11);
1301 layout1->setSpacing(6);
Masahiro Yamada92641152020-08-07 18:18:58 +09001302
1303 QHBoxLayout* layout2 = new QHBoxLayout();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001304 layout2->setContentsMargins(0, 0, 0, 0);
1305 layout2->setSpacing(6);
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001306 layout2->addWidget(new QLabel("Find:", this));
Roman Zippel43bf6122006-06-08 22:12:45 -07001307 editField = new QLineEdit(this);
1308 connect(editField, SIGNAL(returnPressed()), SLOT(search()));
1309 layout2->addWidget(editField);
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001310 searchButton = new QPushButton("Search", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001311 searchButton->setAutoDefault(false);
Roman Zippel43bf6122006-06-08 22:12:45 -07001312 connect(searchButton, SIGNAL(clicked()), SLOT(search()));
1313 layout2->addWidget(searchButton);
1314 layout1->addLayout(layout2);
1315
Roman Zippel7fc925f2006-06-08 22:12:46 -07001316 split = new QSplitter(this);
Markus Heidelberg7298b932009-05-18 01:36:50 +02001317 split->setOrientation(Qt::Vertical);
Masahiro Yamada740fdef2020-08-07 18:18:57 +09001318 list = new ConfigView(split, "search");
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001319 list->list->mode = listMode;
Masahiro Yamada740fdef2020-08-07 18:18:57 +09001320 info = new ConfigInfoView(split, "search");
Roman Zippel43bf6122006-06-08 22:12:45 -07001321 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1322 info, SLOT(setInfo(struct menu *)));
Marco Costalba63431e72006-10-05 19:12:59 +02001323 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1324 parent, SLOT(setMenuLink(struct menu *)));
1325
Roman Zippel43bf6122006-06-08 22:12:45 -07001326 layout1->addWidget(split);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001327
Masahiro Yamada740fdef2020-08-07 18:18:57 +09001328 QVariant x, y;
1329 int width, height;
1330 bool ok;
Roman Zippel7fc925f2006-06-08 22:12:46 -07001331
Masahiro Yamada740fdef2020-08-07 18:18:57 +09001332 configSettings->beginGroup("search");
1333 width = configSettings->value("/window width", parent->width() / 2).toInt();
1334 height = configSettings->value("/window height", parent->height() / 2).toInt();
1335 resize(width, height);
1336 x = configSettings->value("/window x");
1337 y = configSettings->value("/window y");
1338 if (x.isValid() && y.isValid())
1339 move(x.toInt(), y.toInt());
1340 QList<int> sizes = configSettings->readSizes("/split", &ok);
1341 if (ok)
1342 split->setSizes(sizes);
1343 configSettings->endGroup();
1344 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
Roman Zippel7fc925f2006-06-08 22:12:46 -07001345}
1346
1347void ConfigSearchWindow::saveSettings(void)
1348{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001349 if (!objectName().isEmpty()) {
1350 configSettings->beginGroup(objectName());
1351 configSettings->setValue("/window x", pos().x());
1352 configSettings->setValue("/window y", pos().y());
1353 configSettings->setValue("/window width", size().width());
1354 configSettings->setValue("/window height", size().height());
1355 configSettings->writeSizes("/split", split->sizes());
1356 configSettings->endGroup();
1357 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001358}
1359
1360void ConfigSearchWindow::search(void)
1361{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001362 struct symbol **p;
1363 struct property *prop;
1364 ConfigItem *lastItem = NULL;
1365
1366 free(result);
1367 list->list->clear();
1368 info->clear();
1369
1370 result = sym_re_search(editField->text().toLatin1());
1371 if (!result)
1372 return;
1373 for (p = result; *p; p++) {
1374 for_all_prompts((*p), prop)
1375 lastItem = new ConfigItem(list->list, lastItem, prop->menu,
1376 menu_is_visible(prop->menu));
1377 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001378}
1379
Linus Torvalds1da177e2005-04-16 15:20:36 -07001380/*
1381 * Construct the complete config widget
1382 */
1383ConfigMainWindow::ConfigMainWindow(void)
Roman Zippelf12aa702006-11-25 11:09:31 -08001384 : searchWindow(0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001385{
Boris Barbulovski92119932015-09-22 11:36:16 -07001386 bool ok = true;
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001387 QVariant x, y;
1388 int width, height;
Randy Dunlapa54bb702007-10-20 11:18:47 -07001389 char title[256];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001390
Markus Heidelberg8d90c972009-05-18 01:36:52 +02001391 QDesktopWidget *d = configApp->desktop();
Arnaud Lacombe09548282010-08-18 01:57:13 -04001392 snprintf(title, sizeof(title), "%s%s",
1393 rootmenu.prompt->text,
Michal Marek76a136c2010-09-01 17:39:27 +02001394 ""
Michal Marek76a136c2010-09-01 17:39:27 +02001395 );
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001396 setWindowTitle(title);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001397
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001398 width = configSettings->value("/window width", d->width() - 64).toInt();
1399 height = configSettings->value("/window height", d->height() - 64).toInt();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001400 resize(width, height);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001401 x = configSettings->value("/window x");
1402 y = configSettings->value("/window y");
1403 if ((x.isValid())&&(y.isValid()))
1404 move(x.toInt(), y.toInt());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001405
Masahiro Yamada5cb255f2020-08-07 18:19:07 +09001406 // set up icons
1407 ConfigItem::symbolYesIcon = QIcon(QPixmap(xpm_symbol_yes));
1408 ConfigItem::symbolModIcon = QIcon(QPixmap(xpm_symbol_mod));
1409 ConfigItem::symbolNoIcon = QIcon(QPixmap(xpm_symbol_no));
1410 ConfigItem::choiceYesIcon = QIcon(QPixmap(xpm_choice_yes));
1411 ConfigItem::choiceNoIcon = QIcon(QPixmap(xpm_choice_no));
1412 ConfigItem::menuIcon = QIcon(QPixmap(xpm_menu));
1413 ConfigItem::menubackIcon = QIcon(QPixmap(xpm_menuback));
1414
Mauro Carvalho Chehabcce1fab2020-04-02 11:28:00 +02001415 QWidget *widget = new QWidget(this);
1416 QVBoxLayout *layout = new QVBoxLayout(widget);
1417 setCentralWidget(widget);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001418
Mauro Carvalho Chehabcce1fab2020-04-02 11:28:00 +02001419 split1 = new QSplitter(widget);
1420 split1->setOrientation(Qt::Horizontal);
1421 split1->setChildrenCollapsible(false);
1422
1423 menuView = new ConfigView(widget, "menu");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001424 menuList = menuView->list;
1425
Mauro Carvalho Chehabcce1fab2020-04-02 11:28:00 +02001426 split2 = new QSplitter(widget);
1427 split2->setChildrenCollapsible(false);
Markus Heidelberg7298b932009-05-18 01:36:50 +02001428 split2->setOrientation(Qt::Vertical);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001429
1430 // create config tree
Mauro Carvalho Chehabcce1fab2020-04-02 11:28:00 +02001431 configView = new ConfigView(widget, "config");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001432 configList = configView->list;
1433
Mauro Carvalho Chehabcce1fab2020-04-02 11:28:00 +02001434 helpText = new ConfigInfoView(widget, "help");
1435
1436 layout->addWidget(split2);
1437 split2->addWidget(split1);
1438 split1->addWidget(configView);
1439 split1->addWidget(menuView);
1440 split2->addWidget(helpText);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001441
1442 setTabOrder(configList, helpText);
1443 configList->setFocus();
1444
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001445 backAction = new QAction(QPixmap(xpm_back), "Back", this);
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001446 connect(backAction, SIGNAL(triggered(bool)), SLOT(goBack()));
1447
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001448 QAction *quitAction = new QAction("&Quit", this);
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001449 quitAction->setShortcut(Qt::CTRL + Qt::Key_Q);
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001450 connect(quitAction, SIGNAL(triggered(bool)), SLOT(close()));
1451
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001452 QAction *loadAction = new QAction(QPixmap(xpm_load), "&Load", this);
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001453 loadAction->setShortcut(Qt::CTRL + Qt::Key_L);
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001454 connect(loadAction, SIGNAL(triggered(bool)), SLOT(loadConfig()));
1455
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001456 saveAction = new QAction(QPixmap(xpm_save), "&Save", this);
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001457 saveAction->setShortcut(Qt::CTRL + Qt::Key_S);
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001458 connect(saveAction, SIGNAL(triggered(bool)), SLOT(saveConfig()));
1459
Karsten Wiese3b354c52006-12-13 00:34:08 -08001460 conf_set_changed_callback(conf_changed);
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001461
Karsten Wiese3b354c52006-12-13 00:34:08 -08001462 // Set saveAction's initial state
1463 conf_changed();
Masahiro Yamada87419082019-03-11 01:13:15 +09001464 configname = xstrdup(conf_get_configname());
1465
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001466 QAction *saveAsAction = new QAction("Save &As...", this);
Boris Barbulovski92119932015-09-22 11:36:16 -07001467 connect(saveAsAction, SIGNAL(triggered(bool)), SLOT(saveConfigAs()));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001468 QAction *searchAction = new QAction("&Find", this);
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001469 searchAction->setShortcut(Qt::CTRL + Qt::Key_F);
Boris Barbulovski92119932015-09-22 11:36:16 -07001470 connect(searchAction, SIGNAL(triggered(bool)), SLOT(searchConfig()));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001471 singleViewAction = new QAction(QPixmap(xpm_single_view), "Single View", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001472 singleViewAction->setCheckable(true);
Boris Barbulovski92119932015-09-22 11:36:16 -07001473 connect(singleViewAction, SIGNAL(triggered(bool)), SLOT(showSingleView()));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001474 splitViewAction = new QAction(QPixmap(xpm_split_view), "Split View", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001475 splitViewAction->setCheckable(true);
Boris Barbulovski92119932015-09-22 11:36:16 -07001476 connect(splitViewAction, SIGNAL(triggered(bool)), SLOT(showSplitView()));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001477 fullViewAction = new QAction(QPixmap(xpm_tree_view), "Full View", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001478 fullViewAction->setCheckable(true);
Boris Barbulovski92119932015-09-22 11:36:16 -07001479 connect(fullViewAction, SIGNAL(triggered(bool)), SLOT(showFullView()));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001480
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001481 QAction *showNameAction = new QAction("Show Name", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001482 showNameAction->setCheckable(true);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001483 connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool)));
Boris Barbulovski9c862352015-09-22 11:36:12 -07001484 showNameAction->setChecked(configView->showName());
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001485 QAction *showRangeAction = new QAction("Show Range", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001486 showRangeAction->setCheckable(true);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001487 connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool)));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001488 QAction *showDataAction = new QAction("Show Data", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001489 showDataAction->setCheckable(true);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001490 connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool)));
Li Zefan39a48972010-05-10 16:33:41 +08001491
1492 QActionGroup *optGroup = new QActionGroup(this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001493 optGroup->setExclusive(true);
Masahiro Yamadad4bbe8a2020-08-07 18:19:09 +09001494 connect(optGroup, SIGNAL(triggered(QAction*)), configList,
Li Zefan39a48972010-05-10 16:33:41 +08001495 SLOT(setOptionMode(QAction *)));
Masahiro Yamadad4bbe8a2020-08-07 18:19:09 +09001496 connect(optGroup, SIGNAL(triggered(QAction *)), menuList,
Li Zefan39a48972010-05-10 16:33:41 +08001497 SLOT(setOptionMode(QAction *)));
1498
Masahiro Yamadad4bbe8a2020-08-07 18:19:09 +09001499 ConfigList::showNormalAction = new QAction("Show Normal Options", optGroup);
1500 ConfigList::showNormalAction->setCheckable(true);
1501 ConfigList::showAllAction = new QAction("Show All Options", optGroup);
1502 ConfigList::showAllAction->setCheckable(true);
1503 ConfigList::showPromptAction = new QAction("Show Prompt Options", optGroup);
1504 ConfigList::showPromptAction->setCheckable(true);
Li Zefan39a48972010-05-10 16:33:41 +08001505
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001506 QAction *showDebugAction = new QAction("Show Debug Info", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001507 showDebugAction->setCheckable(true);
Roman Zippel43bf6122006-06-08 22:12:45 -07001508 connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
Boris Barbulovski9c862352015-09-22 11:36:12 -07001509 showDebugAction->setChecked(helpText->showDebug());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001510
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001511 QAction *showIntroAction = new QAction("Introduction", this);
Boris Barbulovski92119932015-09-22 11:36:16 -07001512 connect(showIntroAction, SIGNAL(triggered(bool)), SLOT(showIntro()));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001513 QAction *showAboutAction = new QAction("About", this);
Boris Barbulovski92119932015-09-22 11:36:16 -07001514 connect(showAboutAction, SIGNAL(triggered(bool)), SLOT(showAbout()));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001515
1516 // init tool bar
Masahiro Yamada860ec3f2020-08-07 18:18:55 +09001517 QToolBar *toolBar = addToolBar("Tools");
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001518 toolBar->addAction(backAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001519 toolBar->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001520 toolBar->addAction(loadAction);
1521 toolBar->addAction(saveAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001522 toolBar->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001523 toolBar->addAction(singleViewAction);
1524 toolBar->addAction(splitViewAction);
1525 toolBar->addAction(fullViewAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001526
Masahiro Yamada93ebaac2020-08-07 18:18:53 +09001527 // create file menu
1528 QMenu *menu = menuBar()->addMenu("&File");
1529 menu->addAction(loadAction);
1530 menu->addAction(saveAction);
1531 menu->addAction(saveAsAction);
1532 menu->addSeparator();
1533 menu->addAction(quitAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001534
Shlomi Fish66e7c722007-02-14 00:32:58 -08001535 // create edit menu
Masahiro Yamada93ebaac2020-08-07 18:18:53 +09001536 menu = menuBar()->addMenu("&Edit");
1537 menu->addAction(searchAction);
Shlomi Fish66e7c722007-02-14 00:32:58 -08001538
Linus Torvalds1da177e2005-04-16 15:20:36 -07001539 // create options menu
Masahiro Yamada93ebaac2020-08-07 18:18:53 +09001540 menu = menuBar()->addMenu("&Option");
1541 menu->addAction(showNameAction);
1542 menu->addAction(showRangeAction);
1543 menu->addAction(showDataAction);
1544 menu->addSeparator();
1545 menu->addActions(optGroup->actions());
1546 menu->addSeparator();
1547 menu->addAction(showDebugAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001548
1549 // create help menu
Masahiro Yamada93ebaac2020-08-07 18:18:53 +09001550 menu = menuBar()->addMenu("&Help");
1551 menu->addAction(showIntroAction);
1552 menu->addAction(showAboutAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001553
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001554 connect (helpText, SIGNAL (anchorClicked (const QUrl &)),
1555 helpText, SLOT (clicked (const QUrl &)) );
1556
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001557 connect(configList, SIGNAL(menuChanged(struct menu *)),
1558 helpText, SLOT(setInfo(struct menu *)));
1559 connect(configList, SIGNAL(menuSelected(struct menu *)),
1560 SLOT(changeMenu(struct menu *)));
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +02001561 connect(configList, SIGNAL(itemSelected(struct menu *)),
1562 SLOT(changeItens(struct menu *)));
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001563 connect(configList, SIGNAL(parentSelected()),
1564 SLOT(goBack()));
1565 connect(menuList, SIGNAL(menuChanged(struct menu *)),
1566 helpText, SLOT(setInfo(struct menu *)));
1567 connect(menuList, SIGNAL(menuSelected(struct menu *)),
1568 SLOT(changeMenu(struct menu *)));
1569
1570 connect(configList, SIGNAL(gotFocus(struct menu *)),
1571 helpText, SLOT(setInfo(struct menu *)));
1572 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1573 helpText, SLOT(setInfo(struct menu *)));
1574 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1575 SLOT(listFocusChanged(void)));
Roman Zippelb65a47e2006-06-08 22:12:47 -07001576 connect(helpText, SIGNAL(menuSelected(struct menu *)),
1577 SLOT(setMenuLink(struct menu *)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001578
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001579 QString listMode = configSettings->value("/listMode", "symbol").toString();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001580 if (listMode == "single")
1581 showSingleView();
1582 else if (listMode == "full")
1583 showFullView();
1584 else /*if (listMode == "split")*/
1585 showSplitView();
1586
1587 // UI setup done, restore splitter positions
Boris Barbulovski041fbdc2015-09-22 11:36:05 -07001588 QList<int> sizes = configSettings->readSizes("/split1", &ok);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001589 if (ok)
1590 split1->setSizes(sizes);
1591
Roman Zippel7fc925f2006-06-08 22:12:46 -07001592 sizes = configSettings->readSizes("/split2", &ok);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001593 if (ok)
1594 split2->setSizes(sizes);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001595}
1596
Linus Torvalds1da177e2005-04-16 15:20:36 -07001597void ConfigMainWindow::loadConfig(void)
1598{
Masahiro Yamada87419082019-03-11 01:13:15 +09001599 QString str;
1600 QByteArray ba;
1601 const char *name;
1602
1603 str = QFileDialog::getOpenFileName(this, "", configname);
1604 if (str.isNull())
Linus Torvalds1da177e2005-04-16 15:20:36 -07001605 return;
Masahiro Yamada87419082019-03-11 01:13:15 +09001606
1607 ba = str.toLocal8Bit();
1608 name = ba.data();
1609
1610 if (conf_read(name))
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001611 QMessageBox::information(this, "qconf", "Unable to load configuration!");
Masahiro Yamada87419082019-03-11 01:13:15 +09001612
1613 free(configname);
1614 configname = xstrdup(name);
1615
Linus Torvalds1da177e2005-04-16 15:20:36 -07001616 ConfigView::updateListAll();
1617}
1618
Michal Marekbac6aa82011-05-25 15:10:25 +02001619bool ConfigMainWindow::saveConfig(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001620{
Masahiro Yamada87419082019-03-11 01:13:15 +09001621 if (conf_write(configname)) {
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001622 QMessageBox::information(this, "qconf", "Unable to save configuration!");
Michal Marekbac6aa82011-05-25 15:10:25 +02001623 return false;
1624 }
Masahiro Yamada00c864f2018-07-20 16:46:31 +09001625 conf_write_autoconf(0);
1626
Michal Marekbac6aa82011-05-25 15:10:25 +02001627 return true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001628}
1629
1630void ConfigMainWindow::saveConfigAs(void)
1631{
Masahiro Yamada87419082019-03-11 01:13:15 +09001632 QString str;
1633 QByteArray ba;
1634 const char *name;
1635
1636 str = QFileDialog::getSaveFileName(this, "", configname);
1637 if (str.isNull())
Linus Torvalds1da177e2005-04-16 15:20:36 -07001638 return;
Masahiro Yamada87419082019-03-11 01:13:15 +09001639
1640 ba = str.toLocal8Bit();
1641 name = ba.data();
1642
1643 if (conf_write(name)) {
1644 QMessageBox::information(this, "qconf", "Unable to save configuration!");
1645 }
1646 conf_write_autoconf(0);
1647
1648 free(configname);
1649 configname = xstrdup(name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001650}
1651
Roman Zippel43bf6122006-06-08 22:12:45 -07001652void ConfigMainWindow::searchConfig(void)
1653{
1654 if (!searchWindow)
Masahiro Yamada740fdef2020-08-07 18:18:57 +09001655 searchWindow = new ConfigSearchWindow(this);
Roman Zippel43bf6122006-06-08 22:12:45 -07001656 searchWindow->show();
1657}
1658
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +02001659void ConfigMainWindow::changeItens(struct menu *menu)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001660{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001661 configList->setRootMenu(menu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001662}
1663
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +02001664void ConfigMainWindow::changeMenu(struct menu *menu)
1665{
1666 menuList->setRootMenu(menu);
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +02001667}
1668
Roman Zippelb65a47e2006-06-08 22:12:47 -07001669void ConfigMainWindow::setMenuLink(struct menu *menu)
1670{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001671 struct menu *parent;
1672 ConfigList* list = NULL;
1673 ConfigItem* item;
1674
1675 if (configList->menuSkip(menu))
1676 return;
1677
1678 switch (configList->mode) {
1679 case singleMode:
1680 list = configList;
1681 parent = menu_get_parent_menu(menu);
1682 if (!parent)
1683 return;
1684 list->setRootMenu(parent);
1685 break;
Mauro Carvalho Chehabc699eaa2020-06-30 08:26:36 +02001686 case menuMode:
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001687 if (menu->flags & MENU_ROOT) {
Mauro Carvalho Chehabc699eaa2020-06-30 08:26:36 +02001688 menuList->setRootMenu(menu);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001689 configList->clearSelection();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001690 list = configList;
Mauro Carvalho Chehabc699eaa2020-06-30 08:26:36 +02001691 } else {
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001692 parent = menu_get_parent_menu(menu->parent);
1693 if (!parent)
1694 return;
Mauro Carvalho Chehabc699eaa2020-06-30 08:26:36 +02001695
Mauro Carvalho Chehabc699eaa2020-06-30 08:26:36 +02001696 /* Select the config view */
1697 item = configList->findConfigItem(parent);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001698 if (item) {
Mauro Carvalho Chehabb06c3ec2020-06-30 08:26:38 +02001699 configList->setSelected(item, true);
Mauro Carvalho Chehabc699eaa2020-06-30 08:26:36 +02001700 configList->scrollToItem(item);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001701 }
Mauro Carvalho Chehabc699eaa2020-06-30 08:26:36 +02001702
1703 menuList->setRootMenu(parent);
1704 menuList->clearSelection();
1705 list = menuList;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001706 }
1707 break;
1708 case fullMode:
1709 list = configList;
1710 break;
1711 default:
1712 break;
1713 }
1714
1715 if (list) {
1716 item = list->findConfigItem(menu);
1717 if (item) {
Mauro Carvalho Chehabb06c3ec2020-06-30 08:26:38 +02001718 list->setSelected(item, true);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001719 list->scrollToItem(item);
1720 list->setFocus();
Mauro Carvalho Chehab8a3b6e52020-06-30 08:48:35 +02001721 helpText->setInfo(menu);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001722 }
1723 }
Roman Zippelb65a47e2006-06-08 22:12:47 -07001724}
1725
Linus Torvalds1da177e2005-04-16 15:20:36 -07001726void ConfigMainWindow::listFocusChanged(void)
1727{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001728 if (menuList->mode == menuMode)
1729 configList->clearSelection();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001730}
1731
1732void ConfigMainWindow::goBack(void)
1733{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001734 if (configList->rootEntry == &rootmenu)
Boris Barbulovskibe596aa2015-09-22 11:36:28 -07001735 return;
1736
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001737 configList->setParentMenu();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001738}
1739
1740void ConfigMainWindow::showSingleView(void)
1741{
Boris Barbulovski780505e2015-09-22 11:36:13 -07001742 singleViewAction->setEnabled(false);
1743 singleViewAction->setChecked(true);
1744 splitViewAction->setEnabled(true);
1745 splitViewAction->setChecked(false);
1746 fullViewAction->setEnabled(true);
1747 fullViewAction->setChecked(false);
1748
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001749 backAction->setEnabled(true);
1750
Linus Torvalds1da177e2005-04-16 15:20:36 -07001751 menuView->hide();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001752 menuList->setRootMenu(0);
1753 configList->mode = singleMode;
1754 if (configList->rootEntry == &rootmenu)
1755 configList->updateListAll();
1756 else
1757 configList->setRootMenu(&rootmenu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001758 configList->setFocus();
1759}
1760
1761void ConfigMainWindow::showSplitView(void)
1762{
Boris Barbulovski780505e2015-09-22 11:36:13 -07001763 singleViewAction->setEnabled(true);
1764 singleViewAction->setChecked(false);
1765 splitViewAction->setEnabled(false);
1766 splitViewAction->setChecked(true);
1767 fullViewAction->setEnabled(true);
1768 fullViewAction->setChecked(false);
1769
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001770 backAction->setEnabled(false);
1771
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +02001772 configList->mode = menuMode;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001773 if (configList->rootEntry == &rootmenu)
1774 configList->updateListAll();
1775 else
1776 configList->setRootMenu(&rootmenu);
1777 configList->setAllOpen(true);
1778 configApp->processEvents();
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +02001779 menuList->mode = symbolMode;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001780 menuList->setRootMenu(&rootmenu);
1781 menuList->setAllOpen(true);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001782 menuView->show();
1783 menuList->setFocus();
1784}
1785
1786void ConfigMainWindow::showFullView(void)
1787{
Boris Barbulovski780505e2015-09-22 11:36:13 -07001788 singleViewAction->setEnabled(true);
1789 singleViewAction->setChecked(false);
1790 splitViewAction->setEnabled(true);
1791 splitViewAction->setChecked(false);
1792 fullViewAction->setEnabled(false);
1793 fullViewAction->setChecked(true);
1794
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001795 backAction->setEnabled(false);
1796
Linus Torvalds1da177e2005-04-16 15:20:36 -07001797 menuView->hide();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001798 menuList->setRootMenu(0);
1799 configList->mode = fullMode;
1800 if (configList->rootEntry == &rootmenu)
1801 configList->updateListAll();
1802 else
1803 configList->setRootMenu(&rootmenu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001804 configList->setFocus();
1805}
1806
Linus Torvalds1da177e2005-04-16 15:20:36 -07001807/*
1808 * ask for saving configuration before quitting
Linus Torvalds1da177e2005-04-16 15:20:36 -07001809 */
1810void ConfigMainWindow::closeEvent(QCloseEvent* e)
1811{
Karsten Wieseb3214292006-12-13 00:34:06 -08001812 if (!conf_get_changed()) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001813 e->accept();
1814 return;
1815 }
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001816 QMessageBox mb("qconf", "Save configuration?", QMessageBox::Warning,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001817 QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape);
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001818 mb.setButtonText(QMessageBox::Yes, "&Save Changes");
1819 mb.setButtonText(QMessageBox::No, "&Discard Changes");
1820 mb.setButtonText(QMessageBox::Cancel, "Cancel Exit");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001821 switch (mb.exec()) {
1822 case QMessageBox::Yes:
Michal Marekbac6aa82011-05-25 15:10:25 +02001823 if (saveConfig())
1824 e->accept();
1825 else
1826 e->ignore();
1827 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001828 case QMessageBox::No:
1829 e->accept();
1830 break;
1831 case QMessageBox::Cancel:
1832 e->ignore();
1833 break;
1834 }
1835}
1836
1837void ConfigMainWindow::showIntro(void)
1838{
Masahiro Yamada8c30e7e2020-08-29 17:14:07 +09001839 static const QString str =
1840 "Welcome to the qconf graphical configuration tool.\n"
1841 "\n"
1842 "For each option, a blank box indicates the feature is "
1843 "disabled, a check indicates it is enabled, and a dot "
1844 "indicates that it is to be compiled as a module. Clicking on "
1845 "the box will cycle through the three states.\n"
1846 "\n"
1847 "If you do not see an option (e.g., a device driver) that you "
1848 "believe should be present, try turning on Show All Options "
1849 "under the Options menu. Although there is no cross reference "
1850 "yet to help you figure out what other options must be enabled "
1851 "to support the option you are interested in, you can still "
1852 "view the help of a grayed-out option.\n"
1853 "\n"
1854 "Toggling Show Debug Info under the Options menu will show the "
1855 "dependencies, which you can then match by examining other "
1856 "options.\n";
Linus Torvalds1da177e2005-04-16 15:20:36 -07001857
1858 QMessageBox::information(this, "qconf", str);
1859}
1860
1861void ConfigMainWindow::showAbout(void)
1862{
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001863 static const QString str = "qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n"
Boris Barbulovskib4ff1de2015-09-22 11:36:38 -07001864 "Copyright (C) 2015 Boris Barbulovski <bbarbulovski@gmail.com>.\n\n"
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001865 "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n";
Linus Torvalds1da177e2005-04-16 15:20:36 -07001866
1867 QMessageBox::information(this, "qconf", str);
1868}
1869
1870void ConfigMainWindow::saveSettings(void)
1871{
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001872 configSettings->setValue("/window x", pos().x());
1873 configSettings->setValue("/window y", pos().y());
1874 configSettings->setValue("/window width", size().width());
1875 configSettings->setValue("/window height", size().height());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001876
1877 QString entry;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001878 switch(configList->mode) {
1879 case singleMode :
1880 entry = "single";
1881 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001882
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001883 case symbolMode :
1884 entry = "split";
1885 break;
1886
1887 case fullMode :
1888 entry = "full";
1889 break;
1890
1891 default:
1892 break;
1893 }
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001894 configSettings->setValue("/listMode", entry);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001895
Roman Zippel7fc925f2006-06-08 22:12:46 -07001896 configSettings->writeSizes("/split1", split1->sizes());
1897 configSettings->writeSizes("/split2", split2->sizes());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001898}
1899
Karsten Wiese3b354c52006-12-13 00:34:08 -08001900void ConfigMainWindow::conf_changed(void)
1901{
1902 if (saveAction)
1903 saveAction->setEnabled(conf_get_changed());
1904}
1905
Linus Torvalds1da177e2005-04-16 15:20:36 -07001906void fixup_rootmenu(struct menu *menu)
1907{
1908 struct menu *child;
1909 static int menu_cnt = 0;
1910
1911 menu->flags |= MENU_ROOT;
1912 for (child = menu->list; child; child = child->next) {
1913 if (child->prompt && child->prompt->type == P_MENU) {
1914 menu_cnt++;
1915 fixup_rootmenu(child);
1916 menu_cnt--;
1917 } else if (!menu_cnt)
1918 fixup_rootmenu(child);
1919 }
1920}
1921
1922static const char *progname;
1923
1924static void usage(void)
1925{
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001926 printf("%s [-s] <config>\n", progname);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001927 exit(0);
1928}
1929
1930int main(int ac, char** av)
1931{
1932 ConfigMainWindow* v;
1933 const char *name;
1934
Linus Torvalds1da177e2005-04-16 15:20:36 -07001935 progname = av[0];
1936 configApp = new QApplication(ac, av);
1937 if (ac > 1 && av[1][0] == '-') {
1938 switch (av[1][1]) {
Michal Marek0a1f00a2015-04-08 13:30:42 +02001939 case 's':
1940 conf_set_message_callback(NULL);
1941 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001942 case 'h':
1943 case '?':
1944 usage();
1945 }
1946 name = av[2];
1947 } else
1948 name = av[1];
1949 if (!name)
1950 usage();
1951
1952 conf_parse(name);
1953 fixup_rootmenu(&rootmenu);
1954 conf_read(NULL);
1955 //zconfdump(stdout);
1956
Roman Zippel7fc925f2006-06-08 22:12:46 -07001957 configSettings = new ConfigSettings();
1958 configSettings->beginGroup("/kconfig/qconf");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001959 v = new ConfigMainWindow();
1960
1961 //zconfdump(stdout);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001962 configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit()));
1963 configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings()));
Roman Zippel43bf6122006-06-08 22:12:45 -07001964 v->show();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001965 configApp->exec();
1966
Roman Zippel7fc925f2006-06-08 22:12:46 -07001967 configSettings->endGroup();
1968 delete configSettings;
Chris Bainbridge5b61c7b2016-01-08 20:44:04 +00001969 delete v;
1970 delete configApp;
Roman Zippel7fc925f2006-06-08 22:12:46 -07001971
Linus Torvalds1da177e2005-04-16 15:20:36 -07001972 return 0;
1973}