blob: 3f7bee7051e08af53f5c5e4ce4ee36a655290a87 [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
Mauro Carvalho Chehabcce1fab2020-04-02 11:28:00 +02001363 QWidget *widget = new QWidget(this);
1364 QVBoxLayout *layout = new QVBoxLayout(widget);
1365 setCentralWidget(widget);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001366
Mauro Carvalho Chehabcce1fab2020-04-02 11:28:00 +02001367 split1 = new QSplitter(widget);
1368 split1->setOrientation(Qt::Horizontal);
1369 split1->setChildrenCollapsible(false);
1370
1371 menuView = new ConfigView(widget, "menu");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001372 menuList = menuView->list;
1373
Mauro Carvalho Chehabcce1fab2020-04-02 11:28:00 +02001374 split2 = new QSplitter(widget);
1375 split2->setChildrenCollapsible(false);
Markus Heidelberg7298b932009-05-18 01:36:50 +02001376 split2->setOrientation(Qt::Vertical);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001377
1378 // create config tree
Mauro Carvalho Chehabcce1fab2020-04-02 11:28:00 +02001379 configView = new ConfigView(widget, "config");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001380 configList = configView->list;
1381
Mauro Carvalho Chehabcce1fab2020-04-02 11:28:00 +02001382 helpText = new ConfigInfoView(widget, "help");
1383
1384 layout->addWidget(split2);
1385 split2->addWidget(split1);
1386 split1->addWidget(configView);
1387 split1->addWidget(menuView);
1388 split2->addWidget(helpText);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001389
1390 setTabOrder(configList, helpText);
1391 configList->setFocus();
1392
1393 menu = menuBar();
Boris Barbulovskib1f8a452015-09-22 11:36:02 -07001394 toolBar = new QToolBar("Tools", this);
Boris Barbulovski29a70162015-09-22 11:36:10 -07001395 addToolBar(toolBar);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001396
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001397 backAction = new QAction(QPixmap(xpm_back), "Back", this);
Boris Barbulovski92119932015-09-22 11:36:16 -07001398 connect(backAction, SIGNAL(triggered(bool)), SLOT(goBack()));
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001399 backAction->setEnabled(false);
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001400 QAction *quitAction = new QAction("&Quit", this);
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001401 quitAction->setShortcut(Qt::CTRL + Qt::Key_Q);
Boris Barbulovski92119932015-09-22 11:36:16 -07001402 connect(quitAction, SIGNAL(triggered(bool)), SLOT(close()));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001403 QAction *loadAction = new QAction(QPixmap(xpm_load), "&Load", this);
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001404 loadAction->setShortcut(Qt::CTRL + Qt::Key_L);
Boris Barbulovski92119932015-09-22 11:36:16 -07001405 connect(loadAction, SIGNAL(triggered(bool)), SLOT(loadConfig()));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001406 saveAction = new QAction(QPixmap(xpm_save), "&Save", this);
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001407 saveAction->setShortcut(Qt::CTRL + Qt::Key_S);
Boris Barbulovski92119932015-09-22 11:36:16 -07001408 connect(saveAction, SIGNAL(triggered(bool)), SLOT(saveConfig()));
Karsten Wiese3b354c52006-12-13 00:34:08 -08001409 conf_set_changed_callback(conf_changed);
1410 // Set saveAction's initial state
1411 conf_changed();
Masahiro Yamada87419082019-03-11 01:13:15 +09001412 configname = xstrdup(conf_get_configname());
1413
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001414 QAction *saveAsAction = new QAction("Save &As...", this);
Boris Barbulovski92119932015-09-22 11:36:16 -07001415 connect(saveAsAction, SIGNAL(triggered(bool)), SLOT(saveConfigAs()));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001416 QAction *searchAction = new QAction("&Find", this);
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001417 searchAction->setShortcut(Qt::CTRL + Qt::Key_F);
Boris Barbulovski92119932015-09-22 11:36:16 -07001418 connect(searchAction, SIGNAL(triggered(bool)), SLOT(searchConfig()));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001419 singleViewAction = new QAction(QPixmap(xpm_single_view), "Single View", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001420 singleViewAction->setCheckable(true);
Boris Barbulovski92119932015-09-22 11:36:16 -07001421 connect(singleViewAction, SIGNAL(triggered(bool)), SLOT(showSingleView()));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001422 splitViewAction = new QAction(QPixmap(xpm_split_view), "Split View", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001423 splitViewAction->setCheckable(true);
Boris Barbulovski92119932015-09-22 11:36:16 -07001424 connect(splitViewAction, SIGNAL(triggered(bool)), SLOT(showSplitView()));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001425 fullViewAction = new QAction(QPixmap(xpm_tree_view), "Full View", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001426 fullViewAction->setCheckable(true);
Boris Barbulovski92119932015-09-22 11:36:16 -07001427 connect(fullViewAction, SIGNAL(triggered(bool)), SLOT(showFullView()));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001428
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001429 QAction *showNameAction = new QAction("Show Name", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001430 showNameAction->setCheckable(true);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001431 connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool)));
Boris Barbulovski9c862352015-09-22 11:36:12 -07001432 showNameAction->setChecked(configView->showName());
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001433 QAction *showRangeAction = new QAction("Show Range", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001434 showRangeAction->setCheckable(true);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001435 connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool)));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001436 QAction *showDataAction = new QAction("Show Data", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001437 showDataAction->setCheckable(true);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001438 connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool)));
Li Zefan39a48972010-05-10 16:33:41 +08001439
1440 QActionGroup *optGroup = new QActionGroup(this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001441 optGroup->setExclusive(true);
Boris Barbulovski92119932015-09-22 11:36:16 -07001442 connect(optGroup, SIGNAL(triggered(QAction*)), configView,
Li Zefan39a48972010-05-10 16:33:41 +08001443 SLOT(setOptionMode(QAction *)));
Boris Barbulovski92119932015-09-22 11:36:16 -07001444 connect(optGroup, SIGNAL(triggered(QAction *)), menuView,
Li Zefan39a48972010-05-10 16:33:41 +08001445 SLOT(setOptionMode(QAction *)));
1446
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001447 configView->showNormalAction = new QAction("Show Normal Options", optGroup);
1448 configView->showAllAction = new QAction("Show All Options", optGroup);
1449 configView->showPromptAction = new QAction("Show Prompt Options", optGroup);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001450 configView->showNormalAction->setCheckable(true);
1451 configView->showAllAction->setCheckable(true);
1452 configView->showPromptAction->setCheckable(true);
Li Zefan39a48972010-05-10 16:33:41 +08001453
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001454 QAction *showDebugAction = new QAction("Show Debug Info", this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001455 showDebugAction->setCheckable(true);
Roman Zippel43bf6122006-06-08 22:12:45 -07001456 connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
Boris Barbulovski9c862352015-09-22 11:36:12 -07001457 showDebugAction->setChecked(helpText->showDebug());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001458
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001459 QAction *showIntroAction = new QAction("Introduction", this);
Boris Barbulovski92119932015-09-22 11:36:16 -07001460 connect(showIntroAction, SIGNAL(triggered(bool)), SLOT(showIntro()));
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001461 QAction *showAboutAction = new QAction("About", this);
Boris Barbulovski92119932015-09-22 11:36:16 -07001462 connect(showAboutAction, SIGNAL(triggered(bool)), SLOT(showAbout()));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001463
1464 // init tool bar
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001465 toolBar->addAction(backAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001466 toolBar->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001467 toolBar->addAction(loadAction);
1468 toolBar->addAction(saveAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001469 toolBar->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001470 toolBar->addAction(singleViewAction);
1471 toolBar->addAction(splitViewAction);
1472 toolBar->addAction(fullViewAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001473
1474 // create config menu
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001475 QMenu* config = menu->addMenu("&File");
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001476 config->addAction(loadAction);
1477 config->addAction(saveAction);
1478 config->addAction(saveAsAction);
Boris Barbulovski76bede82015-09-22 11:36:07 -07001479 config->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001480 config->addAction(quitAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001481
Shlomi Fish66e7c722007-02-14 00:32:58 -08001482 // create edit menu
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001483 QMenu* editMenu = menu->addMenu("&Edit");
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001484 editMenu->addAction(searchAction);
Shlomi Fish66e7c722007-02-14 00:32:58 -08001485
Linus Torvalds1da177e2005-04-16 15:20:36 -07001486 // create options menu
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001487 QMenu* optionMenu = menu->addMenu("&Option");
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001488 optionMenu->addAction(showNameAction);
1489 optionMenu->addAction(showRangeAction);
1490 optionMenu->addAction(showDataAction);
Boris Barbulovski76bede82015-09-22 11:36:07 -07001491 optionMenu->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001492 optionMenu->addActions(optGroup->actions());
Boris Barbulovski76bede82015-09-22 11:36:07 -07001493 optionMenu->addSeparator();
Boris Barbulovskie0393032016-11-30 14:57:52 -08001494 optionMenu->addAction(showDebugAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001495
1496 // create help menu
Boris Barbulovski76bede82015-09-22 11:36:07 -07001497 menu->addSeparator();
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001498 QMenu* helpMenu = menu->addMenu("&Help");
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001499 helpMenu->addAction(showIntroAction);
1500 helpMenu->addAction(showAboutAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001501
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001502 connect(configList, SIGNAL(menuChanged(struct menu *)),
1503 helpText, SLOT(setInfo(struct menu *)));
1504 connect(configList, SIGNAL(menuSelected(struct menu *)),
1505 SLOT(changeMenu(struct menu *)));
1506 connect(configList, SIGNAL(parentSelected()),
1507 SLOT(goBack()));
1508 connect(menuList, SIGNAL(menuChanged(struct menu *)),
1509 helpText, SLOT(setInfo(struct menu *)));
1510 connect(menuList, SIGNAL(menuSelected(struct menu *)),
1511 SLOT(changeMenu(struct menu *)));
1512
1513 connect(configList, SIGNAL(gotFocus(struct menu *)),
1514 helpText, SLOT(setInfo(struct menu *)));
1515 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1516 helpText, SLOT(setInfo(struct menu *)));
1517 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1518 SLOT(listFocusChanged(void)));
Roman Zippelb65a47e2006-06-08 22:12:47 -07001519 connect(helpText, SIGNAL(menuSelected(struct menu *)),
1520 SLOT(setMenuLink(struct menu *)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001521
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001522 QString listMode = configSettings->value("/listMode", "symbol").toString();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001523 if (listMode == "single")
1524 showSingleView();
1525 else if (listMode == "full")
1526 showFullView();
1527 else /*if (listMode == "split")*/
1528 showSplitView();
1529
1530 // UI setup done, restore splitter positions
Boris Barbulovski041fbdc2015-09-22 11:36:05 -07001531 QList<int> sizes = configSettings->readSizes("/split1", &ok);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001532 if (ok)
1533 split1->setSizes(sizes);
1534
Roman Zippel7fc925f2006-06-08 22:12:46 -07001535 sizes = configSettings->readSizes("/split2", &ok);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001536 if (ok)
1537 split2->setSizes(sizes);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001538}
1539
Linus Torvalds1da177e2005-04-16 15:20:36 -07001540void ConfigMainWindow::loadConfig(void)
1541{
Masahiro Yamada87419082019-03-11 01:13:15 +09001542 QString str;
1543 QByteArray ba;
1544 const char *name;
1545
1546 str = QFileDialog::getOpenFileName(this, "", configname);
1547 if (str.isNull())
Linus Torvalds1da177e2005-04-16 15:20:36 -07001548 return;
Masahiro Yamada87419082019-03-11 01:13:15 +09001549
1550 ba = str.toLocal8Bit();
1551 name = ba.data();
1552
1553 if (conf_read(name))
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001554 QMessageBox::information(this, "qconf", "Unable to load configuration!");
Masahiro Yamada87419082019-03-11 01:13:15 +09001555
1556 free(configname);
1557 configname = xstrdup(name);
1558
Linus Torvalds1da177e2005-04-16 15:20:36 -07001559 ConfigView::updateListAll();
1560}
1561
Michal Marekbac6aa82011-05-25 15:10:25 +02001562bool ConfigMainWindow::saveConfig(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001563{
Masahiro Yamada87419082019-03-11 01:13:15 +09001564 if (conf_write(configname)) {
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001565 QMessageBox::information(this, "qconf", "Unable to save configuration!");
Michal Marekbac6aa82011-05-25 15:10:25 +02001566 return false;
1567 }
Masahiro Yamada00c864f2018-07-20 16:46:31 +09001568 conf_write_autoconf(0);
1569
Michal Marekbac6aa82011-05-25 15:10:25 +02001570 return true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001571}
1572
1573void ConfigMainWindow::saveConfigAs(void)
1574{
Masahiro Yamada87419082019-03-11 01:13:15 +09001575 QString str;
1576 QByteArray ba;
1577 const char *name;
1578
1579 str = QFileDialog::getSaveFileName(this, "", configname);
1580 if (str.isNull())
Linus Torvalds1da177e2005-04-16 15:20:36 -07001581 return;
Masahiro Yamada87419082019-03-11 01:13:15 +09001582
1583 ba = str.toLocal8Bit();
1584 name = ba.data();
1585
1586 if (conf_write(name)) {
1587 QMessageBox::information(this, "qconf", "Unable to save configuration!");
1588 }
1589 conf_write_autoconf(0);
1590
1591 free(configname);
1592 configname = xstrdup(name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001593}
1594
Roman Zippel43bf6122006-06-08 22:12:45 -07001595void ConfigMainWindow::searchConfig(void)
1596{
1597 if (!searchWindow)
Roman Zippel7fc925f2006-06-08 22:12:46 -07001598 searchWindow = new ConfigSearchWindow(this, "search");
Roman Zippel43bf6122006-06-08 22:12:45 -07001599 searchWindow->show();
1600}
1601
Linus Torvalds1da177e2005-04-16 15:20:36 -07001602void ConfigMainWindow::changeMenu(struct menu *menu)
1603{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001604 configList->setRootMenu(menu);
1605 if (configList->rootEntry->parent == &rootmenu)
1606 backAction->setEnabled(false);
1607 else
1608 backAction->setEnabled(true);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001609}
1610
Roman Zippelb65a47e2006-06-08 22:12:47 -07001611void ConfigMainWindow::setMenuLink(struct menu *menu)
1612{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001613 struct menu *parent;
1614 ConfigList* list = NULL;
1615 ConfigItem* item;
1616
1617 if (configList->menuSkip(menu))
1618 return;
1619
1620 switch (configList->mode) {
1621 case singleMode:
1622 list = configList;
1623 parent = menu_get_parent_menu(menu);
1624 if (!parent)
1625 return;
1626 list->setRootMenu(parent);
1627 break;
1628 case symbolMode:
1629 if (menu->flags & MENU_ROOT) {
1630 configList->setRootMenu(menu);
1631 configList->clearSelection();
1632 list = menuList;
1633 } else {
1634 list = configList;
1635 parent = menu_get_parent_menu(menu->parent);
1636 if (!parent)
1637 return;
1638 item = menuList->findConfigItem(parent);
1639 if (item) {
1640 item->setSelected(true);
1641 menuList->scrollToItem(item);
1642 }
1643 list->setRootMenu(parent);
1644 }
1645 break;
1646 case fullMode:
1647 list = configList;
1648 break;
1649 default:
1650 break;
1651 }
1652
1653 if (list) {
1654 item = list->findConfigItem(menu);
1655 if (item) {
1656 item->setSelected(true);
1657 list->scrollToItem(item);
1658 list->setFocus();
1659 }
1660 }
Roman Zippelb65a47e2006-06-08 22:12:47 -07001661}
1662
Linus Torvalds1da177e2005-04-16 15:20:36 -07001663void ConfigMainWindow::listFocusChanged(void)
1664{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001665 if (menuList->mode == menuMode)
1666 configList->clearSelection();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001667}
1668
1669void ConfigMainWindow::goBack(void)
1670{
Boris Barbulovski5df9da92015-09-22 11:36:36 -07001671 ConfigItem* item, *oldSelection;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001672
1673 configList->setParentMenu();
1674 if (configList->rootEntry == &rootmenu)
1675 backAction->setEnabled(false);
Boris Barbulovskibe596aa2015-09-22 11:36:28 -07001676
1677 if (menuList->selectedItems().count() == 0)
1678 return;
1679
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001680 item = (ConfigItem*)menuList->selectedItems().first();
Boris Barbulovski5df9da92015-09-22 11:36:36 -07001681 oldSelection = item;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001682 while (item) {
1683 if (item->menu == configList->rootEntry) {
Boris Barbulovski5df9da92015-09-22 11:36:36 -07001684 oldSelection->setSelected(false);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001685 item->setSelected(true);
1686 break;
1687 }
1688 item = (ConfigItem*)item->parent();
1689 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001690}
1691
1692void ConfigMainWindow::showSingleView(void)
1693{
Boris Barbulovski780505e2015-09-22 11:36:13 -07001694 singleViewAction->setEnabled(false);
1695 singleViewAction->setChecked(true);
1696 splitViewAction->setEnabled(true);
1697 splitViewAction->setChecked(false);
1698 fullViewAction->setEnabled(true);
1699 fullViewAction->setChecked(false);
1700
Linus Torvalds1da177e2005-04-16 15:20:36 -07001701 menuView->hide();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001702 menuList->setRootMenu(0);
1703 configList->mode = singleMode;
1704 if (configList->rootEntry == &rootmenu)
1705 configList->updateListAll();
1706 else
1707 configList->setRootMenu(&rootmenu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001708 configList->setFocus();
1709}
1710
1711void ConfigMainWindow::showSplitView(void)
1712{
Boris Barbulovski780505e2015-09-22 11:36:13 -07001713 singleViewAction->setEnabled(true);
1714 singleViewAction->setChecked(false);
1715 splitViewAction->setEnabled(false);
1716 splitViewAction->setChecked(true);
1717 fullViewAction->setEnabled(true);
1718 fullViewAction->setChecked(false);
1719
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001720 configList->mode = symbolMode;
1721 if (configList->rootEntry == &rootmenu)
1722 configList->updateListAll();
1723 else
1724 configList->setRootMenu(&rootmenu);
1725 configList->setAllOpen(true);
1726 configApp->processEvents();
1727 menuList->mode = menuMode;
1728 menuList->setRootMenu(&rootmenu);
1729 menuList->setAllOpen(true);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001730 menuView->show();
1731 menuList->setFocus();
1732}
1733
1734void ConfigMainWindow::showFullView(void)
1735{
Boris Barbulovski780505e2015-09-22 11:36:13 -07001736 singleViewAction->setEnabled(true);
1737 singleViewAction->setChecked(false);
1738 splitViewAction->setEnabled(true);
1739 splitViewAction->setChecked(false);
1740 fullViewAction->setEnabled(false);
1741 fullViewAction->setChecked(true);
1742
Linus Torvalds1da177e2005-04-16 15:20:36 -07001743 menuView->hide();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001744 menuList->setRootMenu(0);
1745 configList->mode = fullMode;
1746 if (configList->rootEntry == &rootmenu)
1747 configList->updateListAll();
1748 else
1749 configList->setRootMenu(&rootmenu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001750 configList->setFocus();
1751}
1752
Linus Torvalds1da177e2005-04-16 15:20:36 -07001753/*
1754 * ask for saving configuration before quitting
1755 * TODO ask only when something changed
1756 */
1757void ConfigMainWindow::closeEvent(QCloseEvent* e)
1758{
Karsten Wieseb3214292006-12-13 00:34:06 -08001759 if (!conf_get_changed()) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001760 e->accept();
1761 return;
1762 }
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001763 QMessageBox mb("qconf", "Save configuration?", QMessageBox::Warning,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001764 QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape);
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001765 mb.setButtonText(QMessageBox::Yes, "&Save Changes");
1766 mb.setButtonText(QMessageBox::No, "&Discard Changes");
1767 mb.setButtonText(QMessageBox::Cancel, "Cancel Exit");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001768 switch (mb.exec()) {
1769 case QMessageBox::Yes:
Michal Marekbac6aa82011-05-25 15:10:25 +02001770 if (saveConfig())
1771 e->accept();
1772 else
1773 e->ignore();
1774 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001775 case QMessageBox::No:
1776 e->accept();
1777 break;
1778 case QMessageBox::Cancel:
1779 e->ignore();
1780 break;
1781 }
1782}
1783
1784void ConfigMainWindow::showIntro(void)
1785{
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001786 static const QString str = "Welcome to the qconf graphical configuration tool.\n\n"
Linus Torvalds1da177e2005-04-16 15:20:36 -07001787 "For each option, a blank box indicates the feature is disabled, a check\n"
1788 "indicates it is enabled, and a dot indicates that it is to be compiled\n"
1789 "as a module. Clicking on the box will cycle through the three states.\n\n"
1790 "If you do not see an option (e.g., a device driver) that you believe\n"
1791 "should be present, try turning on Show All Options under the Options menu.\n"
1792 "Although there is no cross reference yet to help you figure out what other\n"
1793 "options must be enabled to support the option you are interested in, you can\n"
1794 "still view the help of a grayed-out option.\n\n"
1795 "Toggling Show Debug Info under the Options menu will show the dependencies,\n"
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001796 "which you can then match by examining other options.\n\n";
Linus Torvalds1da177e2005-04-16 15:20:36 -07001797
1798 QMessageBox::information(this, "qconf", str);
1799}
1800
1801void ConfigMainWindow::showAbout(void)
1802{
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001803 static const QString str = "qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n"
Boris Barbulovskib4ff1de2015-09-22 11:36:38 -07001804 "Copyright (C) 2015 Boris Barbulovski <bbarbulovski@gmail.com>.\n\n"
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001805 "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n";
Linus Torvalds1da177e2005-04-16 15:20:36 -07001806
1807 QMessageBox::information(this, "qconf", str);
1808}
1809
1810void ConfigMainWindow::saveSettings(void)
1811{
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001812 configSettings->setValue("/window x", pos().x());
1813 configSettings->setValue("/window y", pos().y());
1814 configSettings->setValue("/window width", size().width());
1815 configSettings->setValue("/window height", size().height());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001816
1817 QString entry;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001818 switch(configList->mode) {
1819 case singleMode :
1820 entry = "single";
1821 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001822
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001823 case symbolMode :
1824 entry = "split";
1825 break;
1826
1827 case fullMode :
1828 entry = "full";
1829 break;
1830
1831 default:
1832 break;
1833 }
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001834 configSettings->setValue("/listMode", entry);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001835
Roman Zippel7fc925f2006-06-08 22:12:46 -07001836 configSettings->writeSizes("/split1", split1->sizes());
1837 configSettings->writeSizes("/split2", split2->sizes());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001838}
1839
Karsten Wiese3b354c52006-12-13 00:34:08 -08001840void ConfigMainWindow::conf_changed(void)
1841{
1842 if (saveAction)
1843 saveAction->setEnabled(conf_get_changed());
1844}
1845
Linus Torvalds1da177e2005-04-16 15:20:36 -07001846void fixup_rootmenu(struct menu *menu)
1847{
1848 struct menu *child;
1849 static int menu_cnt = 0;
1850
1851 menu->flags |= MENU_ROOT;
1852 for (child = menu->list; child; child = child->next) {
1853 if (child->prompt && child->prompt->type == P_MENU) {
1854 menu_cnt++;
1855 fixup_rootmenu(child);
1856 menu_cnt--;
1857 } else if (!menu_cnt)
1858 fixup_rootmenu(child);
1859 }
1860}
1861
1862static const char *progname;
1863
1864static void usage(void)
1865{
Sam Ravnborg694c49a2018-05-22 21:36:12 +02001866 printf("%s [-s] <config>\n", progname);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001867 exit(0);
1868}
1869
1870int main(int ac, char** av)
1871{
1872 ConfigMainWindow* v;
1873 const char *name;
1874
Linus Torvalds1da177e2005-04-16 15:20:36 -07001875 progname = av[0];
1876 configApp = new QApplication(ac, av);
1877 if (ac > 1 && av[1][0] == '-') {
1878 switch (av[1][1]) {
Michal Marek0a1f00a2015-04-08 13:30:42 +02001879 case 's':
1880 conf_set_message_callback(NULL);
1881 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001882 case 'h':
1883 case '?':
1884 usage();
1885 }
1886 name = av[2];
1887 } else
1888 name = av[1];
1889 if (!name)
1890 usage();
1891
1892 conf_parse(name);
1893 fixup_rootmenu(&rootmenu);
1894 conf_read(NULL);
1895 //zconfdump(stdout);
1896
Roman Zippel7fc925f2006-06-08 22:12:46 -07001897 configSettings = new ConfigSettings();
1898 configSettings->beginGroup("/kconfig/qconf");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001899 v = new ConfigMainWindow();
1900
1901 //zconfdump(stdout);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001902 configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit()));
1903 configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings()));
Roman Zippel43bf6122006-06-08 22:12:45 -07001904 v->show();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001905 configApp->exec();
1906
Roman Zippel7fc925f2006-06-08 22:12:46 -07001907 configSettings->endGroup();
1908 delete configSettings;
Chris Bainbridge5b61c7b2016-01-08 20:44:04 +00001909 delete v;
1910 delete configApp;
Roman Zippel7fc925f2006-06-08 22:12:46 -07001911
Linus Torvalds1da177e2005-04-16 15:20:36 -07001912 return 0;
1913}