blob: ae6c725464110c67bf1e72325c4f7fa8879b6c94 [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;
Li Zefanc1f96f02010-05-07 13:58:04 +080068
Boris Barbulovski83c3a1b2016-11-30 14:57:55 -080069 if (contains(key))
70 {
71 QStringList entryList = value(key).toStringList();
72 QStringList::Iterator it;
73
74 for (it = entryList.begin(); it != entryList.end(); ++it)
75 result.push_back((*it).toInt());
76
77 *ok = true;
78 }
79 else
80 *ok = false;
Linus Torvalds1da177e2005-04-16 15:20:36 -070081
82 return result;
83}
84
85/**
86 * Writes a list of integer values to the application settings.
87 */
Boris Barbulovski041fbdc2015-09-22 11:36:05 -070088bool ConfigSettings::writeSizes(const QString& key, const QList<int>& value)
Linus Torvalds1da177e2005-04-16 15:20:36 -070089{
90 QStringList stringList;
Boris Barbulovski041fbdc2015-09-22 11:36:05 -070091 QList<int>::ConstIterator it;
Linus Torvalds1da177e2005-04-16 15:20:36 -070092
93 for (it = value.begin(); it != value.end(); ++it)
94 stringList.push_back(QString::number(*it));
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -070095 setValue(key, stringList);
Boris Barbulovski59e56442015-09-22 11:36:18 -070096
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -070097 return true;
Linus Torvalds1da177e2005-04-16 15:20:36 -070098}
Linus Torvalds1da177e2005-04-16 15:20:36 -070099
Boris Barbulovski59e56442015-09-22 11:36:18 -0700100
101/*
102 * set the new data
103 * TODO check the value
104 */
105void ConfigItem::okRename(int col)
106{
107}
108
109/*
110 * update the displayed of a menu entry
111 */
112void ConfigItem::updateMenu(void)
113{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700114 ConfigList* list;
115 struct symbol* sym;
116 struct property *prop;
117 QString prompt;
118 int type;
119 tristate expr;
120
121 list = listView();
122 if (goParent) {
123 setPixmap(promptColIdx, list->menuBackPix);
124 prompt = "..";
125 goto set_prompt;
126 }
127
128 sym = menu->sym;
129 prop = menu->prompt;
130 prompt = _(menu_get_prompt(menu));
131
132 if (prop) switch (prop->type) {
133 case P_MENU:
134 if (list->mode == singleMode || list->mode == symbolMode) {
135 /* a menuconfig entry is displayed differently
136 * depending whether it's at the view root or a child.
137 */
138 if (sym && list->rootEntry == menu)
139 break;
140 setPixmap(promptColIdx, list->menuPix);
141 } else {
142 if (sym)
143 break;
144 setPixmap(promptColIdx, QIcon());
145 }
146 goto set_prompt;
147 case P_COMMENT:
148 setPixmap(promptColIdx, QIcon());
149 goto set_prompt;
150 default:
151 ;
152 }
153 if (!sym)
154 goto set_prompt;
155
156 setText(nameColIdx, QString::fromLocal8Bit(sym->name));
157
158 type = sym_get_type(sym);
159 switch (type) {
160 case S_BOOLEAN:
161 case S_TRISTATE:
162 char ch;
163
164 if (!sym_is_changable(sym) && list->optMode == normalOpt) {
165 setPixmap(promptColIdx, QIcon());
166 setText(noColIdx, QString::null);
167 setText(modColIdx, QString::null);
168 setText(yesColIdx, QString::null);
169 break;
170 }
171 expr = sym_get_tristate_value(sym);
172 switch (expr) {
173 case yes:
174 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
175 setPixmap(promptColIdx, list->choiceYesPix);
176 else
177 setPixmap(promptColIdx, list->symbolYesPix);
178 setText(yesColIdx, "Y");
179 ch = 'Y';
180 break;
181 case mod:
182 setPixmap(promptColIdx, list->symbolModPix);
183 setText(modColIdx, "M");
184 ch = 'M';
185 break;
186 default:
187 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
188 setPixmap(promptColIdx, list->choiceNoPix);
189 else
190 setPixmap(promptColIdx, list->symbolNoPix);
191 setText(noColIdx, "N");
192 ch = 'N';
193 break;
194 }
195 if (expr != no)
196 setText(noColIdx, sym_tristate_within_range(sym, no) ? "_" : 0);
197 if (expr != mod)
198 setText(modColIdx, sym_tristate_within_range(sym, mod) ? "_" : 0);
199 if (expr != yes)
200 setText(yesColIdx, sym_tristate_within_range(sym, yes) ? "_" : 0);
201
202 setText(dataColIdx, QChar(ch));
203 break;
204 case S_INT:
205 case S_HEX:
206 case S_STRING:
207 const char* data;
208
209 data = sym_get_string_value(sym);
210
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700211 setText(dataColIdx, data);
212 if (type == S_STRING)
213 prompt = QString("%1: %2").arg(prompt).arg(data);
214 else
215 prompt = QString("(%2) %1").arg(prompt).arg(data);
216 break;
217 }
218 if (!sym_has_value(sym) && visible)
219 prompt += _(" (NEW)");
220set_prompt:
221 setText(promptColIdx, prompt);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700222}
223
224void ConfigItem::testUpdateMenu(bool v)
225{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700226 ConfigItem* i;
227
228 visible = v;
229 if (!menu)
230 return;
231
232 sym_calc_value(menu->sym);
233 if (menu->flags & MENU_CHANGED) {
234 /* the menu entry changed, so update all list items */
235 menu->flags &= ~MENU_CHANGED;
236 for (i = (ConfigItem*)menu->data; i; i = i->nextItem)
237 i->updateMenu();
238 } else if (listView()->updateAll)
239 updateMenu();
Boris Barbulovski59e56442015-09-22 11:36:18 -0700240}
241
242
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700243/*
244 * construct a menu entry
245 */
246void ConfigItem::init(void)
247{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700248 if (menu) {
249 ConfigList* list = listView();
250 nextItem = (ConfigItem*)menu->data;
251 menu->data = this;
252
253 if (list->mode != fullMode)
254 setExpanded(true);
255 sym_calc_value(menu->sym);
256 }
257 updateMenu();
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700258}
259
260/*
261 * destruct a menu entry
262 */
263ConfigItem::~ConfigItem(void)
264{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700265 if (menu) {
266 ConfigItem** ip = (ConfigItem**)&menu->data;
267 for (; *ip; ip = &(*ip)->nextItem) {
268 if (*ip == this) {
269 *ip = nextItem;
270 break;
271 }
272 }
273 }
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700274}
275
Roman Zippel43bf6122006-06-08 22:12:45 -0700276ConfigLineEdit::ConfigLineEdit(ConfigView* parent)
277 : Parent(parent)
278{
Boris Barbulovskic14fa5e2015-09-22 11:36:21 -0700279 connect(this, SIGNAL(editingFinished()), SLOT(hide()));
Roman Zippel43bf6122006-06-08 22:12:45 -0700280}
281
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700282void ConfigLineEdit::show(ConfigItem* i)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700283{
284 item = i;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700285 if (sym_get_string_value(item->menu->sym))
286 setText(QString::fromLocal8Bit(sym_get_string_value(item->menu->sym)));
287 else
288 setText(QString::null);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700289 Parent::show();
290 setFocus();
291}
292
293void ConfigLineEdit::keyPressEvent(QKeyEvent* e)
294{
295 switch (e->key()) {
Markus Heidelbergfbb86372009-05-18 01:36:51 +0200296 case Qt::Key_Escape:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700297 break;
Markus Heidelbergfbb86372009-05-18 01:36:51 +0200298 case Qt::Key_Return:
299 case Qt::Key_Enter:
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700300 sym_set_string_value(item->menu->sym, text().toLatin1());
Linus Torvalds1da177e2005-04-16 15:20:36 -0700301 parent()->updateList(item);
302 break;
303 default:
304 Parent::keyPressEvent(e);
305 return;
306 }
307 e->accept();
308 parent()->list->setFocus();
309 hide();
310}
311
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700312ConfigList::ConfigList(ConfigView* p, const char *name)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700313 : Parent(p),
314 updateAll(false),
315 symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no),
316 choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no),
317 menuPix(xpm_menu), menuInvPix(xpm_menu_inv), menuBackPix(xpm_menuback), voidPix(xpm_void),
Boris Barbulovskidbf62932015-09-22 11:36:26 -0700318 showName(false), showRange(false), showData(false), mode(singleMode), optMode(normalOpt),
Boris Barbulovski59e56442015-09-22 11:36:18 -0700319 rootEntry(0), headerPopup(0)
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700320{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700321 int i;
322
323 setObjectName(name);
Boris Barbulovskia5225e92015-09-22 11:36:29 -0700324 setSortingEnabled(false);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700325 setRootIsDecorated(true);
326
Boris Barbulovskif999cc02015-09-22 11:36:31 -0700327 setVerticalScrollMode(ScrollPerPixel);
328 setHorizontalScrollMode(ScrollPerPixel);
329
Boris Barbulovskia52cb322015-09-22 11:36:24 -0700330 setHeaderLabels(QStringList() << _("Option") << _("Name") << "N" << "M" << "Y" << _("Value"));
331
Boris Barbulovskic14fa5e2015-09-22 11:36:21 -0700332 connect(this, SIGNAL(itemSelectionChanged(void)),
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700333 SLOT(updateSelection(void)));
334
335 if (name) {
336 configSettings->beginGroup(name);
337 showName = configSettings->value("/showName", false).toBool();
338 showRange = configSettings->value("/showRange", false).toBool();
339 showData = configSettings->value("/showData", false).toBool();
340 optMode = (enum optionMode)configSettings->value("/optionMode", 0).toInt();
341 configSettings->endGroup();
342 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
343 }
344
345 addColumn(promptColIdx);
346
347 reinit();
348}
349
350bool ConfigList::menuSkip(struct menu *menu)
351{
352 if (optMode == normalOpt && menu_is_visible(menu))
353 return false;
354 if (optMode == promptOpt && menu_has_prompt(menu))
355 return false;
356 if (optMode == allOpt)
357 return false;
358 return true;
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700359}
Boris Barbulovski59e56442015-09-22 11:36:18 -0700360
361void ConfigList::reinit(void)
362{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700363 removeColumn(dataColIdx);
364 removeColumn(yesColIdx);
365 removeColumn(modColIdx);
366 removeColumn(noColIdx);
367 removeColumn(nameColIdx);
368
369 if (showName)
370 addColumn(nameColIdx);
371 if (showRange) {
372 addColumn(noColIdx);
373 addColumn(modColIdx);
374 addColumn(yesColIdx);
375 }
376 if (showData)
377 addColumn(dataColIdx);
378
379 updateListAll();
Boris Barbulovski59e56442015-09-22 11:36:18 -0700380}
381
382void ConfigList::saveSettings(void)
383{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700384 if (!objectName().isEmpty()) {
385 configSettings->beginGroup(objectName());
386 configSettings->setValue("/showName", showName);
387 configSettings->setValue("/showRange", showRange);
388 configSettings->setValue("/showData", showData);
389 configSettings->setValue("/optionMode", (int)optMode);
390 configSettings->endGroup();
391 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700392}
393
394ConfigItem* ConfigList::findConfigItem(struct menu *menu)
395{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700396 ConfigItem* item = (ConfigItem*)menu->data;
397
398 for (; item; item = item->nextItem) {
399 if (this == item->listView())
400 break;
401 }
402
403 return item;
Boris Barbulovski59e56442015-09-22 11:36:18 -0700404}
405
406void ConfigList::updateSelection(void)
407{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700408 struct menu *menu;
409 enum prop_type type;
410
Boris Barbulovskibe596aa2015-09-22 11:36:28 -0700411 if (selectedItems().count() == 0)
412 return;
413
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700414 ConfigItem* item = (ConfigItem*)selectedItems().first();
415 if (!item)
416 return;
417
418 menu = item->menu;
419 emit menuChanged(menu);
420 if (!menu)
421 return;
422 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
423 if (mode == menuMode && type == P_MENU)
424 emit menuSelected(menu);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700425}
426
427void ConfigList::updateList(ConfigItem* item)
428{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700429 ConfigItem* last = 0;
430
431 if (!rootEntry) {
432 if (mode != listMode)
433 goto update;
434 QTreeWidgetItemIterator it(this);
435 ConfigItem* item;
436
437 while (*it) {
438 item = (ConfigItem*)(*it);
439 if (!item->menu)
440 continue;
441 item->testUpdateMenu(menu_is_visible(item->menu));
442
443 ++it;
444 }
445 return;
446 }
447
448 if (rootEntry != &rootmenu && (mode == singleMode ||
449 (mode == symbolMode && rootEntry->parent != &rootmenu))) {
Boris Barbulovskiee7298f2015-09-22 11:36:37 -0700450 item = (ConfigItem *)topLevelItem(0);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700451 if (!item)
452 item = new ConfigItem(this, 0, true);
453 last = item;
454 }
455 if ((mode == singleMode || (mode == symbolMode && !(rootEntry->flags & MENU_ROOT))) &&
456 rootEntry->sym && rootEntry->prompt) {
457 item = last ? last->nextSibling() : firstChild();
458 if (!item)
459 item = new ConfigItem(this, last, rootEntry, true);
460 else
461 item->testUpdateMenu(true);
462
463 updateMenuList(item, rootEntry);
464 update();
Boris Barbulovskif999cc02015-09-22 11:36:31 -0700465 resizeColumnToContents(0);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700466 return;
467 }
468update:
469 updateMenuList(this, rootEntry);
470 update();
Boris Barbulovskif999cc02015-09-22 11:36:31 -0700471 resizeColumnToContents(0);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700472}
473
474void ConfigList::setValue(ConfigItem* item, tristate val)
475{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700476 struct symbol* sym;
477 int type;
478 tristate oldval;
479
480 sym = item->menu ? item->menu->sym : 0;
481 if (!sym)
482 return;
483
484 type = sym_get_type(sym);
485 switch (type) {
486 case S_BOOLEAN:
487 case S_TRISTATE:
488 oldval = sym_get_tristate_value(sym);
489
490 if (!sym_set_tristate_value(sym, val))
491 return;
492 if (oldval == no && item->menu->list)
493 item->setExpanded(true);
494 parent()->updateList(item);
495 break;
496 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700497}
498
499void ConfigList::changeValue(ConfigItem* item)
500{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700501 struct symbol* sym;
502 struct menu* menu;
503 int type, oldexpr, newexpr;
504
505 menu = item->menu;
506 if (!menu)
507 return;
508 sym = menu->sym;
509 if (!sym) {
510 if (item->menu->list)
511 item->setExpanded(!item->isExpanded());
512 return;
513 }
514
515 type = sym_get_type(sym);
516 switch (type) {
517 case S_BOOLEAN:
518 case S_TRISTATE:
519 oldexpr = sym_get_tristate_value(sym);
520 newexpr = sym_toggle_tristate_value(sym);
521 if (item->menu->list) {
522 if (oldexpr == newexpr)
523 item->setExpanded(!item->isExpanded());
524 else if (oldexpr == no)
525 item->setExpanded(true);
526 }
527 if (oldexpr != newexpr)
528 parent()->updateList(item);
529 break;
530 case S_INT:
531 case S_HEX:
532 case S_STRING:
Boris Barbulovskie336b9f2015-09-22 11:36:34 -0700533 parent()->lineEdit->show(item);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700534 break;
535 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700536}
537
538void ConfigList::setRootMenu(struct menu *menu)
539{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700540 enum prop_type type;
541
542 if (rootEntry == menu)
543 return;
544 type = menu && menu->prompt ? menu->prompt->type : P_UNKNOWN;
545 if (type != P_MENU)
546 return;
547 updateMenuList(this, 0);
548 rootEntry = menu;
549 updateListAll();
550 if (currentItem()) {
551 currentItem()->setSelected(hasFocus());
552 scrollToItem(currentItem());
553 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700554}
555
556void ConfigList::setParentMenu(void)
557{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700558 ConfigItem* item;
559 struct menu *oldroot;
560
561 oldroot = rootEntry;
562 if (rootEntry == &rootmenu)
563 return;
564 setRootMenu(menu_get_parent_menu(rootEntry->parent));
565
566 QTreeWidgetItemIterator it(this);
567 while (*it) {
568 item = (ConfigItem *)(*it);
569 if (item->menu == oldroot) {
570 setCurrentItem(item);
571 scrollToItem(item);
572 break;
573 }
574
575 ++it;
576 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700577}
578
579/*
580 * update all the children of a menu entry
581 * removes/adds the entries from the parent widget as necessary
582 *
583 * parent: either the menu list widget or a menu entry widget
584 * menu: entry to be updated
585 */
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700586void ConfigList::updateMenuList(ConfigItem *parent, struct menu* menu)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700587{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700588 struct menu* child;
589 ConfigItem* item;
590 ConfigItem* last;
591 bool visible;
592 enum prop_type type;
593
594 if (!menu) {
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700595 while (parent->childCount() > 0)
596 {
597 delete parent->takeChild(0);
598 }
599
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700600 return;
601 }
602
603 last = parent->firstChild();
604 if (last && !last->goParent)
605 last = 0;
606 for (child = menu->list; child; child = child->next) {
607 item = last ? last->nextSibling() : parent->firstChild();
608 type = child->prompt ? child->prompt->type : P_UNKNOWN;
609
610 switch (mode) {
611 case menuMode:
612 if (!(child->flags & MENU_ROOT))
613 goto hide;
614 break;
615 case symbolMode:
616 if (child->flags & MENU_ROOT)
617 goto hide;
618 break;
619 default:
620 break;
621 }
622
623 visible = menu_is_visible(child);
624 if (!menuSkip(child)) {
625 if (!child->sym && !child->list && !child->prompt)
626 continue;
627 if (!item || item->menu != child)
628 item = new ConfigItem(parent, last, child, visible);
629 else
630 item->testUpdateMenu(visible);
631
632 if (mode == fullMode || mode == menuMode || type != P_MENU)
633 updateMenuList(item, child);
634 else
635 updateMenuList(item, 0);
636 last = item;
637 continue;
638 }
639 hide:
640 if (item && item->menu == child) {
641 last = parent->firstChild();
642 if (last == item)
643 last = 0;
644 else while (last->nextSibling() != item)
645 last = last->nextSibling();
646 delete item;
647 }
648 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700649}
650
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700651void ConfigList::updateMenuList(ConfigList *parent, struct menu* menu)
652{
653 struct menu* child;
654 ConfigItem* item;
655 ConfigItem* last;
656 bool visible;
657 enum prop_type type;
658
659 if (!menu) {
660 while (parent->topLevelItemCount() > 0)
661 {
662 delete parent->takeTopLevelItem(0);
663 }
664
665 return;
666 }
667
668 last = (ConfigItem*)parent->topLevelItem(0);
669 if (last && !last->goParent)
670 last = 0;
671 for (child = menu->list; child; child = child->next) {
672 item = last ? last->nextSibling() : (ConfigItem*)parent->topLevelItem(0);
673 type = child->prompt ? child->prompt->type : P_UNKNOWN;
674
675 switch (mode) {
676 case menuMode:
677 if (!(child->flags & MENU_ROOT))
678 goto hide;
679 break;
680 case symbolMode:
681 if (child->flags & MENU_ROOT)
682 goto hide;
683 break;
684 default:
685 break;
686 }
687
688 visible = menu_is_visible(child);
689 if (!menuSkip(child)) {
690 if (!child->sym && !child->list && !child->prompt)
691 continue;
692 if (!item || item->menu != child)
693 item = new ConfigItem(parent, last, child, visible);
694 else
695 item->testUpdateMenu(visible);
696
697 if (mode == fullMode || mode == menuMode || type != P_MENU)
698 updateMenuList(item, child);
699 else
700 updateMenuList(item, 0);
701 last = item;
702 continue;
703 }
704 hide:
705 if (item && item->menu == child) {
706 last = (ConfigItem*)parent->topLevelItem(0);
707 if (last == item)
708 last = 0;
709 else while (last->nextSibling() != item)
710 last = last->nextSibling();
711 delete item;
712 }
713 }
714}
715
Boris Barbulovski59e56442015-09-22 11:36:18 -0700716void ConfigList::keyPressEvent(QKeyEvent* ev)
717{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700718 QTreeWidgetItem* i = currentItem();
719 ConfigItem* item;
720 struct menu *menu;
721 enum prop_type type;
722
723 if (ev->key() == Qt::Key_Escape && mode != fullMode && mode != listMode) {
724 emit parentSelected();
725 ev->accept();
726 return;
727 }
728
729 if (!i) {
730 Parent::keyPressEvent(ev);
731 return;
732 }
733 item = (ConfigItem*)i;
734
735 switch (ev->key()) {
736 case Qt::Key_Return:
737 case Qt::Key_Enter:
738 if (item->goParent) {
739 emit parentSelected();
740 break;
741 }
742 menu = item->menu;
743 if (!menu)
744 break;
745 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
746 if (type == P_MENU && rootEntry != menu &&
747 mode != fullMode && mode != menuMode) {
748 emit menuSelected(menu);
749 break;
750 }
751 case Qt::Key_Space:
752 changeValue(item);
753 break;
754 case Qt::Key_N:
755 setValue(item, no);
756 break;
757 case Qt::Key_M:
758 setValue(item, mod);
759 break;
760 case Qt::Key_Y:
761 setValue(item, yes);
762 break;
763 default:
764 Parent::keyPressEvent(ev);
765 return;
766 }
767 ev->accept();
Boris Barbulovski59e56442015-09-22 11:36:18 -0700768}
769
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700770void ConfigList::mousePressEvent(QMouseEvent* e)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700771{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700772 //QPoint p(contentsToViewport(e->pos()));
773 //printf("contentsMousePressEvent: %d,%d\n", p.x(), p.y());
774 Parent::mousePressEvent(e);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700775}
776
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700777void ConfigList::mouseReleaseEvent(QMouseEvent* e)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700778{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700779 QPoint p = e->pos();
780 ConfigItem* item = (ConfigItem*)itemAt(p);
781 struct menu *menu;
782 enum prop_type ptype;
783 QIcon icon;
784 int idx, x;
785
786 if (!item)
787 goto skip;
788
789 menu = item->menu;
790 x = header()->offset() + p.x();
Boris Barbulovski76d53cb2015-09-22 11:36:35 -0700791 idx = header()->logicalIndexAt(x);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700792 switch (idx) {
793 case promptColIdx:
794 icon = item->pixmap(promptColIdx);
Boris Barbulovski76d53cb2015-09-22 11:36:35 -0700795 if (!icon.isNull()) {
796 int off = header()->sectionPosition(0) + visualRect(indexAt(p)).x() + 4; // 4 is Hardcoded image offset. There might be a way to do it properly.
797 if (x >= off && x < off + icon.availableSizes().first().width()) {
798 if (item->goParent) {
799 emit parentSelected();
800 break;
801 } else if (!menu)
802 break;
803 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
804 if (ptype == P_MENU && rootEntry != menu &&
805 mode != fullMode && mode != menuMode)
806 emit menuSelected(menu);
807 else
808 changeValue(item);
809 }
810 }
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700811 break;
812 case noColIdx:
813 setValue(item, no);
814 break;
815 case modColIdx:
816 setValue(item, mod);
817 break;
818 case yesColIdx:
819 setValue(item, yes);
820 break;
821 case dataColIdx:
822 changeValue(item);
823 break;
824 }
825
826skip:
827 //printf("contentsMouseReleaseEvent: %d,%d\n", p.x(), p.y());
828 Parent::mouseReleaseEvent(e);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700829}
830
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700831void ConfigList::mouseMoveEvent(QMouseEvent* e)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700832{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700833 //QPoint p(contentsToViewport(e->pos()));
834 //printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y());
835 Parent::mouseMoveEvent(e);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700836}
837
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700838void ConfigList::mouseDoubleClickEvent(QMouseEvent* e)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700839{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700840 QPoint p = e->pos(); // TODO: Check if this works(was contentsToViewport).
841 ConfigItem* item = (ConfigItem*)itemAt(p);
842 struct menu *menu;
843 enum prop_type ptype;
844
845 if (!item)
846 goto skip;
847 if (item->goParent) {
848 emit parentSelected();
849 goto skip;
850 }
851 menu = item->menu;
852 if (!menu)
853 goto skip;
854 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
855 if (ptype == P_MENU && (mode == singleMode || mode == symbolMode))
856 emit menuSelected(menu);
857 else if (menu->sym)
858 changeValue(item);
859
860skip:
861 //printf("contentsMouseDoubleClickEvent: %d,%d\n", p.x(), p.y());
862 Parent::mouseDoubleClickEvent(e);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700863}
864
865void ConfigList::focusInEvent(QFocusEvent *e)
866{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700867 struct menu *menu = NULL;
868
869 Parent::focusInEvent(e);
870
871 ConfigItem* item = (ConfigItem *)currentItem();
872 if (item) {
873 item->setSelected(true);
874 menu = item->menu;
875 }
876 emit gotFocus(menu);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700877}
878
879void ConfigList::contextMenuEvent(QContextMenuEvent *e)
880{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700881 if (e->y() <= header()->geometry().bottom()) {
882 if (!headerPopup) {
883 QAction *action;
884
885 headerPopup = new QMenu(this);
886 action = new QAction(_("Show Name"), this);
887 action->setCheckable(true);
888 connect(action, SIGNAL(toggled(bool)),
889 parent(), SLOT(setShowName(bool)));
890 connect(parent(), SIGNAL(showNameChanged(bool)),
891 action, SLOT(setOn(bool)));
892 action->setChecked(showName);
893 headerPopup->addAction(action);
894 action = new QAction(_("Show Range"), this);
895 action->setCheckable(true);
896 connect(action, SIGNAL(toggled(bool)),
897 parent(), SLOT(setShowRange(bool)));
898 connect(parent(), SIGNAL(showRangeChanged(bool)),
899 action, SLOT(setOn(bool)));
900 action->setChecked(showRange);
901 headerPopup->addAction(action);
902 action = new QAction(_("Show Data"), this);
903 action->setCheckable(true);
904 connect(action, SIGNAL(toggled(bool)),
905 parent(), SLOT(setShowData(bool)));
906 connect(parent(), SIGNAL(showDataChanged(bool)),
907 action, SLOT(setOn(bool)));
908 action->setChecked(showData);
909 headerPopup->addAction(action);
910 }
911 headerPopup->exec(e->globalPos());
912 e->accept();
913 } else
914 e->ignore();
Boris Barbulovski59e56442015-09-22 11:36:18 -0700915}
916
Li Zefan39a48972010-05-10 16:33:41 +0800917ConfigView*ConfigView::viewList;
918QAction *ConfigView::showNormalAction;
919QAction *ConfigView::showAllAction;
920QAction *ConfigView::showPromptAction;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700921
Roman Zippel7fc925f2006-06-08 22:12:46 -0700922ConfigView::ConfigView(QWidget* parent, const char *name)
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -0700923 : Parent(parent)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700924{
Boris Barbulovski9bd36ed2015-09-22 11:36:22 -0700925 setObjectName(name);
Boris Barbulovski29a70162015-09-22 11:36:10 -0700926 QVBoxLayout *verticalLayout = new QVBoxLayout(this);
Boris Barbulovski92298b42015-09-22 11:36:11 -0700927 verticalLayout->setContentsMargins(0, 0, 0, 0);
Boris Barbulovski29a70162015-09-22 11:36:10 -0700928
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700929 list = new ConfigList(this);
Boris Barbulovski29a70162015-09-22 11:36:10 -0700930 verticalLayout->addWidget(list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700931 lineEdit = new ConfigLineEdit(this);
932 lineEdit->hide();
Boris Barbulovski29a70162015-09-22 11:36:10 -0700933 verticalLayout->addWidget(lineEdit);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700934
935 this->nextView = viewList;
936 viewList = this;
937}
938
939ConfigView::~ConfigView(void)
940{
941 ConfigView** vp;
942
943 for (vp = &viewList; *vp; vp = &(*vp)->nextView) {
944 if (*vp == this) {
945 *vp = nextView;
946 break;
947 }
948 }
949}
950
Li Zefan39a48972010-05-10 16:33:41 +0800951void ConfigView::setOptionMode(QAction *act)
Roman Zippel7fc925f2006-06-08 22:12:46 -0700952{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700953 if (act == showNormalAction)
954 list->optMode = normalOpt;
955 else if (act == showAllAction)
956 list->optMode = allOpt;
957 else
958 list->optMode = promptOpt;
959
960 list->updateListAll();
Roman Zippel7fc925f2006-06-08 22:12:46 -0700961}
962
963void ConfigView::setShowName(bool b)
964{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700965 if (list->showName != b) {
966 list->showName = b;
967 list->reinit();
968 emit showNameChanged(b);
969 }
Roman Zippel7fc925f2006-06-08 22:12:46 -0700970}
971
972void ConfigView::setShowRange(bool b)
973{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700974 if (list->showRange != b) {
975 list->showRange = b;
976 list->reinit();
977 emit showRangeChanged(b);
978 }
Roman Zippel7fc925f2006-06-08 22:12:46 -0700979}
980
981void ConfigView::setShowData(bool b)
982{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700983 if (list->showData != b) {
984 list->showData = b;
985 list->reinit();
986 emit showDataChanged(b);
987 }
988}
989
990void ConfigList::setAllOpen(bool open)
991{
992 QTreeWidgetItemIterator it(this);
993
994 while (*it) {
995 (*it)->setExpanded(open);
996
997 ++it;
998 }
Roman Zippel7fc925f2006-06-08 22:12:46 -0700999}
1000
Boris Barbulovski1019f1a2015-09-22 11:36:17 -07001001void ConfigView::updateList(ConfigItem* item)
Roman Zippel7fc925f2006-06-08 22:12:46 -07001002{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001003 ConfigView* v;
1004
1005 for (v = viewList; v; v = v->nextView)
1006 v->list->updateList(item);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001007}
1008
1009void ConfigView::updateListAll(void)
1010{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001011 ConfigView* v;
1012
1013 for (v = viewList; v; v = v->nextView)
1014 v->list->updateListAll();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001015}
1016
Roman Zippel43bf6122006-06-08 22:12:45 -07001017ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name)
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001018 : Parent(parent), sym(0), _menu(0)
Roman Zippel43bf6122006-06-08 22:12:45 -07001019{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001020 setObjectName(name);
1021
1022
1023 if (!objectName().isEmpty()) {
1024 configSettings->beginGroup(objectName());
Boris Barbulovskie0393032016-11-30 14:57:52 -08001025 setShowDebug(configSettings->value("/showDebug", false).toBool());
Roman Zippel7fc925f2006-06-08 22:12:46 -07001026 configSettings->endGroup();
1027 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
1028 }
1029}
1030
1031void ConfigInfoView::saveSettings(void)
1032{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001033 if (!objectName().isEmpty()) {
1034 configSettings->beginGroup(objectName());
1035 configSettings->setValue("/showDebug", showDebug());
1036 configSettings->endGroup();
1037 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001038}
1039
1040void ConfigInfoView::setShowDebug(bool b)
1041{
1042 if (_showDebug != b) {
1043 _showDebug = b;
Alexander Stein133c5f72010-08-31 17:34:37 +02001044 if (_menu)
Roman Zippel43bf6122006-06-08 22:12:45 -07001045 menuInfo();
Roman Zippelab45d192006-06-08 22:12:47 -07001046 else if (sym)
1047 symbolInfo();
Roman Zippel43bf6122006-06-08 22:12:45 -07001048 emit showDebugChanged(b);
1049 }
1050}
1051
1052void ConfigInfoView::setInfo(struct menu *m)
1053{
Alexander Stein133c5f72010-08-31 17:34:37 +02001054 if (_menu == m)
Roman Zippelb65a47e2006-06-08 22:12:47 -07001055 return;
Alexander Stein133c5f72010-08-31 17:34:37 +02001056 _menu = m;
Roman Zippel6fa1da82007-01-10 23:15:31 -08001057 sym = NULL;
Alexander Stein133c5f72010-08-31 17:34:37 +02001058 if (!_menu)
Roman Zippel43bf6122006-06-08 22:12:45 -07001059 clear();
Roman Zippel6fa1da82007-01-10 23:15:31 -08001060 else
Roman Zippel43bf6122006-06-08 22:12:45 -07001061 menuInfo();
1062}
1063
Roman Zippelab45d192006-06-08 22:12:47 -07001064void ConfigInfoView::symbolInfo(void)
1065{
1066 QString str;
1067
1068 str += "<big>Symbol: <b>";
1069 str += print_filter(sym->name);
1070 str += "</b></big><br><br>value: ";
1071 str += print_filter(sym_get_string_value(sym));
1072 str += "<br>visibility: ";
1073 str += sym->visible == yes ? "y" : sym->visible == mod ? "m" : "n";
1074 str += "<br>";
1075 str += debug_info(sym);
1076
1077 setText(str);
1078}
1079
Roman Zippel43bf6122006-06-08 22:12:45 -07001080void ConfigInfoView::menuInfo(void)
1081{
1082 struct symbol* sym;
1083 QString head, debug, help;
1084
Alexander Stein133c5f72010-08-31 17:34:37 +02001085 sym = _menu->sym;
Roman Zippel43bf6122006-06-08 22:12:45 -07001086 if (sym) {
Alexander Stein133c5f72010-08-31 17:34:37 +02001087 if (_menu->prompt) {
Roman Zippel43bf6122006-06-08 22:12:45 -07001088 head += "<big><b>";
Alexander Stein133c5f72010-08-31 17:34:37 +02001089 head += print_filter(_(_menu->prompt->text));
Roman Zippel43bf6122006-06-08 22:12:45 -07001090 head += "</b></big>";
1091 if (sym->name) {
1092 head += " (";
Roman Zippelab45d192006-06-08 22:12:47 -07001093 if (showDebug())
1094 head += QString().sprintf("<a href=\"s%p\">", sym);
Roman Zippel43bf6122006-06-08 22:12:45 -07001095 head += print_filter(sym->name);
Roman Zippelab45d192006-06-08 22:12:47 -07001096 if (showDebug())
1097 head += "</a>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001098 head += ")";
1099 }
1100 } else if (sym->name) {
1101 head += "<big><b>";
Roman Zippelab45d192006-06-08 22:12:47 -07001102 if (showDebug())
1103 head += QString().sprintf("<a href=\"s%p\">", sym);
Roman Zippel43bf6122006-06-08 22:12:45 -07001104 head += print_filter(sym->name);
Roman Zippelab45d192006-06-08 22:12:47 -07001105 if (showDebug())
1106 head += "</a>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001107 head += "</b></big>";
1108 }
1109 head += "<br><br>";
1110
1111 if (showDebug())
1112 debug = debug_info(sym);
1113
Cheng Renquand74c15f2009-07-12 16:11:47 +08001114 struct gstr help_gstr = str_new();
Alexander Stein133c5f72010-08-31 17:34:37 +02001115 menu_get_ext_help(_menu, &help_gstr);
Cheng Renquand74c15f2009-07-12 16:11:47 +08001116 help = print_filter(str_get(&help_gstr));
1117 str_free(&help_gstr);
Alexander Stein133c5f72010-08-31 17:34:37 +02001118 } else if (_menu->prompt) {
Roman Zippel43bf6122006-06-08 22:12:45 -07001119 head += "<big><b>";
Alexander Stein133c5f72010-08-31 17:34:37 +02001120 head += print_filter(_(_menu->prompt->text));
Roman Zippel43bf6122006-06-08 22:12:45 -07001121 head += "</b></big><br><br>";
1122 if (showDebug()) {
Alexander Stein133c5f72010-08-31 17:34:37 +02001123 if (_menu->prompt->visible.expr) {
Roman Zippel43bf6122006-06-08 22:12:45 -07001124 debug += "&nbsp;&nbsp;dep: ";
Alexander Stein133c5f72010-08-31 17:34:37 +02001125 expr_print(_menu->prompt->visible.expr, expr_print_help, &debug, E_NONE);
Roman Zippel43bf6122006-06-08 22:12:45 -07001126 debug += "<br><br>";
1127 }
1128 }
1129 }
1130 if (showDebug())
Alexander Stein133c5f72010-08-31 17:34:37 +02001131 debug += QString().sprintf("defined at %s:%d<br><br>", _menu->file->name, _menu->lineno);
Roman Zippel43bf6122006-06-08 22:12:45 -07001132
1133 setText(head + debug + help);
1134}
1135
1136QString ConfigInfoView::debug_info(struct symbol *sym)
1137{
1138 QString debug;
1139
1140 debug += "type: ";
1141 debug += print_filter(sym_type_name(sym->type));
1142 if (sym_is_choice(sym))
1143 debug += " (choice)";
1144 debug += "<br>";
1145 if (sym->rev_dep.expr) {
1146 debug += "reverse dep: ";
1147 expr_print(sym->rev_dep.expr, expr_print_help, &debug, E_NONE);
1148 debug += "<br>";
1149 }
1150 for (struct property *prop = sym->prop; prop; prop = prop->next) {
1151 switch (prop->type) {
1152 case P_PROMPT:
1153 case P_MENU:
Roman Zippelab45d192006-06-08 22:12:47 -07001154 debug += QString().sprintf("prompt: <a href=\"m%p\">", prop->menu);
Roman Zippel43bf6122006-06-08 22:12:45 -07001155 debug += print_filter(_(prop->text));
Roman Zippelab45d192006-06-08 22:12:47 -07001156 debug += "</a><br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001157 break;
1158 case P_DEFAULT:
Roman Zippel93449082008-01-14 04:50:54 +01001159 case P_SELECT:
1160 case P_RANGE:
1161 case P_ENV:
1162 debug += prop_get_type_name(prop->type);
1163 debug += ": ";
Roman Zippel43bf6122006-06-08 22:12:45 -07001164 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1165 debug += "<br>";
1166 break;
1167 case P_CHOICE:
1168 if (sym_is_choice(sym)) {
1169 debug += "choice: ";
1170 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1171 debug += "<br>";
1172 }
1173 break;
Roman Zippel43bf6122006-06-08 22:12:45 -07001174 default:
1175 debug += "unknown property: ";
1176 debug += prop_get_type_name(prop->type);
1177 debug += "<br>";
1178 }
1179 if (prop->visible.expr) {
1180 debug += "&nbsp;&nbsp;&nbsp;&nbsp;dep: ";
1181 expr_print(prop->visible.expr, expr_print_help, &debug, E_NONE);
1182 debug += "<br>";
1183 }
1184 }
1185 debug += "<br>";
1186
1187 return debug;
1188}
1189
1190QString ConfigInfoView::print_filter(const QString &str)
1191{
1192 QRegExp re("[<>&\"\\n]");
1193 QString res = str;
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001194 for (int i = 0; (i = res.indexOf(re, i)) >= 0;) {
1195 switch (res[i].toLatin1()) {
Roman Zippel43bf6122006-06-08 22:12:45 -07001196 case '<':
1197 res.replace(i, 1, "&lt;");
1198 i += 4;
1199 break;
1200 case '>':
1201 res.replace(i, 1, "&gt;");
1202 i += 4;
1203 break;
1204 case '&':
1205 res.replace(i, 1, "&amp;");
1206 i += 5;
1207 break;
1208 case '"':
1209 res.replace(i, 1, "&quot;");
1210 i += 6;
1211 break;
1212 case '\n':
1213 res.replace(i, 1, "<br>");
1214 i += 4;
1215 break;
1216 }
1217 }
1218 return res;
1219}
1220
Roman Zippelab45d192006-06-08 22:12:47 -07001221void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char *str)
Roman Zippel43bf6122006-06-08 22:12:45 -07001222{
Roman Zippelab45d192006-06-08 22:12:47 -07001223 QString* text = reinterpret_cast<QString*>(data);
1224 QString str2 = print_filter(str);
1225
1226 if (sym && sym->name && !(sym->flags & SYMBOL_CONST)) {
1227 *text += QString().sprintf("<a href=\"s%p\">", sym);
1228 *text += str2;
1229 *text += "</a>";
1230 } else
1231 *text += str2;
Roman Zippel43bf6122006-06-08 22:12:45 -07001232}
1233
Boris Barbulovski924bbb52015-09-22 11:36:06 -07001234QMenu* ConfigInfoView::createStandardContextMenu(const QPoint & pos)
Roman Zippel7fc925f2006-06-08 22:12:46 -07001235{
Boris Barbulovski924bbb52015-09-22 11:36:06 -07001236 QMenu* popup = Parent::createStandardContextMenu(pos);
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001237 QAction* action = new QAction(_("Show Debug Info"), popup);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001238 action->setCheckable(true);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001239 connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
1240 connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool)));
Boris Barbulovski9c862352015-09-22 11:36:12 -07001241 action->setChecked(showDebug());
Boris Barbulovski924bbb52015-09-22 11:36:06 -07001242 popup->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001243 popup->addAction(action);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001244 return popup;
1245}
1246
Boris Barbulovski924bbb52015-09-22 11:36:06 -07001247void ConfigInfoView::contextMenuEvent(QContextMenuEvent *e)
Roman Zippel7fc925f2006-06-08 22:12:46 -07001248{
Boris Barbulovski924bbb52015-09-22 11:36:06 -07001249 Parent::contextMenuEvent(e);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001250}
1251
Marco Costalba63431e72006-10-05 19:12:59 +02001252ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow* parent, const char *name)
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001253 : Parent(parent), result(NULL)
Roman Zippel43bf6122006-06-08 22:12:45 -07001254{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001255 setObjectName(name);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001256 setWindowTitle("Search Config");
Roman Zippel43bf6122006-06-08 22:12:45 -07001257
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001258 QVBoxLayout* layout1 = new QVBoxLayout(this);
1259 layout1->setContentsMargins(11, 11, 11, 11);
1260 layout1->setSpacing(6);
1261 QHBoxLayout* layout2 = new QHBoxLayout(0);
1262 layout2->setContentsMargins(0, 0, 0, 0);
1263 layout2->setSpacing(6);
EGRY Gaborc21a2d92008-01-11 23:52:07 +01001264 layout2->addWidget(new QLabel(_("Find:"), this));
Roman Zippel43bf6122006-06-08 22:12:45 -07001265 editField = new QLineEdit(this);
1266 connect(editField, SIGNAL(returnPressed()), SLOT(search()));
1267 layout2->addWidget(editField);
EGRY Gaborc21a2d92008-01-11 23:52:07 +01001268 searchButton = new QPushButton(_("Search"), this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001269 searchButton->setAutoDefault(false);
Roman Zippel43bf6122006-06-08 22:12:45 -07001270 connect(searchButton, SIGNAL(clicked()), SLOT(search()));
1271 layout2->addWidget(searchButton);
1272 layout1->addLayout(layout2);
1273
Roman Zippel7fc925f2006-06-08 22:12:46 -07001274 split = new QSplitter(this);
Markus Heidelberg7298b932009-05-18 01:36:50 +02001275 split->setOrientation(Qt::Vertical);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001276 list = new ConfigView(split, name);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001277 list->list->mode = listMode;
Roman Zippel7fc925f2006-06-08 22:12:46 -07001278 info = new ConfigInfoView(split, name);
Roman Zippel43bf6122006-06-08 22:12:45 -07001279 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1280 info, SLOT(setInfo(struct menu *)));
Marco Costalba63431e72006-10-05 19:12:59 +02001281 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1282 parent, SLOT(setMenuLink(struct menu *)));
1283
Roman Zippel43bf6122006-06-08 22:12:45 -07001284 layout1->addWidget(split);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001285
1286 if (name) {
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001287 QVariant x, y;
1288 int width, height;
Roman Zippel7fc925f2006-06-08 22:12:46 -07001289 bool ok;
1290
1291 configSettings->beginGroup(name);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001292 width = configSettings->value("/window width", parent->width() / 2).toInt();
1293 height = configSettings->value("/window height", parent->height() / 2).toInt();
Roman Zippel7fc925f2006-06-08 22:12:46 -07001294 resize(width, height);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001295 x = configSettings->value("/window x");
1296 y = configSettings->value("/window y");
1297 if ((x.isValid())&&(y.isValid()))
1298 move(x.toInt(), y.toInt());
Boris Barbulovski041fbdc2015-09-22 11:36:05 -07001299 QList<int> sizes = configSettings->readSizes("/split", &ok);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001300 if (ok)
1301 split->setSizes(sizes);
1302 configSettings->endGroup();
1303 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
1304 }
1305}
1306
1307void ConfigSearchWindow::saveSettings(void)
1308{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001309 if (!objectName().isEmpty()) {
1310 configSettings->beginGroup(objectName());
1311 configSettings->setValue("/window x", pos().x());
1312 configSettings->setValue("/window y", pos().y());
1313 configSettings->setValue("/window width", size().width());
1314 configSettings->setValue("/window height", size().height());
1315 configSettings->writeSizes("/split", split->sizes());
1316 configSettings->endGroup();
1317 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001318}
1319
1320void ConfigSearchWindow::search(void)
1321{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001322 struct symbol **p;
1323 struct property *prop;
1324 ConfigItem *lastItem = NULL;
1325
1326 free(result);
1327 list->list->clear();
1328 info->clear();
1329
1330 result = sym_re_search(editField->text().toLatin1());
1331 if (!result)
1332 return;
1333 for (p = result; *p; p++) {
1334 for_all_prompts((*p), prop)
1335 lastItem = new ConfigItem(list->list, lastItem, prop->menu,
1336 menu_is_visible(prop->menu));
1337 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001338}
1339
Linus Torvalds1da177e2005-04-16 15:20:36 -07001340/*
1341 * Construct the complete config widget
1342 */
1343ConfigMainWindow::ConfigMainWindow(void)
Roman Zippelf12aa702006-11-25 11:09:31 -08001344 : searchWindow(0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001345{
1346 QMenuBar* menu;
Boris Barbulovski92119932015-09-22 11:36:16 -07001347 bool ok = true;
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001348 QVariant x, y;
1349 int width, height;
Randy Dunlapa54bb702007-10-20 11:18:47 -07001350 char title[256];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001351
Markus Heidelberg8d90c972009-05-18 01:36:52 +02001352 QDesktopWidget *d = configApp->desktop();
Arnaud Lacombe09548282010-08-18 01:57:13 -04001353 snprintf(title, sizeof(title), "%s%s",
1354 rootmenu.prompt->text,
Michal Marek76a136c2010-09-01 17:39:27 +02001355 ""
Michal Marek76a136c2010-09-01 17:39:27 +02001356 );
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001357 setWindowTitle(title);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001358
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001359 width = configSettings->value("/window width", d->width() - 64).toInt();
1360 height = configSettings->value("/window height", d->height() - 64).toInt();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001361 resize(width, height);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001362 x = configSettings->value("/window x");
1363 y = configSettings->value("/window y");
1364 if ((x.isValid())&&(y.isValid()))
1365 move(x.toInt(), y.toInt());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001366
1367 split1 = new QSplitter(this);
Markus Heidelberg7298b932009-05-18 01:36:50 +02001368 split1->setOrientation(Qt::Horizontal);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001369 setCentralWidget(split1);
1370
Roman Zippel7fc925f2006-06-08 22:12:46 -07001371 menuView = new ConfigView(split1, "menu");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001372 menuList = menuView->list;
1373
1374 split2 = new QSplitter(split1);
Markus Heidelberg7298b932009-05-18 01:36:50 +02001375 split2->setOrientation(Qt::Vertical);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001376
1377 // create config tree
Roman Zippel7fc925f2006-06-08 22:12:46 -07001378 configView = new ConfigView(split2, "config");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001379 configList = configView->list;
1380
Roman Zippel7fc925f2006-06-08 22:12:46 -07001381 helpText = new ConfigInfoView(split2, "help");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001382
1383 setTabOrder(configList, helpText);
1384 configList->setFocus();
1385
1386 menu = menuBar();
Boris Barbulovskib1f8a452015-09-22 11:36:02 -07001387 toolBar = new QToolBar("Tools", this);
Boris Barbulovski29a70162015-09-22 11:36:10 -07001388 addToolBar(toolBar);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001389
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001390 backAction = new QAction(QPixmap(xpm_back), _("Back"), this);
Boris Barbulovski92119932015-09-22 11:36:16 -07001391 connect(backAction, SIGNAL(triggered(bool)), SLOT(goBack()));
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001392 backAction->setEnabled(false);
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001393 QAction *quitAction = new QAction(_("&Quit"), this);
1394 quitAction->setShortcut(Qt::CTRL + Qt::Key_Q);
Boris Barbulovski92119932015-09-22 11:36:16 -07001395 connect(quitAction, SIGNAL(triggered(bool)), SLOT(close()));
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001396 QAction *loadAction = new QAction(QPixmap(xpm_load), _("&Load"), this);
1397 loadAction->setShortcut(Qt::CTRL + Qt::Key_L);
Boris Barbulovski92119932015-09-22 11:36:16 -07001398 connect(loadAction, SIGNAL(triggered(bool)), SLOT(loadConfig()));
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001399 saveAction = new QAction(QPixmap(xpm_save), _("&Save"), this);
1400 saveAction->setShortcut(Qt::CTRL + Qt::Key_S);
Boris Barbulovski92119932015-09-22 11:36:16 -07001401 connect(saveAction, SIGNAL(triggered(bool)), SLOT(saveConfig()));
Karsten Wiese3b354c52006-12-13 00:34:08 -08001402 conf_set_changed_callback(conf_changed);
1403 // Set saveAction's initial state
1404 conf_changed();
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001405 QAction *saveAsAction = new QAction(_("Save &As..."), this);
Boris Barbulovski92119932015-09-22 11:36:16 -07001406 connect(saveAsAction, SIGNAL(triggered(bool)), SLOT(saveConfigAs()));
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001407 QAction *searchAction = new QAction(_("&Find"), this);
1408 searchAction->setShortcut(Qt::CTRL + Qt::Key_F);
Boris Barbulovski92119932015-09-22 11:36:16 -07001409 connect(searchAction, SIGNAL(triggered(bool)), SLOT(searchConfig()));
Boris Barbulovski780505e2015-09-22 11:36:13 -07001410 singleViewAction = new QAction(QPixmap(xpm_single_view), _("Single View"), this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001411 singleViewAction->setCheckable(true);
Boris Barbulovski92119932015-09-22 11:36:16 -07001412 connect(singleViewAction, SIGNAL(triggered(bool)), SLOT(showSingleView()));
Boris Barbulovski780505e2015-09-22 11:36:13 -07001413 splitViewAction = new QAction(QPixmap(xpm_split_view), _("Split View"), this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001414 splitViewAction->setCheckable(true);
Boris Barbulovski92119932015-09-22 11:36:16 -07001415 connect(splitViewAction, SIGNAL(triggered(bool)), SLOT(showSplitView()));
Boris Barbulovski780505e2015-09-22 11:36:13 -07001416 fullViewAction = new QAction(QPixmap(xpm_tree_view), _("Full View"), this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001417 fullViewAction->setCheckable(true);
Boris Barbulovski92119932015-09-22 11:36:16 -07001418 connect(fullViewAction, SIGNAL(triggered(bool)), SLOT(showFullView()));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001419
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001420 QAction *showNameAction = new QAction(_("Show Name"), this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001421 showNameAction->setCheckable(true);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001422 connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool)));
Boris Barbulovski9c862352015-09-22 11:36:12 -07001423 showNameAction->setChecked(configView->showName());
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001424 QAction *showRangeAction = new QAction(_("Show Range"), this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001425 showRangeAction->setCheckable(true);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001426 connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool)));
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001427 QAction *showDataAction = new QAction(_("Show Data"), this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001428 showDataAction->setCheckable(true);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001429 connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool)));
Li Zefan39a48972010-05-10 16:33:41 +08001430
1431 QActionGroup *optGroup = new QActionGroup(this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001432 optGroup->setExclusive(true);
Boris Barbulovski92119932015-09-22 11:36:16 -07001433 connect(optGroup, SIGNAL(triggered(QAction*)), configView,
Li Zefan39a48972010-05-10 16:33:41 +08001434 SLOT(setOptionMode(QAction *)));
Boris Barbulovski92119932015-09-22 11:36:16 -07001435 connect(optGroup, SIGNAL(triggered(QAction *)), menuView,
Li Zefan39a48972010-05-10 16:33:41 +08001436 SLOT(setOptionMode(QAction *)));
1437
Alexander Stein133c5f72010-08-31 17:34:37 +02001438 configView->showNormalAction = new QAction(_("Show Normal Options"), optGroup);
1439 configView->showAllAction = new QAction(_("Show All Options"), optGroup);
1440 configView->showPromptAction = new QAction(_("Show Prompt Options"), optGroup);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001441 configView->showNormalAction->setCheckable(true);
1442 configView->showAllAction->setCheckable(true);
1443 configView->showPromptAction->setCheckable(true);
Li Zefan39a48972010-05-10 16:33:41 +08001444
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001445 QAction *showDebugAction = new QAction( _("Show Debug Info"), this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001446 showDebugAction->setCheckable(true);
Roman Zippel43bf6122006-06-08 22:12:45 -07001447 connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
Boris Barbulovski9c862352015-09-22 11:36:12 -07001448 showDebugAction->setChecked(helpText->showDebug());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001449
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001450 QAction *showIntroAction = new QAction( _("Introduction"), this);
Boris Barbulovski92119932015-09-22 11:36:16 -07001451 connect(showIntroAction, SIGNAL(triggered(bool)), SLOT(showIntro()));
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001452 QAction *showAboutAction = new QAction( _("About"), this);
Boris Barbulovski92119932015-09-22 11:36:16 -07001453 connect(showAboutAction, SIGNAL(triggered(bool)), SLOT(showAbout()));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001454
1455 // init tool bar
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001456 toolBar->addAction(backAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001457 toolBar->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001458 toolBar->addAction(loadAction);
1459 toolBar->addAction(saveAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001460 toolBar->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001461 toolBar->addAction(singleViewAction);
1462 toolBar->addAction(splitViewAction);
1463 toolBar->addAction(fullViewAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001464
1465 // create config menu
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001466 QMenu* config = menu->addMenu(_("&File"));
1467 config->addAction(loadAction);
1468 config->addAction(saveAction);
1469 config->addAction(saveAsAction);
Boris Barbulovski76bede82015-09-22 11:36:07 -07001470 config->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001471 config->addAction(quitAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001472
Shlomi Fish66e7c722007-02-14 00:32:58 -08001473 // create edit menu
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001474 QMenu* editMenu = menu->addMenu(_("&Edit"));
1475 editMenu->addAction(searchAction);
Shlomi Fish66e7c722007-02-14 00:32:58 -08001476
Linus Torvalds1da177e2005-04-16 15:20:36 -07001477 // create options menu
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001478 QMenu* optionMenu = menu->addMenu(_("&Option"));
1479 optionMenu->addAction(showNameAction);
1480 optionMenu->addAction(showRangeAction);
1481 optionMenu->addAction(showDataAction);
Boris Barbulovski76bede82015-09-22 11:36:07 -07001482 optionMenu->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001483 optionMenu->addActions(optGroup->actions());
Boris Barbulovski76bede82015-09-22 11:36:07 -07001484 optionMenu->addSeparator();
Boris Barbulovskie0393032016-11-30 14:57:52 -08001485 optionMenu->addAction(showDebugAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001486
1487 // create help menu
Boris Barbulovski76bede82015-09-22 11:36:07 -07001488 menu->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001489 QMenu* helpMenu = menu->addMenu(_("&Help"));
1490 helpMenu->addAction(showIntroAction);
1491 helpMenu->addAction(showAboutAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001492
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001493 connect(configList, SIGNAL(menuChanged(struct menu *)),
1494 helpText, SLOT(setInfo(struct menu *)));
1495 connect(configList, SIGNAL(menuSelected(struct menu *)),
1496 SLOT(changeMenu(struct menu *)));
1497 connect(configList, SIGNAL(parentSelected()),
1498 SLOT(goBack()));
1499 connect(menuList, SIGNAL(menuChanged(struct menu *)),
1500 helpText, SLOT(setInfo(struct menu *)));
1501 connect(menuList, SIGNAL(menuSelected(struct menu *)),
1502 SLOT(changeMenu(struct menu *)));
1503
1504 connect(configList, SIGNAL(gotFocus(struct menu *)),
1505 helpText, SLOT(setInfo(struct menu *)));
1506 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1507 helpText, SLOT(setInfo(struct menu *)));
1508 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1509 SLOT(listFocusChanged(void)));
Roman Zippelb65a47e2006-06-08 22:12:47 -07001510 connect(helpText, SIGNAL(menuSelected(struct menu *)),
1511 SLOT(setMenuLink(struct menu *)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001512
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001513 QString listMode = configSettings->value("/listMode", "symbol").toString();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001514 if (listMode == "single")
1515 showSingleView();
1516 else if (listMode == "full")
1517 showFullView();
1518 else /*if (listMode == "split")*/
1519 showSplitView();
1520
1521 // UI setup done, restore splitter positions
Boris Barbulovski041fbdc2015-09-22 11:36:05 -07001522 QList<int> sizes = configSettings->readSizes("/split1", &ok);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001523 if (ok)
1524 split1->setSizes(sizes);
1525
Roman Zippel7fc925f2006-06-08 22:12:46 -07001526 sizes = configSettings->readSizes("/split2", &ok);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001527 if (ok)
1528 split2->setSizes(sizes);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001529}
1530
Linus Torvalds1da177e2005-04-16 15:20:36 -07001531void ConfigMainWindow::loadConfig(void)
1532{
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001533 QString s = QFileDialog::getOpenFileName(this, "", conf_get_configname());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001534 if (s.isNull())
1535 return;
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -07001536 if (conf_read(QFile::encodeName(s)))
EGRY Gaborc21a2d92008-01-11 23:52:07 +01001537 QMessageBox::information(this, "qconf", _("Unable to load configuration!"));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001538 ConfigView::updateListAll();
1539}
1540
Michal Marekbac6aa82011-05-25 15:10:25 +02001541bool ConfigMainWindow::saveConfig(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001542{
Michal Marekbac6aa82011-05-25 15:10:25 +02001543 if (conf_write(NULL)) {
EGRY Gaborc21a2d92008-01-11 23:52:07 +01001544 QMessageBox::information(this, "qconf", _("Unable to save configuration!"));
Michal Marekbac6aa82011-05-25 15:10:25 +02001545 return false;
1546 }
1547 return true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001548}
1549
1550void ConfigMainWindow::saveConfigAs(void)
1551{
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001552 QString s = QFileDialog::getSaveFileName(this, "", conf_get_configname());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001553 if (s.isNull())
1554 return;
Arnaud Lacombed49e4682011-05-24 14:16:18 -04001555 saveConfig();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001556}
1557
Roman Zippel43bf6122006-06-08 22:12:45 -07001558void ConfigMainWindow::searchConfig(void)
1559{
1560 if (!searchWindow)
Roman Zippel7fc925f2006-06-08 22:12:46 -07001561 searchWindow = new ConfigSearchWindow(this, "search");
Roman Zippel43bf6122006-06-08 22:12:45 -07001562 searchWindow->show();
1563}
1564
Linus Torvalds1da177e2005-04-16 15:20:36 -07001565void ConfigMainWindow::changeMenu(struct menu *menu)
1566{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001567 configList->setRootMenu(menu);
1568 if (configList->rootEntry->parent == &rootmenu)
1569 backAction->setEnabled(false);
1570 else
1571 backAction->setEnabled(true);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001572}
1573
Roman Zippelb65a47e2006-06-08 22:12:47 -07001574void ConfigMainWindow::setMenuLink(struct menu *menu)
1575{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001576 struct menu *parent;
1577 ConfigList* list = NULL;
1578 ConfigItem* item;
1579
1580 if (configList->menuSkip(menu))
1581 return;
1582
1583 switch (configList->mode) {
1584 case singleMode:
1585 list = configList;
1586 parent = menu_get_parent_menu(menu);
1587 if (!parent)
1588 return;
1589 list->setRootMenu(parent);
1590 break;
1591 case symbolMode:
1592 if (menu->flags & MENU_ROOT) {
1593 configList->setRootMenu(menu);
1594 configList->clearSelection();
1595 list = menuList;
1596 } else {
1597 list = configList;
1598 parent = menu_get_parent_menu(menu->parent);
1599 if (!parent)
1600 return;
1601 item = menuList->findConfigItem(parent);
1602 if (item) {
1603 item->setSelected(true);
1604 menuList->scrollToItem(item);
1605 }
1606 list->setRootMenu(parent);
1607 }
1608 break;
1609 case fullMode:
1610 list = configList;
1611 break;
1612 default:
1613 break;
1614 }
1615
1616 if (list) {
1617 item = list->findConfigItem(menu);
1618 if (item) {
1619 item->setSelected(true);
1620 list->scrollToItem(item);
1621 list->setFocus();
1622 }
1623 }
Roman Zippelb65a47e2006-06-08 22:12:47 -07001624}
1625
Linus Torvalds1da177e2005-04-16 15:20:36 -07001626void ConfigMainWindow::listFocusChanged(void)
1627{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001628 if (menuList->mode == menuMode)
1629 configList->clearSelection();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001630}
1631
1632void ConfigMainWindow::goBack(void)
1633{
Boris Barbulovski5df9da92015-09-22 11:36:36 -07001634 ConfigItem* item, *oldSelection;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001635
1636 configList->setParentMenu();
1637 if (configList->rootEntry == &rootmenu)
1638 backAction->setEnabled(false);
Boris Barbulovskibe596aa2015-09-22 11:36:28 -07001639
1640 if (menuList->selectedItems().count() == 0)
1641 return;
1642
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001643 item = (ConfigItem*)menuList->selectedItems().first();
Boris Barbulovski5df9da92015-09-22 11:36:36 -07001644 oldSelection = item;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001645 while (item) {
1646 if (item->menu == configList->rootEntry) {
Boris Barbulovski5df9da92015-09-22 11:36:36 -07001647 oldSelection->setSelected(false);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001648 item->setSelected(true);
1649 break;
1650 }
1651 item = (ConfigItem*)item->parent();
1652 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001653}
1654
1655void ConfigMainWindow::showSingleView(void)
1656{
Boris Barbulovski780505e2015-09-22 11:36:13 -07001657 singleViewAction->setEnabled(false);
1658 singleViewAction->setChecked(true);
1659 splitViewAction->setEnabled(true);
1660 splitViewAction->setChecked(false);
1661 fullViewAction->setEnabled(true);
1662 fullViewAction->setChecked(false);
1663
Linus Torvalds1da177e2005-04-16 15:20:36 -07001664 menuView->hide();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001665 menuList->setRootMenu(0);
1666 configList->mode = singleMode;
1667 if (configList->rootEntry == &rootmenu)
1668 configList->updateListAll();
1669 else
1670 configList->setRootMenu(&rootmenu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001671 configList->setFocus();
1672}
1673
1674void ConfigMainWindow::showSplitView(void)
1675{
Boris Barbulovski780505e2015-09-22 11:36:13 -07001676 singleViewAction->setEnabled(true);
1677 singleViewAction->setChecked(false);
1678 splitViewAction->setEnabled(false);
1679 splitViewAction->setChecked(true);
1680 fullViewAction->setEnabled(true);
1681 fullViewAction->setChecked(false);
1682
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001683 configList->mode = symbolMode;
1684 if (configList->rootEntry == &rootmenu)
1685 configList->updateListAll();
1686 else
1687 configList->setRootMenu(&rootmenu);
1688 configList->setAllOpen(true);
1689 configApp->processEvents();
1690 menuList->mode = menuMode;
1691 menuList->setRootMenu(&rootmenu);
1692 menuList->setAllOpen(true);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001693 menuView->show();
1694 menuList->setFocus();
1695}
1696
1697void ConfigMainWindow::showFullView(void)
1698{
Boris Barbulovski780505e2015-09-22 11:36:13 -07001699 singleViewAction->setEnabled(true);
1700 singleViewAction->setChecked(false);
1701 splitViewAction->setEnabled(true);
1702 splitViewAction->setChecked(false);
1703 fullViewAction->setEnabled(false);
1704 fullViewAction->setChecked(true);
1705
Linus Torvalds1da177e2005-04-16 15:20:36 -07001706 menuView->hide();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001707 menuList->setRootMenu(0);
1708 configList->mode = fullMode;
1709 if (configList->rootEntry == &rootmenu)
1710 configList->updateListAll();
1711 else
1712 configList->setRootMenu(&rootmenu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001713 configList->setFocus();
1714}
1715
Linus Torvalds1da177e2005-04-16 15:20:36 -07001716/*
1717 * ask for saving configuration before quitting
1718 * TODO ask only when something changed
1719 */
1720void ConfigMainWindow::closeEvent(QCloseEvent* e)
1721{
Karsten Wieseb3214292006-12-13 00:34:06 -08001722 if (!conf_get_changed()) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001723 e->accept();
1724 return;
1725 }
EGRY Gaborc21a2d92008-01-11 23:52:07 +01001726 QMessageBox mb("qconf", _("Save configuration?"), QMessageBox::Warning,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001727 QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape);
EGRY Gaborc21a2d92008-01-11 23:52:07 +01001728 mb.setButtonText(QMessageBox::Yes, _("&Save Changes"));
1729 mb.setButtonText(QMessageBox::No, _("&Discard Changes"));
1730 mb.setButtonText(QMessageBox::Cancel, _("Cancel Exit"));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001731 switch (mb.exec()) {
1732 case QMessageBox::Yes:
Michal Marekbac6aa82011-05-25 15:10:25 +02001733 if (saveConfig())
1734 e->accept();
1735 else
1736 e->ignore();
1737 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001738 case QMessageBox::No:
1739 e->accept();
1740 break;
1741 case QMessageBox::Cancel:
1742 e->ignore();
1743 break;
1744 }
1745}
1746
1747void ConfigMainWindow::showIntro(void)
1748{
Arnaud Lacombe652cf982010-08-14 23:51:40 -04001749 static const QString str = _("Welcome to the qconf graphical configuration tool.\n\n"
Linus Torvalds1da177e2005-04-16 15:20:36 -07001750 "For each option, a blank box indicates the feature is disabled, a check\n"
1751 "indicates it is enabled, and a dot indicates that it is to be compiled\n"
1752 "as a module. Clicking on the box will cycle through the three states.\n\n"
1753 "If you do not see an option (e.g., a device driver) that you believe\n"
1754 "should be present, try turning on Show All Options under the Options menu.\n"
1755 "Although there is no cross reference yet to help you figure out what other\n"
1756 "options must be enabled to support the option you are interested in, you can\n"
1757 "still view the help of a grayed-out option.\n\n"
1758 "Toggling Show Debug Info under the Options menu will show the dependencies,\n"
EGRY Gaborc21a2d92008-01-11 23:52:07 +01001759 "which you can then match by examining other options.\n\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001760
1761 QMessageBox::information(this, "qconf", str);
1762}
1763
1764void ConfigMainWindow::showAbout(void)
1765{
Boris Barbulovskib4ff1de2015-09-22 11:36:38 -07001766 static const QString str = _("qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n"
1767 "Copyright (C) 2015 Boris Barbulovski <bbarbulovski@gmail.com>.\n\n"
EGRY Gaborc21a2d92008-01-11 23:52:07 +01001768 "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001769
1770 QMessageBox::information(this, "qconf", str);
1771}
1772
1773void ConfigMainWindow::saveSettings(void)
1774{
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001775 configSettings->setValue("/window x", pos().x());
1776 configSettings->setValue("/window y", pos().y());
1777 configSettings->setValue("/window width", size().width());
1778 configSettings->setValue("/window height", size().height());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001779
1780 QString entry;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001781 switch(configList->mode) {
1782 case singleMode :
1783 entry = "single";
1784 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001785
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001786 case symbolMode :
1787 entry = "split";
1788 break;
1789
1790 case fullMode :
1791 entry = "full";
1792 break;
1793
1794 default:
1795 break;
1796 }
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001797 configSettings->setValue("/listMode", entry);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001798
Roman Zippel7fc925f2006-06-08 22:12:46 -07001799 configSettings->writeSizes("/split1", split1->sizes());
1800 configSettings->writeSizes("/split2", split2->sizes());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001801}
1802
Karsten Wiese3b354c52006-12-13 00:34:08 -08001803void ConfigMainWindow::conf_changed(void)
1804{
1805 if (saveAction)
1806 saveAction->setEnabled(conf_get_changed());
1807}
1808
Linus Torvalds1da177e2005-04-16 15:20:36 -07001809void fixup_rootmenu(struct menu *menu)
1810{
1811 struct menu *child;
1812 static int menu_cnt = 0;
1813
1814 menu->flags |= MENU_ROOT;
1815 for (child = menu->list; child; child = child->next) {
1816 if (child->prompt && child->prompt->type == P_MENU) {
1817 menu_cnt++;
1818 fixup_rootmenu(child);
1819 menu_cnt--;
1820 } else if (!menu_cnt)
1821 fixup_rootmenu(child);
1822 }
1823}
1824
1825static const char *progname;
1826
1827static void usage(void)
1828{
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001829 printf(_("%s [-s] <config>\n").toLatin1().constData(), progname);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001830 exit(0);
1831}
1832
1833int main(int ac, char** av)
1834{
1835 ConfigMainWindow* v;
1836 const char *name;
1837
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -07001838 bindtextdomain(PACKAGE, LOCALEDIR);
1839 textdomain(PACKAGE);
1840
Linus Torvalds1da177e2005-04-16 15:20:36 -07001841 progname = av[0];
1842 configApp = new QApplication(ac, av);
1843 if (ac > 1 && av[1][0] == '-') {
1844 switch (av[1][1]) {
Michal Marek0a1f00a2015-04-08 13:30:42 +02001845 case 's':
1846 conf_set_message_callback(NULL);
1847 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001848 case 'h':
1849 case '?':
1850 usage();
1851 }
1852 name = av[2];
1853 } else
1854 name = av[1];
1855 if (!name)
1856 usage();
1857
1858 conf_parse(name);
1859 fixup_rootmenu(&rootmenu);
1860 conf_read(NULL);
1861 //zconfdump(stdout);
1862
Roman Zippel7fc925f2006-06-08 22:12:46 -07001863 configSettings = new ConfigSettings();
1864 configSettings->beginGroup("/kconfig/qconf");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001865 v = new ConfigMainWindow();
1866
1867 //zconfdump(stdout);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001868 configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit()));
1869 configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings()));
Roman Zippel43bf6122006-06-08 22:12:45 -07001870 v->show();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001871 configApp->exec();
1872
Roman Zippel7fc925f2006-06-08 22:12:46 -07001873 configSettings->endGroup();
1874 delete configSettings;
Chris Bainbridge5b61c7b2016-01-08 20:44:04 +00001875 delete v;
1876 delete configApp;
Roman Zippel7fc925f2006-06-08 22:12:46 -07001877
Linus Torvalds1da177e2005-04-16 15:20:36 -07001878 return 0;
1879}