blob: 97631e9a61d802bf90ffa3db628c32fd18416fac [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
3 * Released under the terms of the GNU GPL v2.0.
4 */
5
Alexander Stein133c5f72010-08-31 17:34:37 +02006#include <qglobal.h>
7
Boris Barbulovskib1f8a452015-09-22 11:36:02 -07008#include <QMainWindow>
Boris Barbulovski041fbdc2015-09-22 11:36:05 -07009#include <QList>
Boris Barbulovski924bbb52015-09-22 11:36:06 -070010#include <qtextbrowser.h>
Boris Barbulovski85eaf282015-09-22 11:36:03 -070011#include <QAction>
Boris Barbulovskibea00772015-09-22 11:36:04 -070012#include <QFileDialog>
Boris Barbulovski76bede82015-09-22 11:36:07 -070013#include <QMenu>
Alexander Stein133c5f72010-08-31 17:34:37 +020014
15#include <qapplication.h>
Markus Heidelberg8d90c972009-05-18 01:36:52 +020016#include <qdesktopwidget.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070017#include <qtoolbar.h>
Roman Zippel43bf6122006-06-08 22:12:45 -070018#include <qlayout.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070019#include <qsplitter.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070020#include <qlineedit.h>
Roman Zippel43bf6122006-06-08 22:12:45 -070021#include <qlabel.h>
22#include <qpushbutton.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070023#include <qmenubar.h>
24#include <qmessagebox.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070025#include <qregexp.h>
Alexander Stein133c5f72010-08-31 17:34:37 +020026#include <qevent.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070027
28#include <stdlib.h>
29
30#include "lkc.h"
31#include "qconf.h"
32
33#include "qconf.moc"
34#include "images.c"
35
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -070036#ifdef _
37# undef _
38# define _ qgettext
39#endif
40
Linus Torvalds1da177e2005-04-16 15:20:36 -070041static QApplication *configApp;
Roman Zippel7fc925f2006-06-08 22:12:46 -070042static ConfigSettings *configSettings;
Linus Torvalds1da177e2005-04-16 15:20:36 -070043
Boris Barbulovski85eaf282015-09-22 11:36:03 -070044QAction *ConfigMainWindow::saveAction;
Karsten Wiese3b354c552006-12-13 00:34:08 -080045
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -070046static inline QString qgettext(const char* str)
47{
Roman Zippel43bf6122006-06-08 22:12:45 -070048 return QString::fromLocal8Bit(gettext(str));
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -070049}
50
51static inline QString qgettext(const QString& str)
52{
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -070053 return QString::fromLocal8Bit(gettext(str.toLatin1()));
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -070054}
55
Ben Hutchings00d4f8f2013-10-06 19:21:31 +010056ConfigSettings::ConfigSettings()
57 : QSettings("kernel.org", "qconf")
58{
59}
60
Linus Torvalds1da177e2005-04-16 15:20:36 -070061/**
62 * Reads a list of integer values from the application settings.
63 */
Boris Barbulovski041fbdc2015-09-22 11:36:05 -070064QList<int> ConfigSettings::readSizes(const QString& key, bool *ok)
Linus Torvalds1da177e2005-04-16 15:20:36 -070065{
Boris Barbulovski041fbdc2015-09-22 11:36:05 -070066 QList<int> result;
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -070067 QStringList entryList = value(key).toStringList();
Li Zefanc1f96f02010-05-07 13:58:04 +080068 QStringList::Iterator it;
69
70 for (it = entryList.begin(); it != entryList.end(); ++it)
71 result.push_back((*it).toInt());
Linus Torvalds1da177e2005-04-16 15:20:36 -070072
73 return result;
74}
75
76/**
77 * Writes a list of integer values to the application settings.
78 */
Boris Barbulovski041fbdc2015-09-22 11:36:05 -070079bool ConfigSettings::writeSizes(const QString& key, const QList<int>& value)
Linus Torvalds1da177e2005-04-16 15:20:36 -070080{
81 QStringList stringList;
Boris Barbulovski041fbdc2015-09-22 11:36:05 -070082 QList<int>::ConstIterator it;
Linus Torvalds1da177e2005-04-16 15:20:36 -070083
84 for (it = value.begin(); it != value.end(); ++it)
85 stringList.push_back(QString::number(*it));
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -070086 setValue(key, stringList);
Boris Barbulovski59e56442015-09-22 11:36:18 -070087
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -070088 return true;
Linus Torvalds1da177e2005-04-16 15:20:36 -070089}
Linus Torvalds1da177e2005-04-16 15:20:36 -070090
Boris Barbulovski59e56442015-09-22 11:36:18 -070091
92/*
93 * set the new data
94 * TODO check the value
95 */
96void ConfigItem::okRename(int col)
97{
98}
99
100/*
101 * update the displayed of a menu entry
102 */
103void ConfigItem::updateMenu(void)
104{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700105 ConfigList* list;
106 struct symbol* sym;
107 struct property *prop;
108 QString prompt;
109 int type;
110 tristate expr;
111
112 list = listView();
113 if (goParent) {
114 setPixmap(promptColIdx, list->menuBackPix);
115 prompt = "..";
116 goto set_prompt;
117 }
118
119 sym = menu->sym;
120 prop = menu->prompt;
121 prompt = _(menu_get_prompt(menu));
122
123 if (prop) switch (prop->type) {
124 case P_MENU:
125 if (list->mode == singleMode || list->mode == symbolMode) {
126 /* a menuconfig entry is displayed differently
127 * depending whether it's at the view root or a child.
128 */
129 if (sym && list->rootEntry == menu)
130 break;
131 setPixmap(promptColIdx, list->menuPix);
132 } else {
133 if (sym)
134 break;
135 setPixmap(promptColIdx, QIcon());
136 }
137 goto set_prompt;
138 case P_COMMENT:
139 setPixmap(promptColIdx, QIcon());
140 goto set_prompt;
141 default:
142 ;
143 }
144 if (!sym)
145 goto set_prompt;
146
147 setText(nameColIdx, QString::fromLocal8Bit(sym->name));
148
149 type = sym_get_type(sym);
150 switch (type) {
151 case S_BOOLEAN:
152 case S_TRISTATE:
153 char ch;
154
155 if (!sym_is_changable(sym) && list->optMode == normalOpt) {
156 setPixmap(promptColIdx, QIcon());
157 setText(noColIdx, QString::null);
158 setText(modColIdx, QString::null);
159 setText(yesColIdx, QString::null);
160 break;
161 }
162 expr = sym_get_tristate_value(sym);
163 switch (expr) {
164 case yes:
165 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
166 setPixmap(promptColIdx, list->choiceYesPix);
167 else
168 setPixmap(promptColIdx, list->symbolYesPix);
169 setText(yesColIdx, "Y");
170 ch = 'Y';
171 break;
172 case mod:
173 setPixmap(promptColIdx, list->symbolModPix);
174 setText(modColIdx, "M");
175 ch = 'M';
176 break;
177 default:
178 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
179 setPixmap(promptColIdx, list->choiceNoPix);
180 else
181 setPixmap(promptColIdx, list->symbolNoPix);
182 setText(noColIdx, "N");
183 ch = 'N';
184 break;
185 }
186 if (expr != no)
187 setText(noColIdx, sym_tristate_within_range(sym, no) ? "_" : 0);
188 if (expr != mod)
189 setText(modColIdx, sym_tristate_within_range(sym, mod) ? "_" : 0);
190 if (expr != yes)
191 setText(yesColIdx, sym_tristate_within_range(sym, yes) ? "_" : 0);
192
193 setText(dataColIdx, QChar(ch));
194 break;
195 case S_INT:
196 case S_HEX:
197 case S_STRING:
198 const char* data;
199
200 data = sym_get_string_value(sym);
201
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700202 setText(dataColIdx, data);
203 if (type == S_STRING)
204 prompt = QString("%1: %2").arg(prompt).arg(data);
205 else
206 prompt = QString("(%2) %1").arg(prompt).arg(data);
207 break;
208 }
209 if (!sym_has_value(sym) && visible)
210 prompt += _(" (NEW)");
211set_prompt:
212 setText(promptColIdx, prompt);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700213}
214
215void ConfigItem::testUpdateMenu(bool v)
216{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700217 ConfigItem* i;
218
219 visible = v;
220 if (!menu)
221 return;
222
223 sym_calc_value(menu->sym);
224 if (menu->flags & MENU_CHANGED) {
225 /* the menu entry changed, so update all list items */
226 menu->flags &= ~MENU_CHANGED;
227 for (i = (ConfigItem*)menu->data; i; i = i->nextItem)
228 i->updateMenu();
229 } else if (listView()->updateAll)
230 updateMenu();
Boris Barbulovski59e56442015-09-22 11:36:18 -0700231}
232
233
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700234/*
235 * construct a menu entry
236 */
237void ConfigItem::init(void)
238{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700239 if (menu) {
240 ConfigList* list = listView();
241 nextItem = (ConfigItem*)menu->data;
242 menu->data = this;
243
244 if (list->mode != fullMode)
245 setExpanded(true);
246 sym_calc_value(menu->sym);
247 }
248 updateMenu();
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700249}
250
251/*
252 * destruct a menu entry
253 */
254ConfigItem::~ConfigItem(void)
255{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700256 if (menu) {
257 ConfigItem** ip = (ConfigItem**)&menu->data;
258 for (; *ip; ip = &(*ip)->nextItem) {
259 if (*ip == this) {
260 *ip = nextItem;
261 break;
262 }
263 }
264 }
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700265}
266
Roman Zippel43bf6122006-06-08 22:12:45 -0700267ConfigLineEdit::ConfigLineEdit(ConfigView* parent)
268 : Parent(parent)
269{
Boris Barbulovskic14fa5e2015-09-22 11:36:21 -0700270 connect(this, SIGNAL(editingFinished()), SLOT(hide()));
Roman Zippel43bf6122006-06-08 22:12:45 -0700271}
272
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700273void ConfigLineEdit::show(ConfigItem* i)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700274{
275 item = i;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700276 if (sym_get_string_value(item->menu->sym))
277 setText(QString::fromLocal8Bit(sym_get_string_value(item->menu->sym)));
278 else
279 setText(QString::null);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700280 Parent::show();
281 setFocus();
282}
283
284void ConfigLineEdit::keyPressEvent(QKeyEvent* e)
285{
286 switch (e->key()) {
Markus Heidelbergfbb86372009-05-18 01:36:51 +0200287 case Qt::Key_Escape:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700288 break;
Markus Heidelbergfbb86372009-05-18 01:36:51 +0200289 case Qt::Key_Return:
290 case Qt::Key_Enter:
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700291 sym_set_string_value(item->menu->sym, text().toLatin1());
Linus Torvalds1da177e2005-04-16 15:20:36 -0700292 parent()->updateList(item);
293 break;
294 default:
295 Parent::keyPressEvent(e);
296 return;
297 }
298 e->accept();
299 parent()->list->setFocus();
300 hide();
301}
302
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700303ConfigList::ConfigList(ConfigView* p, const char *name)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700304 : Parent(p),
305 updateAll(false),
306 symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no),
307 choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no),
308 menuPix(xpm_menu), menuInvPix(xpm_menu_inv), menuBackPix(xpm_menuback), voidPix(xpm_void),
Boris Barbulovskidbf62932015-09-22 11:36:26 -0700309 showName(false), showRange(false), showData(false), mode(singleMode), optMode(normalOpt),
Boris Barbulovski59e56442015-09-22 11:36:18 -0700310 rootEntry(0), headerPopup(0)
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700311{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700312 int i;
313
314 setObjectName(name);
Boris Barbulovskia5225e92015-09-22 11:36:29 -0700315 setSortingEnabled(false);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700316 setRootIsDecorated(true);
317
Boris Barbulovskif999cc02015-09-22 11:36:31 -0700318 setVerticalScrollMode(ScrollPerPixel);
319 setHorizontalScrollMode(ScrollPerPixel);
320
Boris Barbulovskia52cb322015-09-22 11:36:24 -0700321 setHeaderLabels(QStringList() << _("Option") << _("Name") << "N" << "M" << "Y" << _("Value"));
322
Boris Barbulovskic14fa5e2015-09-22 11:36:21 -0700323 connect(this, SIGNAL(itemSelectionChanged(void)),
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700324 SLOT(updateSelection(void)));
325
326 if (name) {
327 configSettings->beginGroup(name);
328 showName = configSettings->value("/showName", false).toBool();
329 showRange = configSettings->value("/showRange", false).toBool();
330 showData = configSettings->value("/showData", false).toBool();
331 optMode = (enum optionMode)configSettings->value("/optionMode", 0).toInt();
332 configSettings->endGroup();
333 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
334 }
335
336 addColumn(promptColIdx);
337
338 reinit();
339}
340
341bool ConfigList::menuSkip(struct menu *menu)
342{
343 if (optMode == normalOpt && menu_is_visible(menu))
344 return false;
345 if (optMode == promptOpt && menu_has_prompt(menu))
346 return false;
347 if (optMode == allOpt)
348 return false;
349 return true;
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700350}
Boris Barbulovski59e56442015-09-22 11:36:18 -0700351
352void ConfigList::reinit(void)
353{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700354 removeColumn(dataColIdx);
355 removeColumn(yesColIdx);
356 removeColumn(modColIdx);
357 removeColumn(noColIdx);
358 removeColumn(nameColIdx);
359
360 if (showName)
361 addColumn(nameColIdx);
362 if (showRange) {
363 addColumn(noColIdx);
364 addColumn(modColIdx);
365 addColumn(yesColIdx);
366 }
367 if (showData)
368 addColumn(dataColIdx);
369
370 updateListAll();
Boris Barbulovski59e56442015-09-22 11:36:18 -0700371}
372
373void ConfigList::saveSettings(void)
374{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700375 if (!objectName().isEmpty()) {
376 configSettings->beginGroup(objectName());
377 configSettings->setValue("/showName", showName);
378 configSettings->setValue("/showRange", showRange);
379 configSettings->setValue("/showData", showData);
380 configSettings->setValue("/optionMode", (int)optMode);
381 configSettings->endGroup();
382 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700383}
384
385ConfigItem* ConfigList::findConfigItem(struct menu *menu)
386{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700387 ConfigItem* item = (ConfigItem*)menu->data;
388
389 for (; item; item = item->nextItem) {
390 if (this == item->listView())
391 break;
392 }
393
394 return item;
Boris Barbulovski59e56442015-09-22 11:36:18 -0700395}
396
397void ConfigList::updateSelection(void)
398{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700399 struct menu *menu;
400 enum prop_type type;
401
402 ConfigItem* item = (ConfigItem*)selectedItems().first();
403 if (!item)
404 return;
405
406 menu = item->menu;
407 emit menuChanged(menu);
408 if (!menu)
409 return;
410 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
411 if (mode == menuMode && type == P_MENU)
412 emit menuSelected(menu);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700413}
414
415void ConfigList::updateList(ConfigItem* item)
416{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700417 ConfigItem* last = 0;
418
419 if (!rootEntry) {
420 if (mode != listMode)
421 goto update;
422 QTreeWidgetItemIterator it(this);
423 ConfigItem* item;
424
425 while (*it) {
426 item = (ConfigItem*)(*it);
427 if (!item->menu)
428 continue;
429 item->testUpdateMenu(menu_is_visible(item->menu));
430
431 ++it;
432 }
433 return;
434 }
435
436 if (rootEntry != &rootmenu && (mode == singleMode ||
437 (mode == symbolMode && rootEntry->parent != &rootmenu))) {
438 item = firstChild();
439 if (!item)
440 item = new ConfigItem(this, 0, true);
441 last = item;
442 }
443 if ((mode == singleMode || (mode == symbolMode && !(rootEntry->flags & MENU_ROOT))) &&
444 rootEntry->sym && rootEntry->prompt) {
445 item = last ? last->nextSibling() : firstChild();
446 if (!item)
447 item = new ConfigItem(this, last, rootEntry, true);
448 else
449 item->testUpdateMenu(true);
450
451 updateMenuList(item, rootEntry);
452 update();
Boris Barbulovskif999cc02015-09-22 11:36:31 -0700453 resizeColumnToContents(0);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700454 return;
455 }
456update:
457 updateMenuList(this, rootEntry);
458 update();
Boris Barbulovskif999cc02015-09-22 11:36:31 -0700459 resizeColumnToContents(0);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700460}
461
462void ConfigList::setValue(ConfigItem* item, tristate val)
463{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700464 struct symbol* sym;
465 int type;
466 tristate oldval;
467
468 sym = item->menu ? item->menu->sym : 0;
469 if (!sym)
470 return;
471
472 type = sym_get_type(sym);
473 switch (type) {
474 case S_BOOLEAN:
475 case S_TRISTATE:
476 oldval = sym_get_tristate_value(sym);
477
478 if (!sym_set_tristate_value(sym, val))
479 return;
480 if (oldval == no && item->menu->list)
481 item->setExpanded(true);
482 parent()->updateList(item);
483 break;
484 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700485}
486
487void ConfigList::changeValue(ConfigItem* item)
488{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700489 struct symbol* sym;
490 struct menu* menu;
491 int type, oldexpr, newexpr;
492
493 menu = item->menu;
494 if (!menu)
495 return;
496 sym = menu->sym;
497 if (!sym) {
498 if (item->menu->list)
499 item->setExpanded(!item->isExpanded());
500 return;
501 }
502
503 type = sym_get_type(sym);
504 switch (type) {
505 case S_BOOLEAN:
506 case S_TRISTATE:
507 oldexpr = sym_get_tristate_value(sym);
508 newexpr = sym_toggle_tristate_value(sym);
509 if (item->menu->list) {
510 if (oldexpr == newexpr)
511 item->setExpanded(!item->isExpanded());
512 else if (oldexpr == no)
513 item->setExpanded(true);
514 }
515 if (oldexpr != newexpr)
516 parent()->updateList(item);
517 break;
518 case S_INT:
519 case S_HEX:
520 case S_STRING:
Boris Barbulovskie336b9f2015-09-22 11:36:34 -0700521 parent()->lineEdit->show(item);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700522 break;
523 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700524}
525
526void ConfigList::setRootMenu(struct menu *menu)
527{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700528 enum prop_type type;
529
530 if (rootEntry == menu)
531 return;
532 type = menu && menu->prompt ? menu->prompt->type : P_UNKNOWN;
533 if (type != P_MENU)
534 return;
535 updateMenuList(this, 0);
536 rootEntry = menu;
537 updateListAll();
538 if (currentItem()) {
539 currentItem()->setSelected(hasFocus());
540 scrollToItem(currentItem());
541 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700542}
543
544void ConfigList::setParentMenu(void)
545{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700546 ConfigItem* item;
547 struct menu *oldroot;
548
549 oldroot = rootEntry;
550 if (rootEntry == &rootmenu)
551 return;
552 setRootMenu(menu_get_parent_menu(rootEntry->parent));
553
554 QTreeWidgetItemIterator it(this);
555 while (*it) {
556 item = (ConfigItem *)(*it);
557 if (item->menu == oldroot) {
558 setCurrentItem(item);
559 scrollToItem(item);
560 break;
561 }
562
563 ++it;
564 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700565}
566
567/*
568 * update all the children of a menu entry
569 * removes/adds the entries from the parent widget as necessary
570 *
571 * parent: either the menu list widget or a menu entry widget
572 * menu: entry to be updated
573 */
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700574void ConfigList::updateMenuList(ConfigItem *parent, struct menu* menu)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700575{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700576 struct menu* child;
577 ConfigItem* item;
578 ConfigItem* last;
579 bool visible;
580 enum prop_type type;
581
582 if (!menu) {
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700583 while (parent->childCount() > 0)
584 {
585 delete parent->takeChild(0);
586 }
587
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700588 return;
589 }
590
591 last = parent->firstChild();
592 if (last && !last->goParent)
593 last = 0;
594 for (child = menu->list; child; child = child->next) {
595 item = last ? last->nextSibling() : parent->firstChild();
596 type = child->prompt ? child->prompt->type : P_UNKNOWN;
597
598 switch (mode) {
599 case menuMode:
600 if (!(child->flags & MENU_ROOT))
601 goto hide;
602 break;
603 case symbolMode:
604 if (child->flags & MENU_ROOT)
605 goto hide;
606 break;
607 default:
608 break;
609 }
610
611 visible = menu_is_visible(child);
612 if (!menuSkip(child)) {
613 if (!child->sym && !child->list && !child->prompt)
614 continue;
615 if (!item || item->menu != child)
616 item = new ConfigItem(parent, last, child, visible);
617 else
618 item->testUpdateMenu(visible);
619
620 if (mode == fullMode || mode == menuMode || type != P_MENU)
621 updateMenuList(item, child);
622 else
623 updateMenuList(item, 0);
624 last = item;
625 continue;
626 }
627 hide:
628 if (item && item->menu == child) {
629 last = parent->firstChild();
630 if (last == item)
631 last = 0;
632 else while (last->nextSibling() != item)
633 last = last->nextSibling();
634 delete item;
635 }
636 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700637}
638
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700639void ConfigList::updateMenuList(ConfigList *parent, struct menu* menu)
640{
641 struct menu* child;
642 ConfigItem* item;
643 ConfigItem* last;
644 bool visible;
645 enum prop_type type;
646
647 if (!menu) {
648 while (parent->topLevelItemCount() > 0)
649 {
650 delete parent->takeTopLevelItem(0);
651 }
652
653 return;
654 }
655
656 last = (ConfigItem*)parent->topLevelItem(0);
657 if (last && !last->goParent)
658 last = 0;
659 for (child = menu->list; child; child = child->next) {
660 item = last ? last->nextSibling() : (ConfigItem*)parent->topLevelItem(0);
661 type = child->prompt ? child->prompt->type : P_UNKNOWN;
662
663 switch (mode) {
664 case menuMode:
665 if (!(child->flags & MENU_ROOT))
666 goto hide;
667 break;
668 case symbolMode:
669 if (child->flags & MENU_ROOT)
670 goto hide;
671 break;
672 default:
673 break;
674 }
675
676 visible = menu_is_visible(child);
677 if (!menuSkip(child)) {
678 if (!child->sym && !child->list && !child->prompt)
679 continue;
680 if (!item || item->menu != child)
681 item = new ConfigItem(parent, last, child, visible);
682 else
683 item->testUpdateMenu(visible);
684
685 if (mode == fullMode || mode == menuMode || type != P_MENU)
686 updateMenuList(item, child);
687 else
688 updateMenuList(item, 0);
689 last = item;
690 continue;
691 }
692 hide:
693 if (item && item->menu == child) {
694 last = (ConfigItem*)parent->topLevelItem(0);
695 if (last == item)
696 last = 0;
697 else while (last->nextSibling() != item)
698 last = last->nextSibling();
699 delete item;
700 }
701 }
702}
703
Boris Barbulovski59e56442015-09-22 11:36:18 -0700704void ConfigList::keyPressEvent(QKeyEvent* ev)
705{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700706 QTreeWidgetItem* i = currentItem();
707 ConfigItem* item;
708 struct menu *menu;
709 enum prop_type type;
710
711 if (ev->key() == Qt::Key_Escape && mode != fullMode && mode != listMode) {
712 emit parentSelected();
713 ev->accept();
714 return;
715 }
716
717 if (!i) {
718 Parent::keyPressEvent(ev);
719 return;
720 }
721 item = (ConfigItem*)i;
722
723 switch (ev->key()) {
724 case Qt::Key_Return:
725 case Qt::Key_Enter:
726 if (item->goParent) {
727 emit parentSelected();
728 break;
729 }
730 menu = item->menu;
731 if (!menu)
732 break;
733 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
734 if (type == P_MENU && rootEntry != menu &&
735 mode != fullMode && mode != menuMode) {
736 emit menuSelected(menu);
737 break;
738 }
739 case Qt::Key_Space:
740 changeValue(item);
741 break;
742 case Qt::Key_N:
743 setValue(item, no);
744 break;
745 case Qt::Key_M:
746 setValue(item, mod);
747 break;
748 case Qt::Key_Y:
749 setValue(item, yes);
750 break;
751 default:
752 Parent::keyPressEvent(ev);
753 return;
754 }
755 ev->accept();
Boris Barbulovski59e56442015-09-22 11:36:18 -0700756}
757
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700758void ConfigList::mousePressEvent(QMouseEvent* e)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700759{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700760 //QPoint p(contentsToViewport(e->pos()));
761 //printf("contentsMousePressEvent: %d,%d\n", p.x(), p.y());
762 Parent::mousePressEvent(e);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700763}
764
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700765void ConfigList::mouseReleaseEvent(QMouseEvent* e)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700766{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700767 QPoint p = e->pos();
768 ConfigItem* item = (ConfigItem*)itemAt(p);
769 struct menu *menu;
770 enum prop_type ptype;
771 QIcon icon;
772 int idx, x;
773
774 if (!item)
775 goto skip;
776
777 menu = item->menu;
778 x = header()->offset() + p.x();
Boris Barbulovski76d53cb2015-09-22 11:36:35 -0700779 idx = header()->logicalIndexAt(x);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700780 switch (idx) {
781 case promptColIdx:
782 icon = item->pixmap(promptColIdx);
Boris Barbulovski76d53cb2015-09-22 11:36:35 -0700783 if (!icon.isNull()) {
784 int off = header()->sectionPosition(0) + visualRect(indexAt(p)).x() + 4; // 4 is Hardcoded image offset. There might be a way to do it properly.
785 if (x >= off && x < off + icon.availableSizes().first().width()) {
786 if (item->goParent) {
787 emit parentSelected();
788 break;
789 } else if (!menu)
790 break;
791 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
792 if (ptype == P_MENU && rootEntry != menu &&
793 mode != fullMode && mode != menuMode)
794 emit menuSelected(menu);
795 else
796 changeValue(item);
797 }
798 }
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700799 break;
800 case noColIdx:
801 setValue(item, no);
802 break;
803 case modColIdx:
804 setValue(item, mod);
805 break;
806 case yesColIdx:
807 setValue(item, yes);
808 break;
809 case dataColIdx:
810 changeValue(item);
811 break;
812 }
813
814skip:
815 //printf("contentsMouseReleaseEvent: %d,%d\n", p.x(), p.y());
816 Parent::mouseReleaseEvent(e);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700817}
818
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700819void ConfigList::mouseMoveEvent(QMouseEvent* e)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700820{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700821 //QPoint p(contentsToViewport(e->pos()));
822 //printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y());
823 Parent::mouseMoveEvent(e);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700824}
825
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700826void ConfigList::mouseDoubleClickEvent(QMouseEvent* e)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700827{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700828 QPoint p = e->pos(); // TODO: Check if this works(was contentsToViewport).
829 ConfigItem* item = (ConfigItem*)itemAt(p);
830 struct menu *menu;
831 enum prop_type ptype;
832
833 if (!item)
834 goto skip;
835 if (item->goParent) {
836 emit parentSelected();
837 goto skip;
838 }
839 menu = item->menu;
840 if (!menu)
841 goto skip;
842 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
843 if (ptype == P_MENU && (mode == singleMode || mode == symbolMode))
844 emit menuSelected(menu);
845 else if (menu->sym)
846 changeValue(item);
847
848skip:
849 //printf("contentsMouseDoubleClickEvent: %d,%d\n", p.x(), p.y());
850 Parent::mouseDoubleClickEvent(e);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700851}
852
853void ConfigList::focusInEvent(QFocusEvent *e)
854{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700855 struct menu *menu = NULL;
856
857 Parent::focusInEvent(e);
858
859 ConfigItem* item = (ConfigItem *)currentItem();
860 if (item) {
861 item->setSelected(true);
862 menu = item->menu;
863 }
864 emit gotFocus(menu);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700865}
866
867void ConfigList::contextMenuEvent(QContextMenuEvent *e)
868{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700869 if (e->y() <= header()->geometry().bottom()) {
870 if (!headerPopup) {
871 QAction *action;
872
873 headerPopup = new QMenu(this);
874 action = new QAction(_("Show Name"), this);
875 action->setCheckable(true);
876 connect(action, SIGNAL(toggled(bool)),
877 parent(), SLOT(setShowName(bool)));
878 connect(parent(), SIGNAL(showNameChanged(bool)),
879 action, SLOT(setOn(bool)));
880 action->setChecked(showName);
881 headerPopup->addAction(action);
882 action = new QAction(_("Show Range"), this);
883 action->setCheckable(true);
884 connect(action, SIGNAL(toggled(bool)),
885 parent(), SLOT(setShowRange(bool)));
886 connect(parent(), SIGNAL(showRangeChanged(bool)),
887 action, SLOT(setOn(bool)));
888 action->setChecked(showRange);
889 headerPopup->addAction(action);
890 action = new QAction(_("Show Data"), this);
891 action->setCheckable(true);
892 connect(action, SIGNAL(toggled(bool)),
893 parent(), SLOT(setShowData(bool)));
894 connect(parent(), SIGNAL(showDataChanged(bool)),
895 action, SLOT(setOn(bool)));
896 action->setChecked(showData);
897 headerPopup->addAction(action);
898 }
899 headerPopup->exec(e->globalPos());
900 e->accept();
901 } else
902 e->ignore();
Boris Barbulovski59e56442015-09-22 11:36:18 -0700903}
904
Li Zefan39a48972010-05-10 16:33:41 +0800905ConfigView*ConfigView::viewList;
906QAction *ConfigView::showNormalAction;
907QAction *ConfigView::showAllAction;
908QAction *ConfigView::showPromptAction;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700909
Roman Zippel7fc925f2006-06-08 22:12:46 -0700910ConfigView::ConfigView(QWidget* parent, const char *name)
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -0700911 : Parent(parent)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700912{
Boris Barbulovski9bd36ed2015-09-22 11:36:22 -0700913 setObjectName(name);
Boris Barbulovski29a70162015-09-22 11:36:10 -0700914 QVBoxLayout *verticalLayout = new QVBoxLayout(this);
Boris Barbulovski92298b42015-09-22 11:36:11 -0700915 verticalLayout->setContentsMargins(0, 0, 0, 0);
Boris Barbulovski29a70162015-09-22 11:36:10 -0700916
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700917 list = new ConfigList(this);
Boris Barbulovski29a70162015-09-22 11:36:10 -0700918 verticalLayout->addWidget(list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700919 lineEdit = new ConfigLineEdit(this);
920 lineEdit->hide();
Boris Barbulovski29a70162015-09-22 11:36:10 -0700921 verticalLayout->addWidget(lineEdit);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700922
923 this->nextView = viewList;
924 viewList = this;
925}
926
927ConfigView::~ConfigView(void)
928{
929 ConfigView** vp;
930
931 for (vp = &viewList; *vp; vp = &(*vp)->nextView) {
932 if (*vp == this) {
933 *vp = nextView;
934 break;
935 }
936 }
937}
938
Li Zefan39a48972010-05-10 16:33:41 +0800939void ConfigView::setOptionMode(QAction *act)
Roman Zippel7fc925f2006-06-08 22:12:46 -0700940{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700941 if (act == showNormalAction)
942 list->optMode = normalOpt;
943 else if (act == showAllAction)
944 list->optMode = allOpt;
945 else
946 list->optMode = promptOpt;
947
948 list->updateListAll();
Roman Zippel7fc925f2006-06-08 22:12:46 -0700949}
950
951void ConfigView::setShowName(bool b)
952{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700953 if (list->showName != b) {
954 list->showName = b;
955 list->reinit();
956 emit showNameChanged(b);
957 }
Roman Zippel7fc925f2006-06-08 22:12:46 -0700958}
959
960void ConfigView::setShowRange(bool b)
961{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700962 if (list->showRange != b) {
963 list->showRange = b;
964 list->reinit();
965 emit showRangeChanged(b);
966 }
Roman Zippel7fc925f2006-06-08 22:12:46 -0700967}
968
969void ConfigView::setShowData(bool b)
970{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700971 if (list->showData != b) {
972 list->showData = b;
973 list->reinit();
974 emit showDataChanged(b);
975 }
976}
977
978void ConfigList::setAllOpen(bool open)
979{
980 QTreeWidgetItemIterator it(this);
981
982 while (*it) {
983 (*it)->setExpanded(open);
984
985 ++it;
986 }
Roman Zippel7fc925f2006-06-08 22:12:46 -0700987}
988
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700989void ConfigView::updateList(ConfigItem* item)
Roman Zippel7fc925f2006-06-08 22:12:46 -0700990{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700991 ConfigView* v;
992
993 for (v = viewList; v; v = v->nextView)
994 v->list->updateList(item);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700995}
996
997void ConfigView::updateListAll(void)
998{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700999 ConfigView* v;
1000
1001 for (v = viewList; v; v = v->nextView)
1002 v->list->updateListAll();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001003}
1004
Roman Zippel43bf6122006-06-08 22:12:45 -07001005ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name)
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001006 : Parent(parent), sym(0), _menu(0)
Roman Zippel43bf6122006-06-08 22:12:45 -07001007{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001008 setObjectName(name);
1009
1010
1011 if (!objectName().isEmpty()) {
1012 configSettings->beginGroup(objectName());
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001013 _showDebug = configSettings->value("/showDebug", false).toBool();
Roman Zippel7fc925f2006-06-08 22:12:46 -07001014 configSettings->endGroup();
1015 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
1016 }
1017}
1018
1019void ConfigInfoView::saveSettings(void)
1020{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001021 if (!objectName().isEmpty()) {
1022 configSettings->beginGroup(objectName());
1023 configSettings->setValue("/showDebug", showDebug());
1024 configSettings->endGroup();
1025 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001026}
1027
1028void ConfigInfoView::setShowDebug(bool b)
1029{
1030 if (_showDebug != b) {
1031 _showDebug = b;
Alexander Stein133c5f72010-08-31 17:34:37 +02001032 if (_menu)
Roman Zippel43bf6122006-06-08 22:12:45 -07001033 menuInfo();
Roman Zippelab45d192006-06-08 22:12:47 -07001034 else if (sym)
1035 symbolInfo();
Roman Zippel43bf6122006-06-08 22:12:45 -07001036 emit showDebugChanged(b);
1037 }
1038}
1039
1040void ConfigInfoView::setInfo(struct menu *m)
1041{
Alexander Stein133c5f72010-08-31 17:34:37 +02001042 if (_menu == m)
Roman Zippelb65a47e2006-06-08 22:12:47 -07001043 return;
Alexander Stein133c5f72010-08-31 17:34:37 +02001044 _menu = m;
Roman Zippel6fa1da82007-01-10 23:15:31 -08001045 sym = NULL;
Alexander Stein133c5f72010-08-31 17:34:37 +02001046 if (!_menu)
Roman Zippel43bf6122006-06-08 22:12:45 -07001047 clear();
Roman Zippel6fa1da82007-01-10 23:15:31 -08001048 else
Roman Zippel43bf6122006-06-08 22:12:45 -07001049 menuInfo();
1050}
1051
Roman Zippelab45d192006-06-08 22:12:47 -07001052void ConfigInfoView::symbolInfo(void)
1053{
1054 QString str;
1055
1056 str += "<big>Symbol: <b>";
1057 str += print_filter(sym->name);
1058 str += "</b></big><br><br>value: ";
1059 str += print_filter(sym_get_string_value(sym));
1060 str += "<br>visibility: ";
1061 str += sym->visible == yes ? "y" : sym->visible == mod ? "m" : "n";
1062 str += "<br>";
1063 str += debug_info(sym);
1064
1065 setText(str);
1066}
1067
Roman Zippel43bf6122006-06-08 22:12:45 -07001068void ConfigInfoView::menuInfo(void)
1069{
1070 struct symbol* sym;
1071 QString head, debug, help;
1072
Alexander Stein133c5f72010-08-31 17:34:37 +02001073 sym = _menu->sym;
Roman Zippel43bf6122006-06-08 22:12:45 -07001074 if (sym) {
Alexander Stein133c5f72010-08-31 17:34:37 +02001075 if (_menu->prompt) {
Roman Zippel43bf6122006-06-08 22:12:45 -07001076 head += "<big><b>";
Alexander Stein133c5f72010-08-31 17:34:37 +02001077 head += print_filter(_(_menu->prompt->text));
Roman Zippel43bf6122006-06-08 22:12:45 -07001078 head += "</b></big>";
1079 if (sym->name) {
1080 head += " (";
Roman Zippelab45d192006-06-08 22:12:47 -07001081 if (showDebug())
1082 head += QString().sprintf("<a href=\"s%p\">", sym);
Roman Zippel43bf6122006-06-08 22:12:45 -07001083 head += print_filter(sym->name);
Roman Zippelab45d192006-06-08 22:12:47 -07001084 if (showDebug())
1085 head += "</a>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001086 head += ")";
1087 }
1088 } else if (sym->name) {
1089 head += "<big><b>";
Roman Zippelab45d192006-06-08 22:12:47 -07001090 if (showDebug())
1091 head += QString().sprintf("<a href=\"s%p\">", sym);
Roman Zippel43bf6122006-06-08 22:12:45 -07001092 head += print_filter(sym->name);
Roman Zippelab45d192006-06-08 22:12:47 -07001093 if (showDebug())
1094 head += "</a>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001095 head += "</b></big>";
1096 }
1097 head += "<br><br>";
1098
1099 if (showDebug())
1100 debug = debug_info(sym);
1101
Cheng Renquand74c15f2009-07-12 16:11:47 +08001102 struct gstr help_gstr = str_new();
Alexander Stein133c5f72010-08-31 17:34:37 +02001103 menu_get_ext_help(_menu, &help_gstr);
Cheng Renquand74c15f2009-07-12 16:11:47 +08001104 help = print_filter(str_get(&help_gstr));
1105 str_free(&help_gstr);
Alexander Stein133c5f72010-08-31 17:34:37 +02001106 } else if (_menu->prompt) {
Roman Zippel43bf6122006-06-08 22:12:45 -07001107 head += "<big><b>";
Alexander Stein133c5f72010-08-31 17:34:37 +02001108 head += print_filter(_(_menu->prompt->text));
Roman Zippel43bf6122006-06-08 22:12:45 -07001109 head += "</b></big><br><br>";
1110 if (showDebug()) {
Alexander Stein133c5f72010-08-31 17:34:37 +02001111 if (_menu->prompt->visible.expr) {
Roman Zippel43bf6122006-06-08 22:12:45 -07001112 debug += "&nbsp;&nbsp;dep: ";
Alexander Stein133c5f72010-08-31 17:34:37 +02001113 expr_print(_menu->prompt->visible.expr, expr_print_help, &debug, E_NONE);
Roman Zippel43bf6122006-06-08 22:12:45 -07001114 debug += "<br><br>";
1115 }
1116 }
1117 }
1118 if (showDebug())
Alexander Stein133c5f72010-08-31 17:34:37 +02001119 debug += QString().sprintf("defined at %s:%d<br><br>", _menu->file->name, _menu->lineno);
Roman Zippel43bf6122006-06-08 22:12:45 -07001120
1121 setText(head + debug + help);
1122}
1123
1124QString ConfigInfoView::debug_info(struct symbol *sym)
1125{
1126 QString debug;
1127
1128 debug += "type: ";
1129 debug += print_filter(sym_type_name(sym->type));
1130 if (sym_is_choice(sym))
1131 debug += " (choice)";
1132 debug += "<br>";
1133 if (sym->rev_dep.expr) {
1134 debug += "reverse dep: ";
1135 expr_print(sym->rev_dep.expr, expr_print_help, &debug, E_NONE);
1136 debug += "<br>";
1137 }
1138 for (struct property *prop = sym->prop; prop; prop = prop->next) {
1139 switch (prop->type) {
1140 case P_PROMPT:
1141 case P_MENU:
Roman Zippelab45d192006-06-08 22:12:47 -07001142 debug += QString().sprintf("prompt: <a href=\"m%p\">", prop->menu);
Roman Zippel43bf6122006-06-08 22:12:45 -07001143 debug += print_filter(_(prop->text));
Roman Zippelab45d192006-06-08 22:12:47 -07001144 debug += "</a><br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001145 break;
1146 case P_DEFAULT:
Roman Zippel93449082008-01-14 04:50:54 +01001147 case P_SELECT:
1148 case P_RANGE:
1149 case P_ENV:
1150 debug += prop_get_type_name(prop->type);
1151 debug += ": ";
Roman Zippel43bf6122006-06-08 22:12:45 -07001152 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1153 debug += "<br>";
1154 break;
1155 case P_CHOICE:
1156 if (sym_is_choice(sym)) {
1157 debug += "choice: ";
1158 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1159 debug += "<br>";
1160 }
1161 break;
Roman Zippel43bf6122006-06-08 22:12:45 -07001162 default:
1163 debug += "unknown property: ";
1164 debug += prop_get_type_name(prop->type);
1165 debug += "<br>";
1166 }
1167 if (prop->visible.expr) {
1168 debug += "&nbsp;&nbsp;&nbsp;&nbsp;dep: ";
1169 expr_print(prop->visible.expr, expr_print_help, &debug, E_NONE);
1170 debug += "<br>";
1171 }
1172 }
1173 debug += "<br>";
1174
1175 return debug;
1176}
1177
1178QString ConfigInfoView::print_filter(const QString &str)
1179{
1180 QRegExp re("[<>&\"\\n]");
1181 QString res = str;
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001182 for (int i = 0; (i = res.indexOf(re, i)) >= 0;) {
1183 switch (res[i].toLatin1()) {
Roman Zippel43bf6122006-06-08 22:12:45 -07001184 case '<':
1185 res.replace(i, 1, "&lt;");
1186 i += 4;
1187 break;
1188 case '>':
1189 res.replace(i, 1, "&gt;");
1190 i += 4;
1191 break;
1192 case '&':
1193 res.replace(i, 1, "&amp;");
1194 i += 5;
1195 break;
1196 case '"':
1197 res.replace(i, 1, "&quot;");
1198 i += 6;
1199 break;
1200 case '\n':
1201 res.replace(i, 1, "<br>");
1202 i += 4;
1203 break;
1204 }
1205 }
1206 return res;
1207}
1208
Roman Zippelab45d192006-06-08 22:12:47 -07001209void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char *str)
Roman Zippel43bf6122006-06-08 22:12:45 -07001210{
Roman Zippelab45d192006-06-08 22:12:47 -07001211 QString* text = reinterpret_cast<QString*>(data);
1212 QString str2 = print_filter(str);
1213
1214 if (sym && sym->name && !(sym->flags & SYMBOL_CONST)) {
1215 *text += QString().sprintf("<a href=\"s%p\">", sym);
1216 *text += str2;
1217 *text += "</a>";
1218 } else
1219 *text += str2;
Roman Zippel43bf6122006-06-08 22:12:45 -07001220}
1221
Boris Barbulovski924bbb52015-09-22 11:36:06 -07001222QMenu* ConfigInfoView::createStandardContextMenu(const QPoint & pos)
Roman Zippel7fc925f2006-06-08 22:12:46 -07001223{
Boris Barbulovski924bbb52015-09-22 11:36:06 -07001224 QMenu* popup = Parent::createStandardContextMenu(pos);
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001225 QAction* action = new QAction(_("Show Debug Info"), popup);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001226 action->setCheckable(true);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001227 connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
1228 connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool)));
Boris Barbulovski9c862352015-09-22 11:36:12 -07001229 action->setChecked(showDebug());
Boris Barbulovski924bbb52015-09-22 11:36:06 -07001230 popup->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001231 popup->addAction(action);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001232 return popup;
1233}
1234
Boris Barbulovski924bbb52015-09-22 11:36:06 -07001235void ConfigInfoView::contextMenuEvent(QContextMenuEvent *e)
Roman Zippel7fc925f2006-06-08 22:12:46 -07001236{
Boris Barbulovski924bbb52015-09-22 11:36:06 -07001237 Parent::contextMenuEvent(e);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001238}
1239
Marco Costalba63431e72006-10-05 19:12:59 +02001240ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow* parent, const char *name)
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001241 : Parent(parent), result(NULL)
Roman Zippel43bf6122006-06-08 22:12:45 -07001242{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001243 setObjectName(name);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001244 setWindowTitle("Search Config");
Roman Zippel43bf6122006-06-08 22:12:45 -07001245
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001246 QVBoxLayout* layout1 = new QVBoxLayout(this);
1247 layout1->setContentsMargins(11, 11, 11, 11);
1248 layout1->setSpacing(6);
1249 QHBoxLayout* layout2 = new QHBoxLayout(0);
1250 layout2->setContentsMargins(0, 0, 0, 0);
1251 layout2->setSpacing(6);
EGRY Gaborc21a2d92008-01-11 23:52:07 +01001252 layout2->addWidget(new QLabel(_("Find:"), this));
Roman Zippel43bf6122006-06-08 22:12:45 -07001253 editField = new QLineEdit(this);
1254 connect(editField, SIGNAL(returnPressed()), SLOT(search()));
1255 layout2->addWidget(editField);
EGRY Gaborc21a2d92008-01-11 23:52:07 +01001256 searchButton = new QPushButton(_("Search"), this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001257 searchButton->setAutoDefault(false);
Roman Zippel43bf6122006-06-08 22:12:45 -07001258 connect(searchButton, SIGNAL(clicked()), SLOT(search()));
1259 layout2->addWidget(searchButton);
1260 layout1->addLayout(layout2);
1261
Roman Zippel7fc925f2006-06-08 22:12:46 -07001262 split = new QSplitter(this);
Markus Heidelberg7298b932009-05-18 01:36:50 +02001263 split->setOrientation(Qt::Vertical);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001264 list = new ConfigView(split, name);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001265 list->list->mode = listMode;
Roman Zippel7fc925f2006-06-08 22:12:46 -07001266 info = new ConfigInfoView(split, name);
Roman Zippel43bf6122006-06-08 22:12:45 -07001267 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1268 info, SLOT(setInfo(struct menu *)));
Marco Costalba63431e72006-10-05 19:12:59 +02001269 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1270 parent, SLOT(setMenuLink(struct menu *)));
1271
Roman Zippel43bf6122006-06-08 22:12:45 -07001272 layout1->addWidget(split);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001273
1274 if (name) {
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001275 QVariant x, y;
1276 int width, height;
Roman Zippel7fc925f2006-06-08 22:12:46 -07001277 bool ok;
1278
1279 configSettings->beginGroup(name);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001280 width = configSettings->value("/window width", parent->width() / 2).toInt();
1281 height = configSettings->value("/window height", parent->height() / 2).toInt();
Roman Zippel7fc925f2006-06-08 22:12:46 -07001282 resize(width, height);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001283 x = configSettings->value("/window x");
1284 y = configSettings->value("/window y");
1285 if ((x.isValid())&&(y.isValid()))
1286 move(x.toInt(), y.toInt());
Boris Barbulovski041fbdc2015-09-22 11:36:05 -07001287 QList<int> sizes = configSettings->readSizes("/split", &ok);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001288 if (ok)
1289 split->setSizes(sizes);
1290 configSettings->endGroup();
1291 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
1292 }
1293}
1294
1295void ConfigSearchWindow::saveSettings(void)
1296{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001297 if (!objectName().isEmpty()) {
1298 configSettings->beginGroup(objectName());
1299 configSettings->setValue("/window x", pos().x());
1300 configSettings->setValue("/window y", pos().y());
1301 configSettings->setValue("/window width", size().width());
1302 configSettings->setValue("/window height", size().height());
1303 configSettings->writeSizes("/split", split->sizes());
1304 configSettings->endGroup();
1305 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001306}
1307
1308void ConfigSearchWindow::search(void)
1309{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001310 struct symbol **p;
1311 struct property *prop;
1312 ConfigItem *lastItem = NULL;
1313
1314 free(result);
1315 list->list->clear();
1316 info->clear();
1317
1318 result = sym_re_search(editField->text().toLatin1());
1319 if (!result)
1320 return;
1321 for (p = result; *p; p++) {
1322 for_all_prompts((*p), prop)
1323 lastItem = new ConfigItem(list->list, lastItem, prop->menu,
1324 menu_is_visible(prop->menu));
1325 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001326}
1327
Linus Torvalds1da177e2005-04-16 15:20:36 -07001328/*
1329 * Construct the complete config widget
1330 */
1331ConfigMainWindow::ConfigMainWindow(void)
Roman Zippelf12aa702006-11-25 11:09:31 -08001332 : searchWindow(0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001333{
1334 QMenuBar* menu;
Boris Barbulovski92119932015-09-22 11:36:16 -07001335 bool ok = true;
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001336 QVariant x, y;
1337 int width, height;
Randy Dunlapa54bb702007-10-20 11:18:47 -07001338 char title[256];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001339
Markus Heidelberg8d90c972009-05-18 01:36:52 +02001340 QDesktopWidget *d = configApp->desktop();
Arnaud Lacombe09548282010-08-18 01:57:13 -04001341 snprintf(title, sizeof(title), "%s%s",
1342 rootmenu.prompt->text,
Michal Marek76a136c2010-09-01 17:39:27 +02001343 ""
Michal Marek76a136c2010-09-01 17:39:27 +02001344 );
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001345 setWindowTitle(title);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001346
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001347 width = configSettings->value("/window width", d->width() - 64).toInt();
1348 height = configSettings->value("/window height", d->height() - 64).toInt();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001349 resize(width, height);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001350 x = configSettings->value("/window x");
1351 y = configSettings->value("/window y");
1352 if ((x.isValid())&&(y.isValid()))
1353 move(x.toInt(), y.toInt());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001354
1355 split1 = new QSplitter(this);
Markus Heidelberg7298b932009-05-18 01:36:50 +02001356 split1->setOrientation(Qt::Horizontal);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001357 setCentralWidget(split1);
1358
Roman Zippel7fc925f2006-06-08 22:12:46 -07001359 menuView = new ConfigView(split1, "menu");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001360 menuList = menuView->list;
1361
1362 split2 = new QSplitter(split1);
Markus Heidelberg7298b932009-05-18 01:36:50 +02001363 split2->setOrientation(Qt::Vertical);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001364
1365 // create config tree
Roman Zippel7fc925f2006-06-08 22:12:46 -07001366 configView = new ConfigView(split2, "config");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001367 configList = configView->list;
1368
Roman Zippel7fc925f2006-06-08 22:12:46 -07001369 helpText = new ConfigInfoView(split2, "help");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001370
1371 setTabOrder(configList, helpText);
1372 configList->setFocus();
1373
1374 menu = menuBar();
Boris Barbulovskib1f8a452015-09-22 11:36:02 -07001375 toolBar = new QToolBar("Tools", this);
Boris Barbulovski29a70162015-09-22 11:36:10 -07001376 addToolBar(toolBar);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001377
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001378 backAction = new QAction(QPixmap(xpm_back), _("Back"), this);
Boris Barbulovski92119932015-09-22 11:36:16 -07001379 connect(backAction, SIGNAL(triggered(bool)), SLOT(goBack()));
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001380 backAction->setEnabled(false);
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001381 QAction *quitAction = new QAction(_("&Quit"), this);
1382 quitAction->setShortcut(Qt::CTRL + Qt::Key_Q);
Boris Barbulovski92119932015-09-22 11:36:16 -07001383 connect(quitAction, SIGNAL(triggered(bool)), SLOT(close()));
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001384 QAction *loadAction = new QAction(QPixmap(xpm_load), _("&Load"), this);
1385 loadAction->setShortcut(Qt::CTRL + Qt::Key_L);
Boris Barbulovski92119932015-09-22 11:36:16 -07001386 connect(loadAction, SIGNAL(triggered(bool)), SLOT(loadConfig()));
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001387 saveAction = new QAction(QPixmap(xpm_save), _("&Save"), this);
1388 saveAction->setShortcut(Qt::CTRL + Qt::Key_S);
Boris Barbulovski92119932015-09-22 11:36:16 -07001389 connect(saveAction, SIGNAL(triggered(bool)), SLOT(saveConfig()));
Karsten Wiese3b354c552006-12-13 00:34:08 -08001390 conf_set_changed_callback(conf_changed);
1391 // Set saveAction's initial state
1392 conf_changed();
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001393 QAction *saveAsAction = new QAction(_("Save &As..."), this);
Boris Barbulovski92119932015-09-22 11:36:16 -07001394 connect(saveAsAction, SIGNAL(triggered(bool)), SLOT(saveConfigAs()));
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001395 QAction *searchAction = new QAction(_("&Find"), this);
1396 searchAction->setShortcut(Qt::CTRL + Qt::Key_F);
Boris Barbulovski92119932015-09-22 11:36:16 -07001397 connect(searchAction, SIGNAL(triggered(bool)), SLOT(searchConfig()));
Boris Barbulovski780505e2015-09-22 11:36:13 -07001398 singleViewAction = new QAction(QPixmap(xpm_single_view), _("Single View"), this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001399 singleViewAction->setCheckable(true);
Boris Barbulovski92119932015-09-22 11:36:16 -07001400 connect(singleViewAction, SIGNAL(triggered(bool)), SLOT(showSingleView()));
Boris Barbulovski780505e2015-09-22 11:36:13 -07001401 splitViewAction = new QAction(QPixmap(xpm_split_view), _("Split View"), this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001402 splitViewAction->setCheckable(true);
Boris Barbulovski92119932015-09-22 11:36:16 -07001403 connect(splitViewAction, SIGNAL(triggered(bool)), SLOT(showSplitView()));
Boris Barbulovski780505e2015-09-22 11:36:13 -07001404 fullViewAction = new QAction(QPixmap(xpm_tree_view), _("Full View"), this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001405 fullViewAction->setCheckable(true);
Boris Barbulovski92119932015-09-22 11:36:16 -07001406 connect(fullViewAction, SIGNAL(triggered(bool)), SLOT(showFullView()));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001407
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001408 QAction *showNameAction = new QAction(_("Show Name"), this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001409 showNameAction->setCheckable(true);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001410 connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool)));
Boris Barbulovski9c862352015-09-22 11:36:12 -07001411 showNameAction->setChecked(configView->showName());
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001412 QAction *showRangeAction = new QAction(_("Show Range"), this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001413 showRangeAction->setCheckable(true);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001414 connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool)));
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001415 QAction *showDataAction = new QAction(_("Show Data"), this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001416 showDataAction->setCheckable(true);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001417 connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool)));
Li Zefan39a48972010-05-10 16:33:41 +08001418
1419 QActionGroup *optGroup = new QActionGroup(this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001420 optGroup->setExclusive(true);
Boris Barbulovski92119932015-09-22 11:36:16 -07001421 connect(optGroup, SIGNAL(triggered(QAction*)), configView,
Li Zefan39a48972010-05-10 16:33:41 +08001422 SLOT(setOptionMode(QAction *)));
Boris Barbulovski92119932015-09-22 11:36:16 -07001423 connect(optGroup, SIGNAL(triggered(QAction *)), menuView,
Li Zefan39a48972010-05-10 16:33:41 +08001424 SLOT(setOptionMode(QAction *)));
1425
Alexander Stein133c5f72010-08-31 17:34:37 +02001426 configView->showNormalAction = new QAction(_("Show Normal Options"), optGroup);
1427 configView->showAllAction = new QAction(_("Show All Options"), optGroup);
1428 configView->showPromptAction = new QAction(_("Show Prompt Options"), optGroup);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001429 configView->showNormalAction->setCheckable(true);
1430 configView->showAllAction->setCheckable(true);
1431 configView->showPromptAction->setCheckable(true);
Li Zefan39a48972010-05-10 16:33:41 +08001432
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001433 QAction *showDebugAction = new QAction( _("Show Debug Info"), this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001434 showDebugAction->setCheckable(true);
Roman Zippel43bf6122006-06-08 22:12:45 -07001435 connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
Boris Barbulovski9c862352015-09-22 11:36:12 -07001436 showDebugAction->setChecked(helpText->showDebug());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001437
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001438 QAction *showIntroAction = new QAction( _("Introduction"), this);
Boris Barbulovski92119932015-09-22 11:36:16 -07001439 connect(showIntroAction, SIGNAL(triggered(bool)), SLOT(showIntro()));
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001440 QAction *showAboutAction = new QAction( _("About"), this);
Boris Barbulovski92119932015-09-22 11:36:16 -07001441 connect(showAboutAction, SIGNAL(triggered(bool)), SLOT(showAbout()));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001442
1443 // init tool bar
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001444 toolBar->addAction(backAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001445 toolBar->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001446 toolBar->addAction(loadAction);
1447 toolBar->addAction(saveAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001448 toolBar->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001449 toolBar->addAction(singleViewAction);
1450 toolBar->addAction(splitViewAction);
1451 toolBar->addAction(fullViewAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001452
1453 // create config menu
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001454 QMenu* config = menu->addMenu(_("&File"));
1455 config->addAction(loadAction);
1456 config->addAction(saveAction);
1457 config->addAction(saveAsAction);
Boris Barbulovski76bede82015-09-22 11:36:07 -07001458 config->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001459 config->addAction(quitAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001460
Shlomi Fish66e7c722007-02-14 00:32:58 -08001461 // create edit menu
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001462 QMenu* editMenu = menu->addMenu(_("&Edit"));
1463 editMenu->addAction(searchAction);
Shlomi Fish66e7c722007-02-14 00:32:58 -08001464
Linus Torvalds1da177e2005-04-16 15:20:36 -07001465 // create options menu
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001466 QMenu* optionMenu = menu->addMenu(_("&Option"));
1467 optionMenu->addAction(showNameAction);
1468 optionMenu->addAction(showRangeAction);
1469 optionMenu->addAction(showDataAction);
Boris Barbulovski76bede82015-09-22 11:36:07 -07001470 optionMenu->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001471 optionMenu->addActions(optGroup->actions());
Boris Barbulovski76bede82015-09-22 11:36:07 -07001472 optionMenu->addSeparator();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001473
1474 // create help menu
Boris Barbulovski76bede82015-09-22 11:36:07 -07001475 menu->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001476 QMenu* helpMenu = menu->addMenu(_("&Help"));
1477 helpMenu->addAction(showIntroAction);
1478 helpMenu->addAction(showAboutAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001479
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001480 connect(configList, SIGNAL(menuChanged(struct menu *)),
1481 helpText, SLOT(setInfo(struct menu *)));
1482 connect(configList, SIGNAL(menuSelected(struct menu *)),
1483 SLOT(changeMenu(struct menu *)));
1484 connect(configList, SIGNAL(parentSelected()),
1485 SLOT(goBack()));
1486 connect(menuList, SIGNAL(menuChanged(struct menu *)),
1487 helpText, SLOT(setInfo(struct menu *)));
1488 connect(menuList, SIGNAL(menuSelected(struct menu *)),
1489 SLOT(changeMenu(struct menu *)));
1490
1491 connect(configList, SIGNAL(gotFocus(struct menu *)),
1492 helpText, SLOT(setInfo(struct menu *)));
1493 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1494 helpText, SLOT(setInfo(struct menu *)));
1495 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1496 SLOT(listFocusChanged(void)));
Roman Zippelb65a47e2006-06-08 22:12:47 -07001497 connect(helpText, SIGNAL(menuSelected(struct menu *)),
1498 SLOT(setMenuLink(struct menu *)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001499
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001500 QString listMode = configSettings->value("/listMode", "symbol").toString();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001501 if (listMode == "single")
1502 showSingleView();
1503 else if (listMode == "full")
1504 showFullView();
1505 else /*if (listMode == "split")*/
1506 showSplitView();
1507
1508 // UI setup done, restore splitter positions
Boris Barbulovski041fbdc2015-09-22 11:36:05 -07001509 QList<int> sizes = configSettings->readSizes("/split1", &ok);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001510 if (ok)
1511 split1->setSizes(sizes);
1512
Roman Zippel7fc925f2006-06-08 22:12:46 -07001513 sizes = configSettings->readSizes("/split2", &ok);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001514 if (ok)
1515 split2->setSizes(sizes);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001516}
1517
Linus Torvalds1da177e2005-04-16 15:20:36 -07001518void ConfigMainWindow::loadConfig(void)
1519{
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001520 QString s = QFileDialog::getOpenFileName(this, "", conf_get_configname());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001521 if (s.isNull())
1522 return;
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -07001523 if (conf_read(QFile::encodeName(s)))
EGRY Gaborc21a2d92008-01-11 23:52:07 +01001524 QMessageBox::information(this, "qconf", _("Unable to load configuration!"));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001525 ConfigView::updateListAll();
1526}
1527
Michal Marekbac6aa82011-05-25 15:10:25 +02001528bool ConfigMainWindow::saveConfig(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001529{
Michal Marekbac6aa82011-05-25 15:10:25 +02001530 if (conf_write(NULL)) {
EGRY Gaborc21a2d92008-01-11 23:52:07 +01001531 QMessageBox::information(this, "qconf", _("Unable to save configuration!"));
Michal Marekbac6aa82011-05-25 15:10:25 +02001532 return false;
1533 }
1534 return true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001535}
1536
1537void ConfigMainWindow::saveConfigAs(void)
1538{
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001539 QString s = QFileDialog::getSaveFileName(this, "", conf_get_configname());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001540 if (s.isNull())
1541 return;
Arnaud Lacombed49e4682011-05-24 14:16:18 -04001542 saveConfig();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001543}
1544
Roman Zippel43bf6122006-06-08 22:12:45 -07001545void ConfigMainWindow::searchConfig(void)
1546{
1547 if (!searchWindow)
Roman Zippel7fc925f2006-06-08 22:12:46 -07001548 searchWindow = new ConfigSearchWindow(this, "search");
Roman Zippel43bf6122006-06-08 22:12:45 -07001549 searchWindow->show();
1550}
1551
Linus Torvalds1da177e2005-04-16 15:20:36 -07001552void ConfigMainWindow::changeMenu(struct menu *menu)
1553{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001554 configList->setRootMenu(menu);
1555 if (configList->rootEntry->parent == &rootmenu)
1556 backAction->setEnabled(false);
1557 else
1558 backAction->setEnabled(true);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001559}
1560
Roman Zippelb65a47e2006-06-08 22:12:47 -07001561void ConfigMainWindow::setMenuLink(struct menu *menu)
1562{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001563 struct menu *parent;
1564 ConfigList* list = NULL;
1565 ConfigItem* item;
1566
1567 if (configList->menuSkip(menu))
1568 return;
1569
1570 switch (configList->mode) {
1571 case singleMode:
1572 list = configList;
1573 parent = menu_get_parent_menu(menu);
1574 if (!parent)
1575 return;
1576 list->setRootMenu(parent);
1577 break;
1578 case symbolMode:
1579 if (menu->flags & MENU_ROOT) {
1580 configList->setRootMenu(menu);
1581 configList->clearSelection();
1582 list = menuList;
1583 } else {
1584 list = configList;
1585 parent = menu_get_parent_menu(menu->parent);
1586 if (!parent)
1587 return;
1588 item = menuList->findConfigItem(parent);
1589 if (item) {
1590 item->setSelected(true);
1591 menuList->scrollToItem(item);
1592 }
1593 list->setRootMenu(parent);
1594 }
1595 break;
1596 case fullMode:
1597 list = configList;
1598 break;
1599 default:
1600 break;
1601 }
1602
1603 if (list) {
1604 item = list->findConfigItem(menu);
1605 if (item) {
1606 item->setSelected(true);
1607 list->scrollToItem(item);
1608 list->setFocus();
1609 }
1610 }
Roman Zippelb65a47e2006-06-08 22:12:47 -07001611}
1612
Linus Torvalds1da177e2005-04-16 15:20:36 -07001613void ConfigMainWindow::listFocusChanged(void)
1614{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001615 if (menuList->mode == menuMode)
1616 configList->clearSelection();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001617}
1618
1619void ConfigMainWindow::goBack(void)
1620{
Boris Barbulovski5df9da92015-09-22 11:36:36 -07001621 ConfigItem* item, *oldSelection;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001622
1623 configList->setParentMenu();
1624 if (configList->rootEntry == &rootmenu)
1625 backAction->setEnabled(false);
1626 item = (ConfigItem*)menuList->selectedItems().first();
Boris Barbulovski5df9da92015-09-22 11:36:36 -07001627 oldSelection = item;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001628 while (item) {
1629 if (item->menu == configList->rootEntry) {
Boris Barbulovski5df9da92015-09-22 11:36:36 -07001630 oldSelection->setSelected(false);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001631 item->setSelected(true);
1632 break;
1633 }
1634 item = (ConfigItem*)item->parent();
1635 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001636}
1637
1638void ConfigMainWindow::showSingleView(void)
1639{
Boris Barbulovski780505e2015-09-22 11:36:13 -07001640 singleViewAction->setEnabled(false);
1641 singleViewAction->setChecked(true);
1642 splitViewAction->setEnabled(true);
1643 splitViewAction->setChecked(false);
1644 fullViewAction->setEnabled(true);
1645 fullViewAction->setChecked(false);
1646
Linus Torvalds1da177e2005-04-16 15:20:36 -07001647 menuView->hide();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001648 menuList->setRootMenu(0);
1649 configList->mode = singleMode;
1650 if (configList->rootEntry == &rootmenu)
1651 configList->updateListAll();
1652 else
1653 configList->setRootMenu(&rootmenu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001654 configList->setFocus();
1655}
1656
1657void ConfigMainWindow::showSplitView(void)
1658{
Boris Barbulovski780505e2015-09-22 11:36:13 -07001659 singleViewAction->setEnabled(true);
1660 singleViewAction->setChecked(false);
1661 splitViewAction->setEnabled(false);
1662 splitViewAction->setChecked(true);
1663 fullViewAction->setEnabled(true);
1664 fullViewAction->setChecked(false);
1665
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001666 configList->mode = symbolMode;
1667 if (configList->rootEntry == &rootmenu)
1668 configList->updateListAll();
1669 else
1670 configList->setRootMenu(&rootmenu);
1671 configList->setAllOpen(true);
1672 configApp->processEvents();
1673 menuList->mode = menuMode;
1674 menuList->setRootMenu(&rootmenu);
1675 menuList->setAllOpen(true);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001676 menuView->show();
1677 menuList->setFocus();
1678}
1679
1680void ConfigMainWindow::showFullView(void)
1681{
Boris Barbulovski780505e2015-09-22 11:36:13 -07001682 singleViewAction->setEnabled(true);
1683 singleViewAction->setChecked(false);
1684 splitViewAction->setEnabled(true);
1685 splitViewAction->setChecked(false);
1686 fullViewAction->setEnabled(false);
1687 fullViewAction->setChecked(true);
1688
Linus Torvalds1da177e2005-04-16 15:20:36 -07001689 menuView->hide();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001690 menuList->setRootMenu(0);
1691 configList->mode = fullMode;
1692 if (configList->rootEntry == &rootmenu)
1693 configList->updateListAll();
1694 else
1695 configList->setRootMenu(&rootmenu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001696 configList->setFocus();
1697}
1698
Linus Torvalds1da177e2005-04-16 15:20:36 -07001699/*
1700 * ask for saving configuration before quitting
1701 * TODO ask only when something changed
1702 */
1703void ConfigMainWindow::closeEvent(QCloseEvent* e)
1704{
Karsten Wieseb3214292006-12-13 00:34:06 -08001705 if (!conf_get_changed()) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001706 e->accept();
1707 return;
1708 }
EGRY Gaborc21a2d92008-01-11 23:52:07 +01001709 QMessageBox mb("qconf", _("Save configuration?"), QMessageBox::Warning,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001710 QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape);
EGRY Gaborc21a2d92008-01-11 23:52:07 +01001711 mb.setButtonText(QMessageBox::Yes, _("&Save Changes"));
1712 mb.setButtonText(QMessageBox::No, _("&Discard Changes"));
1713 mb.setButtonText(QMessageBox::Cancel, _("Cancel Exit"));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001714 switch (mb.exec()) {
1715 case QMessageBox::Yes:
Michal Marekbac6aa82011-05-25 15:10:25 +02001716 if (saveConfig())
1717 e->accept();
1718 else
1719 e->ignore();
1720 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001721 case QMessageBox::No:
1722 e->accept();
1723 break;
1724 case QMessageBox::Cancel:
1725 e->ignore();
1726 break;
1727 }
1728}
1729
1730void ConfigMainWindow::showIntro(void)
1731{
Arnaud Lacombe652cf982010-08-14 23:51:40 -04001732 static const QString str = _("Welcome to the qconf graphical configuration tool.\n\n"
Linus Torvalds1da177e2005-04-16 15:20:36 -07001733 "For each option, a blank box indicates the feature is disabled, a check\n"
1734 "indicates it is enabled, and a dot indicates that it is to be compiled\n"
1735 "as a module. Clicking on the box will cycle through the three states.\n\n"
1736 "If you do not see an option (e.g., a device driver) that you believe\n"
1737 "should be present, try turning on Show All Options under the Options menu.\n"
1738 "Although there is no cross reference yet to help you figure out what other\n"
1739 "options must be enabled to support the option you are interested in, you can\n"
1740 "still view the help of a grayed-out option.\n\n"
1741 "Toggling Show Debug Info under the Options menu will show the dependencies,\n"
EGRY Gaborc21a2d92008-01-11 23:52:07 +01001742 "which you can then match by examining other options.\n\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001743
1744 QMessageBox::information(this, "qconf", str);
1745}
1746
1747void ConfigMainWindow::showAbout(void)
1748{
EGRY Gaborc21a2d92008-01-11 23:52:07 +01001749 static const QString str = _("qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n\n"
1750 "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001751
1752 QMessageBox::information(this, "qconf", str);
1753}
1754
1755void ConfigMainWindow::saveSettings(void)
1756{
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001757 configSettings->setValue("/window x", pos().x());
1758 configSettings->setValue("/window y", pos().y());
1759 configSettings->setValue("/window width", size().width());
1760 configSettings->setValue("/window height", size().height());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001761
1762 QString entry;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001763 switch(configList->mode) {
1764 case singleMode :
1765 entry = "single";
1766 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001767
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001768 case symbolMode :
1769 entry = "split";
1770 break;
1771
1772 case fullMode :
1773 entry = "full";
1774 break;
1775
1776 default:
1777 break;
1778 }
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001779 configSettings->setValue("/listMode", entry);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001780
Roman Zippel7fc925f2006-06-08 22:12:46 -07001781 configSettings->writeSizes("/split1", split1->sizes());
1782 configSettings->writeSizes("/split2", split2->sizes());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001783}
1784
Karsten Wiese3b354c552006-12-13 00:34:08 -08001785void ConfigMainWindow::conf_changed(void)
1786{
1787 if (saveAction)
1788 saveAction->setEnabled(conf_get_changed());
1789}
1790
Linus Torvalds1da177e2005-04-16 15:20:36 -07001791void fixup_rootmenu(struct menu *menu)
1792{
1793 struct menu *child;
1794 static int menu_cnt = 0;
1795
1796 menu->flags |= MENU_ROOT;
1797 for (child = menu->list; child; child = child->next) {
1798 if (child->prompt && child->prompt->type == P_MENU) {
1799 menu_cnt++;
1800 fixup_rootmenu(child);
1801 menu_cnt--;
1802 } else if (!menu_cnt)
1803 fixup_rootmenu(child);
1804 }
1805}
1806
1807static const char *progname;
1808
1809static void usage(void)
1810{
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001811 printf(_("%s [-s] <config>\n").toLatin1().constData(), progname);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001812 exit(0);
1813}
1814
1815int main(int ac, char** av)
1816{
1817 ConfigMainWindow* v;
1818 const char *name;
1819
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -07001820 bindtextdomain(PACKAGE, LOCALEDIR);
1821 textdomain(PACKAGE);
1822
Linus Torvalds1da177e2005-04-16 15:20:36 -07001823 progname = av[0];
1824 configApp = new QApplication(ac, av);
1825 if (ac > 1 && av[1][0] == '-') {
1826 switch (av[1][1]) {
Michal Marek0a1f00a2015-04-08 13:30:42 +02001827 case 's':
1828 conf_set_message_callback(NULL);
1829 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001830 case 'h':
1831 case '?':
1832 usage();
1833 }
1834 name = av[2];
1835 } else
1836 name = av[1];
1837 if (!name)
1838 usage();
1839
1840 conf_parse(name);
1841 fixup_rootmenu(&rootmenu);
1842 conf_read(NULL);
1843 //zconfdump(stdout);
1844
Roman Zippel7fc925f2006-06-08 22:12:46 -07001845 configSettings = new ConfigSettings();
1846 configSettings->beginGroup("/kconfig/qconf");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001847 v = new ConfigMainWindow();
1848
1849 //zconfdump(stdout);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001850 configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit()));
1851 configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings()));
Roman Zippel43bf6122006-06-08 22:12:45 -07001852 v->show();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001853 configApp->exec();
1854
Roman Zippel7fc925f2006-06-08 22:12:46 -07001855 configSettings->endGroup();
1856 delete configSettings;
1857
Linus Torvalds1da177e2005-04-16 15:20:36 -07001858 return 0;
1859}