blob: 8ce624a3b54b1f8c5d22a8e07880b26ed2906957 [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 Yamada510bc3c2020-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 Yamada510bc3c2020-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 Yamada510bc3c2020-08-21 02:43:28 +09001089 stream << " (";
Roman Zippelab45d192006-06-08 22:12:47 -07001090 if (showDebug())
Masahiro Yamada510bc3c2020-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 Yamada510bc3c2020-08-21 02:43:28 +09001094 stream << "</a>";
1095 stream << ")";
Roman Zippel43bf6122006-06-08 22:12:45 -07001096 }
1097 } else if (sym->name) {
Masahiro Yamada510bc3c2020-08-21 02:43:28 +09001098 stream << "<big><b>";
Roman Zippelab45d192006-06-08 22:12:47 -07001099 if (showDebug())
Masahiro Yamada510bc3c2020-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 Yamada510bc3c2020-08-21 02:43:28 +09001103 stream << "</a>";
1104 stream << "</b></big>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001105 }
Masahiro Yamada510bc3c2020-08-21 02:43:28 +09001106 stream << "<br><br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001107
1108 if (showDebug())
Masahiro Yamada510bc3c2020-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 Yamada510bc3c2020-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 Yamada510bc3c2020-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 Yamada510bc3c2020-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 Yamada510bc3c2020-08-21 02:43:28 +09001139 QTextStream stream(&debug);
Roman Zippel43bf6122006-06-08 22:12:45 -07001140
Masahiro Yamada510bc3c2020-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 Yamada510bc3c2020-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 Yamada510bc3c2020-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 Yamada510bc3c2020-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 Yamada510bc3c2020-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 Yamada510bc3c2020-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 Yamada510bc3c2020-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 Yamada510bc3c2020-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 Yamada510bc3c2020-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 Yamada510bc3c2020-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 Yamada510bc3c2020-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{
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001839 static const QString str = "Welcome to the qconf graphical configuration tool.\n\n"
Linus Torvalds1da177e2005-04-16 15:20:36 -07001840 "For each option, a blank box indicates the feature is disabled, a check\n"
1841 "indicates it is enabled, and a dot indicates that it is to be compiled\n"
1842 "as a module. Clicking on the box will cycle through the three states.\n\n"
1843 "If you do not see an option (e.g., a device driver) that you believe\n"
1844 "should be present, try turning on Show All Options under the Options menu.\n"
1845 "Although there is no cross reference yet to help you figure out what other\n"
1846 "options must be enabled to support the option you are interested in, you can\n"
1847 "still view the help of a grayed-out option.\n\n"
1848 "Toggling Show Debug Info under the Options menu will show the dependencies,\n"
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001849 "which you can then match by examining other options.\n\n";
Linus Torvalds1da177e2005-04-16 15:20:36 -07001850
1851 QMessageBox::information(this, "qconf", str);
1852}
1853
1854void ConfigMainWindow::showAbout(void)
1855{
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001856 static const QString str = "qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n"
Boris Barbulovskib4ff1de2015-09-22 11:36:38 -07001857 "Copyright (C) 2015 Boris Barbulovski <bbarbulovski@gmail.com>.\n\n"
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001858 "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n";
Linus Torvalds1da177e2005-04-16 15:20:36 -07001859
1860 QMessageBox::information(this, "qconf", str);
1861}
1862
1863void ConfigMainWindow::saveSettings(void)
1864{
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001865 configSettings->setValue("/window x", pos().x());
1866 configSettings->setValue("/window y", pos().y());
1867 configSettings->setValue("/window width", size().width());
1868 configSettings->setValue("/window height", size().height());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001869
1870 QString entry;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001871 switch(configList->mode) {
1872 case singleMode :
1873 entry = "single";
1874 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001875
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001876 case symbolMode :
1877 entry = "split";
1878 break;
1879
1880 case fullMode :
1881 entry = "full";
1882 break;
1883
1884 default:
1885 break;
1886 }
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001887 configSettings->setValue("/listMode", entry);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001888
Roman Zippel7fc925f2006-06-08 22:12:46 -07001889 configSettings->writeSizes("/split1", split1->sizes());
1890 configSettings->writeSizes("/split2", split2->sizes());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001891}
1892
Karsten Wiese3b354c52006-12-13 00:34:08 -08001893void ConfigMainWindow::conf_changed(void)
1894{
1895 if (saveAction)
1896 saveAction->setEnabled(conf_get_changed());
1897}
1898
Linus Torvalds1da177e2005-04-16 15:20:36 -07001899void fixup_rootmenu(struct menu *menu)
1900{
1901 struct menu *child;
1902 static int menu_cnt = 0;
1903
1904 menu->flags |= MENU_ROOT;
1905 for (child = menu->list; child; child = child->next) {
1906 if (child->prompt && child->prompt->type == P_MENU) {
1907 menu_cnt++;
1908 fixup_rootmenu(child);
1909 menu_cnt--;
1910 } else if (!menu_cnt)
1911 fixup_rootmenu(child);
1912 }
1913}
1914
1915static const char *progname;
1916
1917static void usage(void)
1918{
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001919 printf("%s [-s] <config>\n", progname);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001920 exit(0);
1921}
1922
1923int main(int ac, char** av)
1924{
1925 ConfigMainWindow* v;
1926 const char *name;
1927
Linus Torvalds1da177e2005-04-16 15:20:36 -07001928 progname = av[0];
1929 configApp = new QApplication(ac, av);
1930 if (ac > 1 && av[1][0] == '-') {
1931 switch (av[1][1]) {
Michal Marek0a1f00a2015-04-08 13:30:42 +02001932 case 's':
1933 conf_set_message_callback(NULL);
1934 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001935 case 'h':
1936 case '?':
1937 usage();
1938 }
1939 name = av[2];
1940 } else
1941 name = av[1];
1942 if (!name)
1943 usage();
1944
1945 conf_parse(name);
1946 fixup_rootmenu(&rootmenu);
1947 conf_read(NULL);
1948 //zconfdump(stdout);
1949
Roman Zippel7fc925f2006-06-08 22:12:46 -07001950 configSettings = new ConfigSettings();
1951 configSettings->beginGroup("/kconfig/qconf");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001952 v = new ConfigMainWindow();
1953
1954 //zconfdump(stdout);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001955 configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit()));
1956 configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings()));
Roman Zippel43bf6122006-06-08 22:12:45 -07001957 v->show();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001958 configApp->exec();
1959
Roman Zippel7fc925f2006-06-08 22:12:46 -07001960 configSettings->endGroup();
1961 delete configSettings;
Chris Bainbridge5b61c7b2016-01-08 20:44:04 +00001962 delete v;
1963 delete configApp;
Roman Zippel7fc925f2006-06-08 22:12:46 -07001964
Linus Torvalds1da177e2005-04-16 15:20:36 -07001965 return 0;
1966}