blob: 0e66dc73e177ff4c2d23b707e68fb4a3c7f24a83 [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 }
636 hide:
637 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 }
701 hide:
702 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) {
745 emit menuSelected(menu);
746 break;
747 }
748 case Qt::Key_Space:
749 changeValue(item);
750 break;
751 case Qt::Key_N:
752 setValue(item, no);
753 break;
754 case Qt::Key_M:
755 setValue(item, mod);
756 break;
757 case Qt::Key_Y:
758 setValue(item, yes);
759 break;
760 default:
761 Parent::keyPressEvent(ev);
762 return;
763 }
764 ev->accept();
Boris Barbulovski59e56442015-09-22 11:36:18 -0700765}
766
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700767void ConfigList::mousePressEvent(QMouseEvent* e)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700768{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700769 //QPoint p(contentsToViewport(e->pos()));
770 //printf("contentsMousePressEvent: %d,%d\n", p.x(), p.y());
771 Parent::mousePressEvent(e);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700772}
773
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700774void ConfigList::mouseReleaseEvent(QMouseEvent* e)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700775{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700776 QPoint p = e->pos();
777 ConfigItem* item = (ConfigItem*)itemAt(p);
778 struct menu *menu;
779 enum prop_type ptype;
780 QIcon icon;
781 int idx, x;
782
783 if (!item)
784 goto skip;
785
786 menu = item->menu;
787 x = header()->offset() + p.x();
Boris Barbulovski76d53cb2015-09-22 11:36:35 -0700788 idx = header()->logicalIndexAt(x);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700789 switch (idx) {
790 case promptColIdx:
791 icon = item->pixmap(promptColIdx);
Boris Barbulovski76d53cb2015-09-22 11:36:35 -0700792 if (!icon.isNull()) {
793 int off = header()->sectionPosition(0) + visualRect(indexAt(p)).x() + 4; // 4 is Hardcoded image offset. There might be a way to do it properly.
794 if (x >= off && x < off + icon.availableSizes().first().width()) {
795 if (item->goParent) {
796 emit parentSelected();
797 break;
798 } else if (!menu)
799 break;
800 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
801 if (ptype == P_MENU && rootEntry != menu &&
802 mode != fullMode && mode != menuMode)
803 emit menuSelected(menu);
804 else
805 changeValue(item);
806 }
807 }
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700808 break;
809 case noColIdx:
810 setValue(item, no);
811 break;
812 case modColIdx:
813 setValue(item, mod);
814 break;
815 case yesColIdx:
816 setValue(item, yes);
817 break;
818 case dataColIdx:
819 changeValue(item);
820 break;
821 }
822
823skip:
824 //printf("contentsMouseReleaseEvent: %d,%d\n", p.x(), p.y());
825 Parent::mouseReleaseEvent(e);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700826}
827
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700828void ConfigList::mouseMoveEvent(QMouseEvent* e)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700829{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700830 //QPoint p(contentsToViewport(e->pos()));
831 //printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y());
832 Parent::mouseMoveEvent(e);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700833}
834
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700835void ConfigList::mouseDoubleClickEvent(QMouseEvent* e)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700836{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700837 QPoint p = e->pos(); // TODO: Check if this works(was contentsToViewport).
838 ConfigItem* item = (ConfigItem*)itemAt(p);
839 struct menu *menu;
840 enum prop_type ptype;
841
842 if (!item)
843 goto skip;
844 if (item->goParent) {
845 emit parentSelected();
846 goto skip;
847 }
848 menu = item->menu;
849 if (!menu)
850 goto skip;
851 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
852 if (ptype == P_MENU && (mode == singleMode || mode == symbolMode))
853 emit menuSelected(menu);
854 else if (menu->sym)
855 changeValue(item);
856
857skip:
858 //printf("contentsMouseDoubleClickEvent: %d,%d\n", p.x(), p.y());
859 Parent::mouseDoubleClickEvent(e);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700860}
861
862void ConfigList::focusInEvent(QFocusEvent *e)
863{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700864 struct menu *menu = NULL;
865
866 Parent::focusInEvent(e);
867
868 ConfigItem* item = (ConfigItem *)currentItem();
869 if (item) {
870 item->setSelected(true);
871 menu = item->menu;
872 }
873 emit gotFocus(menu);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700874}
875
876void ConfigList::contextMenuEvent(QContextMenuEvent *e)
877{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700878 if (e->y() <= header()->geometry().bottom()) {
879 if (!headerPopup) {
880 QAction *action;
881
882 headerPopup = new QMenu(this);
Sam Ravnborg694c49a2018-05-22 21:36:12 +0200883 action = new QAction("Show Name", this);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700884 action->setCheckable(true);
885 connect(action, SIGNAL(toggled(bool)),
886 parent(), SLOT(setShowName(bool)));
887 connect(parent(), SIGNAL(showNameChanged(bool)),
888 action, SLOT(setOn(bool)));
889 action->setChecked(showName);
890 headerPopup->addAction(action);
Sam Ravnborg694c49a2018-05-22 21:36:12 +0200891 action = new QAction("Show Range", this);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700892 action->setCheckable(true);
893 connect(action, SIGNAL(toggled(bool)),
894 parent(), SLOT(setShowRange(bool)));
895 connect(parent(), SIGNAL(showRangeChanged(bool)),
896 action, SLOT(setOn(bool)));
897 action->setChecked(showRange);
898 headerPopup->addAction(action);
Sam Ravnborg694c49a2018-05-22 21:36:12 +0200899 action = new QAction("Show Data", this);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700900 action->setCheckable(true);
901 connect(action, SIGNAL(toggled(bool)),
902 parent(), SLOT(setShowData(bool)));
903 connect(parent(), SIGNAL(showDataChanged(bool)),
904 action, SLOT(setOn(bool)));
905 action->setChecked(showData);
906 headerPopup->addAction(action);
907 }
908 headerPopup->exec(e->globalPos());
909 e->accept();
910 } else
911 e->ignore();
Boris Barbulovski59e56442015-09-22 11:36:18 -0700912}
913
Li Zefan39a48972010-05-10 16:33:41 +0800914ConfigView*ConfigView::viewList;
915QAction *ConfigView::showNormalAction;
916QAction *ConfigView::showAllAction;
917QAction *ConfigView::showPromptAction;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700918
Roman Zippel7fc925f2006-06-08 22:12:46 -0700919ConfigView::ConfigView(QWidget* parent, const char *name)
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -0700920 : Parent(parent)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700921{
Boris Barbulovski9bd36ed2015-09-22 11:36:22 -0700922 setObjectName(name);
Boris Barbulovski29a70162015-09-22 11:36:10 -0700923 QVBoxLayout *verticalLayout = new QVBoxLayout(this);
Boris Barbulovski92298b42015-09-22 11:36:11 -0700924 verticalLayout->setContentsMargins(0, 0, 0, 0);
Boris Barbulovski29a70162015-09-22 11:36:10 -0700925
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700926 list = new ConfigList(this);
Boris Barbulovski29a70162015-09-22 11:36:10 -0700927 verticalLayout->addWidget(list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700928 lineEdit = new ConfigLineEdit(this);
929 lineEdit->hide();
Boris Barbulovski29a70162015-09-22 11:36:10 -0700930 verticalLayout->addWidget(lineEdit);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700931
932 this->nextView = viewList;
933 viewList = this;
934}
935
936ConfigView::~ConfigView(void)
937{
938 ConfigView** vp;
939
940 for (vp = &viewList; *vp; vp = &(*vp)->nextView) {
941 if (*vp == this) {
942 *vp = nextView;
943 break;
944 }
945 }
946}
947
Li Zefan39a48972010-05-10 16:33:41 +0800948void ConfigView::setOptionMode(QAction *act)
Roman Zippel7fc925f2006-06-08 22:12:46 -0700949{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700950 if (act == showNormalAction)
951 list->optMode = normalOpt;
952 else if (act == showAllAction)
953 list->optMode = allOpt;
954 else
955 list->optMode = promptOpt;
956
957 list->updateListAll();
Roman Zippel7fc925f2006-06-08 22:12:46 -0700958}
959
960void ConfigView::setShowName(bool b)
961{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700962 if (list->showName != b) {
963 list->showName = b;
964 list->reinit();
965 emit showNameChanged(b);
966 }
Roman Zippel7fc925f2006-06-08 22:12:46 -0700967}
968
969void ConfigView::setShowRange(bool b)
970{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700971 if (list->showRange != b) {
972 list->showRange = b;
973 list->reinit();
974 emit showRangeChanged(b);
975 }
Roman Zippel7fc925f2006-06-08 22:12:46 -0700976}
977
978void ConfigView::setShowData(bool b)
979{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700980 if (list->showData != b) {
981 list->showData = b;
982 list->reinit();
983 emit showDataChanged(b);
984 }
985}
986
987void ConfigList::setAllOpen(bool open)
988{
989 QTreeWidgetItemIterator it(this);
990
991 while (*it) {
992 (*it)->setExpanded(open);
993
994 ++it;
995 }
Roman Zippel7fc925f2006-06-08 22:12:46 -0700996}
997
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700998void ConfigView::updateList(ConfigItem* item)
Roman Zippel7fc925f2006-06-08 22:12:46 -0700999{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001000 ConfigView* v;
1001
1002 for (v = viewList; v; v = v->nextView)
1003 v->list->updateList(item);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001004}
1005
1006void ConfigView::updateListAll(void)
1007{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001008 ConfigView* v;
1009
1010 for (v = viewList; v; v = v->nextView)
1011 v->list->updateListAll();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001012}
1013
Roman Zippel43bf6122006-06-08 22:12:45 -07001014ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name)
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001015 : Parent(parent), sym(0), _menu(0)
Roman Zippel43bf6122006-06-08 22:12:45 -07001016{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001017 setObjectName(name);
1018
1019
1020 if (!objectName().isEmpty()) {
1021 configSettings->beginGroup(objectName());
Boris Barbulovskie0393032016-11-30 14:57:52 -08001022 setShowDebug(configSettings->value("/showDebug", false).toBool());
Roman Zippel7fc925f2006-06-08 22:12:46 -07001023 configSettings->endGroup();
1024 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
1025 }
1026}
1027
1028void ConfigInfoView::saveSettings(void)
1029{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001030 if (!objectName().isEmpty()) {
1031 configSettings->beginGroup(objectName());
1032 configSettings->setValue("/showDebug", showDebug());
1033 configSettings->endGroup();
1034 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001035}
1036
1037void ConfigInfoView::setShowDebug(bool b)
1038{
1039 if (_showDebug != b) {
1040 _showDebug = b;
Alexander Stein133c5f72010-08-31 17:34:37 +02001041 if (_menu)
Roman Zippel43bf6122006-06-08 22:12:45 -07001042 menuInfo();
Roman Zippelab45d192006-06-08 22:12:47 -07001043 else if (sym)
1044 symbolInfo();
Roman Zippel43bf6122006-06-08 22:12:45 -07001045 emit showDebugChanged(b);
1046 }
1047}
1048
1049void ConfigInfoView::setInfo(struct menu *m)
1050{
Alexander Stein133c5f72010-08-31 17:34:37 +02001051 if (_menu == m)
Roman Zippelb65a47e2006-06-08 22:12:47 -07001052 return;
Alexander Stein133c5f72010-08-31 17:34:37 +02001053 _menu = m;
Roman Zippel6fa1da82007-01-10 23:15:31 -08001054 sym = NULL;
Alexander Stein133c5f72010-08-31 17:34:37 +02001055 if (!_menu)
Roman Zippel43bf6122006-06-08 22:12:45 -07001056 clear();
Roman Zippel6fa1da82007-01-10 23:15:31 -08001057 else
Roman Zippel43bf6122006-06-08 22:12:45 -07001058 menuInfo();
1059}
1060
Roman Zippelab45d192006-06-08 22:12:47 -07001061void ConfigInfoView::symbolInfo(void)
1062{
1063 QString str;
1064
1065 str += "<big>Symbol: <b>";
1066 str += print_filter(sym->name);
1067 str += "</b></big><br><br>value: ";
1068 str += print_filter(sym_get_string_value(sym));
1069 str += "<br>visibility: ";
1070 str += sym->visible == yes ? "y" : sym->visible == mod ? "m" : "n";
1071 str += "<br>";
1072 str += debug_info(sym);
1073
1074 setText(str);
1075}
1076
Roman Zippel43bf6122006-06-08 22:12:45 -07001077void ConfigInfoView::menuInfo(void)
1078{
1079 struct symbol* sym;
1080 QString head, debug, help;
1081
Alexander Stein133c5f72010-08-31 17:34:37 +02001082 sym = _menu->sym;
Roman Zippel43bf6122006-06-08 22:12:45 -07001083 if (sym) {
Alexander Stein133c5f72010-08-31 17:34:37 +02001084 if (_menu->prompt) {
Roman Zippel43bf6122006-06-08 22:12:45 -07001085 head += "<big><b>";
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001086 head += print_filter(_menu->prompt->text);
Roman Zippel43bf6122006-06-08 22:12:45 -07001087 head += "</b></big>";
1088 if (sym->name) {
1089 head += " (";
Roman Zippelab45d192006-06-08 22:12:47 -07001090 if (showDebug())
1091 head += QString().sprintf("<a href=\"s%p\">", sym);
Roman Zippel43bf6122006-06-08 22:12:45 -07001092 head += print_filter(sym->name);
Roman Zippelab45d192006-06-08 22:12:47 -07001093 if (showDebug())
1094 head += "</a>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001095 head += ")";
1096 }
1097 } else if (sym->name) {
1098 head += "<big><b>";
Roman Zippelab45d192006-06-08 22:12:47 -07001099 if (showDebug())
1100 head += QString().sprintf("<a href=\"s%p\">", sym);
Roman Zippel43bf6122006-06-08 22:12:45 -07001101 head += print_filter(sym->name);
Roman Zippelab45d192006-06-08 22:12:47 -07001102 if (showDebug())
1103 head += "</a>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001104 head += "</b></big>";
1105 }
1106 head += "<br><br>";
1107
1108 if (showDebug())
1109 debug = debug_info(sym);
1110
Cheng Renquand74c15f2009-07-12 16:11:47 +08001111 struct gstr help_gstr = str_new();
Alexander Stein133c5f72010-08-31 17:34:37 +02001112 menu_get_ext_help(_menu, &help_gstr);
Cheng Renquand74c15f2009-07-12 16:11:47 +08001113 help = print_filter(str_get(&help_gstr));
1114 str_free(&help_gstr);
Alexander Stein133c5f72010-08-31 17:34:37 +02001115 } else if (_menu->prompt) {
Roman Zippel43bf6122006-06-08 22:12:45 -07001116 head += "<big><b>";
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001117 head += print_filter(_menu->prompt->text);
Roman Zippel43bf6122006-06-08 22:12:45 -07001118 head += "</b></big><br><br>";
1119 if (showDebug()) {
Alexander Stein133c5f72010-08-31 17:34:37 +02001120 if (_menu->prompt->visible.expr) {
Roman Zippel43bf6122006-06-08 22:12:45 -07001121 debug += "&nbsp;&nbsp;dep: ";
Alexander Stein133c5f72010-08-31 17:34:37 +02001122 expr_print(_menu->prompt->visible.expr, expr_print_help, &debug, E_NONE);
Roman Zippel43bf6122006-06-08 22:12:45 -07001123 debug += "<br><br>";
1124 }
1125 }
1126 }
1127 if (showDebug())
Alexander Stein133c5f72010-08-31 17:34:37 +02001128 debug += QString().sprintf("defined at %s:%d<br><br>", _menu->file->name, _menu->lineno);
Roman Zippel43bf6122006-06-08 22:12:45 -07001129
1130 setText(head + debug + help);
1131}
1132
1133QString ConfigInfoView::debug_info(struct symbol *sym)
1134{
1135 QString debug;
1136
1137 debug += "type: ";
1138 debug += print_filter(sym_type_name(sym->type));
1139 if (sym_is_choice(sym))
1140 debug += " (choice)";
1141 debug += "<br>";
1142 if (sym->rev_dep.expr) {
1143 debug += "reverse dep: ";
1144 expr_print(sym->rev_dep.expr, expr_print_help, &debug, E_NONE);
1145 debug += "<br>";
1146 }
1147 for (struct property *prop = sym->prop; prop; prop = prop->next) {
1148 switch (prop->type) {
1149 case P_PROMPT:
1150 case P_MENU:
Roman Zippelab45d192006-06-08 22:12:47 -07001151 debug += QString().sprintf("prompt: <a href=\"m%p\">", prop->menu);
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001152 debug += print_filter(prop->text);
Roman Zippelab45d192006-06-08 22:12:47 -07001153 debug += "</a><br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001154 break;
1155 case P_DEFAULT:
Roman Zippel93449082008-01-14 04:50:54 +01001156 case P_SELECT:
1157 case P_RANGE:
Roman Zippel93449082008-01-14 04:50:54 +01001158 debug += prop_get_type_name(prop->type);
1159 debug += ": ";
Roman Zippel43bf6122006-06-08 22:12:45 -07001160 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1161 debug += "<br>";
1162 break;
1163 case P_CHOICE:
1164 if (sym_is_choice(sym)) {
1165 debug += "choice: ";
1166 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1167 debug += "<br>";
1168 }
1169 break;
Roman Zippel43bf6122006-06-08 22:12:45 -07001170 default:
1171 debug += "unknown property: ";
1172 debug += prop_get_type_name(prop->type);
1173 debug += "<br>";
1174 }
1175 if (prop->visible.expr) {
1176 debug += "&nbsp;&nbsp;&nbsp;&nbsp;dep: ";
1177 expr_print(prop->visible.expr, expr_print_help, &debug, E_NONE);
1178 debug += "<br>";
1179 }
1180 }
1181 debug += "<br>";
1182
1183 return debug;
1184}
1185
1186QString ConfigInfoView::print_filter(const QString &str)
1187{
1188 QRegExp re("[<>&\"\\n]");
1189 QString res = str;
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001190 for (int i = 0; (i = res.indexOf(re, i)) >= 0;) {
1191 switch (res[i].toLatin1()) {
Roman Zippel43bf6122006-06-08 22:12:45 -07001192 case '<':
1193 res.replace(i, 1, "&lt;");
1194 i += 4;
1195 break;
1196 case '>':
1197 res.replace(i, 1, "&gt;");
1198 i += 4;
1199 break;
1200 case '&':
1201 res.replace(i, 1, "&amp;");
1202 i += 5;
1203 break;
1204 case '"':
1205 res.replace(i, 1, "&quot;");
1206 i += 6;
1207 break;
1208 case '\n':
1209 res.replace(i, 1, "<br>");
1210 i += 4;
1211 break;
1212 }
1213 }
1214 return res;
1215}
1216
Roman Zippelab45d192006-06-08 22:12:47 -07001217void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char *str)
Roman Zippel43bf6122006-06-08 22:12:45 -07001218{
Roman Zippelab45d192006-06-08 22:12:47 -07001219 QString* text = reinterpret_cast<QString*>(data);
1220 QString str2 = print_filter(str);
1221
1222 if (sym && sym->name && !(sym->flags & SYMBOL_CONST)) {
1223 *text += QString().sprintf("<a href=\"s%p\">", sym);
1224 *text += str2;
1225 *text += "</a>";
1226 } else
1227 *text += str2;
Roman Zippel43bf6122006-06-08 22:12:45 -07001228}
1229
Boris Barbulovski924bbb52015-09-22 11:36:06 -07001230QMenu* ConfigInfoView::createStandardContextMenu(const QPoint & pos)
Roman Zippel7fc925f2006-06-08 22:12:46 -07001231{
Boris Barbulovski924bbb52015-09-22 11:36:06 -07001232 QMenu* popup = Parent::createStandardContextMenu(pos);
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001233 QAction* action = new QAction("Show Debug Info", popup);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001234 action->setCheckable(true);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001235 connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
1236 connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool)));
Boris Barbulovski9c862352015-09-22 11:36:12 -07001237 action->setChecked(showDebug());
Boris Barbulovski924bbb52015-09-22 11:36:06 -07001238 popup->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001239 popup->addAction(action);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001240 return popup;
1241}
1242
Boris Barbulovski924bbb52015-09-22 11:36:06 -07001243void ConfigInfoView::contextMenuEvent(QContextMenuEvent *e)
Roman Zippel7fc925f2006-06-08 22:12:46 -07001244{
Boris Barbulovski924bbb52015-09-22 11:36:06 -07001245 Parent::contextMenuEvent(e);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001246}
1247
Marco Costalba63431e72006-10-05 19:12:59 +02001248ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow* parent, const char *name)
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001249 : Parent(parent), result(NULL)
Roman Zippel43bf6122006-06-08 22:12:45 -07001250{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001251 setObjectName(name);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001252 setWindowTitle("Search Config");
Roman Zippel43bf6122006-06-08 22:12:45 -07001253
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001254 QVBoxLayout* layout1 = new QVBoxLayout(this);
1255 layout1->setContentsMargins(11, 11, 11, 11);
1256 layout1->setSpacing(6);
1257 QHBoxLayout* layout2 = new QHBoxLayout(0);
1258 layout2->setContentsMargins(0, 0, 0, 0);
1259 layout2->setSpacing(6);
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001260 layout2->addWidget(new QLabel("Find:", this));
Roman Zippel43bf6122006-06-08 22:12:45 -07001261 editField = new QLineEdit(this);
1262 connect(editField, SIGNAL(returnPressed()), SLOT(search()));
1263 layout2->addWidget(editField);
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001264 searchButton = new QPushButton("Search", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001265 searchButton->setAutoDefault(false);
Roman Zippel43bf6122006-06-08 22:12:45 -07001266 connect(searchButton, SIGNAL(clicked()), SLOT(search()));
1267 layout2->addWidget(searchButton);
1268 layout1->addLayout(layout2);
1269
Roman Zippel7fc925f2006-06-08 22:12:46 -07001270 split = new QSplitter(this);
Markus Heidelberg7298b932009-05-18 01:36:50 +02001271 split->setOrientation(Qt::Vertical);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001272 list = new ConfigView(split, name);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001273 list->list->mode = listMode;
Roman Zippel7fc925f2006-06-08 22:12:46 -07001274 info = new ConfigInfoView(split, name);
Roman Zippel43bf6122006-06-08 22:12:45 -07001275 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1276 info, SLOT(setInfo(struct menu *)));
Marco Costalba63431e72006-10-05 19:12:59 +02001277 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1278 parent, SLOT(setMenuLink(struct menu *)));
1279
Roman Zippel43bf6122006-06-08 22:12:45 -07001280 layout1->addWidget(split);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001281
1282 if (name) {
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001283 QVariant x, y;
1284 int width, height;
Roman Zippel7fc925f2006-06-08 22:12:46 -07001285 bool ok;
1286
1287 configSettings->beginGroup(name);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001288 width = configSettings->value("/window width", parent->width() / 2).toInt();
1289 height = configSettings->value("/window height", parent->height() / 2).toInt();
Roman Zippel7fc925f2006-06-08 22:12:46 -07001290 resize(width, height);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001291 x = configSettings->value("/window x");
1292 y = configSettings->value("/window y");
1293 if ((x.isValid())&&(y.isValid()))
1294 move(x.toInt(), y.toInt());
Boris Barbulovski041fbdc2015-09-22 11:36:05 -07001295 QList<int> sizes = configSettings->readSizes("/split", &ok);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001296 if (ok)
1297 split->setSizes(sizes);
1298 configSettings->endGroup();
1299 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
1300 }
1301}
1302
1303void ConfigSearchWindow::saveSettings(void)
1304{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001305 if (!objectName().isEmpty()) {
1306 configSettings->beginGroup(objectName());
1307 configSettings->setValue("/window x", pos().x());
1308 configSettings->setValue("/window y", pos().y());
1309 configSettings->setValue("/window width", size().width());
1310 configSettings->setValue("/window height", size().height());
1311 configSettings->writeSizes("/split", split->sizes());
1312 configSettings->endGroup();
1313 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001314}
1315
1316void ConfigSearchWindow::search(void)
1317{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001318 struct symbol **p;
1319 struct property *prop;
1320 ConfigItem *lastItem = NULL;
1321
1322 free(result);
1323 list->list->clear();
1324 info->clear();
1325
1326 result = sym_re_search(editField->text().toLatin1());
1327 if (!result)
1328 return;
1329 for (p = result; *p; p++) {
1330 for_all_prompts((*p), prop)
1331 lastItem = new ConfigItem(list->list, lastItem, prop->menu,
1332 menu_is_visible(prop->menu));
1333 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001334}
1335
Linus Torvalds1da177e2005-04-16 15:20:36 -07001336/*
1337 * Construct the complete config widget
1338 */
1339ConfigMainWindow::ConfigMainWindow(void)
Roman Zippelf12aa702006-11-25 11:09:31 -08001340 : searchWindow(0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001341{
1342 QMenuBar* menu;
Boris Barbulovski92119932015-09-22 11:36:16 -07001343 bool ok = true;
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001344 QVariant x, y;
1345 int width, height;
Randy Dunlapa54bb702007-10-20 11:18:47 -07001346 char title[256];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001347
Markus Heidelberg8d90c972009-05-18 01:36:52 +02001348 QDesktopWidget *d = configApp->desktop();
Arnaud Lacombe09548282010-08-18 01:57:13 -04001349 snprintf(title, sizeof(title), "%s%s",
1350 rootmenu.prompt->text,
Michal Marek76a136c2010-09-01 17:39:27 +02001351 ""
Michal Marek76a136c2010-09-01 17:39:27 +02001352 );
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001353 setWindowTitle(title);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001354
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001355 width = configSettings->value("/window width", d->width() - 64).toInt();
1356 height = configSettings->value("/window height", d->height() - 64).toInt();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001357 resize(width, height);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001358 x = configSettings->value("/window x");
1359 y = configSettings->value("/window y");
1360 if ((x.isValid())&&(y.isValid()))
1361 move(x.toInt(), y.toInt());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001362
1363 split1 = new QSplitter(this);
Markus Heidelberg7298b932009-05-18 01:36:50 +02001364 split1->setOrientation(Qt::Horizontal);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001365 setCentralWidget(split1);
1366
Roman Zippel7fc925f2006-06-08 22:12:46 -07001367 menuView = new ConfigView(split1, "menu");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001368 menuList = menuView->list;
1369
1370 split2 = new QSplitter(split1);
Markus Heidelberg7298b932009-05-18 01:36:50 +02001371 split2->setOrientation(Qt::Vertical);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001372
1373 // create config tree
Roman Zippel7fc925f2006-06-08 22:12:46 -07001374 configView = new ConfigView(split2, "config");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001375 configList = configView->list;
1376
Roman Zippel7fc925f2006-06-08 22:12:46 -07001377 helpText = new ConfigInfoView(split2, "help");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001378
1379 setTabOrder(configList, helpText);
1380 configList->setFocus();
1381
1382 menu = menuBar();
Boris Barbulovskib1f8a452015-09-22 11:36:02 -07001383 toolBar = new QToolBar("Tools", this);
Boris Barbulovski29a70162015-09-22 11:36:10 -07001384 addToolBar(toolBar);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001385
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001386 backAction = new QAction(QPixmap(xpm_back), "Back", this);
Boris Barbulovski92119932015-09-22 11:36:16 -07001387 connect(backAction, SIGNAL(triggered(bool)), SLOT(goBack()));
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001388 backAction->setEnabled(false);
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001389 QAction *quitAction = new QAction("&Quit", this);
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001390 quitAction->setShortcut(Qt::CTRL + Qt::Key_Q);
Boris Barbulovski92119932015-09-22 11:36:16 -07001391 connect(quitAction, SIGNAL(triggered(bool)), SLOT(close()));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001392 QAction *loadAction = new QAction(QPixmap(xpm_load), "&Load", this);
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001393 loadAction->setShortcut(Qt::CTRL + Qt::Key_L);
Boris Barbulovski92119932015-09-22 11:36:16 -07001394 connect(loadAction, SIGNAL(triggered(bool)), SLOT(loadConfig()));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001395 saveAction = new QAction(QPixmap(xpm_save), "&Save", this);
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001396 saveAction->setShortcut(Qt::CTRL + Qt::Key_S);
Boris Barbulovski92119932015-09-22 11:36:16 -07001397 connect(saveAction, SIGNAL(triggered(bool)), SLOT(saveConfig()));
Karsten Wiese3b354c52006-12-13 00:34:08 -08001398 conf_set_changed_callback(conf_changed);
1399 // Set saveAction's initial state
1400 conf_changed();
Masahiro Yamada87419082019-03-11 01:13:15 +09001401 configname = xstrdup(conf_get_configname());
1402
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001403 QAction *saveAsAction = new QAction("Save &As...", this);
Boris Barbulovski92119932015-09-22 11:36:16 -07001404 connect(saveAsAction, SIGNAL(triggered(bool)), SLOT(saveConfigAs()));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001405 QAction *searchAction = new QAction("&Find", this);
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001406 searchAction->setShortcut(Qt::CTRL + Qt::Key_F);
Boris Barbulovski92119932015-09-22 11:36:16 -07001407 connect(searchAction, SIGNAL(triggered(bool)), SLOT(searchConfig()));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001408 singleViewAction = new QAction(QPixmap(xpm_single_view), "Single View", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001409 singleViewAction->setCheckable(true);
Boris Barbulovski92119932015-09-22 11:36:16 -07001410 connect(singleViewAction, SIGNAL(triggered(bool)), SLOT(showSingleView()));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001411 splitViewAction = new QAction(QPixmap(xpm_split_view), "Split View", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001412 splitViewAction->setCheckable(true);
Boris Barbulovski92119932015-09-22 11:36:16 -07001413 connect(splitViewAction, SIGNAL(triggered(bool)), SLOT(showSplitView()));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001414 fullViewAction = new QAction(QPixmap(xpm_tree_view), "Full View", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001415 fullViewAction->setCheckable(true);
Boris Barbulovski92119932015-09-22 11:36:16 -07001416 connect(fullViewAction, SIGNAL(triggered(bool)), SLOT(showFullView()));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001417
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001418 QAction *showNameAction = new QAction("Show Name", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001419 showNameAction->setCheckable(true);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001420 connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool)));
Boris Barbulovski9c862352015-09-22 11:36:12 -07001421 showNameAction->setChecked(configView->showName());
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001422 QAction *showRangeAction = new QAction("Show Range", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001423 showRangeAction->setCheckable(true);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001424 connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool)));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001425 QAction *showDataAction = new QAction("Show Data", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001426 showDataAction->setCheckable(true);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001427 connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool)));
Li Zefan39a48972010-05-10 16:33:41 +08001428
1429 QActionGroup *optGroup = new QActionGroup(this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001430 optGroup->setExclusive(true);
Boris Barbulovski92119932015-09-22 11:36:16 -07001431 connect(optGroup, SIGNAL(triggered(QAction*)), configView,
Li Zefan39a48972010-05-10 16:33:41 +08001432 SLOT(setOptionMode(QAction *)));
Boris Barbulovski92119932015-09-22 11:36:16 -07001433 connect(optGroup, SIGNAL(triggered(QAction *)), menuView,
Li Zefan39a48972010-05-10 16:33:41 +08001434 SLOT(setOptionMode(QAction *)));
1435
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001436 configView->showNormalAction = new QAction("Show Normal Options", optGroup);
1437 configView->showAllAction = new QAction("Show All Options", optGroup);
1438 configView->showPromptAction = new QAction("Show Prompt Options", optGroup);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001439 configView->showNormalAction->setCheckable(true);
1440 configView->showAllAction->setCheckable(true);
1441 configView->showPromptAction->setCheckable(true);
Li Zefan39a48972010-05-10 16:33:41 +08001442
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001443 QAction *showDebugAction = new QAction("Show Debug Info", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001444 showDebugAction->setCheckable(true);
Roman Zippel43bf6122006-06-08 22:12:45 -07001445 connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
Boris Barbulovski9c862352015-09-22 11:36:12 -07001446 showDebugAction->setChecked(helpText->showDebug());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001447
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001448 QAction *showIntroAction = new QAction("Introduction", this);
Boris Barbulovski92119932015-09-22 11:36:16 -07001449 connect(showIntroAction, SIGNAL(triggered(bool)), SLOT(showIntro()));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001450 QAction *showAboutAction = new QAction("About", this);
Boris Barbulovski92119932015-09-22 11:36:16 -07001451 connect(showAboutAction, SIGNAL(triggered(bool)), SLOT(showAbout()));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001452
1453 // init tool bar
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001454 toolBar->addAction(backAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001455 toolBar->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001456 toolBar->addAction(loadAction);
1457 toolBar->addAction(saveAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001458 toolBar->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001459 toolBar->addAction(singleViewAction);
1460 toolBar->addAction(splitViewAction);
1461 toolBar->addAction(fullViewAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001462
1463 // create config menu
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001464 QMenu* config = menu->addMenu("&File");
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001465 config->addAction(loadAction);
1466 config->addAction(saveAction);
1467 config->addAction(saveAsAction);
Boris Barbulovski76bede82015-09-22 11:36:07 -07001468 config->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001469 config->addAction(quitAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001470
Shlomi Fish66e7c722007-02-14 00:32:58 -08001471 // create edit menu
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001472 QMenu* editMenu = menu->addMenu("&Edit");
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001473 editMenu->addAction(searchAction);
Shlomi Fish66e7c722007-02-14 00:32:58 -08001474
Linus Torvalds1da177e2005-04-16 15:20:36 -07001475 // create options menu
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001476 QMenu* optionMenu = menu->addMenu("&Option");
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001477 optionMenu->addAction(showNameAction);
1478 optionMenu->addAction(showRangeAction);
1479 optionMenu->addAction(showDataAction);
Boris Barbulovski76bede82015-09-22 11:36:07 -07001480 optionMenu->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001481 optionMenu->addActions(optGroup->actions());
Boris Barbulovski76bede82015-09-22 11:36:07 -07001482 optionMenu->addSeparator();
Boris Barbulovskie0393032016-11-30 14:57:52 -08001483 optionMenu->addAction(showDebugAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001484
1485 // create help menu
Boris Barbulovski76bede82015-09-22 11:36:07 -07001486 menu->addSeparator();
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001487 QMenu* helpMenu = menu->addMenu("&Help");
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001488 helpMenu->addAction(showIntroAction);
1489 helpMenu->addAction(showAboutAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001490
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001491 connect(configList, SIGNAL(menuChanged(struct menu *)),
1492 helpText, SLOT(setInfo(struct menu *)));
1493 connect(configList, SIGNAL(menuSelected(struct menu *)),
1494 SLOT(changeMenu(struct menu *)));
1495 connect(configList, SIGNAL(parentSelected()),
1496 SLOT(goBack()));
1497 connect(menuList, SIGNAL(menuChanged(struct menu *)),
1498 helpText, SLOT(setInfo(struct menu *)));
1499 connect(menuList, SIGNAL(menuSelected(struct menu *)),
1500 SLOT(changeMenu(struct menu *)));
1501
1502 connect(configList, SIGNAL(gotFocus(struct menu *)),
1503 helpText, SLOT(setInfo(struct menu *)));
1504 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1505 helpText, SLOT(setInfo(struct menu *)));
1506 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1507 SLOT(listFocusChanged(void)));
Roman Zippelb65a47e2006-06-08 22:12:47 -07001508 connect(helpText, SIGNAL(menuSelected(struct menu *)),
1509 SLOT(setMenuLink(struct menu *)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001510
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001511 QString listMode = configSettings->value("/listMode", "symbol").toString();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001512 if (listMode == "single")
1513 showSingleView();
1514 else if (listMode == "full")
1515 showFullView();
1516 else /*if (listMode == "split")*/
1517 showSplitView();
1518
1519 // UI setup done, restore splitter positions
Boris Barbulovski041fbdc2015-09-22 11:36:05 -07001520 QList<int> sizes = configSettings->readSizes("/split1", &ok);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001521 if (ok)
1522 split1->setSizes(sizes);
1523
Roman Zippel7fc925f2006-06-08 22:12:46 -07001524 sizes = configSettings->readSizes("/split2", &ok);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001525 if (ok)
1526 split2->setSizes(sizes);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001527}
1528
Linus Torvalds1da177e2005-04-16 15:20:36 -07001529void ConfigMainWindow::loadConfig(void)
1530{
Masahiro Yamada87419082019-03-11 01:13:15 +09001531 QString str;
1532 QByteArray ba;
1533 const char *name;
1534
1535 str = QFileDialog::getOpenFileName(this, "", configname);
1536 if (str.isNull())
Linus Torvalds1da177e2005-04-16 15:20:36 -07001537 return;
Masahiro Yamada87419082019-03-11 01:13:15 +09001538
1539 ba = str.toLocal8Bit();
1540 name = ba.data();
1541
1542 if (conf_read(name))
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001543 QMessageBox::information(this, "qconf", "Unable to load configuration!");
Masahiro Yamada87419082019-03-11 01:13:15 +09001544
1545 free(configname);
1546 configname = xstrdup(name);
1547
Linus Torvalds1da177e2005-04-16 15:20:36 -07001548 ConfigView::updateListAll();
1549}
1550
Michal Marekbac6aa82011-05-25 15:10:25 +02001551bool ConfigMainWindow::saveConfig(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001552{
Masahiro Yamada87419082019-03-11 01:13:15 +09001553 if (conf_write(configname)) {
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001554 QMessageBox::information(this, "qconf", "Unable to save configuration!");
Michal Marekbac6aa82011-05-25 15:10:25 +02001555 return false;
1556 }
Masahiro Yamada00c864f2018-07-20 16:46:31 +09001557 conf_write_autoconf(0);
1558
Michal Marekbac6aa82011-05-25 15:10:25 +02001559 return true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001560}
1561
1562void ConfigMainWindow::saveConfigAs(void)
1563{
Masahiro Yamada87419082019-03-11 01:13:15 +09001564 QString str;
1565 QByteArray ba;
1566 const char *name;
1567
1568 str = QFileDialog::getSaveFileName(this, "", configname);
1569 if (str.isNull())
Linus Torvalds1da177e2005-04-16 15:20:36 -07001570 return;
Masahiro Yamada87419082019-03-11 01:13:15 +09001571
1572 ba = str.toLocal8Bit();
1573 name = ba.data();
1574
1575 if (conf_write(name)) {
1576 QMessageBox::information(this, "qconf", "Unable to save configuration!");
1577 }
1578 conf_write_autoconf(0);
1579
1580 free(configname);
1581 configname = xstrdup(name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001582}
1583
Roman Zippel43bf6122006-06-08 22:12:45 -07001584void ConfigMainWindow::searchConfig(void)
1585{
1586 if (!searchWindow)
Roman Zippel7fc925f2006-06-08 22:12:46 -07001587 searchWindow = new ConfigSearchWindow(this, "search");
Roman Zippel43bf6122006-06-08 22:12:45 -07001588 searchWindow->show();
1589}
1590
Linus Torvalds1da177e2005-04-16 15:20:36 -07001591void ConfigMainWindow::changeMenu(struct menu *menu)
1592{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001593 configList->setRootMenu(menu);
1594 if (configList->rootEntry->parent == &rootmenu)
1595 backAction->setEnabled(false);
1596 else
1597 backAction->setEnabled(true);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001598}
1599
Roman Zippelb65a47e2006-06-08 22:12:47 -07001600void ConfigMainWindow::setMenuLink(struct menu *menu)
1601{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001602 struct menu *parent;
1603 ConfigList* list = NULL;
1604 ConfigItem* item;
1605
1606 if (configList->menuSkip(menu))
1607 return;
1608
1609 switch (configList->mode) {
1610 case singleMode:
1611 list = configList;
1612 parent = menu_get_parent_menu(menu);
1613 if (!parent)
1614 return;
1615 list->setRootMenu(parent);
1616 break;
1617 case symbolMode:
1618 if (menu->flags & MENU_ROOT) {
1619 configList->setRootMenu(menu);
1620 configList->clearSelection();
1621 list = menuList;
1622 } else {
1623 list = configList;
1624 parent = menu_get_parent_menu(menu->parent);
1625 if (!parent)
1626 return;
1627 item = menuList->findConfigItem(parent);
1628 if (item) {
1629 item->setSelected(true);
1630 menuList->scrollToItem(item);
1631 }
1632 list->setRootMenu(parent);
1633 }
1634 break;
1635 case fullMode:
1636 list = configList;
1637 break;
1638 default:
1639 break;
1640 }
1641
1642 if (list) {
1643 item = list->findConfigItem(menu);
1644 if (item) {
1645 item->setSelected(true);
1646 list->scrollToItem(item);
1647 list->setFocus();
1648 }
1649 }
Roman Zippelb65a47e2006-06-08 22:12:47 -07001650}
1651
Linus Torvalds1da177e2005-04-16 15:20:36 -07001652void ConfigMainWindow::listFocusChanged(void)
1653{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001654 if (menuList->mode == menuMode)
1655 configList->clearSelection();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001656}
1657
1658void ConfigMainWindow::goBack(void)
1659{
Boris Barbulovski5df9da92015-09-22 11:36:36 -07001660 ConfigItem* item, *oldSelection;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001661
1662 configList->setParentMenu();
1663 if (configList->rootEntry == &rootmenu)
1664 backAction->setEnabled(false);
Boris Barbulovskibe596aa2015-09-22 11:36:28 -07001665
1666 if (menuList->selectedItems().count() == 0)
1667 return;
1668
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001669 item = (ConfigItem*)menuList->selectedItems().first();
Boris Barbulovski5df9da92015-09-22 11:36:36 -07001670 oldSelection = item;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001671 while (item) {
1672 if (item->menu == configList->rootEntry) {
Boris Barbulovski5df9da92015-09-22 11:36:36 -07001673 oldSelection->setSelected(false);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001674 item->setSelected(true);
1675 break;
1676 }
1677 item = (ConfigItem*)item->parent();
1678 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001679}
1680
1681void ConfigMainWindow::showSingleView(void)
1682{
Boris Barbulovski780505e2015-09-22 11:36:13 -07001683 singleViewAction->setEnabled(false);
1684 singleViewAction->setChecked(true);
1685 splitViewAction->setEnabled(true);
1686 splitViewAction->setChecked(false);
1687 fullViewAction->setEnabled(true);
1688 fullViewAction->setChecked(false);
1689
Linus Torvalds1da177e2005-04-16 15:20:36 -07001690 menuView->hide();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001691 menuList->setRootMenu(0);
1692 configList->mode = singleMode;
1693 if (configList->rootEntry == &rootmenu)
1694 configList->updateListAll();
1695 else
1696 configList->setRootMenu(&rootmenu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001697 configList->setFocus();
1698}
1699
1700void ConfigMainWindow::showSplitView(void)
1701{
Boris Barbulovski780505e2015-09-22 11:36:13 -07001702 singleViewAction->setEnabled(true);
1703 singleViewAction->setChecked(false);
1704 splitViewAction->setEnabled(false);
1705 splitViewAction->setChecked(true);
1706 fullViewAction->setEnabled(true);
1707 fullViewAction->setChecked(false);
1708
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001709 configList->mode = symbolMode;
1710 if (configList->rootEntry == &rootmenu)
1711 configList->updateListAll();
1712 else
1713 configList->setRootMenu(&rootmenu);
1714 configList->setAllOpen(true);
1715 configApp->processEvents();
1716 menuList->mode = menuMode;
1717 menuList->setRootMenu(&rootmenu);
1718 menuList->setAllOpen(true);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001719 menuView->show();
1720 menuList->setFocus();
1721}
1722
1723void ConfigMainWindow::showFullView(void)
1724{
Boris Barbulovski780505e2015-09-22 11:36:13 -07001725 singleViewAction->setEnabled(true);
1726 singleViewAction->setChecked(false);
1727 splitViewAction->setEnabled(true);
1728 splitViewAction->setChecked(false);
1729 fullViewAction->setEnabled(false);
1730 fullViewAction->setChecked(true);
1731
Linus Torvalds1da177e2005-04-16 15:20:36 -07001732 menuView->hide();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001733 menuList->setRootMenu(0);
1734 configList->mode = fullMode;
1735 if (configList->rootEntry == &rootmenu)
1736 configList->updateListAll();
1737 else
1738 configList->setRootMenu(&rootmenu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001739 configList->setFocus();
1740}
1741
Linus Torvalds1da177e2005-04-16 15:20:36 -07001742/*
1743 * ask for saving configuration before quitting
1744 * TODO ask only when something changed
1745 */
1746void ConfigMainWindow::closeEvent(QCloseEvent* e)
1747{
Karsten Wieseb3214292006-12-13 00:34:06 -08001748 if (!conf_get_changed()) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001749 e->accept();
1750 return;
1751 }
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001752 QMessageBox mb("qconf", "Save configuration?", QMessageBox::Warning,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001753 QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape);
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001754 mb.setButtonText(QMessageBox::Yes, "&Save Changes");
1755 mb.setButtonText(QMessageBox::No, "&Discard Changes");
1756 mb.setButtonText(QMessageBox::Cancel, "Cancel Exit");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001757 switch (mb.exec()) {
1758 case QMessageBox::Yes:
Michal Marekbac6aa82011-05-25 15:10:25 +02001759 if (saveConfig())
1760 e->accept();
1761 else
1762 e->ignore();
1763 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001764 case QMessageBox::No:
1765 e->accept();
1766 break;
1767 case QMessageBox::Cancel:
1768 e->ignore();
1769 break;
1770 }
1771}
1772
1773void ConfigMainWindow::showIntro(void)
1774{
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001775 static const QString str = "Welcome to the qconf graphical configuration tool.\n\n"
Linus Torvalds1da177e2005-04-16 15:20:36 -07001776 "For each option, a blank box indicates the feature is disabled, a check\n"
1777 "indicates it is enabled, and a dot indicates that it is to be compiled\n"
1778 "as a module. Clicking on the box will cycle through the three states.\n\n"
1779 "If you do not see an option (e.g., a device driver) that you believe\n"
1780 "should be present, try turning on Show All Options under the Options menu.\n"
1781 "Although there is no cross reference yet to help you figure out what other\n"
1782 "options must be enabled to support the option you are interested in, you can\n"
1783 "still view the help of a grayed-out option.\n\n"
1784 "Toggling Show Debug Info under the Options menu will show the dependencies,\n"
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001785 "which you can then match by examining other options.\n\n";
Linus Torvalds1da177e2005-04-16 15:20:36 -07001786
1787 QMessageBox::information(this, "qconf", str);
1788}
1789
1790void ConfigMainWindow::showAbout(void)
1791{
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001792 static const QString str = "qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n"
Boris Barbulovskib4ff1de2015-09-22 11:36:38 -07001793 "Copyright (C) 2015 Boris Barbulovski <bbarbulovski@gmail.com>.\n\n"
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001794 "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n";
Linus Torvalds1da177e2005-04-16 15:20:36 -07001795
1796 QMessageBox::information(this, "qconf", str);
1797}
1798
1799void ConfigMainWindow::saveSettings(void)
1800{
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001801 configSettings->setValue("/window x", pos().x());
1802 configSettings->setValue("/window y", pos().y());
1803 configSettings->setValue("/window width", size().width());
1804 configSettings->setValue("/window height", size().height());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001805
1806 QString entry;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001807 switch(configList->mode) {
1808 case singleMode :
1809 entry = "single";
1810 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001811
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001812 case symbolMode :
1813 entry = "split";
1814 break;
1815
1816 case fullMode :
1817 entry = "full";
1818 break;
1819
1820 default:
1821 break;
1822 }
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001823 configSettings->setValue("/listMode", entry);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001824
Roman Zippel7fc925f2006-06-08 22:12:46 -07001825 configSettings->writeSizes("/split1", split1->sizes());
1826 configSettings->writeSizes("/split2", split2->sizes());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001827}
1828
Karsten Wiese3b354c52006-12-13 00:34:08 -08001829void ConfigMainWindow::conf_changed(void)
1830{
1831 if (saveAction)
1832 saveAction->setEnabled(conf_get_changed());
1833}
1834
Linus Torvalds1da177e2005-04-16 15:20:36 -07001835void fixup_rootmenu(struct menu *menu)
1836{
1837 struct menu *child;
1838 static int menu_cnt = 0;
1839
1840 menu->flags |= MENU_ROOT;
1841 for (child = menu->list; child; child = child->next) {
1842 if (child->prompt && child->prompt->type == P_MENU) {
1843 menu_cnt++;
1844 fixup_rootmenu(child);
1845 menu_cnt--;
1846 } else if (!menu_cnt)
1847 fixup_rootmenu(child);
1848 }
1849}
1850
1851static const char *progname;
1852
1853static void usage(void)
1854{
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001855 printf("%s [-s] <config>\n", progname);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001856 exit(0);
1857}
1858
1859int main(int ac, char** av)
1860{
1861 ConfigMainWindow* v;
1862 const char *name;
1863
Linus Torvalds1da177e2005-04-16 15:20:36 -07001864 progname = av[0];
1865 configApp = new QApplication(ac, av);
1866 if (ac > 1 && av[1][0] == '-') {
1867 switch (av[1][1]) {
Michal Marek0a1f00a2015-04-08 13:30:42 +02001868 case 's':
1869 conf_set_message_callback(NULL);
1870 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001871 case 'h':
1872 case '?':
1873 usage();
1874 }
1875 name = av[2];
1876 } else
1877 name = av[1];
1878 if (!name)
1879 usage();
1880
1881 conf_parse(name);
1882 fixup_rootmenu(&rootmenu);
1883 conf_read(NULL);
1884 //zconfdump(stdout);
1885
Roman Zippel7fc925f2006-06-08 22:12:46 -07001886 configSettings = new ConfigSettings();
1887 configSettings->beginGroup("/kconfig/qconf");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001888 v = new ConfigMainWindow();
1889
1890 //zconfdump(stdout);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001891 configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit()));
1892 configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings()));
Roman Zippel43bf6122006-06-08 22:12:45 -07001893 v->show();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001894 configApp->exec();
1895
Roman Zippel7fc925f2006-06-08 22:12:46 -07001896 configSettings->endGroup();
1897 delete configSettings;
Chris Bainbridge5b61c7b2016-01-08 20:44:04 +00001898 delete v;
1899 delete configApp;
Roman Zippel7fc925f2006-06-08 22:12:46 -07001900
Linus Torvalds1da177e2005-04-16 15:20:36 -07001901 return 0;
1902}