blob: af8d5cc1b24b277bb5ac1719da62b73dfe892ffe [file] [log] [blame]
Masahiro Yamada0c874102018-12-18 21:13:35 +09001// SPDX-License-Identifier: GPL-2.0
Linus Torvalds1da177e2005-04-16 15:20:36 -07002/*
3 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
Boris Barbulovskib4ff1de2015-09-22 11:36:38 -07004 * Copyright (C) 2015 Boris Barbulovski <bbarbulovski@gmail.com>
Linus Torvalds1da177e2005-04-16 15:20:36 -07005 */
6
Boris Barbulovski85eaf282015-09-22 11:36:03 -07007#include <QAction>
Mauro Carvalho Chehabcf81dfa2020-06-30 08:26:35 +02008#include <QApplication>
9#include <QCloseEvent>
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +020010#include <QDebug>
Mauro Carvalho Chehabcf81dfa2020-06-30 08:26:35 +020011#include <QDesktopWidget>
Boris Barbulovskibea00772015-09-22 11:36:04 -070012#include <QFileDialog>
Mauro Carvalho Chehabcf81dfa2020-06-30 08:26:35 +020013#include <QLabel>
14#include <QLayout>
15#include <QList>
Boris Barbulovski76bede82015-09-22 11:36:07 -070016#include <QMenu>
Mauro Carvalho Chehabcf81dfa2020-06-30 08:26:35 +020017#include <QMenuBar>
18#include <QMessageBox>
19#include <QToolBar>
Linus Torvalds1da177e2005-04-16 15:20:36 -070020
21#include <stdlib.h>
22
23#include "lkc.h"
24#include "qconf.h"
25
Masahiro Yamada3b541978562018-12-21 17:33:07 +090026#include "images.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070027
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -070028
Linus Torvalds1da177e2005-04-16 15:20:36 -070029static QApplication *configApp;
Roman Zippel7fc925f2006-06-08 22:12:46 -070030static ConfigSettings *configSettings;
Linus Torvalds1da177e2005-04-16 15:20:36 -070031
Boris Barbulovski85eaf282015-09-22 11:36:03 -070032QAction *ConfigMainWindow::saveAction;
Karsten Wiese3b354c52006-12-13 00:34:08 -080033
Ben Hutchings00d4f8f2013-10-06 19:21:31 +010034ConfigSettings::ConfigSettings()
35 : QSettings("kernel.org", "qconf")
36{
37}
38
Linus Torvalds1da177e2005-04-16 15:20:36 -070039/**
40 * Reads a list of integer values from the application settings.
41 */
Boris Barbulovski041fbdc2015-09-22 11:36:05 -070042QList<int> ConfigSettings::readSizes(const QString& key, bool *ok)
Linus Torvalds1da177e2005-04-16 15:20:36 -070043{
Boris Barbulovski041fbdc2015-09-22 11:36:05 -070044 QList<int> result;
Li Zefanc1f96f02010-05-07 13:58:04 +080045
Boris Barbulovski83c3a1b2016-11-30 14:57:55 -080046 if (contains(key))
47 {
48 QStringList entryList = value(key).toStringList();
49 QStringList::Iterator it;
50
51 for (it = entryList.begin(); it != entryList.end(); ++it)
52 result.push_back((*it).toInt());
53
54 *ok = true;
55 }
56 else
57 *ok = false;
Linus Torvalds1da177e2005-04-16 15:20:36 -070058
59 return result;
60}
61
62/**
63 * Writes a list of integer values to the application settings.
64 */
Boris Barbulovski041fbdc2015-09-22 11:36:05 -070065bool ConfigSettings::writeSizes(const QString& key, const QList<int>& value)
Linus Torvalds1da177e2005-04-16 15:20:36 -070066{
67 QStringList stringList;
Boris Barbulovski041fbdc2015-09-22 11:36:05 -070068 QList<int>::ConstIterator it;
Linus Torvalds1da177e2005-04-16 15:20:36 -070069
70 for (it = value.begin(); it != value.end(); ++it)
71 stringList.push_back(QString::number(*it));
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -070072 setValue(key, stringList);
Boris Barbulovski59e56442015-09-22 11:36:18 -070073
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -070074 return true;
Linus Torvalds1da177e2005-04-16 15:20:36 -070075}
Linus Torvalds1da177e2005-04-16 15:20:36 -070076
Masahiro Yamada5cb255f2020-08-07 18:19:07 +090077QIcon ConfigItem::symbolYesIcon;
78QIcon ConfigItem::symbolModIcon;
79QIcon ConfigItem::symbolNoIcon;
80QIcon ConfigItem::choiceYesIcon;
81QIcon ConfigItem::choiceNoIcon;
82QIcon ConfigItem::menuIcon;
83QIcon ConfigItem::menubackIcon;
Boris Barbulovski59e56442015-09-22 11:36:18 -070084
85/*
Boris Barbulovski59e56442015-09-22 11:36:18 -070086 * update the displayed of a menu entry
87 */
88void ConfigItem::updateMenu(void)
89{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -070090 ConfigList* list;
91 struct symbol* sym;
92 struct property *prop;
93 QString prompt;
94 int type;
95 tristate expr;
96
97 list = listView();
98 if (goParent) {
Masahiro Yamada5cb255f2020-08-07 18:19:07 +090099 setIcon(promptColIdx, menubackIcon);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700100 prompt = "..";
101 goto set_prompt;
102 }
103
104 sym = menu->sym;
105 prop = menu->prompt;
Masahiro Yamada3c73ff02020-08-07 18:19:02 +0900106 prompt = menu_get_prompt(menu);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700107
108 if (prop) switch (prop->type) {
109 case P_MENU:
110 if (list->mode == singleMode || list->mode == symbolMode) {
111 /* a menuconfig entry is displayed differently
112 * depending whether it's at the view root or a child.
113 */
114 if (sym && list->rootEntry == menu)
115 break;
Masahiro Yamada5cb255f2020-08-07 18:19:07 +0900116 setIcon(promptColIdx, menuIcon);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700117 } else {
118 if (sym)
119 break;
Masahiro Yamada711b8752020-08-07 18:19:03 +0900120 setIcon(promptColIdx, QIcon());
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700121 }
122 goto set_prompt;
123 case P_COMMENT:
Masahiro Yamada711b8752020-08-07 18:19:03 +0900124 setIcon(promptColIdx, QIcon());
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700125 goto set_prompt;
126 default:
127 ;
128 }
129 if (!sym)
130 goto set_prompt;
131
Masahiro Yamada3c73ff02020-08-07 18:19:02 +0900132 setText(nameColIdx, sym->name);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700133
134 type = sym_get_type(sym);
135 switch (type) {
136 case S_BOOLEAN:
137 case S_TRISTATE:
138 char ch;
139
Marco Ammonbaa23ec2019-07-04 12:50:41 +0200140 if (!sym_is_changeable(sym) && list->optMode == normalOpt) {
Masahiro Yamada711b8752020-08-07 18:19:03 +0900141 setIcon(promptColIdx, QIcon());
Mauro Carvalho Chehabcf497b92020-04-02 11:27:58 +0200142 setText(noColIdx, QString());
143 setText(modColIdx, QString());
144 setText(yesColIdx, QString());
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700145 break;
146 }
147 expr = sym_get_tristate_value(sym);
148 switch (expr) {
149 case yes:
150 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
Masahiro Yamada5cb255f2020-08-07 18:19:07 +0900151 setIcon(promptColIdx, choiceYesIcon);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700152 else
Masahiro Yamada5cb255f2020-08-07 18:19:07 +0900153 setIcon(promptColIdx, symbolYesIcon);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700154 setText(yesColIdx, "Y");
155 ch = 'Y';
156 break;
157 case mod:
Masahiro Yamada5cb255f2020-08-07 18:19:07 +0900158 setIcon(promptColIdx, symbolModIcon);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700159 setText(modColIdx, "M");
160 ch = 'M';
161 break;
162 default:
163 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
Masahiro Yamada5cb255f2020-08-07 18:19:07 +0900164 setIcon(promptColIdx, choiceNoIcon);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700165 else
Masahiro Yamada5cb255f2020-08-07 18:19:07 +0900166 setIcon(promptColIdx, symbolNoIcon);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700167 setText(noColIdx, "N");
168 ch = 'N';
169 break;
170 }
171 if (expr != no)
172 setText(noColIdx, sym_tristate_within_range(sym, no) ? "_" : 0);
173 if (expr != mod)
174 setText(modColIdx, sym_tristate_within_range(sym, mod) ? "_" : 0);
175 if (expr != yes)
176 setText(yesColIdx, sym_tristate_within_range(sym, yes) ? "_" : 0);
177
178 setText(dataColIdx, QChar(ch));
179 break;
180 case S_INT:
181 case S_HEX:
182 case S_STRING:
Masahiro Yamada37162a62020-08-29 17:14:12 +0900183 setText(dataColIdx, sym_get_string_value(sym));
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700184 break;
185 }
186 if (!sym_has_value(sym) && visible)
Sam Ravnborg694c49a2018-05-22 21:36:12 +0200187 prompt += " (NEW)";
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700188set_prompt:
189 setText(promptColIdx, prompt);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700190}
191
192void ConfigItem::testUpdateMenu(bool v)
193{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700194 ConfigItem* i;
195
196 visible = v;
197 if (!menu)
198 return;
199
200 sym_calc_value(menu->sym);
201 if (menu->flags & MENU_CHANGED) {
202 /* the menu entry changed, so update all list items */
203 menu->flags &= ~MENU_CHANGED;
204 for (i = (ConfigItem*)menu->data; i; i = i->nextItem)
205 i->updateMenu();
206 } else if (listView()->updateAll)
207 updateMenu();
Boris Barbulovski59e56442015-09-22 11:36:18 -0700208}
209
210
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700211/*
212 * construct a menu entry
213 */
214void ConfigItem::init(void)
215{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700216 if (menu) {
217 ConfigList* list = listView();
218 nextItem = (ConfigItem*)menu->data;
219 menu->data = this;
220
221 if (list->mode != fullMode)
222 setExpanded(true);
223 sym_calc_value(menu->sym);
Masahiro Yamada37162a62020-08-29 17:14:12 +0900224
225 if (menu->sym) {
226 enum symbol_type type = menu->sym->type;
227
228 // Allow to edit "int", "hex", and "string" in-place in
229 // the data column. Unfortunately, you cannot specify
230 // the flags per column. Set ItemIsEditable for all
231 // columns here, and check the column in createEditor().
232 if (type == S_INT || type == S_HEX || type == S_STRING)
233 setFlags(flags() | Qt::ItemIsEditable);
234 }
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700235 }
236 updateMenu();
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700237}
238
239/*
240 * destruct a menu entry
241 */
242ConfigItem::~ConfigItem(void)
243{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700244 if (menu) {
245 ConfigItem** ip = (ConfigItem**)&menu->data;
246 for (; *ip; ip = &(*ip)->nextItem) {
247 if (*ip == this) {
248 *ip = nextItem;
249 break;
250 }
251 }
252 }
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700253}
254
Masahiro Yamada37162a62020-08-29 17:14:12 +0900255QWidget *ConfigItemDelegate::createEditor(QWidget *parent,
256 const QStyleOptionViewItem &option,
257 const QModelIndex &index) const
258{
259 ConfigItem *item;
260
261 // Only the data column is editable
262 if (index.column() != dataColIdx)
263 return nullptr;
264
265 // You cannot edit invisible menus
266 item = static_cast<ConfigItem *>(index.internalPointer());
267 if (!item || !item->menu || !menu_is_visible(item->menu))
268 return nullptr;
269
270 return QStyledItemDelegate::createEditor(parent, option, index);
271}
272
273void ConfigItemDelegate::setModelData(QWidget *editor,
274 QAbstractItemModel *model,
275 const QModelIndex &index) const
276{
277 QLineEdit *lineEdit;
278 ConfigItem *item;
279 struct symbol *sym;
280 bool success;
281
282 lineEdit = qobject_cast<QLineEdit *>(editor);
283 // If this is not a QLineEdit, use the parent's default.
284 // (does this happen?)
285 if (!lineEdit)
286 goto parent;
287
288 item = static_cast<ConfigItem *>(index.internalPointer());
289 if (!item || !item->menu)
290 goto parent;
291
292 sym = item->menu->sym;
293 if (!sym)
294 goto parent;
295
296 success = sym_set_string_value(sym, lineEdit->text().toUtf8().data());
297 if (success) {
298 ConfigList::updateListForAll();
299 } else {
300 QMessageBox::information(editor, "qconf",
301 "Cannot set the data (maybe due to out of range).\n"
302 "Setting the old value.");
303 lineEdit->setText(sym_get_string_value(sym));
304 }
305
306parent:
307 QStyledItemDelegate::setModelData(editor, model, index);
308}
309
Roman Zippel43bf6122006-06-08 22:12:45 -0700310ConfigLineEdit::ConfigLineEdit(ConfigView* parent)
311 : Parent(parent)
312{
Boris Barbulovskic14fa5e2015-09-22 11:36:21 -0700313 connect(this, SIGNAL(editingFinished()), SLOT(hide()));
Roman Zippel43bf6122006-06-08 22:12:45 -0700314}
315
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700316void ConfigLineEdit::show(ConfigItem* i)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700317{
318 item = i;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700319 if (sym_get_string_value(item->menu->sym))
Masahiro Yamada3c73ff02020-08-07 18:19:02 +0900320 setText(sym_get_string_value(item->menu->sym));
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700321 else
Mauro Carvalho Chehabcf497b92020-04-02 11:27:58 +0200322 setText(QString());
Linus Torvalds1da177e2005-04-16 15:20:36 -0700323 Parent::show();
324 setFocus();
325}
326
327void ConfigLineEdit::keyPressEvent(QKeyEvent* e)
328{
329 switch (e->key()) {
Markus Heidelbergfbb86372009-05-18 01:36:51 +0200330 case Qt::Key_Escape:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700331 break;
Markus Heidelbergfbb86372009-05-18 01:36:51 +0200332 case Qt::Key_Return:
333 case Qt::Key_Enter:
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700334 sym_set_string_value(item->menu->sym, text().toLatin1());
Masahiro Yamadaf9b918f2020-08-29 17:14:10 +0900335 ConfigList::updateListForAll();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700336 break;
337 default:
338 Parent::keyPressEvent(e);
339 return;
340 }
341 e->accept();
342 parent()->list->setFocus();
343 hide();
344}
345
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700346ConfigList::ConfigList(ConfigView* p, const char *name)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700347 : Parent(p),
348 updateAll(false),
Masahiro Yamada669a1ee2020-08-29 17:14:11 +0900349 showName(false), showRange(false), mode(singleMode), optMode(normalOpt),
Boris Barbulovski59e56442015-09-22 11:36:18 -0700350 rootEntry(0), headerPopup(0)
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700351{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700352 setObjectName(name);
Boris Barbulovskia5225e92015-09-22 11:36:29 -0700353 setSortingEnabled(false);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700354 setRootIsDecorated(true);
355
Boris Barbulovskif999cc02015-09-22 11:36:31 -0700356 setVerticalScrollMode(ScrollPerPixel);
357 setHorizontalScrollMode(ScrollPerPixel);
358
Masahiro Yamada97bebbc2020-07-30 02:46:17 +0900359 setHeaderLabels(QStringList() << "Option" << "Name" << "N" << "M" << "Y" << "Value");
Boris Barbulovskia52cb322015-09-22 11:36:24 -0700360
Boris Barbulovskic14fa5e2015-09-22 11:36:21 -0700361 connect(this, SIGNAL(itemSelectionChanged(void)),
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700362 SLOT(updateSelection(void)));
363
364 if (name) {
365 configSettings->beginGroup(name);
366 showName = configSettings->value("/showName", false).toBool();
367 showRange = configSettings->value("/showRange", false).toBool();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700368 optMode = (enum optionMode)configSettings->value("/optionMode", 0).toInt();
369 configSettings->endGroup();
370 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
371 }
372
Masahiro Yamadaabf741a2020-08-07 18:19:04 +0900373 showColumn(promptColIdx);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700374
Masahiro Yamada37162a62020-08-29 17:14:12 +0900375 setItemDelegate(new ConfigItemDelegate(this));
376
Masahiro Yamadaf9b918f2020-08-29 17:14:10 +0900377 allLists.append(this);
378
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700379 reinit();
380}
381
Masahiro Yamadaf9b918f2020-08-29 17:14:10 +0900382ConfigList::~ConfigList()
383{
384 allLists.removeOne(this);
385}
386
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700387bool ConfigList::menuSkip(struct menu *menu)
388{
389 if (optMode == normalOpt && menu_is_visible(menu))
390 return false;
391 if (optMode == promptOpt && menu_has_prompt(menu))
392 return false;
393 if (optMode == allOpt)
394 return false;
395 return true;
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700396}
Boris Barbulovski59e56442015-09-22 11:36:18 -0700397
398void ConfigList::reinit(void)
399{
Masahiro Yamadaabf741a2020-08-07 18:19:04 +0900400 hideColumn(yesColIdx);
401 hideColumn(modColIdx);
402 hideColumn(noColIdx);
403 hideColumn(nameColIdx);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700404
405 if (showName)
Masahiro Yamadaabf741a2020-08-07 18:19:04 +0900406 showColumn(nameColIdx);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700407 if (showRange) {
Masahiro Yamadaabf741a2020-08-07 18:19:04 +0900408 showColumn(noColIdx);
409 showColumn(modColIdx);
410 showColumn(yesColIdx);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700411 }
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700412
413 updateListAll();
Boris Barbulovski59e56442015-09-22 11:36:18 -0700414}
415
Masahiro Yamadad4bbe8a2020-08-07 18:19:09 +0900416void ConfigList::setOptionMode(QAction *action)
417{
418 if (action == showNormalAction)
419 optMode = normalOpt;
420 else if (action == showAllAction)
421 optMode = allOpt;
422 else
423 optMode = promptOpt;
424
425 updateListAll();
426}
427
Boris Barbulovski59e56442015-09-22 11:36:18 -0700428void ConfigList::saveSettings(void)
429{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700430 if (!objectName().isEmpty()) {
431 configSettings->beginGroup(objectName());
432 configSettings->setValue("/showName", showName);
433 configSettings->setValue("/showRange", showRange);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700434 configSettings->setValue("/optionMode", (int)optMode);
435 configSettings->endGroup();
436 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700437}
438
439ConfigItem* ConfigList::findConfigItem(struct menu *menu)
440{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700441 ConfigItem* item = (ConfigItem*)menu->data;
442
443 for (; item; item = item->nextItem) {
444 if (this == item->listView())
445 break;
446 }
447
448 return item;
Boris Barbulovski59e56442015-09-22 11:36:18 -0700449}
450
451void ConfigList::updateSelection(void)
452{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700453 struct menu *menu;
454 enum prop_type type;
455
Boris Barbulovskibe596aa2015-09-22 11:36:28 -0700456 if (selectedItems().count() == 0)
457 return;
458
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700459 ConfigItem* item = (ConfigItem*)selectedItems().first();
460 if (!item)
461 return;
462
463 menu = item->menu;
464 emit menuChanged(menu);
465 if (!menu)
466 return;
467 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
468 if (mode == menuMode && type == P_MENU)
469 emit menuSelected(menu);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700470}
471
Masahiro Yamadacb770432020-08-07 18:18:59 +0900472void ConfigList::updateList()
Boris Barbulovski59e56442015-09-22 11:36:18 -0700473{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700474 ConfigItem* last = 0;
Masahiro Yamadacb770432020-08-07 18:18:59 +0900475 ConfigItem *item;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700476
477 if (!rootEntry) {
478 if (mode != listMode)
479 goto update;
480 QTreeWidgetItemIterator it(this);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700481
482 while (*it) {
483 item = (ConfigItem*)(*it);
484 if (!item->menu)
485 continue;
486 item->testUpdateMenu(menu_is_visible(item->menu));
487
488 ++it;
489 }
490 return;
491 }
492
493 if (rootEntry != &rootmenu && (mode == singleMode ||
494 (mode == symbolMode && rootEntry->parent != &rootmenu))) {
Boris Barbulovskiee7298f2015-09-22 11:36:37 -0700495 item = (ConfigItem *)topLevelItem(0);
Masahiro Yamada4b20e102020-08-01 16:08:49 +0900496 if (!item)
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700497 item = new ConfigItem(this, 0, true);
Masahiro Yamada4b20e102020-08-01 16:08:49 +0900498 last = item;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700499 }
500 if ((mode == singleMode || (mode == symbolMode && !(rootEntry->flags & MENU_ROOT))) &&
501 rootEntry->sym && rootEntry->prompt) {
Masahiro Yamadaccf56e52020-08-01 16:08:50 +0900502 item = last ? last->nextSibling() : nullptr;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700503 if (!item)
504 item = new ConfigItem(this, last, rootEntry, true);
505 else
506 item->testUpdateMenu(true);
507
508 updateMenuList(item, rootEntry);
509 update();
Boris Barbulovskif999cc02015-09-22 11:36:31 -0700510 resizeColumnToContents(0);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700511 return;
512 }
513update:
Masahiro Yamada5b75a6c2020-08-07 18:19:01 +0900514 updateMenuList(rootEntry);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700515 update();
Boris Barbulovskif999cc02015-09-22 11:36:31 -0700516 resizeColumnToContents(0);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700517}
518
Masahiro Yamadaf9b918f2020-08-29 17:14:10 +0900519void ConfigList::updateListForAll()
520{
521 QListIterator<ConfigList *> it(allLists);
522
523 while (it.hasNext()) {
524 ConfigList *list = it.next();
525
526 list->updateList();
527 }
528}
529
530void ConfigList::updateListAllForAll()
531{
532 QListIterator<ConfigList *> it(allLists);
533
534 while (it.hasNext()) {
535 ConfigList *list = it.next();
536
537 list->updateList();
538 }
539}
540
Boris Barbulovski59e56442015-09-22 11:36:18 -0700541void ConfigList::setValue(ConfigItem* item, tristate val)
542{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700543 struct symbol* sym;
544 int type;
545 tristate oldval;
546
547 sym = item->menu ? item->menu->sym : 0;
548 if (!sym)
549 return;
550
551 type = sym_get_type(sym);
552 switch (type) {
553 case S_BOOLEAN:
554 case S_TRISTATE:
555 oldval = sym_get_tristate_value(sym);
556
557 if (!sym_set_tristate_value(sym, val))
558 return;
559 if (oldval == no && item->menu->list)
560 item->setExpanded(true);
Masahiro Yamadaf9b918f2020-08-29 17:14:10 +0900561 ConfigList::updateListForAll();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700562 break;
563 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700564}
565
566void ConfigList::changeValue(ConfigItem* item)
567{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700568 struct symbol* sym;
569 struct menu* menu;
570 int type, oldexpr, newexpr;
571
572 menu = item->menu;
573 if (!menu)
574 return;
575 sym = menu->sym;
576 if (!sym) {
577 if (item->menu->list)
578 item->setExpanded(!item->isExpanded());
579 return;
580 }
581
582 type = sym_get_type(sym);
583 switch (type) {
584 case S_BOOLEAN:
585 case S_TRISTATE:
586 oldexpr = sym_get_tristate_value(sym);
587 newexpr = sym_toggle_tristate_value(sym);
588 if (item->menu->list) {
589 if (oldexpr == newexpr)
590 item->setExpanded(!item->isExpanded());
591 else if (oldexpr == no)
592 item->setExpanded(true);
593 }
594 if (oldexpr != newexpr)
Masahiro Yamadaf9b918f2020-08-29 17:14:10 +0900595 ConfigList::updateListForAll();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700596 break;
Masahiro Yamada37162a62020-08-29 17:14:12 +0900597 default:
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700598 break;
599 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700600}
601
602void ConfigList::setRootMenu(struct menu *menu)
603{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700604 enum prop_type type;
605
606 if (rootEntry == menu)
607 return;
608 type = menu && menu->prompt ? menu->prompt->type : P_UNKNOWN;
609 if (type != P_MENU)
610 return;
Masahiro Yamada5b75a6c2020-08-07 18:19:01 +0900611 updateMenuList(0);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700612 rootEntry = menu;
613 updateListAll();
614 if (currentItem()) {
Mauro Carvalho Chehabb06c3ec2020-06-30 08:26:38 +0200615 setSelected(currentItem(), hasFocus());
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700616 scrollToItem(currentItem());
617 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700618}
619
620void ConfigList::setParentMenu(void)
621{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700622 ConfigItem* item;
623 struct menu *oldroot;
624
625 oldroot = rootEntry;
626 if (rootEntry == &rootmenu)
627 return;
628 setRootMenu(menu_get_parent_menu(rootEntry->parent));
629
630 QTreeWidgetItemIterator it(this);
631 while (*it) {
632 item = (ConfigItem *)(*it);
633 if (item->menu == oldroot) {
634 setCurrentItem(item);
635 scrollToItem(item);
636 break;
637 }
638
639 ++it;
640 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700641}
642
643/*
644 * update all the children of a menu entry
645 * removes/adds the entries from the parent widget as necessary
646 *
647 * parent: either the menu list widget or a menu entry widget
648 * menu: entry to be updated
649 */
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700650void ConfigList::updateMenuList(ConfigItem *parent, struct menu* menu)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700651{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700652 struct menu* child;
653 ConfigItem* item;
654 ConfigItem* last;
655 bool visible;
656 enum prop_type type;
657
658 if (!menu) {
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700659 while (parent->childCount() > 0)
660 {
661 delete parent->takeChild(0);
662 }
663
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700664 return;
665 }
666
667 last = parent->firstChild();
668 if (last && !last->goParent)
669 last = 0;
670 for (child = menu->list; child; child = child->next) {
671 item = last ? last->nextSibling() : parent->firstChild();
672 type = child->prompt ? child->prompt->type : P_UNKNOWN;
673
674 switch (mode) {
675 case menuMode:
676 if (!(child->flags & MENU_ROOT))
677 goto hide;
678 break;
679 case symbolMode:
680 if (child->flags & MENU_ROOT)
681 goto hide;
682 break;
683 default:
684 break;
685 }
686
687 visible = menu_is_visible(child);
688 if (!menuSkip(child)) {
689 if (!child->sym && !child->list && !child->prompt)
690 continue;
691 if (!item || item->menu != child)
692 item = new ConfigItem(parent, last, child, visible);
693 else
694 item->testUpdateMenu(visible);
695
696 if (mode == fullMode || mode == menuMode || type != P_MENU)
697 updateMenuList(item, child);
698 else
699 updateMenuList(item, 0);
700 last = item;
701 continue;
702 }
Mauro Carvalho Chehab60969f02020-04-02 11:28:03 +0200703hide:
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700704 if (item && item->menu == child) {
705 last = parent->firstChild();
706 if (last == item)
707 last = 0;
708 else while (last->nextSibling() != item)
709 last = last->nextSibling();
710 delete item;
711 }
712 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700713}
714
Masahiro Yamada5b75a6c2020-08-07 18:19:01 +0900715void ConfigList::updateMenuList(struct menu *menu)
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700716{
717 struct menu* child;
718 ConfigItem* item;
719 ConfigItem* last;
720 bool visible;
721 enum prop_type type;
722
723 if (!menu) {
Masahiro Yamada5b75a6c2020-08-07 18:19:01 +0900724 while (topLevelItemCount() > 0)
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700725 {
Masahiro Yamada5b75a6c2020-08-07 18:19:01 +0900726 delete takeTopLevelItem(0);
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700727 }
728
729 return;
730 }
731
Masahiro Yamada5b75a6c2020-08-07 18:19:01 +0900732 last = (ConfigItem *)topLevelItem(0);
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700733 if (last && !last->goParent)
734 last = 0;
735 for (child = menu->list; child; child = child->next) {
Masahiro Yamada5b75a6c2020-08-07 18:19:01 +0900736 item = last ? last->nextSibling() : (ConfigItem *)topLevelItem(0);
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700737 type = child->prompt ? child->prompt->type : P_UNKNOWN;
738
739 switch (mode) {
740 case menuMode:
741 if (!(child->flags & MENU_ROOT))
742 goto hide;
743 break;
744 case symbolMode:
745 if (child->flags & MENU_ROOT)
746 goto hide;
747 break;
748 default:
749 break;
750 }
751
752 visible = menu_is_visible(child);
753 if (!menuSkip(child)) {
754 if (!child->sym && !child->list && !child->prompt)
755 continue;
756 if (!item || item->menu != child)
Masahiro Yamada5b75a6c2020-08-07 18:19:01 +0900757 item = new ConfigItem(this, last, child, visible);
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700758 else
759 item->testUpdateMenu(visible);
760
761 if (mode == fullMode || mode == menuMode || type != P_MENU)
762 updateMenuList(item, child);
763 else
764 updateMenuList(item, 0);
765 last = item;
766 continue;
767 }
Mauro Carvalho Chehab60969f02020-04-02 11:28:03 +0200768hide:
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700769 if (item && item->menu == child) {
Masahiro Yamada5b75a6c2020-08-07 18:19:01 +0900770 last = (ConfigItem *)topLevelItem(0);
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700771 if (last == item)
772 last = 0;
773 else while (last->nextSibling() != item)
774 last = last->nextSibling();
775 delete item;
776 }
777 }
778}
779
Boris Barbulovski59e56442015-09-22 11:36:18 -0700780void ConfigList::keyPressEvent(QKeyEvent* ev)
781{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700782 QTreeWidgetItem* i = currentItem();
783 ConfigItem* item;
784 struct menu *menu;
785 enum prop_type type;
786
787 if (ev->key() == Qt::Key_Escape && mode != fullMode && mode != listMode) {
788 emit parentSelected();
789 ev->accept();
790 return;
791 }
792
793 if (!i) {
794 Parent::keyPressEvent(ev);
795 return;
796 }
797 item = (ConfigItem*)i;
798
799 switch (ev->key()) {
800 case Qt::Key_Return:
801 case Qt::Key_Enter:
802 if (item->goParent) {
803 emit parentSelected();
804 break;
805 }
806 menu = item->menu;
807 if (!menu)
808 break;
809 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
810 if (type == P_MENU && rootEntry != menu &&
811 mode != fullMode && mode != menuMode) {
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +0200812 if (mode == menuMode)
813 emit menuSelected(menu);
814 else
815 emit itemSelected(menu);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700816 break;
817 }
818 case Qt::Key_Space:
819 changeValue(item);
820 break;
821 case Qt::Key_N:
822 setValue(item, no);
823 break;
824 case Qt::Key_M:
825 setValue(item, mod);
826 break;
827 case Qt::Key_Y:
828 setValue(item, yes);
829 break;
830 default:
831 Parent::keyPressEvent(ev);
832 return;
833 }
834 ev->accept();
Boris Barbulovski59e56442015-09-22 11:36:18 -0700835}
836
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700837void ConfigList::mousePressEvent(QMouseEvent* e)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700838{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700839 //QPoint p(contentsToViewport(e->pos()));
840 //printf("contentsMousePressEvent: %d,%d\n", p.x(), p.y());
841 Parent::mousePressEvent(e);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700842}
843
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700844void ConfigList::mouseReleaseEvent(QMouseEvent* e)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700845{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700846 QPoint p = e->pos();
847 ConfigItem* item = (ConfigItem*)itemAt(p);
848 struct menu *menu;
849 enum prop_type ptype;
850 QIcon icon;
851 int idx, x;
852
853 if (!item)
854 goto skip;
855
856 menu = item->menu;
857 x = header()->offset() + p.x();
Boris Barbulovski76d53cb2015-09-22 11:36:35 -0700858 idx = header()->logicalIndexAt(x);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700859 switch (idx) {
860 case promptColIdx:
Masahiro Yamada711b8752020-08-07 18:19:03 +0900861 icon = item->icon(promptColIdx);
Boris Barbulovski76d53cb2015-09-22 11:36:35 -0700862 if (!icon.isNull()) {
863 int off = header()->sectionPosition(0) + visualRect(indexAt(p)).x() + 4; // 4 is Hardcoded image offset. There might be a way to do it properly.
864 if (x >= off && x < off + icon.availableSizes().first().width()) {
865 if (item->goParent) {
866 emit parentSelected();
867 break;
868 } else if (!menu)
869 break;
870 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
871 if (ptype == P_MENU && rootEntry != menu &&
Maxime Chretien7eb7c106f2020-07-08 15:32:15 +0200872 mode != fullMode && mode != menuMode &&
873 mode != listMode)
Boris Barbulovski76d53cb2015-09-22 11:36:35 -0700874 emit menuSelected(menu);
875 else
876 changeValue(item);
877 }
878 }
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700879 break;
880 case noColIdx:
881 setValue(item, no);
882 break;
883 case modColIdx:
884 setValue(item, mod);
885 break;
886 case yesColIdx:
887 setValue(item, yes);
888 break;
889 case dataColIdx:
890 changeValue(item);
891 break;
892 }
893
894skip:
895 //printf("contentsMouseReleaseEvent: %d,%d\n", p.x(), p.y());
896 Parent::mouseReleaseEvent(e);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700897}
898
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700899void ConfigList::mouseMoveEvent(QMouseEvent* e)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700900{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700901 //QPoint p(contentsToViewport(e->pos()));
902 //printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y());
903 Parent::mouseMoveEvent(e);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700904}
905
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700906void ConfigList::mouseDoubleClickEvent(QMouseEvent* e)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700907{
Mauro Carvalho Chehabe1f77692020-04-02 11:28:02 +0200908 QPoint p = e->pos();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700909 ConfigItem* item = (ConfigItem*)itemAt(p);
910 struct menu *menu;
911 enum prop_type ptype;
912
913 if (!item)
914 goto skip;
915 if (item->goParent) {
916 emit parentSelected();
917 goto skip;
918 }
919 menu = item->menu;
920 if (!menu)
921 goto skip;
922 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
Maxime Chretien7eb7c106f2020-07-08 15:32:15 +0200923 if (ptype == P_MENU && mode != listMode) {
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +0200924 if (mode == singleMode)
925 emit itemSelected(menu);
926 else if (mode == symbolMode)
927 emit menuSelected(menu);
928 } else if (menu->sym)
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700929 changeValue(item);
930
931skip:
932 //printf("contentsMouseDoubleClickEvent: %d,%d\n", p.x(), p.y());
933 Parent::mouseDoubleClickEvent(e);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700934}
935
936void ConfigList::focusInEvent(QFocusEvent *e)
937{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700938 struct menu *menu = NULL;
939
940 Parent::focusInEvent(e);
941
942 ConfigItem* item = (ConfigItem *)currentItem();
943 if (item) {
Mauro Carvalho Chehabb06c3ec2020-06-30 08:26:38 +0200944 setSelected(item, true);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700945 menu = item->menu;
946 }
947 emit gotFocus(menu);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700948}
949
950void ConfigList::contextMenuEvent(QContextMenuEvent *e)
951{
Masahiro Yamadafa8de0a2020-08-07 18:19:08 +0900952 if (!headerPopup) {
953 QAction *action;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700954
Masahiro Yamadafa8de0a2020-08-07 18:19:08 +0900955 headerPopup = new QMenu(this);
956 action = new QAction("Show Name", this);
957 action->setCheckable(true);
958 connect(action, SIGNAL(toggled(bool)),
959 parent(), SLOT(setShowName(bool)));
960 connect(parent(), SIGNAL(showNameChanged(bool)),
Masahiro Yamadad85de332020-08-18 01:36:29 +0900961 action, SLOT(setChecked(bool)));
Masahiro Yamadafa8de0a2020-08-07 18:19:08 +0900962 action->setChecked(showName);
963 headerPopup->addAction(action);
964
965 action = new QAction("Show Range", this);
966 action->setCheckable(true);
967 connect(action, SIGNAL(toggled(bool)),
968 parent(), SLOT(setShowRange(bool)));
969 connect(parent(), SIGNAL(showRangeChanged(bool)),
Masahiro Yamadad85de332020-08-18 01:36:29 +0900970 action, SLOT(setChecked(bool)));
Masahiro Yamadafa8de0a2020-08-07 18:19:08 +0900971 action->setChecked(showRange);
972 headerPopup->addAction(action);
Masahiro Yamadafa8de0a2020-08-07 18:19:08 +0900973 }
974
975 headerPopup->exec(e->globalPos());
976 e->accept();
Boris Barbulovski59e56442015-09-22 11:36:18 -0700977}
978
Masahiro Yamadaf9b918f2020-08-29 17:14:10 +0900979QList<ConfigList *> ConfigList::allLists;
Masahiro Yamadad4bbe8a2020-08-07 18:19:09 +0900980QAction *ConfigList::showNormalAction;
981QAction *ConfigList::showAllAction;
982QAction *ConfigList::showPromptAction;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700983
Roman Zippel7fc925f2006-06-08 22:12:46 -0700984ConfigView::ConfigView(QWidget* parent, const char *name)
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -0700985 : Parent(parent)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700986{
Boris Barbulovski9bd36ed2015-09-22 11:36:22 -0700987 setObjectName(name);
Boris Barbulovski29a70162015-09-22 11:36:10 -0700988 QVBoxLayout *verticalLayout = new QVBoxLayout(this);
Boris Barbulovski92298b42015-09-22 11:36:11 -0700989 verticalLayout->setContentsMargins(0, 0, 0, 0);
Boris Barbulovski29a70162015-09-22 11:36:10 -0700990
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700991 list = new ConfigList(this);
Boris Barbulovski29a70162015-09-22 11:36:10 -0700992 verticalLayout->addWidget(list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700993 lineEdit = new ConfigLineEdit(this);
994 lineEdit->hide();
Boris Barbulovski29a70162015-09-22 11:36:10 -0700995 verticalLayout->addWidget(lineEdit);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700996}
997
Roman Zippel7fc925f2006-06-08 22:12:46 -0700998void ConfigView::setShowName(bool b)
999{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001000 if (list->showName != b) {
1001 list->showName = b;
1002 list->reinit();
1003 emit showNameChanged(b);
1004 }
Roman Zippel7fc925f2006-06-08 22:12:46 -07001005}
1006
1007void ConfigView::setShowRange(bool b)
1008{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001009 if (list->showRange != b) {
1010 list->showRange = b;
1011 list->reinit();
1012 emit showRangeChanged(b);
1013 }
Roman Zippel7fc925f2006-06-08 22:12:46 -07001014}
1015
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001016void ConfigList::setAllOpen(bool open)
1017{
1018 QTreeWidgetItemIterator it(this);
1019
1020 while (*it) {
1021 (*it)->setExpanded(open);
1022
1023 ++it;
1024 }
Roman Zippel7fc925f2006-06-08 22:12:46 -07001025}
1026
Roman Zippel43bf6122006-06-08 22:12:45 -07001027ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name)
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001028 : Parent(parent), sym(0), _menu(0)
Roman Zippel43bf6122006-06-08 22:12:45 -07001029{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001030 setObjectName(name);
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001031 setOpenLinks(false);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001032
1033 if (!objectName().isEmpty()) {
1034 configSettings->beginGroup(objectName());
Boris Barbulovskie0393032016-11-30 14:57:52 -08001035 setShowDebug(configSettings->value("/showDebug", false).toBool());
Roman Zippel7fc925f2006-06-08 22:12:46 -07001036 configSettings->endGroup();
1037 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
1038 }
Masahiro Yamada7d1300e2020-08-18 01:36:30 +09001039
1040 contextMenu = createStandardContextMenu();
1041 QAction *action = new QAction("Show Debug Info", contextMenu);
1042
1043 action->setCheckable(true);
1044 connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
1045 connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setChecked(bool)));
1046 action->setChecked(showDebug());
1047 contextMenu->addSeparator();
1048 contextMenu->addAction(action);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001049}
1050
1051void ConfigInfoView::saveSettings(void)
1052{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001053 if (!objectName().isEmpty()) {
1054 configSettings->beginGroup(objectName());
1055 configSettings->setValue("/showDebug", showDebug());
1056 configSettings->endGroup();
1057 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001058}
1059
1060void ConfigInfoView::setShowDebug(bool b)
1061{
1062 if (_showDebug != b) {
1063 _showDebug = b;
Alexander Stein133c5f72010-08-31 17:34:37 +02001064 if (_menu)
Roman Zippel43bf6122006-06-08 22:12:45 -07001065 menuInfo();
Roman Zippelab45d192006-06-08 22:12:47 -07001066 else if (sym)
1067 symbolInfo();
Roman Zippel43bf6122006-06-08 22:12:45 -07001068 emit showDebugChanged(b);
1069 }
1070}
1071
1072void ConfigInfoView::setInfo(struct menu *m)
1073{
Alexander Stein133c5f72010-08-31 17:34:37 +02001074 if (_menu == m)
Roman Zippelb65a47e2006-06-08 22:12:47 -07001075 return;
Alexander Stein133c5f72010-08-31 17:34:37 +02001076 _menu = m;
Roman Zippel6fa1da82007-01-10 23:15:31 -08001077 sym = NULL;
Alexander Stein133c5f72010-08-31 17:34:37 +02001078 if (!_menu)
Roman Zippel43bf6122006-06-08 22:12:45 -07001079 clear();
Roman Zippel6fa1da82007-01-10 23:15:31 -08001080 else
Roman Zippel43bf6122006-06-08 22:12:45 -07001081 menuInfo();
1082}
1083
Roman Zippelab45d192006-06-08 22:12:47 -07001084void ConfigInfoView::symbolInfo(void)
1085{
1086 QString str;
1087
1088 str += "<big>Symbol: <b>";
1089 str += print_filter(sym->name);
1090 str += "</b></big><br><br>value: ";
1091 str += print_filter(sym_get_string_value(sym));
1092 str += "<br>visibility: ";
1093 str += sym->visible == yes ? "y" : sym->visible == mod ? "m" : "n";
1094 str += "<br>";
1095 str += debug_info(sym);
1096
1097 setText(str);
1098}
1099
Roman Zippel43bf6122006-06-08 22:12:45 -07001100void ConfigInfoView::menuInfo(void)
1101{
1102 struct symbol* sym;
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001103 QString info;
1104 QTextStream stream(&info);
Roman Zippel43bf6122006-06-08 22:12:45 -07001105
Alexander Stein133c5f72010-08-31 17:34:37 +02001106 sym = _menu->sym;
Roman Zippel43bf6122006-06-08 22:12:45 -07001107 if (sym) {
Alexander Stein133c5f72010-08-31 17:34:37 +02001108 if (_menu->prompt) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001109 stream << "<big><b>";
1110 stream << print_filter(_menu->prompt->text);
1111 stream << "</b></big>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001112 if (sym->name) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001113 stream << " (";
Roman Zippelab45d192006-06-08 22:12:47 -07001114 if (showDebug())
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001115 stream << "<a href=\"s" << sym->name << "\">";
1116 stream << print_filter(sym->name);
Roman Zippelab45d192006-06-08 22:12:47 -07001117 if (showDebug())
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001118 stream << "</a>";
1119 stream << ")";
Roman Zippel43bf6122006-06-08 22:12:45 -07001120 }
1121 } else if (sym->name) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001122 stream << "<big><b>";
Roman Zippelab45d192006-06-08 22:12:47 -07001123 if (showDebug())
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001124 stream << "<a href=\"s" << sym->name << "\">";
1125 stream << print_filter(sym->name);
Roman Zippelab45d192006-06-08 22:12:47 -07001126 if (showDebug())
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001127 stream << "</a>";
1128 stream << "</b></big>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001129 }
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001130 stream << "<br><br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001131
1132 if (showDebug())
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001133 stream << debug_info(sym);
1134
Masahiro Yamadaa46afd12020-09-14 23:59:48 +09001135 struct gstr help_gstr = str_new();
1136
1137 menu_get_ext_help(_menu, &help_gstr);
1138 stream << print_filter(str_get(&help_gstr));
1139 str_free(&help_gstr);
Alexander Stein133c5f72010-08-31 17:34:37 +02001140 } else if (_menu->prompt) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001141 stream << "<big><b>";
1142 stream << print_filter(_menu->prompt->text);
1143 stream << "</b></big><br><br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001144 if (showDebug()) {
Alexander Stein133c5f72010-08-31 17:34:37 +02001145 if (_menu->prompt->visible.expr) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001146 stream << "&nbsp;&nbsp;dep: ";
1147 expr_print(_menu->prompt->visible.expr,
1148 expr_print_help, &stream, E_NONE);
1149 stream << "<br><br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001150 }
Masahiro Yamadaa46afd12020-09-14 23:59:48 +09001151
1152 stream << "defined at " << _menu->file->name << ":"
1153 << _menu->lineno << "<br><br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001154 }
1155 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001156
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001157 setText(info);
Roman Zippel43bf6122006-06-08 22:12:45 -07001158}
1159
1160QString ConfigInfoView::debug_info(struct symbol *sym)
1161{
1162 QString debug;
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001163 QTextStream stream(&debug);
Roman Zippel43bf6122006-06-08 22:12:45 -07001164
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001165 stream << "type: ";
1166 stream << print_filter(sym_type_name(sym->type));
Roman Zippel43bf6122006-06-08 22:12:45 -07001167 if (sym_is_choice(sym))
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001168 stream << " (choice)";
Roman Zippel43bf6122006-06-08 22:12:45 -07001169 debug += "<br>";
1170 if (sym->rev_dep.expr) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001171 stream << "reverse dep: ";
1172 expr_print(sym->rev_dep.expr, expr_print_help, &stream, E_NONE);
1173 stream << "<br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001174 }
1175 for (struct property *prop = sym->prop; prop; prop = prop->next) {
1176 switch (prop->type) {
1177 case P_PROMPT:
1178 case P_MENU:
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001179 stream << "prompt: <a href=\"m" << sym->name << "\">";
1180 stream << print_filter(prop->text);
1181 stream << "</a><br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001182 break;
1183 case P_DEFAULT:
Roman Zippel93449082008-01-14 04:50:54 +01001184 case P_SELECT:
1185 case P_RANGE:
Mauro Carvalho Chehab8f8499a2020-06-30 08:48:53 +02001186 case P_COMMENT:
1187 case P_IMPLY:
1188 case P_SYMBOL:
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001189 stream << prop_get_type_name(prop->type);
1190 stream << ": ";
1191 expr_print(prop->expr, expr_print_help,
1192 &stream, E_NONE);
1193 stream << "<br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001194 break;
1195 case P_CHOICE:
1196 if (sym_is_choice(sym)) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001197 stream << "choice: ";
1198 expr_print(prop->expr, expr_print_help,
1199 &stream, E_NONE);
1200 stream << "<br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001201 }
1202 break;
Roman Zippel43bf6122006-06-08 22:12:45 -07001203 default:
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001204 stream << "unknown property: ";
1205 stream << prop_get_type_name(prop->type);
1206 stream << "<br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001207 }
1208 if (prop->visible.expr) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001209 stream << "&nbsp;&nbsp;&nbsp;&nbsp;dep: ";
1210 expr_print(prop->visible.expr, expr_print_help,
1211 &stream, E_NONE);
1212 stream << "<br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001213 }
1214 }
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001215 stream << "<br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001216
1217 return debug;
1218}
1219
1220QString ConfigInfoView::print_filter(const QString &str)
1221{
1222 QRegExp re("[<>&\"\\n]");
1223 QString res = str;
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001224 for (int i = 0; (i = res.indexOf(re, i)) >= 0;) {
1225 switch (res[i].toLatin1()) {
Roman Zippel43bf6122006-06-08 22:12:45 -07001226 case '<':
1227 res.replace(i, 1, "&lt;");
1228 i += 4;
1229 break;
1230 case '>':
1231 res.replace(i, 1, "&gt;");
1232 i += 4;
1233 break;
1234 case '&':
1235 res.replace(i, 1, "&amp;");
1236 i += 5;
1237 break;
1238 case '"':
1239 res.replace(i, 1, "&quot;");
1240 i += 6;
1241 break;
1242 case '\n':
1243 res.replace(i, 1, "<br>");
1244 i += 4;
1245 break;
1246 }
1247 }
1248 return res;
1249}
1250
Roman Zippelab45d192006-06-08 22:12:47 -07001251void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char *str)
Roman Zippel43bf6122006-06-08 22:12:45 -07001252{
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001253 QTextStream *stream = reinterpret_cast<QTextStream *>(data);
Roman Zippelab45d192006-06-08 22:12:47 -07001254
1255 if (sym && sym->name && !(sym->flags & SYMBOL_CONST)) {
Masahiro Yamada510bc3cb2020-08-21 02:43:28 +09001256 *stream << "<a href=\"s" << sym->name << "\">";
1257 *stream << print_filter(str);
1258 *stream << "</a>";
1259 } else {
1260 *stream << print_filter(str);
1261 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001262}
1263
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001264void ConfigInfoView::clicked(const QUrl &url)
1265{
1266 QByteArray str = url.toEncoded();
1267 const std::size_t count = str.size();
1268 char *data = new char[count + 1];
1269 struct symbol **result;
1270 struct menu *m = NULL;
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001271
1272 if (count < 1) {
Masahiro Yamadac9b09a922020-07-30 02:02:39 +09001273 delete[] data;
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001274 return;
1275 }
1276
1277 memcpy(data, str.constData(), count);
1278 data[count] = '\0';
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001279
1280 /* Seek for exact match */
1281 data[0] = '^';
1282 strcat(data, "$");
1283 result = sym_re_search(data);
1284 if (!result) {
Masahiro Yamadac9b09a922020-07-30 02:02:39 +09001285 delete[] data;
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001286 return;
1287 }
1288
1289 sym = *result;
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001290
Mauro Carvalho Chehab8a3b6e52020-06-30 08:48:35 +02001291 /* Seek for the menu which holds the symbol */
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001292 for (struct property *prop = sym->prop; prop; prop = prop->next) {
1293 if (prop->type != P_PROMPT && prop->type != P_MENU)
1294 continue;
1295 m = prop->menu;
1296 break;
1297 }
1298
1299 if (!m) {
Mauro Carvalho Chehab8a3b6e52020-06-30 08:48:35 +02001300 /* Symbol is not visible as a menu */
1301 symbolInfo();
1302 emit showDebugChanged(true);
1303 } else {
1304 emit menuSelected(m);
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001305 }
1306
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001307 free(result);
Masahiro Yamadaa608b6a2020-09-09 07:16:37 +09001308 delete[] data;
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001309}
1310
Masahiro Yamada7d1300e2020-08-18 01:36:30 +09001311void ConfigInfoView::contextMenuEvent(QContextMenuEvent *event)
Roman Zippel7fc925f2006-06-08 22:12:46 -07001312{
Masahiro Yamada7d1300e2020-08-18 01:36:30 +09001313 contextMenu->popup(event->globalPos());
1314 event->accept();
Roman Zippel7fc925f2006-06-08 22:12:46 -07001315}
1316
Masahiro Yamada740fdef2020-08-07 18:18:57 +09001317ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow *parent)
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001318 : Parent(parent), result(NULL)
Roman Zippel43bf6122006-06-08 22:12:45 -07001319{
Masahiro Yamada740fdef2020-08-07 18:18:57 +09001320 setObjectName("search");
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001321 setWindowTitle("Search Config");
Roman Zippel43bf6122006-06-08 22:12:45 -07001322
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001323 QVBoxLayout* layout1 = new QVBoxLayout(this);
1324 layout1->setContentsMargins(11, 11, 11, 11);
1325 layout1->setSpacing(6);
Masahiro Yamada92641152020-08-07 18:18:58 +09001326
1327 QHBoxLayout* layout2 = new QHBoxLayout();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001328 layout2->setContentsMargins(0, 0, 0, 0);
1329 layout2->setSpacing(6);
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001330 layout2->addWidget(new QLabel("Find:", this));
Roman Zippel43bf6122006-06-08 22:12:45 -07001331 editField = new QLineEdit(this);
1332 connect(editField, SIGNAL(returnPressed()), SLOT(search()));
1333 layout2->addWidget(editField);
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001334 searchButton = new QPushButton("Search", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001335 searchButton->setAutoDefault(false);
Roman Zippel43bf6122006-06-08 22:12:45 -07001336 connect(searchButton, SIGNAL(clicked()), SLOT(search()));
1337 layout2->addWidget(searchButton);
1338 layout1->addLayout(layout2);
1339
Roman Zippel7fc925f2006-06-08 22:12:46 -07001340 split = new QSplitter(this);
Markus Heidelberg7298b932009-05-18 01:36:50 +02001341 split->setOrientation(Qt::Vertical);
Masahiro Yamada740fdef2020-08-07 18:18:57 +09001342 list = new ConfigView(split, "search");
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001343 list->list->mode = listMode;
Masahiro Yamada740fdef2020-08-07 18:18:57 +09001344 info = new ConfigInfoView(split, "search");
Roman Zippel43bf6122006-06-08 22:12:45 -07001345 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1346 info, SLOT(setInfo(struct menu *)));
Marco Costalba63431e72006-10-05 19:12:59 +02001347 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1348 parent, SLOT(setMenuLink(struct menu *)));
1349
Roman Zippel43bf6122006-06-08 22:12:45 -07001350 layout1->addWidget(split);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001351
Masahiro Yamada740fdef2020-08-07 18:18:57 +09001352 QVariant x, y;
1353 int width, height;
1354 bool ok;
Roman Zippel7fc925f2006-06-08 22:12:46 -07001355
Masahiro Yamada740fdef2020-08-07 18:18:57 +09001356 configSettings->beginGroup("search");
1357 width = configSettings->value("/window width", parent->width() / 2).toInt();
1358 height = configSettings->value("/window height", parent->height() / 2).toInt();
1359 resize(width, height);
1360 x = configSettings->value("/window x");
1361 y = configSettings->value("/window y");
1362 if (x.isValid() && y.isValid())
1363 move(x.toInt(), y.toInt());
1364 QList<int> sizes = configSettings->readSizes("/split", &ok);
1365 if (ok)
1366 split->setSizes(sizes);
1367 configSettings->endGroup();
1368 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
Roman Zippel7fc925f2006-06-08 22:12:46 -07001369}
1370
1371void ConfigSearchWindow::saveSettings(void)
1372{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001373 if (!objectName().isEmpty()) {
1374 configSettings->beginGroup(objectName());
1375 configSettings->setValue("/window x", pos().x());
1376 configSettings->setValue("/window y", pos().y());
1377 configSettings->setValue("/window width", size().width());
1378 configSettings->setValue("/window height", size().height());
1379 configSettings->writeSizes("/split", split->sizes());
1380 configSettings->endGroup();
1381 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001382}
1383
1384void ConfigSearchWindow::search(void)
1385{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001386 struct symbol **p;
1387 struct property *prop;
1388 ConfigItem *lastItem = NULL;
1389
1390 free(result);
1391 list->list->clear();
1392 info->clear();
1393
1394 result = sym_re_search(editField->text().toLatin1());
1395 if (!result)
1396 return;
1397 for (p = result; *p; p++) {
1398 for_all_prompts((*p), prop)
1399 lastItem = new ConfigItem(list->list, lastItem, prop->menu,
1400 menu_is_visible(prop->menu));
1401 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001402}
1403
Linus Torvalds1da177e2005-04-16 15:20:36 -07001404/*
1405 * Construct the complete config widget
1406 */
1407ConfigMainWindow::ConfigMainWindow(void)
Roman Zippelf12aa702006-11-25 11:09:31 -08001408 : searchWindow(0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001409{
Boris Barbulovski92119932015-09-22 11:36:16 -07001410 bool ok = true;
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001411 QVariant x, y;
1412 int width, height;
Randy Dunlapa54bb702007-10-20 11:18:47 -07001413 char title[256];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001414
Markus Heidelberg8d90c972009-05-18 01:36:52 +02001415 QDesktopWidget *d = configApp->desktop();
Arnaud Lacombe09548282010-08-18 01:57:13 -04001416 snprintf(title, sizeof(title), "%s%s",
1417 rootmenu.prompt->text,
Michal Marek76a136c2010-09-01 17:39:27 +02001418 ""
Michal Marek76a136c2010-09-01 17:39:27 +02001419 );
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001420 setWindowTitle(title);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001421
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001422 width = configSettings->value("/window width", d->width() - 64).toInt();
1423 height = configSettings->value("/window height", d->height() - 64).toInt();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001424 resize(width, height);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001425 x = configSettings->value("/window x");
1426 y = configSettings->value("/window y");
1427 if ((x.isValid())&&(y.isValid()))
1428 move(x.toInt(), y.toInt());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001429
Masahiro Yamada5cb255f2020-08-07 18:19:07 +09001430 // set up icons
1431 ConfigItem::symbolYesIcon = QIcon(QPixmap(xpm_symbol_yes));
1432 ConfigItem::symbolModIcon = QIcon(QPixmap(xpm_symbol_mod));
1433 ConfigItem::symbolNoIcon = QIcon(QPixmap(xpm_symbol_no));
1434 ConfigItem::choiceYesIcon = QIcon(QPixmap(xpm_choice_yes));
1435 ConfigItem::choiceNoIcon = QIcon(QPixmap(xpm_choice_no));
1436 ConfigItem::menuIcon = QIcon(QPixmap(xpm_menu));
1437 ConfigItem::menubackIcon = QIcon(QPixmap(xpm_menuback));
1438
Mauro Carvalho Chehabcce1fab2020-04-02 11:28:00 +02001439 QWidget *widget = new QWidget(this);
1440 QVBoxLayout *layout = new QVBoxLayout(widget);
1441 setCentralWidget(widget);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001442
Mauro Carvalho Chehabcce1fab2020-04-02 11:28:00 +02001443 split1 = new QSplitter(widget);
1444 split1->setOrientation(Qt::Horizontal);
1445 split1->setChildrenCollapsible(false);
1446
1447 menuView = new ConfigView(widget, "menu");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001448 menuList = menuView->list;
1449
Mauro Carvalho Chehabcce1fab2020-04-02 11:28:00 +02001450 split2 = new QSplitter(widget);
1451 split2->setChildrenCollapsible(false);
Markus Heidelberg7298b932009-05-18 01:36:50 +02001452 split2->setOrientation(Qt::Vertical);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001453
1454 // create config tree
Mauro Carvalho Chehabcce1fab2020-04-02 11:28:00 +02001455 configView = new ConfigView(widget, "config");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001456 configList = configView->list;
1457
Mauro Carvalho Chehabcce1fab2020-04-02 11:28:00 +02001458 helpText = new ConfigInfoView(widget, "help");
1459
1460 layout->addWidget(split2);
1461 split2->addWidget(split1);
1462 split1->addWidget(configView);
1463 split1->addWidget(menuView);
1464 split2->addWidget(helpText);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001465
1466 setTabOrder(configList, helpText);
1467 configList->setFocus();
1468
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001469 backAction = new QAction(QPixmap(xpm_back), "Back", this);
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001470 connect(backAction, SIGNAL(triggered(bool)), SLOT(goBack()));
1471
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001472 QAction *quitAction = new QAction("&Quit", this);
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001473 quitAction->setShortcut(Qt::CTRL + Qt::Key_Q);
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001474 connect(quitAction, SIGNAL(triggered(bool)), SLOT(close()));
1475
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001476 QAction *loadAction = new QAction(QPixmap(xpm_load), "&Load", this);
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001477 loadAction->setShortcut(Qt::CTRL + Qt::Key_L);
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001478 connect(loadAction, SIGNAL(triggered(bool)), SLOT(loadConfig()));
1479
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001480 saveAction = new QAction(QPixmap(xpm_save), "&Save", this);
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001481 saveAction->setShortcut(Qt::CTRL + Qt::Key_S);
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001482 connect(saveAction, SIGNAL(triggered(bool)), SLOT(saveConfig()));
1483
Karsten Wiese3b354c52006-12-13 00:34:08 -08001484 conf_set_changed_callback(conf_changed);
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001485
Karsten Wiese3b354c52006-12-13 00:34:08 -08001486 // Set saveAction's initial state
1487 conf_changed();
Masahiro Yamada87419082019-03-11 01:13:15 +09001488 configname = xstrdup(conf_get_configname());
1489
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001490 QAction *saveAsAction = new QAction("Save &As...", this);
Boris Barbulovski92119932015-09-22 11:36:16 -07001491 connect(saveAsAction, SIGNAL(triggered(bool)), SLOT(saveConfigAs()));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001492 QAction *searchAction = new QAction("&Find", this);
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001493 searchAction->setShortcut(Qt::CTRL + Qt::Key_F);
Boris Barbulovski92119932015-09-22 11:36:16 -07001494 connect(searchAction, SIGNAL(triggered(bool)), SLOT(searchConfig()));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001495 singleViewAction = new QAction(QPixmap(xpm_single_view), "Single View", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001496 singleViewAction->setCheckable(true);
Boris Barbulovski92119932015-09-22 11:36:16 -07001497 connect(singleViewAction, SIGNAL(triggered(bool)), SLOT(showSingleView()));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001498 splitViewAction = new QAction(QPixmap(xpm_split_view), "Split View", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001499 splitViewAction->setCheckable(true);
Boris Barbulovski92119932015-09-22 11:36:16 -07001500 connect(splitViewAction, SIGNAL(triggered(bool)), SLOT(showSplitView()));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001501 fullViewAction = new QAction(QPixmap(xpm_tree_view), "Full View", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001502 fullViewAction->setCheckable(true);
Boris Barbulovski92119932015-09-22 11:36:16 -07001503 connect(fullViewAction, SIGNAL(triggered(bool)), SLOT(showFullView()));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001504
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001505 QAction *showNameAction = new QAction("Show Name", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001506 showNameAction->setCheckable(true);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001507 connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool)));
Boris Barbulovski9c862352015-09-22 11:36:12 -07001508 showNameAction->setChecked(configView->showName());
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001509 QAction *showRangeAction = new QAction("Show Range", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001510 showRangeAction->setCheckable(true);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001511 connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool)));
Li Zefan39a48972010-05-10 16:33:41 +08001512
1513 QActionGroup *optGroup = new QActionGroup(this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001514 optGroup->setExclusive(true);
Masahiro Yamadad4bbe8a2020-08-07 18:19:09 +09001515 connect(optGroup, SIGNAL(triggered(QAction*)), configList,
Li Zefan39a48972010-05-10 16:33:41 +08001516 SLOT(setOptionMode(QAction *)));
Masahiro Yamadad4bbe8a2020-08-07 18:19:09 +09001517 connect(optGroup, SIGNAL(triggered(QAction *)), menuList,
Li Zefan39a48972010-05-10 16:33:41 +08001518 SLOT(setOptionMode(QAction *)));
1519
Masahiro Yamadad4bbe8a2020-08-07 18:19:09 +09001520 ConfigList::showNormalAction = new QAction("Show Normal Options", optGroup);
1521 ConfigList::showNormalAction->setCheckable(true);
1522 ConfigList::showAllAction = new QAction("Show All Options", optGroup);
1523 ConfigList::showAllAction->setCheckable(true);
1524 ConfigList::showPromptAction = new QAction("Show Prompt Options", optGroup);
1525 ConfigList::showPromptAction->setCheckable(true);
Li Zefan39a48972010-05-10 16:33:41 +08001526
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001527 QAction *showDebugAction = new QAction("Show Debug Info", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001528 showDebugAction->setCheckable(true);
Roman Zippel43bf6122006-06-08 22:12:45 -07001529 connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
Boris Barbulovski9c862352015-09-22 11:36:12 -07001530 showDebugAction->setChecked(helpText->showDebug());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001531
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001532 QAction *showIntroAction = new QAction("Introduction", this);
Boris Barbulovski92119932015-09-22 11:36:16 -07001533 connect(showIntroAction, SIGNAL(triggered(bool)), SLOT(showIntro()));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001534 QAction *showAboutAction = new QAction("About", this);
Boris Barbulovski92119932015-09-22 11:36:16 -07001535 connect(showAboutAction, SIGNAL(triggered(bool)), SLOT(showAbout()));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001536
1537 // init tool bar
Masahiro Yamada860ec3f2020-08-07 18:18:55 +09001538 QToolBar *toolBar = addToolBar("Tools");
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001539 toolBar->addAction(backAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001540 toolBar->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001541 toolBar->addAction(loadAction);
1542 toolBar->addAction(saveAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001543 toolBar->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001544 toolBar->addAction(singleViewAction);
1545 toolBar->addAction(splitViewAction);
1546 toolBar->addAction(fullViewAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001547
Masahiro Yamada93ebaac2020-08-07 18:18:53 +09001548 // create file menu
1549 QMenu *menu = menuBar()->addMenu("&File");
1550 menu->addAction(loadAction);
1551 menu->addAction(saveAction);
1552 menu->addAction(saveAsAction);
1553 menu->addSeparator();
1554 menu->addAction(quitAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001555
Shlomi Fish66e7c722007-02-14 00:32:58 -08001556 // create edit menu
Masahiro Yamada93ebaac2020-08-07 18:18:53 +09001557 menu = menuBar()->addMenu("&Edit");
1558 menu->addAction(searchAction);
Shlomi Fish66e7c722007-02-14 00:32:58 -08001559
Linus Torvalds1da177e2005-04-16 15:20:36 -07001560 // create options menu
Masahiro Yamada93ebaac2020-08-07 18:18:53 +09001561 menu = menuBar()->addMenu("&Option");
1562 menu->addAction(showNameAction);
1563 menu->addAction(showRangeAction);
Masahiro Yamada93ebaac2020-08-07 18:18:53 +09001564 menu->addSeparator();
1565 menu->addActions(optGroup->actions());
1566 menu->addSeparator();
1567 menu->addAction(showDebugAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001568
1569 // create help menu
Masahiro Yamada93ebaac2020-08-07 18:18:53 +09001570 menu = menuBar()->addMenu("&Help");
1571 menu->addAction(showIntroAction);
1572 menu->addAction(showAboutAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001573
Mauro Carvalho Chehabc4f73982020-06-30 08:26:37 +02001574 connect (helpText, SIGNAL (anchorClicked (const QUrl &)),
1575 helpText, SLOT (clicked (const QUrl &)) );
1576
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001577 connect(configList, SIGNAL(menuChanged(struct menu *)),
1578 helpText, SLOT(setInfo(struct menu *)));
1579 connect(configList, SIGNAL(menuSelected(struct menu *)),
1580 SLOT(changeMenu(struct menu *)));
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +02001581 connect(configList, SIGNAL(itemSelected(struct menu *)),
1582 SLOT(changeItens(struct menu *)));
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001583 connect(configList, SIGNAL(parentSelected()),
1584 SLOT(goBack()));
1585 connect(menuList, SIGNAL(menuChanged(struct menu *)),
1586 helpText, SLOT(setInfo(struct menu *)));
1587 connect(menuList, SIGNAL(menuSelected(struct menu *)),
1588 SLOT(changeMenu(struct menu *)));
1589
1590 connect(configList, SIGNAL(gotFocus(struct menu *)),
1591 helpText, SLOT(setInfo(struct menu *)));
1592 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1593 helpText, SLOT(setInfo(struct menu *)));
1594 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1595 SLOT(listFocusChanged(void)));
Roman Zippelb65a47e2006-06-08 22:12:47 -07001596 connect(helpText, SIGNAL(menuSelected(struct menu *)),
1597 SLOT(setMenuLink(struct menu *)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001598
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001599 QString listMode = configSettings->value("/listMode", "symbol").toString();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001600 if (listMode == "single")
1601 showSingleView();
1602 else if (listMode == "full")
1603 showFullView();
1604 else /*if (listMode == "split")*/
1605 showSplitView();
1606
1607 // UI setup done, restore splitter positions
Boris Barbulovski041fbdc2015-09-22 11:36:05 -07001608 QList<int> sizes = configSettings->readSizes("/split1", &ok);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001609 if (ok)
1610 split1->setSizes(sizes);
1611
Roman Zippel7fc925f2006-06-08 22:12:46 -07001612 sizes = configSettings->readSizes("/split2", &ok);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001613 if (ok)
1614 split2->setSizes(sizes);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001615}
1616
Linus Torvalds1da177e2005-04-16 15:20:36 -07001617void ConfigMainWindow::loadConfig(void)
1618{
Masahiro Yamada87419082019-03-11 01:13:15 +09001619 QString str;
1620 QByteArray ba;
1621 const char *name;
1622
1623 str = QFileDialog::getOpenFileName(this, "", configname);
1624 if (str.isNull())
Linus Torvalds1da177e2005-04-16 15:20:36 -07001625 return;
Masahiro Yamada87419082019-03-11 01:13:15 +09001626
1627 ba = str.toLocal8Bit();
1628 name = ba.data();
1629
1630 if (conf_read(name))
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001631 QMessageBox::information(this, "qconf", "Unable to load configuration!");
Masahiro Yamada87419082019-03-11 01:13:15 +09001632
1633 free(configname);
1634 configname = xstrdup(name);
1635
Masahiro Yamadaf9b918f2020-08-29 17:14:10 +09001636 ConfigList::updateListAllForAll();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001637}
1638
Michal Marekbac6aa82011-05-25 15:10:25 +02001639bool ConfigMainWindow::saveConfig(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001640{
Masahiro Yamada87419082019-03-11 01:13:15 +09001641 if (conf_write(configname)) {
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001642 QMessageBox::information(this, "qconf", "Unable to save configuration!");
Michal Marekbac6aa82011-05-25 15:10:25 +02001643 return false;
1644 }
Masahiro Yamada00c864f2018-07-20 16:46:31 +09001645 conf_write_autoconf(0);
1646
Michal Marekbac6aa82011-05-25 15:10:25 +02001647 return true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001648}
1649
1650void ConfigMainWindow::saveConfigAs(void)
1651{
Masahiro Yamada87419082019-03-11 01:13:15 +09001652 QString str;
1653 QByteArray ba;
1654 const char *name;
1655
1656 str = QFileDialog::getSaveFileName(this, "", configname);
1657 if (str.isNull())
Linus Torvalds1da177e2005-04-16 15:20:36 -07001658 return;
Masahiro Yamada87419082019-03-11 01:13:15 +09001659
1660 ba = str.toLocal8Bit();
1661 name = ba.data();
1662
1663 if (conf_write(name)) {
1664 QMessageBox::information(this, "qconf", "Unable to save configuration!");
1665 }
1666 conf_write_autoconf(0);
1667
1668 free(configname);
1669 configname = xstrdup(name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001670}
1671
Roman Zippel43bf6122006-06-08 22:12:45 -07001672void ConfigMainWindow::searchConfig(void)
1673{
1674 if (!searchWindow)
Masahiro Yamada740fdef2020-08-07 18:18:57 +09001675 searchWindow = new ConfigSearchWindow(this);
Roman Zippel43bf6122006-06-08 22:12:45 -07001676 searchWindow->show();
1677}
1678
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +02001679void ConfigMainWindow::changeItens(struct menu *menu)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001680{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001681 configList->setRootMenu(menu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001682}
1683
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +02001684void ConfigMainWindow::changeMenu(struct menu *menu)
1685{
1686 menuList->setRootMenu(menu);
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +02001687}
1688
Roman Zippelb65a47e2006-06-08 22:12:47 -07001689void ConfigMainWindow::setMenuLink(struct menu *menu)
1690{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001691 struct menu *parent;
1692 ConfigList* list = NULL;
1693 ConfigItem* item;
1694
1695 if (configList->menuSkip(menu))
1696 return;
1697
1698 switch (configList->mode) {
1699 case singleMode:
1700 list = configList;
1701 parent = menu_get_parent_menu(menu);
1702 if (!parent)
1703 return;
1704 list->setRootMenu(parent);
1705 break;
Mauro Carvalho Chehabc699eaa2020-06-30 08:26:36 +02001706 case menuMode:
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001707 if (menu->flags & MENU_ROOT) {
Mauro Carvalho Chehabc699eaa2020-06-30 08:26:36 +02001708 menuList->setRootMenu(menu);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001709 configList->clearSelection();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001710 list = configList;
Mauro Carvalho Chehabc699eaa2020-06-30 08:26:36 +02001711 } else {
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001712 parent = menu_get_parent_menu(menu->parent);
1713 if (!parent)
1714 return;
Mauro Carvalho Chehabc699eaa2020-06-30 08:26:36 +02001715
Mauro Carvalho Chehabc699eaa2020-06-30 08:26:36 +02001716 /* Select the config view */
1717 item = configList->findConfigItem(parent);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001718 if (item) {
Mauro Carvalho Chehabb06c3ec2020-06-30 08:26:38 +02001719 configList->setSelected(item, true);
Mauro Carvalho Chehabc699eaa2020-06-30 08:26:36 +02001720 configList->scrollToItem(item);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001721 }
Mauro Carvalho Chehabc699eaa2020-06-30 08:26:36 +02001722
1723 menuList->setRootMenu(parent);
1724 menuList->clearSelection();
1725 list = menuList;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001726 }
1727 break;
1728 case fullMode:
1729 list = configList;
1730 break;
1731 default:
1732 break;
1733 }
1734
1735 if (list) {
1736 item = list->findConfigItem(menu);
1737 if (item) {
Mauro Carvalho Chehabb06c3ec2020-06-30 08:26:38 +02001738 list->setSelected(item, true);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001739 list->scrollToItem(item);
1740 list->setFocus();
Mauro Carvalho Chehab8a3b6e52020-06-30 08:48:35 +02001741 helpText->setInfo(menu);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001742 }
1743 }
Roman Zippelb65a47e2006-06-08 22:12:47 -07001744}
1745
Linus Torvalds1da177e2005-04-16 15:20:36 -07001746void ConfigMainWindow::listFocusChanged(void)
1747{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001748 if (menuList->mode == menuMode)
1749 configList->clearSelection();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001750}
1751
1752void ConfigMainWindow::goBack(void)
1753{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001754 if (configList->rootEntry == &rootmenu)
Boris Barbulovskibe596aa2015-09-22 11:36:28 -07001755 return;
1756
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001757 configList->setParentMenu();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001758}
1759
1760void ConfigMainWindow::showSingleView(void)
1761{
Boris Barbulovski780505e2015-09-22 11:36:13 -07001762 singleViewAction->setEnabled(false);
1763 singleViewAction->setChecked(true);
1764 splitViewAction->setEnabled(true);
1765 splitViewAction->setChecked(false);
1766 fullViewAction->setEnabled(true);
1767 fullViewAction->setChecked(false);
1768
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001769 backAction->setEnabled(true);
1770
Linus Torvalds1da177e2005-04-16 15:20:36 -07001771 menuView->hide();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001772 menuList->setRootMenu(0);
1773 configList->mode = singleMode;
1774 if (configList->rootEntry == &rootmenu)
1775 configList->updateListAll();
1776 else
1777 configList->setRootMenu(&rootmenu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001778 configList->setFocus();
1779}
1780
1781void ConfigMainWindow::showSplitView(void)
1782{
Boris Barbulovski780505e2015-09-22 11:36:13 -07001783 singleViewAction->setEnabled(true);
1784 singleViewAction->setChecked(false);
1785 splitViewAction->setEnabled(false);
1786 splitViewAction->setChecked(true);
1787 fullViewAction->setEnabled(true);
1788 fullViewAction->setChecked(false);
1789
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001790 backAction->setEnabled(false);
1791
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +02001792 configList->mode = menuMode;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001793 if (configList->rootEntry == &rootmenu)
1794 configList->updateListAll();
1795 else
1796 configList->setRootMenu(&rootmenu);
1797 configList->setAllOpen(true);
1798 configApp->processEvents();
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +02001799 menuList->mode = symbolMode;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001800 menuList->setRootMenu(&rootmenu);
1801 menuList->setAllOpen(true);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001802 menuView->show();
1803 menuList->setFocus();
1804}
1805
1806void ConfigMainWindow::showFullView(void)
1807{
Boris Barbulovski780505e2015-09-22 11:36:13 -07001808 singleViewAction->setEnabled(true);
1809 singleViewAction->setChecked(false);
1810 splitViewAction->setEnabled(true);
1811 splitViewAction->setChecked(false);
1812 fullViewAction->setEnabled(false);
1813 fullViewAction->setChecked(true);
1814
Mauro Carvalho Chehabaf737b4d2020-06-30 08:26:39 +02001815 backAction->setEnabled(false);
1816
Linus Torvalds1da177e2005-04-16 15:20:36 -07001817 menuView->hide();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001818 menuList->setRootMenu(0);
1819 configList->mode = fullMode;
1820 if (configList->rootEntry == &rootmenu)
1821 configList->updateListAll();
1822 else
1823 configList->setRootMenu(&rootmenu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001824 configList->setFocus();
1825}
1826
Linus Torvalds1da177e2005-04-16 15:20:36 -07001827/*
1828 * ask for saving configuration before quitting
Linus Torvalds1da177e2005-04-16 15:20:36 -07001829 */
1830void ConfigMainWindow::closeEvent(QCloseEvent* e)
1831{
Karsten Wieseb3214292006-12-13 00:34:06 -08001832 if (!conf_get_changed()) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001833 e->accept();
1834 return;
1835 }
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001836 QMessageBox mb("qconf", "Save configuration?", QMessageBox::Warning,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001837 QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape);
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001838 mb.setButtonText(QMessageBox::Yes, "&Save Changes");
1839 mb.setButtonText(QMessageBox::No, "&Discard Changes");
1840 mb.setButtonText(QMessageBox::Cancel, "Cancel Exit");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001841 switch (mb.exec()) {
1842 case QMessageBox::Yes:
Michal Marekbac6aa82011-05-25 15:10:25 +02001843 if (saveConfig())
1844 e->accept();
1845 else
1846 e->ignore();
1847 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001848 case QMessageBox::No:
1849 e->accept();
1850 break;
1851 case QMessageBox::Cancel:
1852 e->ignore();
1853 break;
1854 }
1855}
1856
1857void ConfigMainWindow::showIntro(void)
1858{
Masahiro Yamada8c30e7e2020-08-29 17:14:07 +09001859 static const QString str =
1860 "Welcome to the qconf graphical configuration tool.\n"
1861 "\n"
Masahiro Yamada37162a62020-08-29 17:14:12 +09001862 "For bool and tristate options, a blank box indicates the "
1863 "feature is disabled, a check indicates it is enabled, and a "
1864 "dot indicates that it is to be compiled as a module. Clicking "
1865 "on the box will cycle through the three states. For int, hex, "
1866 "and string options, double-clicking or pressing F2 on the "
1867 "Value cell will allow you to edit the value.\n"
Masahiro Yamada8c30e7e2020-08-29 17:14:07 +09001868 "\n"
1869 "If you do not see an option (e.g., a device driver) that you "
1870 "believe should be present, try turning on Show All Options "
Masahiro Yamada1fb75242020-08-29 17:14:08 +09001871 "under the Options menu. Enabling Show Debug Info will help you"
1872 "figure out what other options must be enabled to support the "
1873 "option you are interested in, and hyperlinks will navigate to "
1874 "them.\n"
Masahiro Yamada8c30e7e2020-08-29 17:14:07 +09001875 "\n"
1876 "Toggling Show Debug Info under the Options menu will show the "
1877 "dependencies, which you can then match by examining other "
1878 "options.\n";
Linus Torvalds1da177e2005-04-16 15:20:36 -07001879
1880 QMessageBox::information(this, "qconf", str);
1881}
1882
1883void ConfigMainWindow::showAbout(void)
1884{
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001885 static const QString str = "qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n"
Boris Barbulovskib4ff1de2015-09-22 11:36:38 -07001886 "Copyright (C) 2015 Boris Barbulovski <bbarbulovski@gmail.com>.\n\n"
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001887 "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n";
Linus Torvalds1da177e2005-04-16 15:20:36 -07001888
1889 QMessageBox::information(this, "qconf", str);
1890}
1891
1892void ConfigMainWindow::saveSettings(void)
1893{
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001894 configSettings->setValue("/window x", pos().x());
1895 configSettings->setValue("/window y", pos().y());
1896 configSettings->setValue("/window width", size().width());
1897 configSettings->setValue("/window height", size().height());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001898
1899 QString entry;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001900 switch(configList->mode) {
1901 case singleMode :
1902 entry = "single";
1903 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001904
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001905 case symbolMode :
1906 entry = "split";
1907 break;
1908
1909 case fullMode :
1910 entry = "full";
1911 break;
1912
1913 default:
1914 break;
1915 }
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001916 configSettings->setValue("/listMode", entry);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001917
Roman Zippel7fc925f2006-06-08 22:12:46 -07001918 configSettings->writeSizes("/split1", split1->sizes());
1919 configSettings->writeSizes("/split2", split2->sizes());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001920}
1921
Karsten Wiese3b354c52006-12-13 00:34:08 -08001922void ConfigMainWindow::conf_changed(void)
1923{
1924 if (saveAction)
1925 saveAction->setEnabled(conf_get_changed());
1926}
1927
Linus Torvalds1da177e2005-04-16 15:20:36 -07001928void fixup_rootmenu(struct menu *menu)
1929{
1930 struct menu *child;
1931 static int menu_cnt = 0;
1932
1933 menu->flags |= MENU_ROOT;
1934 for (child = menu->list; child; child = child->next) {
1935 if (child->prompt && child->prompt->type == P_MENU) {
1936 menu_cnt++;
1937 fixup_rootmenu(child);
1938 menu_cnt--;
1939 } else if (!menu_cnt)
1940 fixup_rootmenu(child);
1941 }
1942}
1943
1944static const char *progname;
1945
1946static void usage(void)
1947{
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001948 printf("%s [-s] <config>\n", progname);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001949 exit(0);
1950}
1951
1952int main(int ac, char** av)
1953{
1954 ConfigMainWindow* v;
1955 const char *name;
1956
Linus Torvalds1da177e2005-04-16 15:20:36 -07001957 progname = av[0];
1958 configApp = new QApplication(ac, av);
1959 if (ac > 1 && av[1][0] == '-') {
1960 switch (av[1][1]) {
Michal Marek0a1f00a2015-04-08 13:30:42 +02001961 case 's':
1962 conf_set_message_callback(NULL);
1963 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001964 case 'h':
1965 case '?':
1966 usage();
1967 }
1968 name = av[2];
1969 } else
1970 name = av[1];
1971 if (!name)
1972 usage();
1973
1974 conf_parse(name);
1975 fixup_rootmenu(&rootmenu);
1976 conf_read(NULL);
1977 //zconfdump(stdout);
1978
Roman Zippel7fc925f2006-06-08 22:12:46 -07001979 configSettings = new ConfigSettings();
1980 configSettings->beginGroup("/kconfig/qconf");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001981 v = new ConfigMainWindow();
1982
1983 //zconfdump(stdout);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001984 configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit()));
1985 configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings()));
Roman Zippel43bf6122006-06-08 22:12:45 -07001986 v->show();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001987 configApp->exec();
1988
Roman Zippel7fc925f2006-06-08 22:12:46 -07001989 configSettings->endGroup();
1990 delete configSettings;
Chris Bainbridge5b61c7b2016-01-08 20:44:04 +00001991 delete v;
1992 delete configApp;
Roman Zippel7fc925f2006-06-08 22:12:46 -07001993
Linus Torvalds1da177e2005-04-16 15:20:36 -07001994 return 0;
1995}