blob: 73ce56a76271eed52f61be0bc6b95e52334326e0 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
Boris Barbulovskib4ff1de2015-09-22 11:36:38 -07003 * Copyright (C) 2015 Boris Barbulovski <bbarbulovski@gmail.com>
Linus Torvalds1da177e2005-04-16 15:20:36 -07004 * Released under the terms of the GNU GPL v2.0.
5 */
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"
35#include "images.c"
36
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -070037#ifdef _
38# undef _
39# define _ qgettext
40#endif
41
Linus Torvalds1da177e2005-04-16 15:20:36 -070042static QApplication *configApp;
Roman Zippel7fc925f2006-06-08 22:12:46 -070043static ConfigSettings *configSettings;
Linus Torvalds1da177e2005-04-16 15:20:36 -070044
Boris Barbulovski85eaf282015-09-22 11:36:03 -070045QAction *ConfigMainWindow::saveAction;
Karsten Wiese3b354c52006-12-13 00:34:08 -080046
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -070047static inline QString qgettext(const char* str)
48{
Roman Zippel43bf6122006-06-08 22:12:45 -070049 return QString::fromLocal8Bit(gettext(str));
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -070050}
51
52static inline QString qgettext(const QString& str)
53{
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -070054 return QString::fromLocal8Bit(gettext(str.toLatin1()));
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -070055}
56
Ben Hutchings00d4f8f2013-10-06 19:21:31 +010057ConfigSettings::ConfigSettings()
58 : QSettings("kernel.org", "qconf")
59{
60}
61
Linus Torvalds1da177e2005-04-16 15:20:36 -070062/**
63 * Reads a list of integer values from the application settings.
64 */
Boris Barbulovski041fbdc2015-09-22 11:36:05 -070065QList<int> ConfigSettings::readSizes(const QString& key, bool *ok)
Linus Torvalds1da177e2005-04-16 15:20:36 -070066{
Boris Barbulovski041fbdc2015-09-22 11:36:05 -070067 QList<int> result;
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -070068 QStringList entryList = value(key).toStringList();
Li Zefanc1f96f02010-05-07 13:58:04 +080069 QStringList::Iterator it;
70
71 for (it = entryList.begin(); it != entryList.end(); ++it)
72 result.push_back((*it).toInt());
Linus Torvalds1da177e2005-04-16 15:20:36 -070073
74 return result;
75}
76
77/**
78 * Writes a list of integer values to the application settings.
79 */
Boris Barbulovski041fbdc2015-09-22 11:36:05 -070080bool ConfigSettings::writeSizes(const QString& key, const QList<int>& value)
Linus Torvalds1da177e2005-04-16 15:20:36 -070081{
82 QStringList stringList;
Boris Barbulovski041fbdc2015-09-22 11:36:05 -070083 QList<int>::ConstIterator it;
Linus Torvalds1da177e2005-04-16 15:20:36 -070084
85 for (it = value.begin(); it != value.end(); ++it)
86 stringList.push_back(QString::number(*it));
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -070087 setValue(key, stringList);
Boris Barbulovski59e56442015-09-22 11:36:18 -070088
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -070089 return true;
Linus Torvalds1da177e2005-04-16 15:20:36 -070090}
Linus Torvalds1da177e2005-04-16 15:20:36 -070091
Boris Barbulovski59e56442015-09-22 11:36:18 -070092
93/*
94 * set the new data
95 * TODO check the value
96 */
97void ConfigItem::okRename(int col)
98{
99}
100
101/*
102 * update the displayed of a menu entry
103 */
104void ConfigItem::updateMenu(void)
105{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700106 ConfigList* list;
107 struct symbol* sym;
108 struct property *prop;
109 QString prompt;
110 int type;
111 tristate expr;
112
113 list = listView();
114 if (goParent) {
115 setPixmap(promptColIdx, list->menuBackPix);
116 prompt = "..";
117 goto set_prompt;
118 }
119
120 sym = menu->sym;
121 prop = menu->prompt;
122 prompt = _(menu_get_prompt(menu));
123
124 if (prop) switch (prop->type) {
125 case P_MENU:
126 if (list->mode == singleMode || list->mode == symbolMode) {
127 /* a menuconfig entry is displayed differently
128 * depending whether it's at the view root or a child.
129 */
130 if (sym && list->rootEntry == menu)
131 break;
132 setPixmap(promptColIdx, list->menuPix);
133 } else {
134 if (sym)
135 break;
136 setPixmap(promptColIdx, QIcon());
137 }
138 goto set_prompt;
139 case P_COMMENT:
140 setPixmap(promptColIdx, QIcon());
141 goto set_prompt;
142 default:
143 ;
144 }
145 if (!sym)
146 goto set_prompt;
147
148 setText(nameColIdx, QString::fromLocal8Bit(sym->name));
149
150 type = sym_get_type(sym);
151 switch (type) {
152 case S_BOOLEAN:
153 case S_TRISTATE:
154 char ch;
155
156 if (!sym_is_changable(sym) && list->optMode == normalOpt) {
157 setPixmap(promptColIdx, QIcon());
158 setText(noColIdx, QString::null);
159 setText(modColIdx, QString::null);
160 setText(yesColIdx, QString::null);
161 break;
162 }
163 expr = sym_get_tristate_value(sym);
164 switch (expr) {
165 case yes:
166 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
167 setPixmap(promptColIdx, list->choiceYesPix);
168 else
169 setPixmap(promptColIdx, list->symbolYesPix);
170 setText(yesColIdx, "Y");
171 ch = 'Y';
172 break;
173 case mod:
174 setPixmap(promptColIdx, list->symbolModPix);
175 setText(modColIdx, "M");
176 ch = 'M';
177 break;
178 default:
179 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
180 setPixmap(promptColIdx, list->choiceNoPix);
181 else
182 setPixmap(promptColIdx, list->symbolNoPix);
183 setText(noColIdx, "N");
184 ch = 'N';
185 break;
186 }
187 if (expr != no)
188 setText(noColIdx, sym_tristate_within_range(sym, no) ? "_" : 0);
189 if (expr != mod)
190 setText(modColIdx, sym_tristate_within_range(sym, mod) ? "_" : 0);
191 if (expr != yes)
192 setText(yesColIdx, sym_tristate_within_range(sym, yes) ? "_" : 0);
193
194 setText(dataColIdx, QChar(ch));
195 break;
196 case S_INT:
197 case S_HEX:
198 case S_STRING:
199 const char* data;
200
201 data = sym_get_string_value(sym);
202
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700203 setText(dataColIdx, data);
204 if (type == S_STRING)
205 prompt = QString("%1: %2").arg(prompt).arg(data);
206 else
207 prompt = QString("(%2) %1").arg(prompt).arg(data);
208 break;
209 }
210 if (!sym_has_value(sym) && visible)
211 prompt += _(" (NEW)");
212set_prompt:
213 setText(promptColIdx, prompt);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700214}
215
216void ConfigItem::testUpdateMenu(bool v)
217{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700218 ConfigItem* i;
219
220 visible = v;
221 if (!menu)
222 return;
223
224 sym_calc_value(menu->sym);
225 if (menu->flags & MENU_CHANGED) {
226 /* the menu entry changed, so update all list items */
227 menu->flags &= ~MENU_CHANGED;
228 for (i = (ConfigItem*)menu->data; i; i = i->nextItem)
229 i->updateMenu();
230 } else if (listView()->updateAll)
231 updateMenu();
Boris Barbulovski59e56442015-09-22 11:36:18 -0700232}
233
234
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700235/*
236 * construct a menu entry
237 */
238void ConfigItem::init(void)
239{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700240 if (menu) {
241 ConfigList* list = listView();
242 nextItem = (ConfigItem*)menu->data;
243 menu->data = this;
244
245 if (list->mode != fullMode)
246 setExpanded(true);
247 sym_calc_value(menu->sym);
248 }
249 updateMenu();
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700250}
251
252/*
253 * destruct a menu entry
254 */
255ConfigItem::~ConfigItem(void)
256{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700257 if (menu) {
258 ConfigItem** ip = (ConfigItem**)&menu->data;
259 for (; *ip; ip = &(*ip)->nextItem) {
260 if (*ip == this) {
261 *ip = nextItem;
262 break;
263 }
264 }
265 }
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700266}
267
Roman Zippel43bf6122006-06-08 22:12:45 -0700268ConfigLineEdit::ConfigLineEdit(ConfigView* parent)
269 : Parent(parent)
270{
Boris Barbulovskic14fa5e2015-09-22 11:36:21 -0700271 connect(this, SIGNAL(editingFinished()), SLOT(hide()));
Roman Zippel43bf6122006-06-08 22:12:45 -0700272}
273
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700274void ConfigLineEdit::show(ConfigItem* i)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700275{
276 item = i;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700277 if (sym_get_string_value(item->menu->sym))
278 setText(QString::fromLocal8Bit(sym_get_string_value(item->menu->sym)));
279 else
280 setText(QString::null);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700281 Parent::show();
282 setFocus();
283}
284
285void ConfigLineEdit::keyPressEvent(QKeyEvent* e)
286{
287 switch (e->key()) {
Markus Heidelbergfbb86372009-05-18 01:36:51 +0200288 case Qt::Key_Escape:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700289 break;
Markus Heidelbergfbb86372009-05-18 01:36:51 +0200290 case Qt::Key_Return:
291 case Qt::Key_Enter:
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700292 sym_set_string_value(item->menu->sym, text().toLatin1());
Linus Torvalds1da177e2005-04-16 15:20:36 -0700293 parent()->updateList(item);
294 break;
295 default:
296 Parent::keyPressEvent(e);
297 return;
298 }
299 e->accept();
300 parent()->list->setFocus();
301 hide();
302}
303
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700304ConfigList::ConfigList(ConfigView* p, const char *name)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700305 : Parent(p),
306 updateAll(false),
307 symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no),
308 choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no),
309 menuPix(xpm_menu), menuInvPix(xpm_menu_inv), menuBackPix(xpm_menuback), voidPix(xpm_void),
Boris Barbulovskidbf62932015-09-22 11:36:26 -0700310 showName(false), showRange(false), showData(false), mode(singleMode), optMode(normalOpt),
Boris Barbulovski59e56442015-09-22 11:36:18 -0700311 rootEntry(0), headerPopup(0)
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700312{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700313 int i;
314
315 setObjectName(name);
Boris Barbulovskia5225e92015-09-22 11:36:29 -0700316 setSortingEnabled(false);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700317 setRootIsDecorated(true);
318
Boris Barbulovskif999cc02015-09-22 11:36:31 -0700319 setVerticalScrollMode(ScrollPerPixel);
320 setHorizontalScrollMode(ScrollPerPixel);
321
Boris Barbulovskia52cb3212015-09-22 11:36:24 -0700322 setHeaderLabels(QStringList() << _("Option") << _("Name") << "N" << "M" << "Y" << _("Value"));
323
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
403 ConfigItem* item = (ConfigItem*)selectedItems().first();
404 if (!item)
405 return;
406
407 menu = item->menu;
408 emit menuChanged(menu);
409 if (!menu)
410 return;
411 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
412 if (mode == menuMode && type == P_MENU)
413 emit menuSelected(menu);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700414}
415
416void ConfigList::updateList(ConfigItem* item)
417{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700418 ConfigItem* last = 0;
419
420 if (!rootEntry) {
421 if (mode != listMode)
422 goto update;
423 QTreeWidgetItemIterator it(this);
424 ConfigItem* item;
425
426 while (*it) {
427 item = (ConfigItem*)(*it);
428 if (!item->menu)
429 continue;
430 item->testUpdateMenu(menu_is_visible(item->menu));
431
432 ++it;
433 }
434 return;
435 }
436
437 if (rootEntry != &rootmenu && (mode == singleMode ||
438 (mode == symbolMode && rootEntry->parent != &rootmenu))) {
Boris Barbulovskiee7298f2015-09-22 11:36:37 -0700439 item = (ConfigItem *)topLevelItem(0);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700440 if (!item)
441 item = new ConfigItem(this, 0, true);
442 last = item;
443 }
444 if ((mode == singleMode || (mode == symbolMode && !(rootEntry->flags & MENU_ROOT))) &&
445 rootEntry->sym && rootEntry->prompt) {
446 item = last ? last->nextSibling() : firstChild();
447 if (!item)
448 item = new ConfigItem(this, last, rootEntry, true);
449 else
450 item->testUpdateMenu(true);
451
452 updateMenuList(item, rootEntry);
453 update();
Boris Barbulovskif999cc02015-09-22 11:36:31 -0700454 resizeColumnToContents(0);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700455 return;
456 }
457update:
458 updateMenuList(this, rootEntry);
459 update();
Boris Barbulovskif999cc02015-09-22 11:36:31 -0700460 resizeColumnToContents(0);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700461}
462
463void ConfigList::setValue(ConfigItem* item, tristate val)
464{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700465 struct symbol* sym;
466 int type;
467 tristate oldval;
468
469 sym = item->menu ? item->menu->sym : 0;
470 if (!sym)
471 return;
472
473 type = sym_get_type(sym);
474 switch (type) {
475 case S_BOOLEAN:
476 case S_TRISTATE:
477 oldval = sym_get_tristate_value(sym);
478
479 if (!sym_set_tristate_value(sym, val))
480 return;
481 if (oldval == no && item->menu->list)
482 item->setExpanded(true);
483 parent()->updateList(item);
484 break;
485 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700486}
487
488void ConfigList::changeValue(ConfigItem* item)
489{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700490 struct symbol* sym;
491 struct menu* menu;
492 int type, oldexpr, newexpr;
493
494 menu = item->menu;
495 if (!menu)
496 return;
497 sym = menu->sym;
498 if (!sym) {
499 if (item->menu->list)
500 item->setExpanded(!item->isExpanded());
501 return;
502 }
503
504 type = sym_get_type(sym);
505 switch (type) {
506 case S_BOOLEAN:
507 case S_TRISTATE:
508 oldexpr = sym_get_tristate_value(sym);
509 newexpr = sym_toggle_tristate_value(sym);
510 if (item->menu->list) {
511 if (oldexpr == newexpr)
512 item->setExpanded(!item->isExpanded());
513 else if (oldexpr == no)
514 item->setExpanded(true);
515 }
516 if (oldexpr != newexpr)
517 parent()->updateList(item);
518 break;
519 case S_INT:
520 case S_HEX:
521 case S_STRING:
Boris Barbulovskie336b9f2015-09-22 11:36:34 -0700522 parent()->lineEdit->show(item);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700523 break;
524 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700525}
526
527void ConfigList::setRootMenu(struct menu *menu)
528{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700529 enum prop_type type;
530
531 if (rootEntry == menu)
532 return;
533 type = menu && menu->prompt ? menu->prompt->type : P_UNKNOWN;
534 if (type != P_MENU)
535 return;
536 updateMenuList(this, 0);
537 rootEntry = menu;
538 updateListAll();
539 if (currentItem()) {
540 currentItem()->setSelected(hasFocus());
541 scrollToItem(currentItem());
542 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700543}
544
545void ConfigList::setParentMenu(void)
546{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700547 ConfigItem* item;
548 struct menu *oldroot;
549
550 oldroot = rootEntry;
551 if (rootEntry == &rootmenu)
552 return;
553 setRootMenu(menu_get_parent_menu(rootEntry->parent));
554
555 QTreeWidgetItemIterator it(this);
556 while (*it) {
557 item = (ConfigItem *)(*it);
558 if (item->menu == oldroot) {
559 setCurrentItem(item);
560 scrollToItem(item);
561 break;
562 }
563
564 ++it;
565 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700566}
567
568/*
569 * update all the children of a menu entry
570 * removes/adds the entries from the parent widget as necessary
571 *
572 * parent: either the menu list widget or a menu entry widget
573 * menu: entry to be updated
574 */
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700575void ConfigList::updateMenuList(ConfigItem *parent, struct menu* menu)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700576{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700577 struct menu* child;
578 ConfigItem* item;
579 ConfigItem* last;
580 bool visible;
581 enum prop_type type;
582
583 if (!menu) {
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700584 while (parent->childCount() > 0)
585 {
586 delete parent->takeChild(0);
587 }
588
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700589 return;
590 }
591
592 last = parent->firstChild();
593 if (last && !last->goParent)
594 last = 0;
595 for (child = menu->list; child; child = child->next) {
596 item = last ? last->nextSibling() : parent->firstChild();
597 type = child->prompt ? child->prompt->type : P_UNKNOWN;
598
599 switch (mode) {
600 case menuMode:
601 if (!(child->flags & MENU_ROOT))
602 goto hide;
603 break;
604 case symbolMode:
605 if (child->flags & MENU_ROOT)
606 goto hide;
607 break;
608 default:
609 break;
610 }
611
612 visible = menu_is_visible(child);
613 if (!menuSkip(child)) {
614 if (!child->sym && !child->list && !child->prompt)
615 continue;
616 if (!item || item->menu != child)
617 item = new ConfigItem(parent, last, child, visible);
618 else
619 item->testUpdateMenu(visible);
620
621 if (mode == fullMode || mode == menuMode || type != P_MENU)
622 updateMenuList(item, child);
623 else
624 updateMenuList(item, 0);
625 last = item;
626 continue;
627 }
628 hide:
629 if (item && item->menu == child) {
630 last = parent->firstChild();
631 if (last == item)
632 last = 0;
633 else while (last->nextSibling() != item)
634 last = last->nextSibling();
635 delete item;
636 }
637 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700638}
639
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700640void ConfigList::updateMenuList(ConfigList *parent, struct menu* menu)
641{
642 struct menu* child;
643 ConfigItem* item;
644 ConfigItem* last;
645 bool visible;
646 enum prop_type type;
647
648 if (!menu) {
649 while (parent->topLevelItemCount() > 0)
650 {
651 delete parent->takeTopLevelItem(0);
652 }
653
654 return;
655 }
656
657 last = (ConfigItem*)parent->topLevelItem(0);
658 if (last && !last->goParent)
659 last = 0;
660 for (child = menu->list; child; child = child->next) {
661 item = last ? last->nextSibling() : (ConfigItem*)parent->topLevelItem(0);
662 type = child->prompt ? child->prompt->type : P_UNKNOWN;
663
664 switch (mode) {
665 case menuMode:
666 if (!(child->flags & MENU_ROOT))
667 goto hide;
668 break;
669 case symbolMode:
670 if (child->flags & MENU_ROOT)
671 goto hide;
672 break;
673 default:
674 break;
675 }
676
677 visible = menu_is_visible(child);
678 if (!menuSkip(child)) {
679 if (!child->sym && !child->list && !child->prompt)
680 continue;
681 if (!item || item->menu != child)
682 item = new ConfigItem(parent, last, child, visible);
683 else
684 item->testUpdateMenu(visible);
685
686 if (mode == fullMode || mode == menuMode || type != P_MENU)
687 updateMenuList(item, child);
688 else
689 updateMenuList(item, 0);
690 last = item;
691 continue;
692 }
693 hide:
694 if (item && item->menu == child) {
695 last = (ConfigItem*)parent->topLevelItem(0);
696 if (last == item)
697 last = 0;
698 else while (last->nextSibling() != item)
699 last = last->nextSibling();
700 delete item;
701 }
702 }
703}
704
Boris Barbulovski59e56442015-09-22 11:36:18 -0700705void ConfigList::keyPressEvent(QKeyEvent* ev)
706{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700707 QTreeWidgetItem* i = currentItem();
708 ConfigItem* item;
709 struct menu *menu;
710 enum prop_type type;
711
712 if (ev->key() == Qt::Key_Escape && mode != fullMode && mode != listMode) {
713 emit parentSelected();
714 ev->accept();
715 return;
716 }
717
718 if (!i) {
719 Parent::keyPressEvent(ev);
720 return;
721 }
722 item = (ConfigItem*)i;
723
724 switch (ev->key()) {
725 case Qt::Key_Return:
726 case Qt::Key_Enter:
727 if (item->goParent) {
728 emit parentSelected();
729 break;
730 }
731 menu = item->menu;
732 if (!menu)
733 break;
734 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
735 if (type == P_MENU && rootEntry != menu &&
736 mode != fullMode && mode != menuMode) {
737 emit menuSelected(menu);
738 break;
739 }
740 case Qt::Key_Space:
741 changeValue(item);
742 break;
743 case Qt::Key_N:
744 setValue(item, no);
745 break;
746 case Qt::Key_M:
747 setValue(item, mod);
748 break;
749 case Qt::Key_Y:
750 setValue(item, yes);
751 break;
752 default:
753 Parent::keyPressEvent(ev);
754 return;
755 }
756 ev->accept();
Boris Barbulovski59e56442015-09-22 11:36:18 -0700757}
758
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700759void ConfigList::mousePressEvent(QMouseEvent* e)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700760{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700761 //QPoint p(contentsToViewport(e->pos()));
762 //printf("contentsMousePressEvent: %d,%d\n", p.x(), p.y());
763 Parent::mousePressEvent(e);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700764}
765
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700766void ConfigList::mouseReleaseEvent(QMouseEvent* e)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700767{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700768 QPoint p = e->pos();
769 ConfigItem* item = (ConfigItem*)itemAt(p);
770 struct menu *menu;
771 enum prop_type ptype;
772 QIcon icon;
773 int idx, x;
774
775 if (!item)
776 goto skip;
777
778 menu = item->menu;
779 x = header()->offset() + p.x();
Boris Barbulovski76d53cb2015-09-22 11:36:35 -0700780 idx = header()->logicalIndexAt(x);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700781 switch (idx) {
782 case promptColIdx:
783 icon = item->pixmap(promptColIdx);
Boris Barbulovski76d53cb2015-09-22 11:36:35 -0700784 if (!icon.isNull()) {
785 int off = header()->sectionPosition(0) + visualRect(indexAt(p)).x() + 4; // 4 is Hardcoded image offset. There might be a way to do it properly.
786 if (x >= off && x < off + icon.availableSizes().first().width()) {
787 if (item->goParent) {
788 emit parentSelected();
789 break;
790 } else if (!menu)
791 break;
792 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
793 if (ptype == P_MENU && rootEntry != menu &&
794 mode != fullMode && mode != menuMode)
795 emit menuSelected(menu);
796 else
797 changeValue(item);
798 }
799 }
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700800 break;
801 case noColIdx:
802 setValue(item, no);
803 break;
804 case modColIdx:
805 setValue(item, mod);
806 break;
807 case yesColIdx:
808 setValue(item, yes);
809 break;
810 case dataColIdx:
811 changeValue(item);
812 break;
813 }
814
815skip:
816 //printf("contentsMouseReleaseEvent: %d,%d\n", p.x(), p.y());
817 Parent::mouseReleaseEvent(e);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700818}
819
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700820void ConfigList::mouseMoveEvent(QMouseEvent* e)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700821{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700822 //QPoint p(contentsToViewport(e->pos()));
823 //printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y());
824 Parent::mouseMoveEvent(e);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700825}
826
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700827void ConfigList::mouseDoubleClickEvent(QMouseEvent* e)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700828{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700829 QPoint p = e->pos(); // TODO: Check if this works(was contentsToViewport).
830 ConfigItem* item = (ConfigItem*)itemAt(p);
831 struct menu *menu;
832 enum prop_type ptype;
833
834 if (!item)
835 goto skip;
836 if (item->goParent) {
837 emit parentSelected();
838 goto skip;
839 }
840 menu = item->menu;
841 if (!menu)
842 goto skip;
843 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
844 if (ptype == P_MENU && (mode == singleMode || mode == symbolMode))
845 emit menuSelected(menu);
846 else if (menu->sym)
847 changeValue(item);
848
849skip:
850 //printf("contentsMouseDoubleClickEvent: %d,%d\n", p.x(), p.y());
851 Parent::mouseDoubleClickEvent(e);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700852}
853
854void ConfigList::focusInEvent(QFocusEvent *e)
855{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700856 struct menu *menu = NULL;
857
858 Parent::focusInEvent(e);
859
860 ConfigItem* item = (ConfigItem *)currentItem();
861 if (item) {
862 item->setSelected(true);
863 menu = item->menu;
864 }
865 emit gotFocus(menu);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700866}
867
868void ConfigList::contextMenuEvent(QContextMenuEvent *e)
869{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700870 if (e->y() <= header()->geometry().bottom()) {
871 if (!headerPopup) {
872 QAction *action;
873
874 headerPopup = new QMenu(this);
875 action = new QAction(_("Show Name"), this);
876 action->setCheckable(true);
877 connect(action, SIGNAL(toggled(bool)),
878 parent(), SLOT(setShowName(bool)));
879 connect(parent(), SIGNAL(showNameChanged(bool)),
880 action, SLOT(setOn(bool)));
881 action->setChecked(showName);
882 headerPopup->addAction(action);
883 action = new QAction(_("Show Range"), this);
884 action->setCheckable(true);
885 connect(action, SIGNAL(toggled(bool)),
886 parent(), SLOT(setShowRange(bool)));
887 connect(parent(), SIGNAL(showRangeChanged(bool)),
888 action, SLOT(setOn(bool)));
889 action->setChecked(showRange);
890 headerPopup->addAction(action);
891 action = new QAction(_("Show Data"), this);
892 action->setCheckable(true);
893 connect(action, SIGNAL(toggled(bool)),
894 parent(), SLOT(setShowData(bool)));
895 connect(parent(), SIGNAL(showDataChanged(bool)),
896 action, SLOT(setOn(bool)));
897 action->setChecked(showData);
898 headerPopup->addAction(action);
899 }
900 headerPopup->exec(e->globalPos());
901 e->accept();
902 } else
903 e->ignore();
Boris Barbulovski59e56442015-09-22 11:36:18 -0700904}
905
Li Zefan39a48972010-05-10 16:33:41 +0800906ConfigView*ConfigView::viewList;
907QAction *ConfigView::showNormalAction;
908QAction *ConfigView::showAllAction;
909QAction *ConfigView::showPromptAction;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700910
Roman Zippel7fc925f2006-06-08 22:12:46 -0700911ConfigView::ConfigView(QWidget* parent, const char *name)
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -0700912 : Parent(parent)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700913{
Boris Barbulovski9bd36ed2015-09-22 11:36:22 -0700914 setObjectName(name);
Boris Barbulovski29a70162015-09-22 11:36:10 -0700915 QVBoxLayout *verticalLayout = new QVBoxLayout(this);
Boris Barbulovski92298b42015-09-22 11:36:11 -0700916 verticalLayout->setContentsMargins(0, 0, 0, 0);
Boris Barbulovski29a70162015-09-22 11:36:10 -0700917
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700918 list = new ConfigList(this);
Boris Barbulovski29a70162015-09-22 11:36:10 -0700919 verticalLayout->addWidget(list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700920 lineEdit = new ConfigLineEdit(this);
921 lineEdit->hide();
Boris Barbulovski29a70162015-09-22 11:36:10 -0700922 verticalLayout->addWidget(lineEdit);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700923
924 this->nextView = viewList;
925 viewList = this;
926}
927
928ConfigView::~ConfigView(void)
929{
930 ConfigView** vp;
931
932 for (vp = &viewList; *vp; vp = &(*vp)->nextView) {
933 if (*vp == this) {
934 *vp = nextView;
935 break;
936 }
937 }
938}
939
Li Zefan39a48972010-05-10 16:33:41 +0800940void ConfigView::setOptionMode(QAction *act)
Roman Zippel7fc925f2006-06-08 22:12:46 -0700941{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700942 if (act == showNormalAction)
943 list->optMode = normalOpt;
944 else if (act == showAllAction)
945 list->optMode = allOpt;
946 else
947 list->optMode = promptOpt;
948
949 list->updateListAll();
Roman Zippel7fc925f2006-06-08 22:12:46 -0700950}
951
952void ConfigView::setShowName(bool b)
953{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700954 if (list->showName != b) {
955 list->showName = b;
956 list->reinit();
957 emit showNameChanged(b);
958 }
Roman Zippel7fc925f2006-06-08 22:12:46 -0700959}
960
961void ConfigView::setShowRange(bool b)
962{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700963 if (list->showRange != b) {
964 list->showRange = b;
965 list->reinit();
966 emit showRangeChanged(b);
967 }
Roman Zippel7fc925f2006-06-08 22:12:46 -0700968}
969
970void ConfigView::setShowData(bool b)
971{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700972 if (list->showData != b) {
973 list->showData = b;
974 list->reinit();
975 emit showDataChanged(b);
976 }
977}
978
979void ConfigList::setAllOpen(bool open)
980{
981 QTreeWidgetItemIterator it(this);
982
983 while (*it) {
984 (*it)->setExpanded(open);
985
986 ++it;
987 }
Roman Zippel7fc925f2006-06-08 22:12:46 -0700988}
989
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700990void ConfigView::updateList(ConfigItem* item)
Roman Zippel7fc925f2006-06-08 22:12:46 -0700991{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700992 ConfigView* v;
993
994 for (v = viewList; v; v = v->nextView)
995 v->list->updateList(item);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700996}
997
998void ConfigView::updateListAll(void)
999{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001000 ConfigView* v;
1001
1002 for (v = viewList; v; v = v->nextView)
1003 v->list->updateListAll();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001004}
1005
Roman Zippel43bf6122006-06-08 22:12:45 -07001006ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name)
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001007 : Parent(parent), sym(0), _menu(0)
Roman Zippel43bf6122006-06-08 22:12:45 -07001008{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001009 setObjectName(name);
1010
1011
1012 if (!objectName().isEmpty()) {
1013 configSettings->beginGroup(objectName());
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001014 _showDebug = configSettings->value("/showDebug", false).toBool();
Roman Zippel7fc925f2006-06-08 22:12:46 -07001015 configSettings->endGroup();
1016 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
1017 }
1018}
1019
1020void ConfigInfoView::saveSettings(void)
1021{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001022 if (!objectName().isEmpty()) {
1023 configSettings->beginGroup(objectName());
1024 configSettings->setValue("/showDebug", showDebug());
1025 configSettings->endGroup();
1026 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001027}
1028
1029void ConfigInfoView::setShowDebug(bool b)
1030{
1031 if (_showDebug != b) {
1032 _showDebug = b;
Alexander Stein133c5f72010-08-31 17:34:37 +02001033 if (_menu)
Roman Zippel43bf6122006-06-08 22:12:45 -07001034 menuInfo();
Roman Zippelab45d192006-06-08 22:12:47 -07001035 else if (sym)
1036 symbolInfo();
Roman Zippel43bf6122006-06-08 22:12:45 -07001037 emit showDebugChanged(b);
1038 }
1039}
1040
1041void ConfigInfoView::setInfo(struct menu *m)
1042{
Alexander Stein133c5f72010-08-31 17:34:37 +02001043 if (_menu == m)
Roman Zippelb65a47e2006-06-08 22:12:47 -07001044 return;
Alexander Stein133c5f72010-08-31 17:34:37 +02001045 _menu = m;
Roman Zippel6fa1da82007-01-10 23:15:31 -08001046 sym = NULL;
Alexander Stein133c5f72010-08-31 17:34:37 +02001047 if (!_menu)
Roman Zippel43bf6122006-06-08 22:12:45 -07001048 clear();
Roman Zippel6fa1da82007-01-10 23:15:31 -08001049 else
Roman Zippel43bf6122006-06-08 22:12:45 -07001050 menuInfo();
1051}
1052
Roman Zippelab45d192006-06-08 22:12:47 -07001053void ConfigInfoView::symbolInfo(void)
1054{
1055 QString str;
1056
1057 str += "<big>Symbol: <b>";
1058 str += print_filter(sym->name);
1059 str += "</b></big><br><br>value: ";
1060 str += print_filter(sym_get_string_value(sym));
1061 str += "<br>visibility: ";
1062 str += sym->visible == yes ? "y" : sym->visible == mod ? "m" : "n";
1063 str += "<br>";
1064 str += debug_info(sym);
1065
1066 setText(str);
1067}
1068
Roman Zippel43bf6122006-06-08 22:12:45 -07001069void ConfigInfoView::menuInfo(void)
1070{
1071 struct symbol* sym;
1072 QString head, debug, help;
1073
Alexander Stein133c5f72010-08-31 17:34:37 +02001074 sym = _menu->sym;
Roman Zippel43bf6122006-06-08 22:12:45 -07001075 if (sym) {
Alexander Stein133c5f72010-08-31 17:34:37 +02001076 if (_menu->prompt) {
Roman Zippel43bf6122006-06-08 22:12:45 -07001077 head += "<big><b>";
Alexander Stein133c5f72010-08-31 17:34:37 +02001078 head += print_filter(_(_menu->prompt->text));
Roman Zippel43bf6122006-06-08 22:12:45 -07001079 head += "</b></big>";
1080 if (sym->name) {
1081 head += " (";
Roman Zippelab45d192006-06-08 22:12:47 -07001082 if (showDebug())
1083 head += QString().sprintf("<a href=\"s%p\">", sym);
Roman Zippel43bf6122006-06-08 22:12:45 -07001084 head += print_filter(sym->name);
Roman Zippelab45d192006-06-08 22:12:47 -07001085 if (showDebug())
1086 head += "</a>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001087 head += ")";
1088 }
1089 } else if (sym->name) {
1090 head += "<big><b>";
Roman Zippelab45d192006-06-08 22:12:47 -07001091 if (showDebug())
1092 head += QString().sprintf("<a href=\"s%p\">", sym);
Roman Zippel43bf6122006-06-08 22:12:45 -07001093 head += print_filter(sym->name);
Roman Zippelab45d192006-06-08 22:12:47 -07001094 if (showDebug())
1095 head += "</a>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001096 head += "</b></big>";
1097 }
1098 head += "<br><br>";
1099
1100 if (showDebug())
1101 debug = debug_info(sym);
1102
Cheng Renquand74c15f2009-07-12 16:11:47 +08001103 struct gstr help_gstr = str_new();
Alexander Stein133c5f72010-08-31 17:34:37 +02001104 menu_get_ext_help(_menu, &help_gstr);
Cheng Renquand74c15f2009-07-12 16:11:47 +08001105 help = print_filter(str_get(&help_gstr));
1106 str_free(&help_gstr);
Alexander Stein133c5f72010-08-31 17:34:37 +02001107 } else if (_menu->prompt) {
Roman Zippel43bf6122006-06-08 22:12:45 -07001108 head += "<big><b>";
Alexander Stein133c5f72010-08-31 17:34:37 +02001109 head += print_filter(_(_menu->prompt->text));
Roman Zippel43bf6122006-06-08 22:12:45 -07001110 head += "</b></big><br><br>";
1111 if (showDebug()) {
Alexander Stein133c5f72010-08-31 17:34:37 +02001112 if (_menu->prompt->visible.expr) {
Roman Zippel43bf6122006-06-08 22:12:45 -07001113 debug += "&nbsp;&nbsp;dep: ";
Alexander Stein133c5f72010-08-31 17:34:37 +02001114 expr_print(_menu->prompt->visible.expr, expr_print_help, &debug, E_NONE);
Roman Zippel43bf6122006-06-08 22:12:45 -07001115 debug += "<br><br>";
1116 }
1117 }
1118 }
1119 if (showDebug())
Alexander Stein133c5f72010-08-31 17:34:37 +02001120 debug += QString().sprintf("defined at %s:%d<br><br>", _menu->file->name, _menu->lineno);
Roman Zippel43bf6122006-06-08 22:12:45 -07001121
1122 setText(head + debug + help);
1123}
1124
1125QString ConfigInfoView::debug_info(struct symbol *sym)
1126{
1127 QString debug;
1128
1129 debug += "type: ";
1130 debug += print_filter(sym_type_name(sym->type));
1131 if (sym_is_choice(sym))
1132 debug += " (choice)";
1133 debug += "<br>";
1134 if (sym->rev_dep.expr) {
1135 debug += "reverse dep: ";
1136 expr_print(sym->rev_dep.expr, expr_print_help, &debug, E_NONE);
1137 debug += "<br>";
1138 }
1139 for (struct property *prop = sym->prop; prop; prop = prop->next) {
1140 switch (prop->type) {
1141 case P_PROMPT:
1142 case P_MENU:
Roman Zippelab45d192006-06-08 22:12:47 -07001143 debug += QString().sprintf("prompt: <a href=\"m%p\">", prop->menu);
Roman Zippel43bf6122006-06-08 22:12:45 -07001144 debug += print_filter(_(prop->text));
Roman Zippelab45d192006-06-08 22:12:47 -07001145 debug += "</a><br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001146 break;
1147 case P_DEFAULT:
Roman Zippel93449082008-01-14 04:50:54 +01001148 case P_SELECT:
1149 case P_RANGE:
1150 case P_ENV:
1151 debug += prop_get_type_name(prop->type);
1152 debug += ": ";
Roman Zippel43bf6122006-06-08 22:12:45 -07001153 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1154 debug += "<br>";
1155 break;
1156 case P_CHOICE:
1157 if (sym_is_choice(sym)) {
1158 debug += "choice: ";
1159 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1160 debug += "<br>";
1161 }
1162 break;
Roman Zippel43bf6122006-06-08 22:12:45 -07001163 default:
1164 debug += "unknown property: ";
1165 debug += prop_get_type_name(prop->type);
1166 debug += "<br>";
1167 }
1168 if (prop->visible.expr) {
1169 debug += "&nbsp;&nbsp;&nbsp;&nbsp;dep: ";
1170 expr_print(prop->visible.expr, expr_print_help, &debug, E_NONE);
1171 debug += "<br>";
1172 }
1173 }
1174 debug += "<br>";
1175
1176 return debug;
1177}
1178
1179QString ConfigInfoView::print_filter(const QString &str)
1180{
1181 QRegExp re("[<>&\"\\n]");
1182 QString res = str;
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001183 for (int i = 0; (i = res.indexOf(re, i)) >= 0;) {
1184 switch (res[i].toLatin1()) {
Roman Zippel43bf6122006-06-08 22:12:45 -07001185 case '<':
1186 res.replace(i, 1, "&lt;");
1187 i += 4;
1188 break;
1189 case '>':
1190 res.replace(i, 1, "&gt;");
1191 i += 4;
1192 break;
1193 case '&':
1194 res.replace(i, 1, "&amp;");
1195 i += 5;
1196 break;
1197 case '"':
1198 res.replace(i, 1, "&quot;");
1199 i += 6;
1200 break;
1201 case '\n':
1202 res.replace(i, 1, "<br>");
1203 i += 4;
1204 break;
1205 }
1206 }
1207 return res;
1208}
1209
Roman Zippelab45d192006-06-08 22:12:47 -07001210void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char *str)
Roman Zippel43bf6122006-06-08 22:12:45 -07001211{
Roman Zippelab45d192006-06-08 22:12:47 -07001212 QString* text = reinterpret_cast<QString*>(data);
1213 QString str2 = print_filter(str);
1214
1215 if (sym && sym->name && !(sym->flags & SYMBOL_CONST)) {
1216 *text += QString().sprintf("<a href=\"s%p\">", sym);
1217 *text += str2;
1218 *text += "</a>";
1219 } else
1220 *text += str2;
Roman Zippel43bf6122006-06-08 22:12:45 -07001221}
1222
Boris Barbulovski924bbb52015-09-22 11:36:06 -07001223QMenu* ConfigInfoView::createStandardContextMenu(const QPoint & pos)
Roman Zippel7fc925f2006-06-08 22:12:46 -07001224{
Boris Barbulovski924bbb52015-09-22 11:36:06 -07001225 QMenu* popup = Parent::createStandardContextMenu(pos);
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001226 QAction* action = new QAction(_("Show Debug Info"), popup);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001227 action->setCheckable(true);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001228 connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
1229 connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool)));
Boris Barbulovski9c862352015-09-22 11:36:12 -07001230 action->setChecked(showDebug());
Boris Barbulovski924bbb52015-09-22 11:36:06 -07001231 popup->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001232 popup->addAction(action);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001233 return popup;
1234}
1235
Boris Barbulovski924bbb52015-09-22 11:36:06 -07001236void ConfigInfoView::contextMenuEvent(QContextMenuEvent *e)
Roman Zippel7fc925f2006-06-08 22:12:46 -07001237{
Boris Barbulovski924bbb52015-09-22 11:36:06 -07001238 Parent::contextMenuEvent(e);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001239}
1240
Marco Costalba63431e72006-10-05 19:12:59 +02001241ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow* parent, const char *name)
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001242 : Parent(parent), result(NULL)
Roman Zippel43bf6122006-06-08 22:12:45 -07001243{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001244 setObjectName(name);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001245 setWindowTitle("Search Config");
Roman Zippel43bf6122006-06-08 22:12:45 -07001246
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001247 QVBoxLayout* layout1 = new QVBoxLayout(this);
1248 layout1->setContentsMargins(11, 11, 11, 11);
1249 layout1->setSpacing(6);
1250 QHBoxLayout* layout2 = new QHBoxLayout(0);
1251 layout2->setContentsMargins(0, 0, 0, 0);
1252 layout2->setSpacing(6);
EGRY Gaborc21a2d92008-01-11 23:52:07 +01001253 layout2->addWidget(new QLabel(_("Find:"), this));
Roman Zippel43bf6122006-06-08 22:12:45 -07001254 editField = new QLineEdit(this);
1255 connect(editField, SIGNAL(returnPressed()), SLOT(search()));
1256 layout2->addWidget(editField);
EGRY Gaborc21a2d92008-01-11 23:52:07 +01001257 searchButton = new QPushButton(_("Search"), this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001258 searchButton->setAutoDefault(false);
Roman Zippel43bf6122006-06-08 22:12:45 -07001259 connect(searchButton, SIGNAL(clicked()), SLOT(search()));
1260 layout2->addWidget(searchButton);
1261 layout1->addLayout(layout2);
1262
Roman Zippel7fc925f2006-06-08 22:12:46 -07001263 split = new QSplitter(this);
Markus Heidelberg7298b932009-05-18 01:36:50 +02001264 split->setOrientation(Qt::Vertical);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001265 list = new ConfigView(split, name);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001266 list->list->mode = listMode;
Roman Zippel7fc925f2006-06-08 22:12:46 -07001267 info = new ConfigInfoView(split, name);
Roman Zippel43bf6122006-06-08 22:12:45 -07001268 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1269 info, SLOT(setInfo(struct menu *)));
Marco Costalba63431e72006-10-05 19:12:59 +02001270 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1271 parent, SLOT(setMenuLink(struct menu *)));
1272
Roman Zippel43bf6122006-06-08 22:12:45 -07001273 layout1->addWidget(split);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001274
1275 if (name) {
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001276 QVariant x, y;
1277 int width, height;
Roman Zippel7fc925f2006-06-08 22:12:46 -07001278 bool ok;
1279
1280 configSettings->beginGroup(name);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001281 width = configSettings->value("/window width", parent->width() / 2).toInt();
1282 height = configSettings->value("/window height", parent->height() / 2).toInt();
Roman Zippel7fc925f2006-06-08 22:12:46 -07001283 resize(width, height);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001284 x = configSettings->value("/window x");
1285 y = configSettings->value("/window y");
1286 if ((x.isValid())&&(y.isValid()))
1287 move(x.toInt(), y.toInt());
Boris Barbulovski041fbdc2015-09-22 11:36:05 -07001288 QList<int> sizes = configSettings->readSizes("/split", &ok);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001289 if (ok)
1290 split->setSizes(sizes);
1291 configSettings->endGroup();
1292 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
1293 }
1294}
1295
1296void ConfigSearchWindow::saveSettings(void)
1297{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001298 if (!objectName().isEmpty()) {
1299 configSettings->beginGroup(objectName());
1300 configSettings->setValue("/window x", pos().x());
1301 configSettings->setValue("/window y", pos().y());
1302 configSettings->setValue("/window width", size().width());
1303 configSettings->setValue("/window height", size().height());
1304 configSettings->writeSizes("/split", split->sizes());
1305 configSettings->endGroup();
1306 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001307}
1308
1309void ConfigSearchWindow::search(void)
1310{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001311 struct symbol **p;
1312 struct property *prop;
1313 ConfigItem *lastItem = NULL;
1314
1315 free(result);
1316 list->list->clear();
1317 info->clear();
1318
1319 result = sym_re_search(editField->text().toLatin1());
1320 if (!result)
1321 return;
1322 for (p = result; *p; p++) {
1323 for_all_prompts((*p), prop)
1324 lastItem = new ConfigItem(list->list, lastItem, prop->menu,
1325 menu_is_visible(prop->menu));
1326 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001327}
1328
Linus Torvalds1da177e2005-04-16 15:20:36 -07001329/*
1330 * Construct the complete config widget
1331 */
1332ConfigMainWindow::ConfigMainWindow(void)
Roman Zippelf12aa702006-11-25 11:09:31 -08001333 : searchWindow(0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001334{
1335 QMenuBar* menu;
Boris Barbulovski92119932015-09-22 11:36:16 -07001336 bool ok = true;
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001337 QVariant x, y;
1338 int width, height;
Randy Dunlapa54bb702007-10-20 11:18:47 -07001339 char title[256];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001340
Markus Heidelberg8d90c972009-05-18 01:36:52 +02001341 QDesktopWidget *d = configApp->desktop();
Arnaud Lacombe09548282010-08-18 01:57:13 -04001342 snprintf(title, sizeof(title), "%s%s",
1343 rootmenu.prompt->text,
Michal Marek76a136c2010-09-01 17:39:27 +02001344 ""
Michal Marek76a136c2010-09-01 17:39:27 +02001345 );
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001346 setWindowTitle(title);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001347
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001348 width = configSettings->value("/window width", d->width() - 64).toInt();
1349 height = configSettings->value("/window height", d->height() - 64).toInt();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001350 resize(width, height);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001351 x = configSettings->value("/window x");
1352 y = configSettings->value("/window y");
1353 if ((x.isValid())&&(y.isValid()))
1354 move(x.toInt(), y.toInt());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001355
1356 split1 = new QSplitter(this);
Markus Heidelberg7298b932009-05-18 01:36:50 +02001357 split1->setOrientation(Qt::Horizontal);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001358 setCentralWidget(split1);
1359
Roman Zippel7fc925f2006-06-08 22:12:46 -07001360 menuView = new ConfigView(split1, "menu");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001361 menuList = menuView->list;
1362
1363 split2 = new QSplitter(split1);
Markus Heidelberg7298b932009-05-18 01:36:50 +02001364 split2->setOrientation(Qt::Vertical);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001365
1366 // create config tree
Roman Zippel7fc925f2006-06-08 22:12:46 -07001367 configView = new ConfigView(split2, "config");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001368 configList = configView->list;
1369
Roman Zippel7fc925f2006-06-08 22:12:46 -07001370 helpText = new ConfigInfoView(split2, "help");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001371
1372 setTabOrder(configList, helpText);
1373 configList->setFocus();
1374
1375 menu = menuBar();
Boris Barbulovskib1f8a452015-09-22 11:36:02 -07001376 toolBar = new QToolBar("Tools", this);
Boris Barbulovski29a70162015-09-22 11:36:10 -07001377 addToolBar(toolBar);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001378
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001379 backAction = new QAction(QPixmap(xpm_back), _("Back"), this);
Boris Barbulovski92119932015-09-22 11:36:16 -07001380 connect(backAction, SIGNAL(triggered(bool)), SLOT(goBack()));
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001381 backAction->setEnabled(false);
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001382 QAction *quitAction = new QAction(_("&Quit"), this);
1383 quitAction->setShortcut(Qt::CTRL + Qt::Key_Q);
Boris Barbulovski92119932015-09-22 11:36:16 -07001384 connect(quitAction, SIGNAL(triggered(bool)), SLOT(close()));
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001385 QAction *loadAction = new QAction(QPixmap(xpm_load), _("&Load"), this);
1386 loadAction->setShortcut(Qt::CTRL + Qt::Key_L);
Boris Barbulovski92119932015-09-22 11:36:16 -07001387 connect(loadAction, SIGNAL(triggered(bool)), SLOT(loadConfig()));
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001388 saveAction = new QAction(QPixmap(xpm_save), _("&Save"), this);
1389 saveAction->setShortcut(Qt::CTRL + Qt::Key_S);
Boris Barbulovski92119932015-09-22 11:36:16 -07001390 connect(saveAction, SIGNAL(triggered(bool)), SLOT(saveConfig()));
Karsten Wiese3b354c52006-12-13 00:34:08 -08001391 conf_set_changed_callback(conf_changed);
1392 // Set saveAction's initial state
1393 conf_changed();
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001394 QAction *saveAsAction = new QAction(_("Save &As..."), this);
Boris Barbulovski92119932015-09-22 11:36:16 -07001395 connect(saveAsAction, SIGNAL(triggered(bool)), SLOT(saveConfigAs()));
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001396 QAction *searchAction = new QAction(_("&Find"), this);
1397 searchAction->setShortcut(Qt::CTRL + Qt::Key_F);
Boris Barbulovski92119932015-09-22 11:36:16 -07001398 connect(searchAction, SIGNAL(triggered(bool)), SLOT(searchConfig()));
Boris Barbulovski780505e2015-09-22 11:36:13 -07001399 singleViewAction = new QAction(QPixmap(xpm_single_view), _("Single View"), this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001400 singleViewAction->setCheckable(true);
Boris Barbulovski92119932015-09-22 11:36:16 -07001401 connect(singleViewAction, SIGNAL(triggered(bool)), SLOT(showSingleView()));
Boris Barbulovski780505e2015-09-22 11:36:13 -07001402 splitViewAction = new QAction(QPixmap(xpm_split_view), _("Split View"), this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001403 splitViewAction->setCheckable(true);
Boris Barbulovski92119932015-09-22 11:36:16 -07001404 connect(splitViewAction, SIGNAL(triggered(bool)), SLOT(showSplitView()));
Boris Barbulovski780505e2015-09-22 11:36:13 -07001405 fullViewAction = new QAction(QPixmap(xpm_tree_view), _("Full View"), this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001406 fullViewAction->setCheckable(true);
Boris Barbulovski92119932015-09-22 11:36:16 -07001407 connect(fullViewAction, SIGNAL(triggered(bool)), SLOT(showFullView()));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001408
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001409 QAction *showNameAction = new QAction(_("Show Name"), this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001410 showNameAction->setCheckable(true);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001411 connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool)));
Boris Barbulovski9c862352015-09-22 11:36:12 -07001412 showNameAction->setChecked(configView->showName());
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001413 QAction *showRangeAction = new QAction(_("Show Range"), this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001414 showRangeAction->setCheckable(true);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001415 connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool)));
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001416 QAction *showDataAction = new QAction(_("Show Data"), this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001417 showDataAction->setCheckable(true);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001418 connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool)));
Li Zefan39a48972010-05-10 16:33:41 +08001419
1420 QActionGroup *optGroup = new QActionGroup(this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001421 optGroup->setExclusive(true);
Boris Barbulovski92119932015-09-22 11:36:16 -07001422 connect(optGroup, SIGNAL(triggered(QAction*)), configView,
Li Zefan39a48972010-05-10 16:33:41 +08001423 SLOT(setOptionMode(QAction *)));
Boris Barbulovski92119932015-09-22 11:36:16 -07001424 connect(optGroup, SIGNAL(triggered(QAction *)), menuView,
Li Zefan39a48972010-05-10 16:33:41 +08001425 SLOT(setOptionMode(QAction *)));
1426
Alexander Stein133c5f72010-08-31 17:34:37 +02001427 configView->showNormalAction = new QAction(_("Show Normal Options"), optGroup);
1428 configView->showAllAction = new QAction(_("Show All Options"), optGroup);
1429 configView->showPromptAction = new QAction(_("Show Prompt Options"), optGroup);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001430 configView->showNormalAction->setCheckable(true);
1431 configView->showAllAction->setCheckable(true);
1432 configView->showPromptAction->setCheckable(true);
Li Zefan39a48972010-05-10 16:33:41 +08001433
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001434 QAction *showDebugAction = new QAction( _("Show Debug Info"), this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001435 showDebugAction->setCheckable(true);
Roman Zippel43bf6122006-06-08 22:12:45 -07001436 connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
Boris Barbulovski9c862352015-09-22 11:36:12 -07001437 showDebugAction->setChecked(helpText->showDebug());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001438
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001439 QAction *showIntroAction = new QAction( _("Introduction"), this);
Boris Barbulovski92119932015-09-22 11:36:16 -07001440 connect(showIntroAction, SIGNAL(triggered(bool)), SLOT(showIntro()));
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001441 QAction *showAboutAction = new QAction( _("About"), this);
Boris Barbulovski92119932015-09-22 11:36:16 -07001442 connect(showAboutAction, SIGNAL(triggered(bool)), SLOT(showAbout()));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001443
1444 // init tool bar
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001445 toolBar->addAction(backAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001446 toolBar->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001447 toolBar->addAction(loadAction);
1448 toolBar->addAction(saveAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001449 toolBar->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001450 toolBar->addAction(singleViewAction);
1451 toolBar->addAction(splitViewAction);
1452 toolBar->addAction(fullViewAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001453
1454 // create config menu
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001455 QMenu* config = menu->addMenu(_("&File"));
1456 config->addAction(loadAction);
1457 config->addAction(saveAction);
1458 config->addAction(saveAsAction);
Boris Barbulovski76bede82015-09-22 11:36:07 -07001459 config->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001460 config->addAction(quitAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001461
Shlomi Fish66e7c722007-02-14 00:32:58 -08001462 // create edit menu
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001463 QMenu* editMenu = menu->addMenu(_("&Edit"));
1464 editMenu->addAction(searchAction);
Shlomi Fish66e7c722007-02-14 00:32:58 -08001465
Linus Torvalds1da177e2005-04-16 15:20:36 -07001466 // create options menu
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001467 QMenu* optionMenu = menu->addMenu(_("&Option"));
1468 optionMenu->addAction(showNameAction);
1469 optionMenu->addAction(showRangeAction);
1470 optionMenu->addAction(showDataAction);
Boris Barbulovski76bede82015-09-22 11:36:07 -07001471 optionMenu->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001472 optionMenu->addActions(optGroup->actions());
Boris Barbulovski76bede82015-09-22 11:36:07 -07001473 optionMenu->addSeparator();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001474
1475 // create help menu
Boris Barbulovski76bede82015-09-22 11:36:07 -07001476 menu->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001477 QMenu* helpMenu = menu->addMenu(_("&Help"));
1478 helpMenu->addAction(showIntroAction);
1479 helpMenu->addAction(showAboutAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001480
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001481 connect(configList, SIGNAL(menuChanged(struct menu *)),
1482 helpText, SLOT(setInfo(struct menu *)));
1483 connect(configList, SIGNAL(menuSelected(struct menu *)),
1484 SLOT(changeMenu(struct menu *)));
1485 connect(configList, SIGNAL(parentSelected()),
1486 SLOT(goBack()));
1487 connect(menuList, SIGNAL(menuChanged(struct menu *)),
1488 helpText, SLOT(setInfo(struct menu *)));
1489 connect(menuList, SIGNAL(menuSelected(struct menu *)),
1490 SLOT(changeMenu(struct menu *)));
1491
1492 connect(configList, SIGNAL(gotFocus(struct menu *)),
1493 helpText, SLOT(setInfo(struct menu *)));
1494 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1495 helpText, SLOT(setInfo(struct menu *)));
1496 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1497 SLOT(listFocusChanged(void)));
Roman Zippelb65a47e2006-06-08 22:12:47 -07001498 connect(helpText, SIGNAL(menuSelected(struct menu *)),
1499 SLOT(setMenuLink(struct menu *)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001500
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001501 QString listMode = configSettings->value("/listMode", "symbol").toString();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001502 if (listMode == "single")
1503 showSingleView();
1504 else if (listMode == "full")
1505 showFullView();
1506 else /*if (listMode == "split")*/
1507 showSplitView();
1508
1509 // UI setup done, restore splitter positions
Boris Barbulovski041fbdc2015-09-22 11:36:05 -07001510 QList<int> sizes = configSettings->readSizes("/split1", &ok);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001511 if (ok)
1512 split1->setSizes(sizes);
1513
Roman Zippel7fc925f2006-06-08 22:12:46 -07001514 sizes = configSettings->readSizes("/split2", &ok);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001515 if (ok)
1516 split2->setSizes(sizes);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001517}
1518
Linus Torvalds1da177e2005-04-16 15:20:36 -07001519void ConfigMainWindow::loadConfig(void)
1520{
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001521 QString s = QFileDialog::getOpenFileName(this, "", conf_get_configname());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001522 if (s.isNull())
1523 return;
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -07001524 if (conf_read(QFile::encodeName(s)))
EGRY Gaborc21a2d92008-01-11 23:52:07 +01001525 QMessageBox::information(this, "qconf", _("Unable to load configuration!"));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001526 ConfigView::updateListAll();
1527}
1528
Michal Marekbac6aa82011-05-25 15:10:25 +02001529bool ConfigMainWindow::saveConfig(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001530{
Michal Marekbac6aa82011-05-25 15:10:25 +02001531 if (conf_write(NULL)) {
EGRY Gaborc21a2d92008-01-11 23:52:07 +01001532 QMessageBox::information(this, "qconf", _("Unable to save configuration!"));
Michal Marekbac6aa82011-05-25 15:10:25 +02001533 return false;
1534 }
1535 return true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001536}
1537
1538void ConfigMainWindow::saveConfigAs(void)
1539{
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001540 QString s = QFileDialog::getSaveFileName(this, "", conf_get_configname());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001541 if (s.isNull())
1542 return;
Arnaud Lacombed49e4682011-05-24 14:16:18 -04001543 saveConfig();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001544}
1545
Roman Zippel43bf6122006-06-08 22:12:45 -07001546void ConfigMainWindow::searchConfig(void)
1547{
1548 if (!searchWindow)
Roman Zippel7fc925f2006-06-08 22:12:46 -07001549 searchWindow = new ConfigSearchWindow(this, "search");
Roman Zippel43bf6122006-06-08 22:12:45 -07001550 searchWindow->show();
1551}
1552
Linus Torvalds1da177e2005-04-16 15:20:36 -07001553void ConfigMainWindow::changeMenu(struct menu *menu)
1554{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001555 configList->setRootMenu(menu);
1556 if (configList->rootEntry->parent == &rootmenu)
1557 backAction->setEnabled(false);
1558 else
1559 backAction->setEnabled(true);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001560}
1561
Roman Zippelb65a47e2006-06-08 22:12:47 -07001562void ConfigMainWindow::setMenuLink(struct menu *menu)
1563{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001564 struct menu *parent;
1565 ConfigList* list = NULL;
1566 ConfigItem* item;
1567
1568 if (configList->menuSkip(menu))
1569 return;
1570
1571 switch (configList->mode) {
1572 case singleMode:
1573 list = configList;
1574 parent = menu_get_parent_menu(menu);
1575 if (!parent)
1576 return;
1577 list->setRootMenu(parent);
1578 break;
1579 case symbolMode:
1580 if (menu->flags & MENU_ROOT) {
1581 configList->setRootMenu(menu);
1582 configList->clearSelection();
1583 list = menuList;
1584 } else {
1585 list = configList;
1586 parent = menu_get_parent_menu(menu->parent);
1587 if (!parent)
1588 return;
1589 item = menuList->findConfigItem(parent);
1590 if (item) {
1591 item->setSelected(true);
1592 menuList->scrollToItem(item);
1593 }
1594 list->setRootMenu(parent);
1595 }
1596 break;
1597 case fullMode:
1598 list = configList;
1599 break;
1600 default:
1601 break;
1602 }
1603
1604 if (list) {
1605 item = list->findConfigItem(menu);
1606 if (item) {
1607 item->setSelected(true);
1608 list->scrollToItem(item);
1609 list->setFocus();
1610 }
1611 }
Roman Zippelb65a47e2006-06-08 22:12:47 -07001612}
1613
Linus Torvalds1da177e2005-04-16 15:20:36 -07001614void ConfigMainWindow::listFocusChanged(void)
1615{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001616 if (menuList->mode == menuMode)
1617 configList->clearSelection();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001618}
1619
1620void ConfigMainWindow::goBack(void)
1621{
Boris Barbulovski5df9da92015-09-22 11:36:36 -07001622 ConfigItem* item, *oldSelection;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001623
1624 configList->setParentMenu();
1625 if (configList->rootEntry == &rootmenu)
1626 backAction->setEnabled(false);
1627 item = (ConfigItem*)menuList->selectedItems().first();
Boris Barbulovski5df9da92015-09-22 11:36:36 -07001628 oldSelection = item;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001629 while (item) {
1630 if (item->menu == configList->rootEntry) {
Boris Barbulovski5df9da92015-09-22 11:36:36 -07001631 oldSelection->setSelected(false);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001632 item->setSelected(true);
1633 break;
1634 }
1635 item = (ConfigItem*)item->parent();
1636 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001637}
1638
1639void ConfigMainWindow::showSingleView(void)
1640{
Boris Barbulovski780505e2015-09-22 11:36:13 -07001641 singleViewAction->setEnabled(false);
1642 singleViewAction->setChecked(true);
1643 splitViewAction->setEnabled(true);
1644 splitViewAction->setChecked(false);
1645 fullViewAction->setEnabled(true);
1646 fullViewAction->setChecked(false);
1647
Linus Torvalds1da177e2005-04-16 15:20:36 -07001648 menuView->hide();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001649 menuList->setRootMenu(0);
1650 configList->mode = singleMode;
1651 if (configList->rootEntry == &rootmenu)
1652 configList->updateListAll();
1653 else
1654 configList->setRootMenu(&rootmenu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001655 configList->setFocus();
1656}
1657
1658void ConfigMainWindow::showSplitView(void)
1659{
Boris Barbulovski780505e2015-09-22 11:36:13 -07001660 singleViewAction->setEnabled(true);
1661 singleViewAction->setChecked(false);
1662 splitViewAction->setEnabled(false);
1663 splitViewAction->setChecked(true);
1664 fullViewAction->setEnabled(true);
1665 fullViewAction->setChecked(false);
1666
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001667 configList->mode = symbolMode;
1668 if (configList->rootEntry == &rootmenu)
1669 configList->updateListAll();
1670 else
1671 configList->setRootMenu(&rootmenu);
1672 configList->setAllOpen(true);
1673 configApp->processEvents();
1674 menuList->mode = menuMode;
1675 menuList->setRootMenu(&rootmenu);
1676 menuList->setAllOpen(true);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001677 menuView->show();
1678 menuList->setFocus();
1679}
1680
1681void ConfigMainWindow::showFullView(void)
1682{
Boris Barbulovski780505e2015-09-22 11:36:13 -07001683 singleViewAction->setEnabled(true);
1684 singleViewAction->setChecked(false);
1685 splitViewAction->setEnabled(true);
1686 splitViewAction->setChecked(false);
1687 fullViewAction->setEnabled(false);
1688 fullViewAction->setChecked(true);
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 = fullMode;
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
Linus Torvalds1da177e2005-04-16 15:20:36 -07001700/*
1701 * ask for saving configuration before quitting
1702 * TODO ask only when something changed
1703 */
1704void ConfigMainWindow::closeEvent(QCloseEvent* e)
1705{
Karsten Wieseb3214292006-12-13 00:34:06 -08001706 if (!conf_get_changed()) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001707 e->accept();
1708 return;
1709 }
EGRY Gaborc21a2d92008-01-11 23:52:07 +01001710 QMessageBox mb("qconf", _("Save configuration?"), QMessageBox::Warning,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001711 QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape);
EGRY Gaborc21a2d92008-01-11 23:52:07 +01001712 mb.setButtonText(QMessageBox::Yes, _("&Save Changes"));
1713 mb.setButtonText(QMessageBox::No, _("&Discard Changes"));
1714 mb.setButtonText(QMessageBox::Cancel, _("Cancel Exit"));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001715 switch (mb.exec()) {
1716 case QMessageBox::Yes:
Michal Marekbac6aa82011-05-25 15:10:25 +02001717 if (saveConfig())
1718 e->accept();
1719 else
1720 e->ignore();
1721 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001722 case QMessageBox::No:
1723 e->accept();
1724 break;
1725 case QMessageBox::Cancel:
1726 e->ignore();
1727 break;
1728 }
1729}
1730
1731void ConfigMainWindow::showIntro(void)
1732{
Arnaud Lacombe652cf982010-08-14 23:51:40 -04001733 static const QString str = _("Welcome to the qconf graphical configuration tool.\n\n"
Linus Torvalds1da177e2005-04-16 15:20:36 -07001734 "For each option, a blank box indicates the feature is disabled, a check\n"
1735 "indicates it is enabled, and a dot indicates that it is to be compiled\n"
1736 "as a module. Clicking on the box will cycle through the three states.\n\n"
1737 "If you do not see an option (e.g., a device driver) that you believe\n"
1738 "should be present, try turning on Show All Options under the Options menu.\n"
1739 "Although there is no cross reference yet to help you figure out what other\n"
1740 "options must be enabled to support the option you are interested in, you can\n"
1741 "still view the help of a grayed-out option.\n\n"
1742 "Toggling Show Debug Info under the Options menu will show the dependencies,\n"
EGRY Gaborc21a2d92008-01-11 23:52:07 +01001743 "which you can then match by examining other options.\n\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001744
1745 QMessageBox::information(this, "qconf", str);
1746}
1747
1748void ConfigMainWindow::showAbout(void)
1749{
Boris Barbulovskib4ff1de2015-09-22 11:36:38 -07001750 static const QString str = _("qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n"
1751 "Copyright (C) 2015 Boris Barbulovski <bbarbulovski@gmail.com>.\n\n"
EGRY Gaborc21a2d92008-01-11 23:52:07 +01001752 "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001753
1754 QMessageBox::information(this, "qconf", str);
1755}
1756
1757void ConfigMainWindow::saveSettings(void)
1758{
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001759 configSettings->setValue("/window x", pos().x());
1760 configSettings->setValue("/window y", pos().y());
1761 configSettings->setValue("/window width", size().width());
1762 configSettings->setValue("/window height", size().height());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001763
1764 QString entry;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001765 switch(configList->mode) {
1766 case singleMode :
1767 entry = "single";
1768 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001769
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001770 case symbolMode :
1771 entry = "split";
1772 break;
1773
1774 case fullMode :
1775 entry = "full";
1776 break;
1777
1778 default:
1779 break;
1780 }
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001781 configSettings->setValue("/listMode", entry);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001782
Roman Zippel7fc925f2006-06-08 22:12:46 -07001783 configSettings->writeSizes("/split1", split1->sizes());
1784 configSettings->writeSizes("/split2", split2->sizes());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001785}
1786
Karsten Wiese3b354c52006-12-13 00:34:08 -08001787void ConfigMainWindow::conf_changed(void)
1788{
1789 if (saveAction)
1790 saveAction->setEnabled(conf_get_changed());
1791}
1792
Linus Torvalds1da177e2005-04-16 15:20:36 -07001793void fixup_rootmenu(struct menu *menu)
1794{
1795 struct menu *child;
1796 static int menu_cnt = 0;
1797
1798 menu->flags |= MENU_ROOT;
1799 for (child = menu->list; child; child = child->next) {
1800 if (child->prompt && child->prompt->type == P_MENU) {
1801 menu_cnt++;
1802 fixup_rootmenu(child);
1803 menu_cnt--;
1804 } else if (!menu_cnt)
1805 fixup_rootmenu(child);
1806 }
1807}
1808
1809static const char *progname;
1810
1811static void usage(void)
1812{
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001813 printf(_("%s [-s] <config>\n").toLatin1().constData(), progname);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001814 exit(0);
1815}
1816
1817int main(int ac, char** av)
1818{
1819 ConfigMainWindow* v;
1820 const char *name;
1821
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -07001822 bindtextdomain(PACKAGE, LOCALEDIR);
1823 textdomain(PACKAGE);
1824
Linus Torvalds1da177e2005-04-16 15:20:36 -07001825 progname = av[0];
1826 configApp = new QApplication(ac, av);
1827 if (ac > 1 && av[1][0] == '-') {
1828 switch (av[1][1]) {
Michal Marek0a1f00a2015-04-08 13:30:42 +02001829 case 's':
1830 conf_set_message_callback(NULL);
1831 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001832 case 'h':
1833 case '?':
1834 usage();
1835 }
1836 name = av[2];
1837 } else
1838 name = av[1];
1839 if (!name)
1840 usage();
1841
1842 conf_parse(name);
1843 fixup_rootmenu(&rootmenu);
1844 conf_read(NULL);
1845 //zconfdump(stdout);
1846
Roman Zippel7fc925f2006-06-08 22:12:46 -07001847 configSettings = new ConfigSettings();
1848 configSettings->beginGroup("/kconfig/qconf");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001849 v = new ConfigMainWindow();
1850
1851 //zconfdump(stdout);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001852 configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit()));
1853 configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings()));
Roman Zippel43bf6122006-06-08 22:12:45 -07001854 v->show();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001855 configApp->exec();
1856
Roman Zippel7fc925f2006-06-08 22:12:46 -07001857 configSettings->endGroup();
1858 delete configSettings;
1859
Linus Torvalds1da177e2005-04-16 15:20:36 -07001860 return 0;
1861}