blob: c0ac8f7b5f1abd532300cad586b47ed8e4d78ad3 [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
Alexander Stein133c5f72010-08-31 17:34:37 +02007#include <qglobal.h>
8
Boris Barbulovskib1f8a452015-09-22 11:36:02 -07009#include <QMainWindow>
Boris Barbulovski041fbdc2015-09-22 11:36:05 -070010#include <QList>
Boris Barbulovski924bbb52015-09-22 11:36:06 -070011#include <qtextbrowser.h>
Boris Barbulovski85eaf282015-09-22 11:36:03 -070012#include <QAction>
Boris Barbulovskibea00772015-09-22 11:36:04 -070013#include <QFileDialog>
Boris Barbulovski76bede82015-09-22 11:36:07 -070014#include <QMenu>
Alexander Stein133c5f72010-08-31 17:34:37 +020015
16#include <qapplication.h>
Markus Heidelberg8d90c972009-05-18 01:36:52 +020017#include <qdesktopwidget.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070018#include <qtoolbar.h>
Roman Zippel43bf6122006-06-08 22:12:45 -070019#include <qlayout.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070020#include <qsplitter.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070021#include <qlineedit.h>
Roman Zippel43bf6122006-06-08 22:12:45 -070022#include <qlabel.h>
23#include <qpushbutton.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070024#include <qmenubar.h>
25#include <qmessagebox.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070026#include <qregexp.h>
Alexander Stein133c5f72010-08-31 17:34:37 +020027#include <qevent.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070028
29#include <stdlib.h>
30
31#include "lkc.h"
32#include "qconf.h"
33
34#include "qconf.moc"
Masahiro Yamada3b541978562018-12-21 17:33:07 +090035#include "images.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070036
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -070037
Linus Torvalds1da177e2005-04-16 15:20:36 -070038static QApplication *configApp;
Roman Zippel7fc925f2006-06-08 22:12:46 -070039static ConfigSettings *configSettings;
Linus Torvalds1da177e2005-04-16 15:20:36 -070040
Boris Barbulovski85eaf282015-09-22 11:36:03 -070041QAction *ConfigMainWindow::saveAction;
Karsten Wiese3b354c52006-12-13 00:34:08 -080042
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -070043static inline QString qgettext(const char* str)
44{
Sam Ravnborg694c49a2018-05-22 21:36:12 +020045 return QString::fromLocal8Bit(str);
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -070046}
47
Ben Hutchings00d4f8f2013-10-06 19:21:31 +010048ConfigSettings::ConfigSettings()
49 : QSettings("kernel.org", "qconf")
50{
51}
52
Linus Torvalds1da177e2005-04-16 15:20:36 -070053/**
54 * Reads a list of integer values from the application settings.
55 */
Boris Barbulovski041fbdc2015-09-22 11:36:05 -070056QList<int> ConfigSettings::readSizes(const QString& key, bool *ok)
Linus Torvalds1da177e2005-04-16 15:20:36 -070057{
Boris Barbulovski041fbdc2015-09-22 11:36:05 -070058 QList<int> result;
Li Zefanc1f96f02010-05-07 13:58:04 +080059
Boris Barbulovski83c3a1b2016-11-30 14:57:55 -080060 if (contains(key))
61 {
62 QStringList entryList = value(key).toStringList();
63 QStringList::Iterator it;
64
65 for (it = entryList.begin(); it != entryList.end(); ++it)
66 result.push_back((*it).toInt());
67
68 *ok = true;
69 }
70 else
71 *ok = false;
Linus Torvalds1da177e2005-04-16 15:20:36 -070072
73 return result;
74}
75
76/**
77 * Writes a list of integer values to the application settings.
78 */
Boris Barbulovski041fbdc2015-09-22 11:36:05 -070079bool ConfigSettings::writeSizes(const QString& key, const QList<int>& value)
Linus Torvalds1da177e2005-04-16 15:20:36 -070080{
81 QStringList stringList;
Boris Barbulovski041fbdc2015-09-22 11:36:05 -070082 QList<int>::ConstIterator it;
Linus Torvalds1da177e2005-04-16 15:20:36 -070083
84 for (it = value.begin(); it != value.end(); ++it)
85 stringList.push_back(QString::number(*it));
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -070086 setValue(key, stringList);
Boris Barbulovski59e56442015-09-22 11:36:18 -070087
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -070088 return true;
Linus Torvalds1da177e2005-04-16 15:20:36 -070089}
Linus Torvalds1da177e2005-04-16 15:20:36 -070090
Boris Barbulovski59e56442015-09-22 11:36:18 -070091
92/*
93 * set the new data
94 * TODO check the value
95 */
96void ConfigItem::okRename(int col)
97{
98}
99
100/*
101 * update the displayed of a menu entry
102 */
103void ConfigItem::updateMenu(void)
104{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700105 ConfigList* list;
106 struct symbol* sym;
107 struct property *prop;
108 QString prompt;
109 int type;
110 tristate expr;
111
112 list = listView();
113 if (goParent) {
114 setPixmap(promptColIdx, list->menuBackPix);
115 prompt = "..";
116 goto set_prompt;
117 }
118
119 sym = menu->sym;
120 prop = menu->prompt;
Sam Ravnborg694c49a2018-05-22 21:36:12 +0200121 prompt = qgettext(menu_get_prompt(menu));
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700122
123 if (prop) switch (prop->type) {
124 case P_MENU:
125 if (list->mode == singleMode || list->mode == symbolMode) {
126 /* a menuconfig entry is displayed differently
127 * depending whether it's at the view root or a child.
128 */
129 if (sym && list->rootEntry == menu)
130 break;
131 setPixmap(promptColIdx, list->menuPix);
132 } else {
133 if (sym)
134 break;
135 setPixmap(promptColIdx, QIcon());
136 }
137 goto set_prompt;
138 case P_COMMENT:
139 setPixmap(promptColIdx, QIcon());
140 goto set_prompt;
141 default:
142 ;
143 }
144 if (!sym)
145 goto set_prompt;
146
147 setText(nameColIdx, QString::fromLocal8Bit(sym->name));
148
149 type = sym_get_type(sym);
150 switch (type) {
151 case S_BOOLEAN:
152 case S_TRISTATE:
153 char ch;
154
Marco Ammonbaa23ec2019-07-04 12:50:41 +0200155 if (!sym_is_changeable(sym) && list->optMode == normalOpt) {
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700156 setPixmap(promptColIdx, QIcon());
Mauro Carvalho Chehabcf497b92020-04-02 11:27:58 +0200157 setText(noColIdx, QString());
158 setText(modColIdx, QString());
159 setText(yesColIdx, QString());
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700160 break;
161 }
162 expr = sym_get_tristate_value(sym);
163 switch (expr) {
164 case yes:
165 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
166 setPixmap(promptColIdx, list->choiceYesPix);
167 else
168 setPixmap(promptColIdx, list->symbolYesPix);
169 setText(yesColIdx, "Y");
170 ch = 'Y';
171 break;
172 case mod:
173 setPixmap(promptColIdx, list->symbolModPix);
174 setText(modColIdx, "M");
175 ch = 'M';
176 break;
177 default:
178 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
179 setPixmap(promptColIdx, list->choiceNoPix);
180 else
181 setPixmap(promptColIdx, list->symbolNoPix);
182 setText(noColIdx, "N");
183 ch = 'N';
184 break;
185 }
186 if (expr != no)
187 setText(noColIdx, sym_tristate_within_range(sym, no) ? "_" : 0);
188 if (expr != mod)
189 setText(modColIdx, sym_tristate_within_range(sym, mod) ? "_" : 0);
190 if (expr != yes)
191 setText(yesColIdx, sym_tristate_within_range(sym, yes) ? "_" : 0);
192
193 setText(dataColIdx, QChar(ch));
194 break;
195 case S_INT:
196 case S_HEX:
197 case S_STRING:
198 const char* data;
199
200 data = sym_get_string_value(sym);
201
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700202 setText(dataColIdx, data);
203 if (type == S_STRING)
204 prompt = QString("%1: %2").arg(prompt).arg(data);
205 else
206 prompt = QString("(%2) %1").arg(prompt).arg(data);
207 break;
208 }
209 if (!sym_has_value(sym) && visible)
Sam Ravnborg694c49a2018-05-22 21:36:12 +0200210 prompt += " (NEW)";
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700211set_prompt:
212 setText(promptColIdx, prompt);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700213}
214
215void ConfigItem::testUpdateMenu(bool v)
216{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700217 ConfigItem* i;
218
219 visible = v;
220 if (!menu)
221 return;
222
223 sym_calc_value(menu->sym);
224 if (menu->flags & MENU_CHANGED) {
225 /* the menu entry changed, so update all list items */
226 menu->flags &= ~MENU_CHANGED;
227 for (i = (ConfigItem*)menu->data; i; i = i->nextItem)
228 i->updateMenu();
229 } else if (listView()->updateAll)
230 updateMenu();
Boris Barbulovski59e56442015-09-22 11:36:18 -0700231}
232
233
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700234/*
235 * construct a menu entry
236 */
237void ConfigItem::init(void)
238{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700239 if (menu) {
240 ConfigList* list = listView();
241 nextItem = (ConfigItem*)menu->data;
242 menu->data = this;
243
244 if (list->mode != fullMode)
245 setExpanded(true);
246 sym_calc_value(menu->sym);
247 }
248 updateMenu();
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700249}
250
251/*
252 * destruct a menu entry
253 */
254ConfigItem::~ConfigItem(void)
255{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700256 if (menu) {
257 ConfigItem** ip = (ConfigItem**)&menu->data;
258 for (; *ip; ip = &(*ip)->nextItem) {
259 if (*ip == this) {
260 *ip = nextItem;
261 break;
262 }
263 }
264 }
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700265}
266
Roman Zippel43bf6122006-06-08 22:12:45 -0700267ConfigLineEdit::ConfigLineEdit(ConfigView* parent)
268 : Parent(parent)
269{
Boris Barbulovskic14fa5e2015-09-22 11:36:21 -0700270 connect(this, SIGNAL(editingFinished()), SLOT(hide()));
Roman Zippel43bf6122006-06-08 22:12:45 -0700271}
272
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700273void ConfigLineEdit::show(ConfigItem* i)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700274{
275 item = i;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700276 if (sym_get_string_value(item->menu->sym))
277 setText(QString::fromLocal8Bit(sym_get_string_value(item->menu->sym)));
278 else
Mauro Carvalho Chehabcf497b92020-04-02 11:27:58 +0200279 setText(QString());
Linus Torvalds1da177e2005-04-16 15:20:36 -0700280 Parent::show();
281 setFocus();
282}
283
284void ConfigLineEdit::keyPressEvent(QKeyEvent* e)
285{
286 switch (e->key()) {
Markus Heidelbergfbb86372009-05-18 01:36:51 +0200287 case Qt::Key_Escape:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700288 break;
Markus Heidelbergfbb86372009-05-18 01:36:51 +0200289 case Qt::Key_Return:
290 case Qt::Key_Enter:
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700291 sym_set_string_value(item->menu->sym, text().toLatin1());
Linus Torvalds1da177e2005-04-16 15:20:36 -0700292 parent()->updateList(item);
293 break;
294 default:
295 Parent::keyPressEvent(e);
296 return;
297 }
298 e->accept();
299 parent()->list->setFocus();
300 hide();
301}
302
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700303ConfigList::ConfigList(ConfigView* p, const char *name)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700304 : Parent(p),
305 updateAll(false),
306 symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no),
307 choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no),
308 menuPix(xpm_menu), menuInvPix(xpm_menu_inv), menuBackPix(xpm_menuback), voidPix(xpm_void),
Boris Barbulovskidbf62932015-09-22 11:36:26 -0700309 showName(false), showRange(false), showData(false), mode(singleMode), optMode(normalOpt),
Boris Barbulovski59e56442015-09-22 11:36:18 -0700310 rootEntry(0), headerPopup(0)
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700311{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700312 setObjectName(name);
Boris Barbulovskia5225e92015-09-22 11:36:29 -0700313 setSortingEnabled(false);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700314 setRootIsDecorated(true);
315
Boris Barbulovskif999cc02015-09-22 11:36:31 -0700316 setVerticalScrollMode(ScrollPerPixel);
317 setHorizontalScrollMode(ScrollPerPixel);
318
Mauro Carvalho Chehab5752ff02020-04-02 11:27:59 +0200319 if (mode == symbolMode)
320 setHeaderLabels(QStringList() << "Item" << "Name" << "N" << "M" << "Y" << "Value");
321 else
322 setHeaderLabels(QStringList() << "Option" << "Name" << "N" << "M" << "Y" << "Value");
Boris Barbulovskia52cb322015-09-22 11:36:24 -0700323
Boris Barbulovskic14fa5e2015-09-22 11:36:21 -0700324 connect(this, SIGNAL(itemSelectionChanged(void)),
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700325 SLOT(updateSelection(void)));
326
327 if (name) {
328 configSettings->beginGroup(name);
329 showName = configSettings->value("/showName", false).toBool();
330 showRange = configSettings->value("/showRange", false).toBool();
331 showData = configSettings->value("/showData", false).toBool();
332 optMode = (enum optionMode)configSettings->value("/optionMode", 0).toInt();
333 configSettings->endGroup();
334 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
335 }
336
337 addColumn(promptColIdx);
338
339 reinit();
340}
341
342bool ConfigList::menuSkip(struct menu *menu)
343{
344 if (optMode == normalOpt && menu_is_visible(menu))
345 return false;
346 if (optMode == promptOpt && menu_has_prompt(menu))
347 return false;
348 if (optMode == allOpt)
349 return false;
350 return true;
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700351}
Boris Barbulovski59e56442015-09-22 11:36:18 -0700352
353void ConfigList::reinit(void)
354{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700355 removeColumn(dataColIdx);
356 removeColumn(yesColIdx);
357 removeColumn(modColIdx);
358 removeColumn(noColIdx);
359 removeColumn(nameColIdx);
360
361 if (showName)
362 addColumn(nameColIdx);
363 if (showRange) {
364 addColumn(noColIdx);
365 addColumn(modColIdx);
366 addColumn(yesColIdx);
367 }
368 if (showData)
369 addColumn(dataColIdx);
370
371 updateListAll();
Boris Barbulovski59e56442015-09-22 11:36:18 -0700372}
373
374void ConfigList::saveSettings(void)
375{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700376 if (!objectName().isEmpty()) {
377 configSettings->beginGroup(objectName());
378 configSettings->setValue("/showName", showName);
379 configSettings->setValue("/showRange", showRange);
380 configSettings->setValue("/showData", showData);
381 configSettings->setValue("/optionMode", (int)optMode);
382 configSettings->endGroup();
383 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700384}
385
386ConfigItem* ConfigList::findConfigItem(struct menu *menu)
387{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700388 ConfigItem* item = (ConfigItem*)menu->data;
389
390 for (; item; item = item->nextItem) {
391 if (this == item->listView())
392 break;
393 }
394
395 return item;
Boris Barbulovski59e56442015-09-22 11:36:18 -0700396}
397
398void ConfigList::updateSelection(void)
399{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700400 struct menu *menu;
401 enum prop_type type;
402
Mauro Carvalho Chehab5752ff02020-04-02 11:27:59 +0200403 if (mode == symbolMode)
404 setHeaderLabels(QStringList() << "Item" << "Name" << "N" << "M" << "Y" << "Value");
405 else
406 setHeaderLabels(QStringList() << "Option" << "Name" << "N" << "M" << "Y" << "Value");
407
Boris Barbulovskibe596aa2015-09-22 11:36:28 -0700408 if (selectedItems().count() == 0)
409 return;
410
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700411 ConfigItem* item = (ConfigItem*)selectedItems().first();
412 if (!item)
413 return;
414
415 menu = item->menu;
416 emit menuChanged(menu);
417 if (!menu)
418 return;
419 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
420 if (mode == menuMode && type == P_MENU)
421 emit menuSelected(menu);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700422}
423
424void ConfigList::updateList(ConfigItem* item)
425{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700426 ConfigItem* last = 0;
427
428 if (!rootEntry) {
429 if (mode != listMode)
430 goto update;
431 QTreeWidgetItemIterator it(this);
432 ConfigItem* item;
433
434 while (*it) {
435 item = (ConfigItem*)(*it);
436 if (!item->menu)
437 continue;
438 item->testUpdateMenu(menu_is_visible(item->menu));
439
440 ++it;
441 }
442 return;
443 }
444
445 if (rootEntry != &rootmenu && (mode == singleMode ||
446 (mode == symbolMode && rootEntry->parent != &rootmenu))) {
Boris Barbulovskiee7298f2015-09-22 11:36:37 -0700447 item = (ConfigItem *)topLevelItem(0);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700448 if (!item)
449 item = new ConfigItem(this, 0, true);
450 last = item;
451 }
452 if ((mode == singleMode || (mode == symbolMode && !(rootEntry->flags & MENU_ROOT))) &&
453 rootEntry->sym && rootEntry->prompt) {
454 item = last ? last->nextSibling() : firstChild();
455 if (!item)
456 item = new ConfigItem(this, last, rootEntry, true);
457 else
458 item->testUpdateMenu(true);
459
460 updateMenuList(item, rootEntry);
461 update();
Boris Barbulovskif999cc02015-09-22 11:36:31 -0700462 resizeColumnToContents(0);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700463 return;
464 }
465update:
466 updateMenuList(this, rootEntry);
467 update();
Boris Barbulovskif999cc02015-09-22 11:36:31 -0700468 resizeColumnToContents(0);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700469}
470
471void ConfigList::setValue(ConfigItem* item, tristate val)
472{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700473 struct symbol* sym;
474 int type;
475 tristate oldval;
476
477 sym = item->menu ? item->menu->sym : 0;
478 if (!sym)
479 return;
480
481 type = sym_get_type(sym);
482 switch (type) {
483 case S_BOOLEAN:
484 case S_TRISTATE:
485 oldval = sym_get_tristate_value(sym);
486
487 if (!sym_set_tristate_value(sym, val))
488 return;
489 if (oldval == no && item->menu->list)
490 item->setExpanded(true);
491 parent()->updateList(item);
492 break;
493 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700494}
495
496void ConfigList::changeValue(ConfigItem* item)
497{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700498 struct symbol* sym;
499 struct menu* menu;
500 int type, oldexpr, newexpr;
501
502 menu = item->menu;
503 if (!menu)
504 return;
505 sym = menu->sym;
506 if (!sym) {
507 if (item->menu->list)
508 item->setExpanded(!item->isExpanded());
509 return;
510 }
511
512 type = sym_get_type(sym);
513 switch (type) {
514 case S_BOOLEAN:
515 case S_TRISTATE:
516 oldexpr = sym_get_tristate_value(sym);
517 newexpr = sym_toggle_tristate_value(sym);
518 if (item->menu->list) {
519 if (oldexpr == newexpr)
520 item->setExpanded(!item->isExpanded());
521 else if (oldexpr == no)
522 item->setExpanded(true);
523 }
524 if (oldexpr != newexpr)
525 parent()->updateList(item);
526 break;
527 case S_INT:
528 case S_HEX:
529 case S_STRING:
Boris Barbulovskie336b9f2015-09-22 11:36:34 -0700530 parent()->lineEdit->show(item);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700531 break;
532 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700533}
534
535void ConfigList::setRootMenu(struct menu *menu)
536{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700537 enum prop_type type;
538
539 if (rootEntry == menu)
540 return;
541 type = menu && menu->prompt ? menu->prompt->type : P_UNKNOWN;
542 if (type != P_MENU)
543 return;
544 updateMenuList(this, 0);
545 rootEntry = menu;
546 updateListAll();
547 if (currentItem()) {
548 currentItem()->setSelected(hasFocus());
549 scrollToItem(currentItem());
550 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700551}
552
553void ConfigList::setParentMenu(void)
554{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700555 ConfigItem* item;
556 struct menu *oldroot;
557
558 oldroot = rootEntry;
559 if (rootEntry == &rootmenu)
560 return;
561 setRootMenu(menu_get_parent_menu(rootEntry->parent));
562
563 QTreeWidgetItemIterator it(this);
564 while (*it) {
565 item = (ConfigItem *)(*it);
566 if (item->menu == oldroot) {
567 setCurrentItem(item);
568 scrollToItem(item);
569 break;
570 }
571
572 ++it;
573 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700574}
575
576/*
577 * update all the children of a menu entry
578 * removes/adds the entries from the parent widget as necessary
579 *
580 * parent: either the menu list widget or a menu entry widget
581 * menu: entry to be updated
582 */
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700583void ConfigList::updateMenuList(ConfigItem *parent, struct menu* menu)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700584{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700585 struct menu* child;
586 ConfigItem* item;
587 ConfigItem* last;
588 bool visible;
589 enum prop_type type;
590
591 if (!menu) {
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700592 while (parent->childCount() > 0)
593 {
594 delete parent->takeChild(0);
595 }
596
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700597 return;
598 }
599
600 last = parent->firstChild();
601 if (last && !last->goParent)
602 last = 0;
603 for (child = menu->list; child; child = child->next) {
604 item = last ? last->nextSibling() : parent->firstChild();
605 type = child->prompt ? child->prompt->type : P_UNKNOWN;
606
607 switch (mode) {
608 case menuMode:
609 if (!(child->flags & MENU_ROOT))
610 goto hide;
611 break;
612 case symbolMode:
613 if (child->flags & MENU_ROOT)
614 goto hide;
615 break;
616 default:
617 break;
618 }
619
620 visible = menu_is_visible(child);
621 if (!menuSkip(child)) {
622 if (!child->sym && !child->list && !child->prompt)
623 continue;
624 if (!item || item->menu != child)
625 item = new ConfigItem(parent, last, child, visible);
626 else
627 item->testUpdateMenu(visible);
628
629 if (mode == fullMode || mode == menuMode || type != P_MENU)
630 updateMenuList(item, child);
631 else
632 updateMenuList(item, 0);
633 last = item;
634 continue;
635 }
Mauro Carvalho Chehab60969f02020-04-02 11:28:03 +0200636hide:
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700637 if (item && item->menu == child) {
638 last = parent->firstChild();
639 if (last == item)
640 last = 0;
641 else while (last->nextSibling() != item)
642 last = last->nextSibling();
643 delete item;
644 }
645 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700646}
647
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700648void ConfigList::updateMenuList(ConfigList *parent, struct menu* menu)
649{
650 struct menu* child;
651 ConfigItem* item;
652 ConfigItem* last;
653 bool visible;
654 enum prop_type type;
655
656 if (!menu) {
657 while (parent->topLevelItemCount() > 0)
658 {
659 delete parent->takeTopLevelItem(0);
660 }
661
662 return;
663 }
664
665 last = (ConfigItem*)parent->topLevelItem(0);
666 if (last && !last->goParent)
667 last = 0;
668 for (child = menu->list; child; child = child->next) {
669 item = last ? last->nextSibling() : (ConfigItem*)parent->topLevelItem(0);
670 type = child->prompt ? child->prompt->type : P_UNKNOWN;
671
672 switch (mode) {
673 case menuMode:
674 if (!(child->flags & MENU_ROOT))
675 goto hide;
676 break;
677 case symbolMode:
678 if (child->flags & MENU_ROOT)
679 goto hide;
680 break;
681 default:
682 break;
683 }
684
685 visible = menu_is_visible(child);
686 if (!menuSkip(child)) {
687 if (!child->sym && !child->list && !child->prompt)
688 continue;
689 if (!item || item->menu != child)
690 item = new ConfigItem(parent, last, child, visible);
691 else
692 item->testUpdateMenu(visible);
693
694 if (mode == fullMode || mode == menuMode || type != P_MENU)
695 updateMenuList(item, child);
696 else
697 updateMenuList(item, 0);
698 last = item;
699 continue;
700 }
Mauro Carvalho Chehab60969f02020-04-02 11:28:03 +0200701hide:
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700702 if (item && item->menu == child) {
703 last = (ConfigItem*)parent->topLevelItem(0);
704 if (last == item)
705 last = 0;
706 else while (last->nextSibling() != item)
707 last = last->nextSibling();
708 delete item;
709 }
710 }
711}
712
Boris Barbulovski59e56442015-09-22 11:36:18 -0700713void ConfigList::keyPressEvent(QKeyEvent* ev)
714{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700715 QTreeWidgetItem* i = currentItem();
716 ConfigItem* item;
717 struct menu *menu;
718 enum prop_type type;
719
720 if (ev->key() == Qt::Key_Escape && mode != fullMode && mode != listMode) {
721 emit parentSelected();
722 ev->accept();
723 return;
724 }
725
726 if (!i) {
727 Parent::keyPressEvent(ev);
728 return;
729 }
730 item = (ConfigItem*)i;
731
732 switch (ev->key()) {
733 case Qt::Key_Return:
734 case Qt::Key_Enter:
735 if (item->goParent) {
736 emit parentSelected();
737 break;
738 }
739 menu = item->menu;
740 if (!menu)
741 break;
742 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
743 if (type == P_MENU && rootEntry != menu &&
744 mode != fullMode && mode != menuMode) {
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +0200745 if (mode == menuMode)
746 emit menuSelected(menu);
747 else
748 emit itemSelected(menu);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700749 break;
750 }
751 case Qt::Key_Space:
752 changeValue(item);
753 break;
754 case Qt::Key_N:
755 setValue(item, no);
756 break;
757 case Qt::Key_M:
758 setValue(item, mod);
759 break;
760 case Qt::Key_Y:
761 setValue(item, yes);
762 break;
763 default:
764 Parent::keyPressEvent(ev);
765 return;
766 }
767 ev->accept();
Boris Barbulovski59e56442015-09-22 11:36:18 -0700768}
769
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700770void ConfigList::mousePressEvent(QMouseEvent* e)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700771{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700772 //QPoint p(contentsToViewport(e->pos()));
773 //printf("contentsMousePressEvent: %d,%d\n", p.x(), p.y());
774 Parent::mousePressEvent(e);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700775}
776
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700777void ConfigList::mouseReleaseEvent(QMouseEvent* e)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700778{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700779 QPoint p = e->pos();
780 ConfigItem* item = (ConfigItem*)itemAt(p);
781 struct menu *menu;
782 enum prop_type ptype;
783 QIcon icon;
784 int idx, x;
785
786 if (!item)
787 goto skip;
788
789 menu = item->menu;
790 x = header()->offset() + p.x();
Boris Barbulovski76d53cb2015-09-22 11:36:35 -0700791 idx = header()->logicalIndexAt(x);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700792 switch (idx) {
793 case promptColIdx:
794 icon = item->pixmap(promptColIdx);
Boris Barbulovski76d53cb2015-09-22 11:36:35 -0700795 if (!icon.isNull()) {
796 int off = header()->sectionPosition(0) + visualRect(indexAt(p)).x() + 4; // 4 is Hardcoded image offset. There might be a way to do it properly.
797 if (x >= off && x < off + icon.availableSizes().first().width()) {
798 if (item->goParent) {
799 emit parentSelected();
800 break;
801 } else if (!menu)
802 break;
803 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
804 if (ptype == P_MENU && rootEntry != menu &&
805 mode != fullMode && mode != menuMode)
806 emit menuSelected(menu);
807 else
808 changeValue(item);
809 }
810 }
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700811 break;
812 case noColIdx:
813 setValue(item, no);
814 break;
815 case modColIdx:
816 setValue(item, mod);
817 break;
818 case yesColIdx:
819 setValue(item, yes);
820 break;
821 case dataColIdx:
822 changeValue(item);
823 break;
824 }
825
826skip:
827 //printf("contentsMouseReleaseEvent: %d,%d\n", p.x(), p.y());
828 Parent::mouseReleaseEvent(e);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700829}
830
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700831void ConfigList::mouseMoveEvent(QMouseEvent* e)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700832{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700833 //QPoint p(contentsToViewport(e->pos()));
834 //printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y());
835 Parent::mouseMoveEvent(e);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700836}
837
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700838void ConfigList::mouseDoubleClickEvent(QMouseEvent* e)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700839{
Mauro Carvalho Chehabe1f77692020-04-02 11:28:02 +0200840 QPoint p = e->pos();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700841 ConfigItem* item = (ConfigItem*)itemAt(p);
842 struct menu *menu;
843 enum prop_type ptype;
844
845 if (!item)
846 goto skip;
847 if (item->goParent) {
848 emit parentSelected();
849 goto skip;
850 }
851 menu = item->menu;
852 if (!menu)
853 goto skip;
854 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +0200855 if (ptype == P_MENU) {
856 if (mode == singleMode)
857 emit itemSelected(menu);
858 else if (mode == symbolMode)
859 emit menuSelected(menu);
860 } else if (menu->sym)
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700861 changeValue(item);
862
863skip:
864 //printf("contentsMouseDoubleClickEvent: %d,%d\n", p.x(), p.y());
865 Parent::mouseDoubleClickEvent(e);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700866}
867
868void ConfigList::focusInEvent(QFocusEvent *e)
869{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700870 struct menu *menu = NULL;
871
872 Parent::focusInEvent(e);
873
874 ConfigItem* item = (ConfigItem *)currentItem();
875 if (item) {
876 item->setSelected(true);
877 menu = item->menu;
878 }
879 emit gotFocus(menu);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700880}
881
882void ConfigList::contextMenuEvent(QContextMenuEvent *e)
883{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700884 if (e->y() <= header()->geometry().bottom()) {
885 if (!headerPopup) {
886 QAction *action;
887
888 headerPopup = new QMenu(this);
Sam Ravnborg694c49a2018-05-22 21:36:12 +0200889 action = new QAction("Show Name", this);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700890 action->setCheckable(true);
891 connect(action, SIGNAL(toggled(bool)),
892 parent(), SLOT(setShowName(bool)));
893 connect(parent(), SIGNAL(showNameChanged(bool)),
894 action, SLOT(setOn(bool)));
895 action->setChecked(showName);
896 headerPopup->addAction(action);
Sam Ravnborg694c49a2018-05-22 21:36:12 +0200897 action = new QAction("Show Range", this);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700898 action->setCheckable(true);
899 connect(action, SIGNAL(toggled(bool)),
900 parent(), SLOT(setShowRange(bool)));
901 connect(parent(), SIGNAL(showRangeChanged(bool)),
902 action, SLOT(setOn(bool)));
903 action->setChecked(showRange);
904 headerPopup->addAction(action);
Sam Ravnborg694c49a2018-05-22 21:36:12 +0200905 action = new QAction("Show Data", this);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700906 action->setCheckable(true);
907 connect(action, SIGNAL(toggled(bool)),
908 parent(), SLOT(setShowData(bool)));
909 connect(parent(), SIGNAL(showDataChanged(bool)),
910 action, SLOT(setOn(bool)));
911 action->setChecked(showData);
912 headerPopup->addAction(action);
913 }
914 headerPopup->exec(e->globalPos());
915 e->accept();
916 } else
917 e->ignore();
Boris Barbulovski59e56442015-09-22 11:36:18 -0700918}
919
Li Zefan39a48972010-05-10 16:33:41 +0800920ConfigView*ConfigView::viewList;
921QAction *ConfigView::showNormalAction;
922QAction *ConfigView::showAllAction;
923QAction *ConfigView::showPromptAction;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700924
Roman Zippel7fc925f2006-06-08 22:12:46 -0700925ConfigView::ConfigView(QWidget* parent, const char *name)
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -0700926 : Parent(parent)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700927{
Boris Barbulovski9bd36ed2015-09-22 11:36:22 -0700928 setObjectName(name);
Boris Barbulovski29a70162015-09-22 11:36:10 -0700929 QVBoxLayout *verticalLayout = new QVBoxLayout(this);
Boris Barbulovski92298b42015-09-22 11:36:11 -0700930 verticalLayout->setContentsMargins(0, 0, 0, 0);
Boris Barbulovski29a70162015-09-22 11:36:10 -0700931
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700932 list = new ConfigList(this);
Boris Barbulovski29a70162015-09-22 11:36:10 -0700933 verticalLayout->addWidget(list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700934 lineEdit = new ConfigLineEdit(this);
935 lineEdit->hide();
Boris Barbulovski29a70162015-09-22 11:36:10 -0700936 verticalLayout->addWidget(lineEdit);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700937
938 this->nextView = viewList;
939 viewList = this;
940}
941
942ConfigView::~ConfigView(void)
943{
944 ConfigView** vp;
945
946 for (vp = &viewList; *vp; vp = &(*vp)->nextView) {
947 if (*vp == this) {
948 *vp = nextView;
949 break;
950 }
951 }
952}
953
Li Zefan39a48972010-05-10 16:33:41 +0800954void ConfigView::setOptionMode(QAction *act)
Roman Zippel7fc925f2006-06-08 22:12:46 -0700955{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700956 if (act == showNormalAction)
957 list->optMode = normalOpt;
958 else if (act == showAllAction)
959 list->optMode = allOpt;
960 else
961 list->optMode = promptOpt;
962
963 list->updateListAll();
Roman Zippel7fc925f2006-06-08 22:12:46 -0700964}
965
966void ConfigView::setShowName(bool b)
967{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700968 if (list->showName != b) {
969 list->showName = b;
970 list->reinit();
971 emit showNameChanged(b);
972 }
Roman Zippel7fc925f2006-06-08 22:12:46 -0700973}
974
975void ConfigView::setShowRange(bool b)
976{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700977 if (list->showRange != b) {
978 list->showRange = b;
979 list->reinit();
980 emit showRangeChanged(b);
981 }
Roman Zippel7fc925f2006-06-08 22:12:46 -0700982}
983
984void ConfigView::setShowData(bool b)
985{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700986 if (list->showData != b) {
987 list->showData = b;
988 list->reinit();
989 emit showDataChanged(b);
990 }
991}
992
993void ConfigList::setAllOpen(bool open)
994{
995 QTreeWidgetItemIterator it(this);
996
997 while (*it) {
998 (*it)->setExpanded(open);
999
1000 ++it;
1001 }
Roman Zippel7fc925f2006-06-08 22:12:46 -07001002}
1003
Boris Barbulovski1019f1a2015-09-22 11:36:17 -07001004void ConfigView::updateList(ConfigItem* item)
Roman Zippel7fc925f2006-06-08 22:12:46 -07001005{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001006 ConfigView* v;
1007
1008 for (v = viewList; v; v = v->nextView)
1009 v->list->updateList(item);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001010}
1011
1012void ConfigView::updateListAll(void)
1013{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001014 ConfigView* v;
1015
1016 for (v = viewList; v; v = v->nextView)
1017 v->list->updateListAll();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001018}
1019
Roman Zippel43bf6122006-06-08 22:12:45 -07001020ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name)
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001021 : Parent(parent), sym(0), _menu(0)
Roman Zippel43bf6122006-06-08 22:12:45 -07001022{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001023 setObjectName(name);
1024
1025
1026 if (!objectName().isEmpty()) {
1027 configSettings->beginGroup(objectName());
Boris Barbulovskie0393032016-11-30 14:57:52 -08001028 setShowDebug(configSettings->value("/showDebug", false).toBool());
Roman Zippel7fc925f2006-06-08 22:12:46 -07001029 configSettings->endGroup();
1030 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
1031 }
1032}
1033
1034void ConfigInfoView::saveSettings(void)
1035{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001036 if (!objectName().isEmpty()) {
1037 configSettings->beginGroup(objectName());
1038 configSettings->setValue("/showDebug", showDebug());
1039 configSettings->endGroup();
1040 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001041}
1042
1043void ConfigInfoView::setShowDebug(bool b)
1044{
1045 if (_showDebug != b) {
1046 _showDebug = b;
Alexander Stein133c5f72010-08-31 17:34:37 +02001047 if (_menu)
Roman Zippel43bf6122006-06-08 22:12:45 -07001048 menuInfo();
Roman Zippelab45d192006-06-08 22:12:47 -07001049 else if (sym)
1050 symbolInfo();
Roman Zippel43bf6122006-06-08 22:12:45 -07001051 emit showDebugChanged(b);
1052 }
1053}
1054
1055void ConfigInfoView::setInfo(struct menu *m)
1056{
Alexander Stein133c5f72010-08-31 17:34:37 +02001057 if (_menu == m)
Roman Zippelb65a47e2006-06-08 22:12:47 -07001058 return;
Alexander Stein133c5f72010-08-31 17:34:37 +02001059 _menu = m;
Roman Zippel6fa1da82007-01-10 23:15:31 -08001060 sym = NULL;
Alexander Stein133c5f72010-08-31 17:34:37 +02001061 if (!_menu)
Roman Zippel43bf6122006-06-08 22:12:45 -07001062 clear();
Roman Zippel6fa1da82007-01-10 23:15:31 -08001063 else
Roman Zippel43bf6122006-06-08 22:12:45 -07001064 menuInfo();
1065}
1066
Roman Zippelab45d192006-06-08 22:12:47 -07001067void ConfigInfoView::symbolInfo(void)
1068{
1069 QString str;
1070
1071 str += "<big>Symbol: <b>";
1072 str += print_filter(sym->name);
1073 str += "</b></big><br><br>value: ";
1074 str += print_filter(sym_get_string_value(sym));
1075 str += "<br>visibility: ";
1076 str += sym->visible == yes ? "y" : sym->visible == mod ? "m" : "n";
1077 str += "<br>";
1078 str += debug_info(sym);
1079
1080 setText(str);
1081}
1082
Roman Zippel43bf6122006-06-08 22:12:45 -07001083void ConfigInfoView::menuInfo(void)
1084{
1085 struct symbol* sym;
1086 QString head, debug, help;
1087
Alexander Stein133c5f72010-08-31 17:34:37 +02001088 sym = _menu->sym;
Roman Zippel43bf6122006-06-08 22:12:45 -07001089 if (sym) {
Alexander Stein133c5f72010-08-31 17:34:37 +02001090 if (_menu->prompt) {
Roman Zippel43bf6122006-06-08 22:12:45 -07001091 head += "<big><b>";
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001092 head += print_filter(_menu->prompt->text);
Roman Zippel43bf6122006-06-08 22:12:45 -07001093 head += "</b></big>";
1094 if (sym->name) {
1095 head += " (";
Roman Zippelab45d192006-06-08 22:12:47 -07001096 if (showDebug())
1097 head += QString().sprintf("<a href=\"s%p\">", sym);
Roman Zippel43bf6122006-06-08 22:12:45 -07001098 head += print_filter(sym->name);
Roman Zippelab45d192006-06-08 22:12:47 -07001099 if (showDebug())
1100 head += "</a>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001101 head += ")";
1102 }
1103 } else if (sym->name) {
1104 head += "<big><b>";
Roman Zippelab45d192006-06-08 22:12:47 -07001105 if (showDebug())
1106 head += QString().sprintf("<a href=\"s%p\">", sym);
Roman Zippel43bf6122006-06-08 22:12:45 -07001107 head += print_filter(sym->name);
Roman Zippelab45d192006-06-08 22:12:47 -07001108 if (showDebug())
1109 head += "</a>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001110 head += "</b></big>";
1111 }
1112 head += "<br><br>";
1113
1114 if (showDebug())
1115 debug = debug_info(sym);
1116
Cheng Renquand74c15f2009-07-12 16:11:47 +08001117 struct gstr help_gstr = str_new();
Alexander Stein133c5f72010-08-31 17:34:37 +02001118 menu_get_ext_help(_menu, &help_gstr);
Cheng Renquand74c15f2009-07-12 16:11:47 +08001119 help = print_filter(str_get(&help_gstr));
1120 str_free(&help_gstr);
Alexander Stein133c5f72010-08-31 17:34:37 +02001121 } else if (_menu->prompt) {
Roman Zippel43bf6122006-06-08 22:12:45 -07001122 head += "<big><b>";
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001123 head += print_filter(_menu->prompt->text);
Roman Zippel43bf6122006-06-08 22:12:45 -07001124 head += "</b></big><br><br>";
1125 if (showDebug()) {
Alexander Stein133c5f72010-08-31 17:34:37 +02001126 if (_menu->prompt->visible.expr) {
Roman Zippel43bf6122006-06-08 22:12:45 -07001127 debug += "&nbsp;&nbsp;dep: ";
Alexander Stein133c5f72010-08-31 17:34:37 +02001128 expr_print(_menu->prompt->visible.expr, expr_print_help, &debug, E_NONE);
Roman Zippel43bf6122006-06-08 22:12:45 -07001129 debug += "<br><br>";
1130 }
1131 }
1132 }
1133 if (showDebug())
Alexander Stein133c5f72010-08-31 17:34:37 +02001134 debug += QString().sprintf("defined at %s:%d<br><br>", _menu->file->name, _menu->lineno);
Roman Zippel43bf6122006-06-08 22:12:45 -07001135
1136 setText(head + debug + help);
1137}
1138
1139QString ConfigInfoView::debug_info(struct symbol *sym)
1140{
1141 QString debug;
1142
1143 debug += "type: ";
1144 debug += print_filter(sym_type_name(sym->type));
1145 if (sym_is_choice(sym))
1146 debug += " (choice)";
1147 debug += "<br>";
1148 if (sym->rev_dep.expr) {
1149 debug += "reverse dep: ";
1150 expr_print(sym->rev_dep.expr, expr_print_help, &debug, E_NONE);
1151 debug += "<br>";
1152 }
1153 for (struct property *prop = sym->prop; prop; prop = prop->next) {
1154 switch (prop->type) {
1155 case P_PROMPT:
1156 case P_MENU:
Roman Zippelab45d192006-06-08 22:12:47 -07001157 debug += QString().sprintf("prompt: <a href=\"m%p\">", prop->menu);
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001158 debug += print_filter(prop->text);
Roman Zippelab45d192006-06-08 22:12:47 -07001159 debug += "</a><br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001160 break;
1161 case P_DEFAULT:
Roman Zippel93449082008-01-14 04:50:54 +01001162 case P_SELECT:
1163 case P_RANGE:
Roman Zippel93449082008-01-14 04:50:54 +01001164 debug += prop_get_type_name(prop->type);
1165 debug += ": ";
Roman Zippel43bf6122006-06-08 22:12:45 -07001166 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1167 debug += "<br>";
1168 break;
1169 case P_CHOICE:
1170 if (sym_is_choice(sym)) {
1171 debug += "choice: ";
1172 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1173 debug += "<br>";
1174 }
1175 break;
Roman Zippel43bf6122006-06-08 22:12:45 -07001176 default:
1177 debug += "unknown property: ";
1178 debug += prop_get_type_name(prop->type);
1179 debug += "<br>";
1180 }
1181 if (prop->visible.expr) {
1182 debug += "&nbsp;&nbsp;&nbsp;&nbsp;dep: ";
1183 expr_print(prop->visible.expr, expr_print_help, &debug, E_NONE);
1184 debug += "<br>";
1185 }
1186 }
1187 debug += "<br>";
1188
1189 return debug;
1190}
1191
1192QString ConfigInfoView::print_filter(const QString &str)
1193{
1194 QRegExp re("[<>&\"\\n]");
1195 QString res = str;
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001196 for (int i = 0; (i = res.indexOf(re, i)) >= 0;) {
1197 switch (res[i].toLatin1()) {
Roman Zippel43bf6122006-06-08 22:12:45 -07001198 case '<':
1199 res.replace(i, 1, "&lt;");
1200 i += 4;
1201 break;
1202 case '>':
1203 res.replace(i, 1, "&gt;");
1204 i += 4;
1205 break;
1206 case '&':
1207 res.replace(i, 1, "&amp;");
1208 i += 5;
1209 break;
1210 case '"':
1211 res.replace(i, 1, "&quot;");
1212 i += 6;
1213 break;
1214 case '\n':
1215 res.replace(i, 1, "<br>");
1216 i += 4;
1217 break;
1218 }
1219 }
1220 return res;
1221}
1222
Roman Zippelab45d192006-06-08 22:12:47 -07001223void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char *str)
Roman Zippel43bf6122006-06-08 22:12:45 -07001224{
Roman Zippelab45d192006-06-08 22:12:47 -07001225 QString* text = reinterpret_cast<QString*>(data);
1226 QString str2 = print_filter(str);
1227
1228 if (sym && sym->name && !(sym->flags & SYMBOL_CONST)) {
1229 *text += QString().sprintf("<a href=\"s%p\">", sym);
1230 *text += str2;
1231 *text += "</a>";
1232 } else
1233 *text += str2;
Roman Zippel43bf6122006-06-08 22:12:45 -07001234}
1235
Boris Barbulovski924bbb52015-09-22 11:36:06 -07001236QMenu* ConfigInfoView::createStandardContextMenu(const QPoint & pos)
Roman Zippel7fc925f2006-06-08 22:12:46 -07001237{
Boris Barbulovski924bbb52015-09-22 11:36:06 -07001238 QMenu* popup = Parent::createStandardContextMenu(pos);
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001239 QAction* action = new QAction("Show Debug Info", popup);
Mauro Carvalho Chehab60969f02020-04-02 11:28:03 +02001240
1241 action->setCheckable(true);
1242 connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
1243 connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool)));
1244 action->setChecked(showDebug());
Boris Barbulovski924bbb52015-09-22 11:36:06 -07001245 popup->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001246 popup->addAction(action);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001247 return popup;
1248}
1249
Boris Barbulovski924bbb52015-09-22 11:36:06 -07001250void ConfigInfoView::contextMenuEvent(QContextMenuEvent *e)
Roman Zippel7fc925f2006-06-08 22:12:46 -07001251{
Boris Barbulovski924bbb52015-09-22 11:36:06 -07001252 Parent::contextMenuEvent(e);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001253}
1254
Marco Costalba63431e72006-10-05 19:12:59 +02001255ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow* parent, const char *name)
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001256 : Parent(parent), result(NULL)
Roman Zippel43bf6122006-06-08 22:12:45 -07001257{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001258 setObjectName(name);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001259 setWindowTitle("Search Config");
Roman Zippel43bf6122006-06-08 22:12:45 -07001260
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001261 QVBoxLayout* layout1 = new QVBoxLayout(this);
1262 layout1->setContentsMargins(11, 11, 11, 11);
1263 layout1->setSpacing(6);
1264 QHBoxLayout* layout2 = new QHBoxLayout(0);
1265 layout2->setContentsMargins(0, 0, 0, 0);
1266 layout2->setSpacing(6);
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001267 layout2->addWidget(new QLabel("Find:", this));
Roman Zippel43bf6122006-06-08 22:12:45 -07001268 editField = new QLineEdit(this);
1269 connect(editField, SIGNAL(returnPressed()), SLOT(search()));
1270 layout2->addWidget(editField);
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001271 searchButton = new QPushButton("Search", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001272 searchButton->setAutoDefault(false);
Roman Zippel43bf6122006-06-08 22:12:45 -07001273 connect(searchButton, SIGNAL(clicked()), SLOT(search()));
1274 layout2->addWidget(searchButton);
1275 layout1->addLayout(layout2);
1276
Roman Zippel7fc925f2006-06-08 22:12:46 -07001277 split = new QSplitter(this);
Markus Heidelberg7298b932009-05-18 01:36:50 +02001278 split->setOrientation(Qt::Vertical);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001279 list = new ConfigView(split, name);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001280 list->list->mode = listMode;
Roman Zippel7fc925f2006-06-08 22:12:46 -07001281 info = new ConfigInfoView(split, name);
Roman Zippel43bf6122006-06-08 22:12:45 -07001282 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1283 info, SLOT(setInfo(struct menu *)));
Marco Costalba63431e72006-10-05 19:12:59 +02001284 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1285 parent, SLOT(setMenuLink(struct menu *)));
1286
Roman Zippel43bf6122006-06-08 22:12:45 -07001287 layout1->addWidget(split);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001288
1289 if (name) {
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001290 QVariant x, y;
1291 int width, height;
Roman Zippel7fc925f2006-06-08 22:12:46 -07001292 bool ok;
1293
1294 configSettings->beginGroup(name);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001295 width = configSettings->value("/window width", parent->width() / 2).toInt();
1296 height = configSettings->value("/window height", parent->height() / 2).toInt();
Roman Zippel7fc925f2006-06-08 22:12:46 -07001297 resize(width, height);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001298 x = configSettings->value("/window x");
1299 y = configSettings->value("/window y");
1300 if ((x.isValid())&&(y.isValid()))
1301 move(x.toInt(), y.toInt());
Boris Barbulovski041fbdc2015-09-22 11:36:05 -07001302 QList<int> sizes = configSettings->readSizes("/split", &ok);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001303 if (ok)
1304 split->setSizes(sizes);
1305 configSettings->endGroup();
1306 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
1307 }
1308}
1309
1310void ConfigSearchWindow::saveSettings(void)
1311{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001312 if (!objectName().isEmpty()) {
1313 configSettings->beginGroup(objectName());
1314 configSettings->setValue("/window x", pos().x());
1315 configSettings->setValue("/window y", pos().y());
1316 configSettings->setValue("/window width", size().width());
1317 configSettings->setValue("/window height", size().height());
1318 configSettings->writeSizes("/split", split->sizes());
1319 configSettings->endGroup();
1320 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001321}
1322
1323void ConfigSearchWindow::search(void)
1324{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001325 struct symbol **p;
1326 struct property *prop;
1327 ConfigItem *lastItem = NULL;
1328
1329 free(result);
1330 list->list->clear();
1331 info->clear();
1332
1333 result = sym_re_search(editField->text().toLatin1());
1334 if (!result)
1335 return;
1336 for (p = result; *p; p++) {
1337 for_all_prompts((*p), prop)
1338 lastItem = new ConfigItem(list->list, lastItem, prop->menu,
1339 menu_is_visible(prop->menu));
1340 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001341}
1342
Linus Torvalds1da177e2005-04-16 15:20:36 -07001343/*
1344 * Construct the complete config widget
1345 */
1346ConfigMainWindow::ConfigMainWindow(void)
Roman Zippelf12aa702006-11-25 11:09:31 -08001347 : searchWindow(0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001348{
1349 QMenuBar* menu;
Boris Barbulovski92119932015-09-22 11:36:16 -07001350 bool ok = true;
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001351 QVariant x, y;
1352 int width, height;
Randy Dunlapa54bb702007-10-20 11:18:47 -07001353 char title[256];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001354
Markus Heidelberg8d90c972009-05-18 01:36:52 +02001355 QDesktopWidget *d = configApp->desktop();
Arnaud Lacombe09548282010-08-18 01:57:13 -04001356 snprintf(title, sizeof(title), "%s%s",
1357 rootmenu.prompt->text,
Michal Marek76a136c2010-09-01 17:39:27 +02001358 ""
Michal Marek76a136c2010-09-01 17:39:27 +02001359 );
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001360 setWindowTitle(title);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001361
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001362 width = configSettings->value("/window width", d->width() - 64).toInt();
1363 height = configSettings->value("/window height", d->height() - 64).toInt();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001364 resize(width, height);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001365 x = configSettings->value("/window x");
1366 y = configSettings->value("/window y");
1367 if ((x.isValid())&&(y.isValid()))
1368 move(x.toInt(), y.toInt());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001369
Mauro Carvalho Chehabcce1fab2020-04-02 11:28:00 +02001370 QWidget *widget = new QWidget(this);
1371 QVBoxLayout *layout = new QVBoxLayout(widget);
1372 setCentralWidget(widget);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001373
Mauro Carvalho Chehabcce1fab2020-04-02 11:28:00 +02001374 split1 = new QSplitter(widget);
1375 split1->setOrientation(Qt::Horizontal);
1376 split1->setChildrenCollapsible(false);
1377
1378 menuView = new ConfigView(widget, "menu");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001379 menuList = menuView->list;
1380
Mauro Carvalho Chehabcce1fab2020-04-02 11:28:00 +02001381 split2 = new QSplitter(widget);
1382 split2->setChildrenCollapsible(false);
Markus Heidelberg7298b932009-05-18 01:36:50 +02001383 split2->setOrientation(Qt::Vertical);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001384
1385 // create config tree
Mauro Carvalho Chehabcce1fab2020-04-02 11:28:00 +02001386 configView = new ConfigView(widget, "config");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001387 configList = configView->list;
1388
Mauro Carvalho Chehabcce1fab2020-04-02 11:28:00 +02001389 helpText = new ConfigInfoView(widget, "help");
1390
1391 layout->addWidget(split2);
1392 split2->addWidget(split1);
1393 split1->addWidget(configView);
1394 split1->addWidget(menuView);
1395 split2->addWidget(helpText);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001396
1397 setTabOrder(configList, helpText);
1398 configList->setFocus();
1399
1400 menu = menuBar();
Boris Barbulovskib1f8a452015-09-22 11:36:02 -07001401 toolBar = new QToolBar("Tools", this);
Boris Barbulovski29a70162015-09-22 11:36:10 -07001402 addToolBar(toolBar);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001403
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001404 backAction = new QAction(QPixmap(xpm_back), "Back", this);
Boris Barbulovski92119932015-09-22 11:36:16 -07001405 connect(backAction, SIGNAL(triggered(bool)), SLOT(goBack()));
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001406 backAction->setEnabled(false);
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001407 QAction *quitAction = new QAction("&Quit", this);
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001408 quitAction->setShortcut(Qt::CTRL + Qt::Key_Q);
Boris Barbulovski92119932015-09-22 11:36:16 -07001409 connect(quitAction, SIGNAL(triggered(bool)), SLOT(close()));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001410 QAction *loadAction = new QAction(QPixmap(xpm_load), "&Load", this);
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001411 loadAction->setShortcut(Qt::CTRL + Qt::Key_L);
Boris Barbulovski92119932015-09-22 11:36:16 -07001412 connect(loadAction, SIGNAL(triggered(bool)), SLOT(loadConfig()));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001413 saveAction = new QAction(QPixmap(xpm_save), "&Save", this);
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001414 saveAction->setShortcut(Qt::CTRL + Qt::Key_S);
Boris Barbulovski92119932015-09-22 11:36:16 -07001415 connect(saveAction, SIGNAL(triggered(bool)), SLOT(saveConfig()));
Karsten Wiese3b354c52006-12-13 00:34:08 -08001416 conf_set_changed_callback(conf_changed);
1417 // Set saveAction's initial state
1418 conf_changed();
Masahiro Yamada87419082019-03-11 01:13:15 +09001419 configname = xstrdup(conf_get_configname());
1420
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001421 QAction *saveAsAction = new QAction("Save &As...", this);
Boris Barbulovski92119932015-09-22 11:36:16 -07001422 connect(saveAsAction, SIGNAL(triggered(bool)), SLOT(saveConfigAs()));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001423 QAction *searchAction = new QAction("&Find", this);
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001424 searchAction->setShortcut(Qt::CTRL + Qt::Key_F);
Boris Barbulovski92119932015-09-22 11:36:16 -07001425 connect(searchAction, SIGNAL(triggered(bool)), SLOT(searchConfig()));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001426 singleViewAction = new QAction(QPixmap(xpm_single_view), "Single View", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001427 singleViewAction->setCheckable(true);
Boris Barbulovski92119932015-09-22 11:36:16 -07001428 connect(singleViewAction, SIGNAL(triggered(bool)), SLOT(showSingleView()));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001429 splitViewAction = new QAction(QPixmap(xpm_split_view), "Split View", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001430 splitViewAction->setCheckable(true);
Boris Barbulovski92119932015-09-22 11:36:16 -07001431 connect(splitViewAction, SIGNAL(triggered(bool)), SLOT(showSplitView()));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001432 fullViewAction = new QAction(QPixmap(xpm_tree_view), "Full View", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001433 fullViewAction->setCheckable(true);
Boris Barbulovski92119932015-09-22 11:36:16 -07001434 connect(fullViewAction, SIGNAL(triggered(bool)), SLOT(showFullView()));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001435
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001436 QAction *showNameAction = new QAction("Show Name", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001437 showNameAction->setCheckable(true);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001438 connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool)));
Boris Barbulovski9c862352015-09-22 11:36:12 -07001439 showNameAction->setChecked(configView->showName());
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001440 QAction *showRangeAction = new QAction("Show Range", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001441 showRangeAction->setCheckable(true);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001442 connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool)));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001443 QAction *showDataAction = new QAction("Show Data", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001444 showDataAction->setCheckable(true);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001445 connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool)));
Li Zefan39a48972010-05-10 16:33:41 +08001446
1447 QActionGroup *optGroup = new QActionGroup(this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001448 optGroup->setExclusive(true);
Boris Barbulovski92119932015-09-22 11:36:16 -07001449 connect(optGroup, SIGNAL(triggered(QAction*)), configView,
Li Zefan39a48972010-05-10 16:33:41 +08001450 SLOT(setOptionMode(QAction *)));
Boris Barbulovski92119932015-09-22 11:36:16 -07001451 connect(optGroup, SIGNAL(triggered(QAction *)), menuView,
Li Zefan39a48972010-05-10 16:33:41 +08001452 SLOT(setOptionMode(QAction *)));
1453
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001454 configView->showNormalAction = new QAction("Show Normal Options", optGroup);
1455 configView->showAllAction = new QAction("Show All Options", optGroup);
1456 configView->showPromptAction = new QAction("Show Prompt Options", optGroup);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001457 configView->showNormalAction->setCheckable(true);
1458 configView->showAllAction->setCheckable(true);
1459 configView->showPromptAction->setCheckable(true);
Li Zefan39a48972010-05-10 16:33:41 +08001460
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001461 QAction *showDebugAction = new QAction("Show Debug Info", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001462 showDebugAction->setCheckable(true);
Roman Zippel43bf6122006-06-08 22:12:45 -07001463 connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
Boris Barbulovski9c862352015-09-22 11:36:12 -07001464 showDebugAction->setChecked(helpText->showDebug());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001465
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001466 QAction *showIntroAction = new QAction("Introduction", this);
Boris Barbulovski92119932015-09-22 11:36:16 -07001467 connect(showIntroAction, SIGNAL(triggered(bool)), SLOT(showIntro()));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001468 QAction *showAboutAction = new QAction("About", this);
Boris Barbulovski92119932015-09-22 11:36:16 -07001469 connect(showAboutAction, SIGNAL(triggered(bool)), SLOT(showAbout()));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001470
1471 // init tool bar
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001472 toolBar->addAction(backAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001473 toolBar->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001474 toolBar->addAction(loadAction);
1475 toolBar->addAction(saveAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001476 toolBar->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001477 toolBar->addAction(singleViewAction);
1478 toolBar->addAction(splitViewAction);
1479 toolBar->addAction(fullViewAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001480
1481 // create config menu
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001482 QMenu* config = menu->addMenu("&File");
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001483 config->addAction(loadAction);
1484 config->addAction(saveAction);
1485 config->addAction(saveAsAction);
Boris Barbulovski76bede82015-09-22 11:36:07 -07001486 config->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001487 config->addAction(quitAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001488
Shlomi Fish66e7c722007-02-14 00:32:58 -08001489 // create edit menu
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001490 QMenu* editMenu = menu->addMenu("&Edit");
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001491 editMenu->addAction(searchAction);
Shlomi Fish66e7c722007-02-14 00:32:58 -08001492
Linus Torvalds1da177e2005-04-16 15:20:36 -07001493 // create options menu
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001494 QMenu* optionMenu = menu->addMenu("&Option");
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001495 optionMenu->addAction(showNameAction);
1496 optionMenu->addAction(showRangeAction);
1497 optionMenu->addAction(showDataAction);
Boris Barbulovski76bede82015-09-22 11:36:07 -07001498 optionMenu->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001499 optionMenu->addActions(optGroup->actions());
Boris Barbulovski76bede82015-09-22 11:36:07 -07001500 optionMenu->addSeparator();
Boris Barbulovskie0393032016-11-30 14:57:52 -08001501 optionMenu->addAction(showDebugAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001502
1503 // create help menu
Boris Barbulovski76bede82015-09-22 11:36:07 -07001504 menu->addSeparator();
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001505 QMenu* helpMenu = menu->addMenu("&Help");
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001506 helpMenu->addAction(showIntroAction);
1507 helpMenu->addAction(showAboutAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001508
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001509 connect(configList, SIGNAL(menuChanged(struct menu *)),
1510 helpText, SLOT(setInfo(struct menu *)));
1511 connect(configList, SIGNAL(menuSelected(struct menu *)),
1512 SLOT(changeMenu(struct menu *)));
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +02001513 connect(configList, SIGNAL(itemSelected(struct menu *)),
1514 SLOT(changeItens(struct menu *)));
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001515 connect(configList, SIGNAL(parentSelected()),
1516 SLOT(goBack()));
1517 connect(menuList, SIGNAL(menuChanged(struct menu *)),
1518 helpText, SLOT(setInfo(struct menu *)));
1519 connect(menuList, SIGNAL(menuSelected(struct menu *)),
1520 SLOT(changeMenu(struct menu *)));
1521
1522 connect(configList, SIGNAL(gotFocus(struct menu *)),
1523 helpText, SLOT(setInfo(struct menu *)));
1524 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1525 helpText, SLOT(setInfo(struct menu *)));
1526 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1527 SLOT(listFocusChanged(void)));
Roman Zippelb65a47e2006-06-08 22:12:47 -07001528 connect(helpText, SIGNAL(menuSelected(struct menu *)),
1529 SLOT(setMenuLink(struct menu *)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001530
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001531 QString listMode = configSettings->value("/listMode", "symbol").toString();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001532 if (listMode == "single")
1533 showSingleView();
1534 else if (listMode == "full")
1535 showFullView();
1536 else /*if (listMode == "split")*/
1537 showSplitView();
1538
1539 // UI setup done, restore splitter positions
Boris Barbulovski041fbdc2015-09-22 11:36:05 -07001540 QList<int> sizes = configSettings->readSizes("/split1", &ok);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001541 if (ok)
1542 split1->setSizes(sizes);
1543
Roman Zippel7fc925f2006-06-08 22:12:46 -07001544 sizes = configSettings->readSizes("/split2", &ok);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001545 if (ok)
1546 split2->setSizes(sizes);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001547}
1548
Linus Torvalds1da177e2005-04-16 15:20:36 -07001549void ConfigMainWindow::loadConfig(void)
1550{
Masahiro Yamada87419082019-03-11 01:13:15 +09001551 QString str;
1552 QByteArray ba;
1553 const char *name;
1554
1555 str = QFileDialog::getOpenFileName(this, "", configname);
1556 if (str.isNull())
Linus Torvalds1da177e2005-04-16 15:20:36 -07001557 return;
Masahiro Yamada87419082019-03-11 01:13:15 +09001558
1559 ba = str.toLocal8Bit();
1560 name = ba.data();
1561
1562 if (conf_read(name))
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001563 QMessageBox::information(this, "qconf", "Unable to load configuration!");
Masahiro Yamada87419082019-03-11 01:13:15 +09001564
1565 free(configname);
1566 configname = xstrdup(name);
1567
Linus Torvalds1da177e2005-04-16 15:20:36 -07001568 ConfigView::updateListAll();
1569}
1570
Michal Marekbac6aa82011-05-25 15:10:25 +02001571bool ConfigMainWindow::saveConfig(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001572{
Masahiro Yamada87419082019-03-11 01:13:15 +09001573 if (conf_write(configname)) {
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001574 QMessageBox::information(this, "qconf", "Unable to save configuration!");
Michal Marekbac6aa82011-05-25 15:10:25 +02001575 return false;
1576 }
Masahiro Yamada00c864f2018-07-20 16:46:31 +09001577 conf_write_autoconf(0);
1578
Michal Marekbac6aa82011-05-25 15:10:25 +02001579 return true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001580}
1581
1582void ConfigMainWindow::saveConfigAs(void)
1583{
Masahiro Yamada87419082019-03-11 01:13:15 +09001584 QString str;
1585 QByteArray ba;
1586 const char *name;
1587
1588 str = QFileDialog::getSaveFileName(this, "", configname);
1589 if (str.isNull())
Linus Torvalds1da177e2005-04-16 15:20:36 -07001590 return;
Masahiro Yamada87419082019-03-11 01:13:15 +09001591
1592 ba = str.toLocal8Bit();
1593 name = ba.data();
1594
1595 if (conf_write(name)) {
1596 QMessageBox::information(this, "qconf", "Unable to save configuration!");
1597 }
1598 conf_write_autoconf(0);
1599
1600 free(configname);
1601 configname = xstrdup(name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001602}
1603
Roman Zippel43bf6122006-06-08 22:12:45 -07001604void ConfigMainWindow::searchConfig(void)
1605{
1606 if (!searchWindow)
Roman Zippel7fc925f2006-06-08 22:12:46 -07001607 searchWindow = new ConfigSearchWindow(this, "search");
Roman Zippel43bf6122006-06-08 22:12:45 -07001608 searchWindow->show();
1609}
1610
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +02001611void ConfigMainWindow::changeItens(struct menu *menu)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001612{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001613 configList->setRootMenu(menu);
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +02001614
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001615 if (configList->rootEntry->parent == &rootmenu)
1616 backAction->setEnabled(false);
1617 else
1618 backAction->setEnabled(true);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001619}
1620
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +02001621void ConfigMainWindow::changeMenu(struct menu *menu)
1622{
1623 menuList->setRootMenu(menu);
1624
1625 if (menuList->rootEntry->parent == &rootmenu)
1626 backAction->setEnabled(false);
1627 else
1628 backAction->setEnabled(true);
1629}
1630
Roman Zippelb65a47e2006-06-08 22:12:47 -07001631void ConfigMainWindow::setMenuLink(struct menu *menu)
1632{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001633 struct menu *parent;
1634 ConfigList* list = NULL;
1635 ConfigItem* item;
1636
1637 if (configList->menuSkip(menu))
1638 return;
1639
1640 switch (configList->mode) {
1641 case singleMode:
1642 list = configList;
1643 parent = menu_get_parent_menu(menu);
1644 if (!parent)
1645 return;
1646 list->setRootMenu(parent);
1647 break;
1648 case symbolMode:
1649 if (menu->flags & MENU_ROOT) {
1650 configList->setRootMenu(menu);
1651 configList->clearSelection();
1652 list = menuList;
1653 } else {
1654 list = configList;
1655 parent = menu_get_parent_menu(menu->parent);
1656 if (!parent)
1657 return;
1658 item = menuList->findConfigItem(parent);
1659 if (item) {
1660 item->setSelected(true);
1661 menuList->scrollToItem(item);
1662 }
1663 list->setRootMenu(parent);
1664 }
1665 break;
1666 case fullMode:
1667 list = configList;
1668 break;
1669 default:
1670 break;
1671 }
1672
1673 if (list) {
1674 item = list->findConfigItem(menu);
1675 if (item) {
1676 item->setSelected(true);
1677 list->scrollToItem(item);
1678 list->setFocus();
1679 }
1680 }
Roman Zippelb65a47e2006-06-08 22:12:47 -07001681}
1682
Linus Torvalds1da177e2005-04-16 15:20:36 -07001683void ConfigMainWindow::listFocusChanged(void)
1684{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001685 if (menuList->mode == menuMode)
1686 configList->clearSelection();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001687}
1688
1689void ConfigMainWindow::goBack(void)
1690{
Boris Barbulovski5df9da92015-09-22 11:36:36 -07001691 ConfigItem* item, *oldSelection;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001692
1693 configList->setParentMenu();
1694 if (configList->rootEntry == &rootmenu)
1695 backAction->setEnabled(false);
Boris Barbulovskibe596aa2015-09-22 11:36:28 -07001696
1697 if (menuList->selectedItems().count() == 0)
1698 return;
1699
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001700 item = (ConfigItem*)menuList->selectedItems().first();
Boris Barbulovski5df9da92015-09-22 11:36:36 -07001701 oldSelection = item;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001702 while (item) {
1703 if (item->menu == configList->rootEntry) {
Boris Barbulovski5df9da92015-09-22 11:36:36 -07001704 oldSelection->setSelected(false);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001705 item->setSelected(true);
1706 break;
1707 }
1708 item = (ConfigItem*)item->parent();
1709 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001710}
1711
1712void ConfigMainWindow::showSingleView(void)
1713{
Boris Barbulovski780505e2015-09-22 11:36:13 -07001714 singleViewAction->setEnabled(false);
1715 singleViewAction->setChecked(true);
1716 splitViewAction->setEnabled(true);
1717 splitViewAction->setChecked(false);
1718 fullViewAction->setEnabled(true);
1719 fullViewAction->setChecked(false);
1720
Linus Torvalds1da177e2005-04-16 15:20:36 -07001721 menuView->hide();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001722 menuList->setRootMenu(0);
1723 configList->mode = singleMode;
1724 if (configList->rootEntry == &rootmenu)
1725 configList->updateListAll();
1726 else
1727 configList->setRootMenu(&rootmenu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001728 configList->setFocus();
1729}
1730
1731void ConfigMainWindow::showSplitView(void)
1732{
Boris Barbulovski780505e2015-09-22 11:36:13 -07001733 singleViewAction->setEnabled(true);
1734 singleViewAction->setChecked(false);
1735 splitViewAction->setEnabled(false);
1736 splitViewAction->setChecked(true);
1737 fullViewAction->setEnabled(true);
1738 fullViewAction->setChecked(false);
1739
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +02001740 configList->mode = menuMode;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001741 if (configList->rootEntry == &rootmenu)
1742 configList->updateListAll();
1743 else
1744 configList->setRootMenu(&rootmenu);
1745 configList->setAllOpen(true);
1746 configApp->processEvents();
Mauro Carvalho Chehabb3111422020-04-02 11:28:01 +02001747 menuList->mode = symbolMode;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001748 menuList->setRootMenu(&rootmenu);
1749 menuList->setAllOpen(true);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001750 menuView->show();
1751 menuList->setFocus();
1752}
1753
1754void ConfigMainWindow::showFullView(void)
1755{
Boris Barbulovski780505e2015-09-22 11:36:13 -07001756 singleViewAction->setEnabled(true);
1757 singleViewAction->setChecked(false);
1758 splitViewAction->setEnabled(true);
1759 splitViewAction->setChecked(false);
1760 fullViewAction->setEnabled(false);
1761 fullViewAction->setChecked(true);
1762
Linus Torvalds1da177e2005-04-16 15:20:36 -07001763 menuView->hide();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001764 menuList->setRootMenu(0);
1765 configList->mode = fullMode;
1766 if (configList->rootEntry == &rootmenu)
1767 configList->updateListAll();
1768 else
1769 configList->setRootMenu(&rootmenu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001770 configList->setFocus();
1771}
1772
Linus Torvalds1da177e2005-04-16 15:20:36 -07001773/*
1774 * ask for saving configuration before quitting
Linus Torvalds1da177e2005-04-16 15:20:36 -07001775 */
1776void ConfigMainWindow::closeEvent(QCloseEvent* e)
1777{
Karsten Wieseb3214292006-12-13 00:34:06 -08001778 if (!conf_get_changed()) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001779 e->accept();
1780 return;
1781 }
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001782 QMessageBox mb("qconf", "Save configuration?", QMessageBox::Warning,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001783 QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape);
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001784 mb.setButtonText(QMessageBox::Yes, "&Save Changes");
1785 mb.setButtonText(QMessageBox::No, "&Discard Changes");
1786 mb.setButtonText(QMessageBox::Cancel, "Cancel Exit");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001787 switch (mb.exec()) {
1788 case QMessageBox::Yes:
Michal Marekbac6aa82011-05-25 15:10:25 +02001789 if (saveConfig())
1790 e->accept();
1791 else
1792 e->ignore();
1793 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001794 case QMessageBox::No:
1795 e->accept();
1796 break;
1797 case QMessageBox::Cancel:
1798 e->ignore();
1799 break;
1800 }
1801}
1802
1803void ConfigMainWindow::showIntro(void)
1804{
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001805 static const QString str = "Welcome to the qconf graphical configuration tool.\n\n"
Linus Torvalds1da177e2005-04-16 15:20:36 -07001806 "For each option, a blank box indicates the feature is disabled, a check\n"
1807 "indicates it is enabled, and a dot indicates that it is to be compiled\n"
1808 "as a module. Clicking on the box will cycle through the three states.\n\n"
1809 "If you do not see an option (e.g., a device driver) that you believe\n"
1810 "should be present, try turning on Show All Options under the Options menu.\n"
1811 "Although there is no cross reference yet to help you figure out what other\n"
1812 "options must be enabled to support the option you are interested in, you can\n"
1813 "still view the help of a grayed-out option.\n\n"
1814 "Toggling Show Debug Info under the Options menu will show the dependencies,\n"
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001815 "which you can then match by examining other options.\n\n";
Linus Torvalds1da177e2005-04-16 15:20:36 -07001816
1817 QMessageBox::information(this, "qconf", str);
1818}
1819
1820void ConfigMainWindow::showAbout(void)
1821{
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001822 static const QString str = "qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n"
Boris Barbulovskib4ff1de2015-09-22 11:36:38 -07001823 "Copyright (C) 2015 Boris Barbulovski <bbarbulovski@gmail.com>.\n\n"
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001824 "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n";
Linus Torvalds1da177e2005-04-16 15:20:36 -07001825
1826 QMessageBox::information(this, "qconf", str);
1827}
1828
1829void ConfigMainWindow::saveSettings(void)
1830{
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001831 configSettings->setValue("/window x", pos().x());
1832 configSettings->setValue("/window y", pos().y());
1833 configSettings->setValue("/window width", size().width());
1834 configSettings->setValue("/window height", size().height());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001835
1836 QString entry;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001837 switch(configList->mode) {
1838 case singleMode :
1839 entry = "single";
1840 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001841
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001842 case symbolMode :
1843 entry = "split";
1844 break;
1845
1846 case fullMode :
1847 entry = "full";
1848 break;
1849
1850 default:
1851 break;
1852 }
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001853 configSettings->setValue("/listMode", entry);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001854
Roman Zippel7fc925f2006-06-08 22:12:46 -07001855 configSettings->writeSizes("/split1", split1->sizes());
1856 configSettings->writeSizes("/split2", split2->sizes());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001857}
1858
Karsten Wiese3b354c52006-12-13 00:34:08 -08001859void ConfigMainWindow::conf_changed(void)
1860{
1861 if (saveAction)
1862 saveAction->setEnabled(conf_get_changed());
1863}
1864
Linus Torvalds1da177e2005-04-16 15:20:36 -07001865void fixup_rootmenu(struct menu *menu)
1866{
1867 struct menu *child;
1868 static int menu_cnt = 0;
1869
1870 menu->flags |= MENU_ROOT;
1871 for (child = menu->list; child; child = child->next) {
1872 if (child->prompt && child->prompt->type == P_MENU) {
1873 menu_cnt++;
1874 fixup_rootmenu(child);
1875 menu_cnt--;
1876 } else if (!menu_cnt)
1877 fixup_rootmenu(child);
1878 }
1879}
1880
1881static const char *progname;
1882
1883static void usage(void)
1884{
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001885 printf("%s [-s] <config>\n", progname);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001886 exit(0);
1887}
1888
1889int main(int ac, char** av)
1890{
1891 ConfigMainWindow* v;
1892 const char *name;
1893
Linus Torvalds1da177e2005-04-16 15:20:36 -07001894 progname = av[0];
1895 configApp = new QApplication(ac, av);
1896 if (ac > 1 && av[1][0] == '-') {
1897 switch (av[1][1]) {
Michal Marek0a1f00a2015-04-08 13:30:42 +02001898 case 's':
1899 conf_set_message_callback(NULL);
1900 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001901 case 'h':
1902 case '?':
1903 usage();
1904 }
1905 name = av[2];
1906 } else
1907 name = av[1];
1908 if (!name)
1909 usage();
1910
1911 conf_parse(name);
1912 fixup_rootmenu(&rootmenu);
1913 conf_read(NULL);
1914 //zconfdump(stdout);
1915
Roman Zippel7fc925f2006-06-08 22:12:46 -07001916 configSettings = new ConfigSettings();
1917 configSettings->beginGroup("/kconfig/qconf");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001918 v = new ConfigMainWindow();
1919
1920 //zconfdump(stdout);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001921 configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit()));
1922 configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings()));
Roman Zippel43bf6122006-06-08 22:12:45 -07001923 v->show();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001924 configApp->exec();
1925
Roman Zippel7fc925f2006-06-08 22:12:46 -07001926 configSettings->endGroup();
1927 delete configSettings;
Chris Bainbridge5b61c7b2016-01-08 20:44:04 +00001928 delete v;
1929 delete configApp;
Roman Zippel7fc925f2006-06-08 22:12:46 -07001930
Linus Torvalds1da177e2005-04-16 15:20:36 -07001931 return 0;
1932}