blob: b03cfadbd9ef80b4374ddfd12694274cef5f4258 [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 Wiese3b354c52006-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 Barbulovskia52cb3212015-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();
779 idx = header()->sectionPosition(x);
780 switch (idx) {
781 case promptColIdx:
782 icon = item->pixmap(promptColIdx);
783 break;
784 case noColIdx:
785 setValue(item, no);
786 break;
787 case modColIdx:
788 setValue(item, mod);
789 break;
790 case yesColIdx:
791 setValue(item, yes);
792 break;
793 case dataColIdx:
794 changeValue(item);
795 break;
796 }
797
798skip:
799 //printf("contentsMouseReleaseEvent: %d,%d\n", p.x(), p.y());
800 Parent::mouseReleaseEvent(e);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700801}
802
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700803void ConfigList::mouseMoveEvent(QMouseEvent* e)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700804{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700805 //QPoint p(contentsToViewport(e->pos()));
806 //printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y());
807 Parent::mouseMoveEvent(e);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700808}
809
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700810void ConfigList::mouseDoubleClickEvent(QMouseEvent* e)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700811{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700812 QPoint p = e->pos(); // TODO: Check if this works(was contentsToViewport).
813 ConfigItem* item = (ConfigItem*)itemAt(p);
814 struct menu *menu;
815 enum prop_type ptype;
816
817 if (!item)
818 goto skip;
819 if (item->goParent) {
820 emit parentSelected();
821 goto skip;
822 }
823 menu = item->menu;
824 if (!menu)
825 goto skip;
826 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
827 if (ptype == P_MENU && (mode == singleMode || mode == symbolMode))
828 emit menuSelected(menu);
829 else if (menu->sym)
830 changeValue(item);
831
832skip:
833 //printf("contentsMouseDoubleClickEvent: %d,%d\n", p.x(), p.y());
834 Parent::mouseDoubleClickEvent(e);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700835}
836
837void ConfigList::focusInEvent(QFocusEvent *e)
838{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700839 struct menu *menu = NULL;
840
841 Parent::focusInEvent(e);
842
843 ConfigItem* item = (ConfigItem *)currentItem();
844 if (item) {
845 item->setSelected(true);
846 menu = item->menu;
847 }
848 emit gotFocus(menu);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700849}
850
851void ConfigList::contextMenuEvent(QContextMenuEvent *e)
852{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700853 if (e->y() <= header()->geometry().bottom()) {
854 if (!headerPopup) {
855 QAction *action;
856
857 headerPopup = new QMenu(this);
858 action = new QAction(_("Show Name"), this);
859 action->setCheckable(true);
860 connect(action, SIGNAL(toggled(bool)),
861 parent(), SLOT(setShowName(bool)));
862 connect(parent(), SIGNAL(showNameChanged(bool)),
863 action, SLOT(setOn(bool)));
864 action->setChecked(showName);
865 headerPopup->addAction(action);
866 action = new QAction(_("Show Range"), this);
867 action->setCheckable(true);
868 connect(action, SIGNAL(toggled(bool)),
869 parent(), SLOT(setShowRange(bool)));
870 connect(parent(), SIGNAL(showRangeChanged(bool)),
871 action, SLOT(setOn(bool)));
872 action->setChecked(showRange);
873 headerPopup->addAction(action);
874 action = new QAction(_("Show Data"), this);
875 action->setCheckable(true);
876 connect(action, SIGNAL(toggled(bool)),
877 parent(), SLOT(setShowData(bool)));
878 connect(parent(), SIGNAL(showDataChanged(bool)),
879 action, SLOT(setOn(bool)));
880 action->setChecked(showData);
881 headerPopup->addAction(action);
882 }
883 headerPopup->exec(e->globalPos());
884 e->accept();
885 } else
886 e->ignore();
Boris Barbulovski59e56442015-09-22 11:36:18 -0700887}
888
Li Zefan39a48972010-05-10 16:33:41 +0800889ConfigView*ConfigView::viewList;
890QAction *ConfigView::showNormalAction;
891QAction *ConfigView::showAllAction;
892QAction *ConfigView::showPromptAction;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700893
Roman Zippel7fc925f2006-06-08 22:12:46 -0700894ConfigView::ConfigView(QWidget* parent, const char *name)
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -0700895 : Parent(parent)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700896{
Boris Barbulovski9bd36ed2015-09-22 11:36:22 -0700897 setObjectName(name);
Boris Barbulovski29a70162015-09-22 11:36:10 -0700898 QVBoxLayout *verticalLayout = new QVBoxLayout(this);
Boris Barbulovski92298b42015-09-22 11:36:11 -0700899 verticalLayout->setContentsMargins(0, 0, 0, 0);
Boris Barbulovski29a70162015-09-22 11:36:10 -0700900
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700901 list = new ConfigList(this);
Boris Barbulovski29a70162015-09-22 11:36:10 -0700902 verticalLayout->addWidget(list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700903 lineEdit = new ConfigLineEdit(this);
904 lineEdit->hide();
Boris Barbulovski29a70162015-09-22 11:36:10 -0700905 verticalLayout->addWidget(lineEdit);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700906
907 this->nextView = viewList;
908 viewList = this;
909}
910
911ConfigView::~ConfigView(void)
912{
913 ConfigView** vp;
914
915 for (vp = &viewList; *vp; vp = &(*vp)->nextView) {
916 if (*vp == this) {
917 *vp = nextView;
918 break;
919 }
920 }
921}
922
Li Zefan39a48972010-05-10 16:33:41 +0800923void ConfigView::setOptionMode(QAction *act)
Roman Zippel7fc925f2006-06-08 22:12:46 -0700924{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700925 if (act == showNormalAction)
926 list->optMode = normalOpt;
927 else if (act == showAllAction)
928 list->optMode = allOpt;
929 else
930 list->optMode = promptOpt;
931
932 list->updateListAll();
Roman Zippel7fc925f2006-06-08 22:12:46 -0700933}
934
935void ConfigView::setShowName(bool b)
936{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700937 if (list->showName != b) {
938 list->showName = b;
939 list->reinit();
940 emit showNameChanged(b);
941 }
Roman Zippel7fc925f2006-06-08 22:12:46 -0700942}
943
944void ConfigView::setShowRange(bool b)
945{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700946 if (list->showRange != b) {
947 list->showRange = b;
948 list->reinit();
949 emit showRangeChanged(b);
950 }
Roman Zippel7fc925f2006-06-08 22:12:46 -0700951}
952
953void ConfigView::setShowData(bool b)
954{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700955 if (list->showData != b) {
956 list->showData = b;
957 list->reinit();
958 emit showDataChanged(b);
959 }
960}
961
962void ConfigList::setAllOpen(bool open)
963{
964 QTreeWidgetItemIterator it(this);
965
966 while (*it) {
967 (*it)->setExpanded(open);
968
969 ++it;
970 }
Roman Zippel7fc925f2006-06-08 22:12:46 -0700971}
972
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700973void ConfigView::updateList(ConfigItem* item)
Roman Zippel7fc925f2006-06-08 22:12:46 -0700974{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700975 ConfigView* v;
976
977 for (v = viewList; v; v = v->nextView)
978 v->list->updateList(item);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700979}
980
981void ConfigView::updateListAll(void)
982{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700983 ConfigView* v;
984
985 for (v = viewList; v; v = v->nextView)
986 v->list->updateListAll();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700987}
988
Roman Zippel43bf6122006-06-08 22:12:45 -0700989ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name)
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -0700990 : Parent(parent), sym(0), _menu(0)
Roman Zippel43bf6122006-06-08 22:12:45 -0700991{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700992 setObjectName(name);
993
994
995 if (!objectName().isEmpty()) {
996 configSettings->beginGroup(objectName());
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -0700997 _showDebug = configSettings->value("/showDebug", false).toBool();
Roman Zippel7fc925f2006-06-08 22:12:46 -0700998 configSettings->endGroup();
999 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
1000 }
1001}
1002
1003void ConfigInfoView::saveSettings(void)
1004{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001005 if (!objectName().isEmpty()) {
1006 configSettings->beginGroup(objectName());
1007 configSettings->setValue("/showDebug", showDebug());
1008 configSettings->endGroup();
1009 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001010}
1011
1012void ConfigInfoView::setShowDebug(bool b)
1013{
1014 if (_showDebug != b) {
1015 _showDebug = b;
Alexander Stein133c5f72010-08-31 17:34:37 +02001016 if (_menu)
Roman Zippel43bf6122006-06-08 22:12:45 -07001017 menuInfo();
Roman Zippelab45d192006-06-08 22:12:47 -07001018 else if (sym)
1019 symbolInfo();
Roman Zippel43bf6122006-06-08 22:12:45 -07001020 emit showDebugChanged(b);
1021 }
1022}
1023
1024void ConfigInfoView::setInfo(struct menu *m)
1025{
Alexander Stein133c5f72010-08-31 17:34:37 +02001026 if (_menu == m)
Roman Zippelb65a47e2006-06-08 22:12:47 -07001027 return;
Alexander Stein133c5f72010-08-31 17:34:37 +02001028 _menu = m;
Roman Zippel6fa1da82007-01-10 23:15:31 -08001029 sym = NULL;
Alexander Stein133c5f72010-08-31 17:34:37 +02001030 if (!_menu)
Roman Zippel43bf6122006-06-08 22:12:45 -07001031 clear();
Roman Zippel6fa1da82007-01-10 23:15:31 -08001032 else
Roman Zippel43bf6122006-06-08 22:12:45 -07001033 menuInfo();
1034}
1035
Roman Zippelab45d192006-06-08 22:12:47 -07001036void ConfigInfoView::symbolInfo(void)
1037{
1038 QString str;
1039
1040 str += "<big>Symbol: <b>";
1041 str += print_filter(sym->name);
1042 str += "</b></big><br><br>value: ";
1043 str += print_filter(sym_get_string_value(sym));
1044 str += "<br>visibility: ";
1045 str += sym->visible == yes ? "y" : sym->visible == mod ? "m" : "n";
1046 str += "<br>";
1047 str += debug_info(sym);
1048
1049 setText(str);
1050}
1051
Roman Zippel43bf6122006-06-08 22:12:45 -07001052void ConfigInfoView::menuInfo(void)
1053{
1054 struct symbol* sym;
1055 QString head, debug, help;
1056
Alexander Stein133c5f72010-08-31 17:34:37 +02001057 sym = _menu->sym;
Roman Zippel43bf6122006-06-08 22:12:45 -07001058 if (sym) {
Alexander Stein133c5f72010-08-31 17:34:37 +02001059 if (_menu->prompt) {
Roman Zippel43bf6122006-06-08 22:12:45 -07001060 head += "<big><b>";
Alexander Stein133c5f72010-08-31 17:34:37 +02001061 head += print_filter(_(_menu->prompt->text));
Roman Zippel43bf6122006-06-08 22:12:45 -07001062 head += "</b></big>";
1063 if (sym->name) {
1064 head += " (";
Roman Zippelab45d192006-06-08 22:12:47 -07001065 if (showDebug())
1066 head += QString().sprintf("<a href=\"s%p\">", sym);
Roman Zippel43bf6122006-06-08 22:12:45 -07001067 head += print_filter(sym->name);
Roman Zippelab45d192006-06-08 22:12:47 -07001068 if (showDebug())
1069 head += "</a>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001070 head += ")";
1071 }
1072 } else if (sym->name) {
1073 head += "<big><b>";
Roman Zippelab45d192006-06-08 22:12:47 -07001074 if (showDebug())
1075 head += QString().sprintf("<a href=\"s%p\">", sym);
Roman Zippel43bf6122006-06-08 22:12:45 -07001076 head += print_filter(sym->name);
Roman Zippelab45d192006-06-08 22:12:47 -07001077 if (showDebug())
1078 head += "</a>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001079 head += "</b></big>";
1080 }
1081 head += "<br><br>";
1082
1083 if (showDebug())
1084 debug = debug_info(sym);
1085
Cheng Renquand74c15f2009-07-12 16:11:47 +08001086 struct gstr help_gstr = str_new();
Alexander Stein133c5f72010-08-31 17:34:37 +02001087 menu_get_ext_help(_menu, &help_gstr);
Cheng Renquand74c15f2009-07-12 16:11:47 +08001088 help = print_filter(str_get(&help_gstr));
1089 str_free(&help_gstr);
Alexander Stein133c5f72010-08-31 17:34:37 +02001090 } else if (_menu->prompt) {
Roman Zippel43bf6122006-06-08 22:12:45 -07001091 head += "<big><b>";
Alexander Stein133c5f72010-08-31 17:34:37 +02001092 head += print_filter(_(_menu->prompt->text));
Roman Zippel43bf6122006-06-08 22:12:45 -07001093 head += "</b></big><br><br>";
1094 if (showDebug()) {
Alexander Stein133c5f72010-08-31 17:34:37 +02001095 if (_menu->prompt->visible.expr) {
Roman Zippel43bf6122006-06-08 22:12:45 -07001096 debug += "&nbsp;&nbsp;dep: ";
Alexander Stein133c5f72010-08-31 17:34:37 +02001097 expr_print(_menu->prompt->visible.expr, expr_print_help, &debug, E_NONE);
Roman Zippel43bf6122006-06-08 22:12:45 -07001098 debug += "<br><br>";
1099 }
1100 }
1101 }
1102 if (showDebug())
Alexander Stein133c5f72010-08-31 17:34:37 +02001103 debug += QString().sprintf("defined at %s:%d<br><br>", _menu->file->name, _menu->lineno);
Roman Zippel43bf6122006-06-08 22:12:45 -07001104
1105 setText(head + debug + help);
1106}
1107
1108QString ConfigInfoView::debug_info(struct symbol *sym)
1109{
1110 QString debug;
1111
1112 debug += "type: ";
1113 debug += print_filter(sym_type_name(sym->type));
1114 if (sym_is_choice(sym))
1115 debug += " (choice)";
1116 debug += "<br>";
1117 if (sym->rev_dep.expr) {
1118 debug += "reverse dep: ";
1119 expr_print(sym->rev_dep.expr, expr_print_help, &debug, E_NONE);
1120 debug += "<br>";
1121 }
1122 for (struct property *prop = sym->prop; prop; prop = prop->next) {
1123 switch (prop->type) {
1124 case P_PROMPT:
1125 case P_MENU:
Roman Zippelab45d192006-06-08 22:12:47 -07001126 debug += QString().sprintf("prompt: <a href=\"m%p\">", prop->menu);
Roman Zippel43bf6122006-06-08 22:12:45 -07001127 debug += print_filter(_(prop->text));
Roman Zippelab45d192006-06-08 22:12:47 -07001128 debug += "</a><br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001129 break;
1130 case P_DEFAULT:
Roman Zippel93449082008-01-14 04:50:54 +01001131 case P_SELECT:
1132 case P_RANGE:
1133 case P_ENV:
1134 debug += prop_get_type_name(prop->type);
1135 debug += ": ";
Roman Zippel43bf6122006-06-08 22:12:45 -07001136 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1137 debug += "<br>";
1138 break;
1139 case P_CHOICE:
1140 if (sym_is_choice(sym)) {
1141 debug += "choice: ";
1142 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1143 debug += "<br>";
1144 }
1145 break;
Roman Zippel43bf6122006-06-08 22:12:45 -07001146 default:
1147 debug += "unknown property: ";
1148 debug += prop_get_type_name(prop->type);
1149 debug += "<br>";
1150 }
1151 if (prop->visible.expr) {
1152 debug += "&nbsp;&nbsp;&nbsp;&nbsp;dep: ";
1153 expr_print(prop->visible.expr, expr_print_help, &debug, E_NONE);
1154 debug += "<br>";
1155 }
1156 }
1157 debug += "<br>";
1158
1159 return debug;
1160}
1161
1162QString ConfigInfoView::print_filter(const QString &str)
1163{
1164 QRegExp re("[<>&\"\\n]");
1165 QString res = str;
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001166 for (int i = 0; (i = res.indexOf(re, i)) >= 0;) {
1167 switch (res[i].toLatin1()) {
Roman Zippel43bf6122006-06-08 22:12:45 -07001168 case '<':
1169 res.replace(i, 1, "&lt;");
1170 i += 4;
1171 break;
1172 case '>':
1173 res.replace(i, 1, "&gt;");
1174 i += 4;
1175 break;
1176 case '&':
1177 res.replace(i, 1, "&amp;");
1178 i += 5;
1179 break;
1180 case '"':
1181 res.replace(i, 1, "&quot;");
1182 i += 6;
1183 break;
1184 case '\n':
1185 res.replace(i, 1, "<br>");
1186 i += 4;
1187 break;
1188 }
1189 }
1190 return res;
1191}
1192
Roman Zippelab45d192006-06-08 22:12:47 -07001193void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char *str)
Roman Zippel43bf6122006-06-08 22:12:45 -07001194{
Roman Zippelab45d192006-06-08 22:12:47 -07001195 QString* text = reinterpret_cast<QString*>(data);
1196 QString str2 = print_filter(str);
1197
1198 if (sym && sym->name && !(sym->flags & SYMBOL_CONST)) {
1199 *text += QString().sprintf("<a href=\"s%p\">", sym);
1200 *text += str2;
1201 *text += "</a>";
1202 } else
1203 *text += str2;
Roman Zippel43bf6122006-06-08 22:12:45 -07001204}
1205
Boris Barbulovski924bbb52015-09-22 11:36:06 -07001206QMenu* ConfigInfoView::createStandardContextMenu(const QPoint & pos)
Roman Zippel7fc925f2006-06-08 22:12:46 -07001207{
Boris Barbulovski924bbb52015-09-22 11:36:06 -07001208 QMenu* popup = Parent::createStandardContextMenu(pos);
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001209 QAction* action = new QAction(_("Show Debug Info"), popup);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001210 action->setCheckable(true);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001211 connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
1212 connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool)));
Boris Barbulovski9c862352015-09-22 11:36:12 -07001213 action->setChecked(showDebug());
Boris Barbulovski924bbb52015-09-22 11:36:06 -07001214 popup->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001215 popup->addAction(action);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001216 return popup;
1217}
1218
Boris Barbulovski924bbb52015-09-22 11:36:06 -07001219void ConfigInfoView::contextMenuEvent(QContextMenuEvent *e)
Roman Zippel7fc925f2006-06-08 22:12:46 -07001220{
Boris Barbulovski924bbb52015-09-22 11:36:06 -07001221 Parent::contextMenuEvent(e);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001222}
1223
Marco Costalba63431e72006-10-05 19:12:59 +02001224ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow* parent, const char *name)
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001225 : Parent(parent), result(NULL)
Roman Zippel43bf6122006-06-08 22:12:45 -07001226{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001227 setObjectName(name);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001228 setWindowTitle("Search Config");
Roman Zippel43bf6122006-06-08 22:12:45 -07001229
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001230 QVBoxLayout* layout1 = new QVBoxLayout(this);
1231 layout1->setContentsMargins(11, 11, 11, 11);
1232 layout1->setSpacing(6);
1233 QHBoxLayout* layout2 = new QHBoxLayout(0);
1234 layout2->setContentsMargins(0, 0, 0, 0);
1235 layout2->setSpacing(6);
EGRY Gaborc21a2d92008-01-11 23:52:07 +01001236 layout2->addWidget(new QLabel(_("Find:"), this));
Roman Zippel43bf6122006-06-08 22:12:45 -07001237 editField = new QLineEdit(this);
1238 connect(editField, SIGNAL(returnPressed()), SLOT(search()));
1239 layout2->addWidget(editField);
EGRY Gaborc21a2d92008-01-11 23:52:07 +01001240 searchButton = new QPushButton(_("Search"), this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001241 searchButton->setAutoDefault(false);
Roman Zippel43bf6122006-06-08 22:12:45 -07001242 connect(searchButton, SIGNAL(clicked()), SLOT(search()));
1243 layout2->addWidget(searchButton);
1244 layout1->addLayout(layout2);
1245
Roman Zippel7fc925f2006-06-08 22:12:46 -07001246 split = new QSplitter(this);
Markus Heidelberg7298b932009-05-18 01:36:50 +02001247 split->setOrientation(Qt::Vertical);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001248 list = new ConfigView(split, name);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001249 list->list->mode = listMode;
Roman Zippel7fc925f2006-06-08 22:12:46 -07001250 info = new ConfigInfoView(split, name);
Roman Zippel43bf6122006-06-08 22:12:45 -07001251 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1252 info, SLOT(setInfo(struct menu *)));
Marco Costalba63431e72006-10-05 19:12:59 +02001253 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1254 parent, SLOT(setMenuLink(struct menu *)));
1255
Roman Zippel43bf6122006-06-08 22:12:45 -07001256 layout1->addWidget(split);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001257
1258 if (name) {
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001259 QVariant x, y;
1260 int width, height;
Roman Zippel7fc925f2006-06-08 22:12:46 -07001261 bool ok;
1262
1263 configSettings->beginGroup(name);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001264 width = configSettings->value("/window width", parent->width() / 2).toInt();
1265 height = configSettings->value("/window height", parent->height() / 2).toInt();
Roman Zippel7fc925f2006-06-08 22:12:46 -07001266 resize(width, height);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001267 x = configSettings->value("/window x");
1268 y = configSettings->value("/window y");
1269 if ((x.isValid())&&(y.isValid()))
1270 move(x.toInt(), y.toInt());
Boris Barbulovski041fbdc2015-09-22 11:36:05 -07001271 QList<int> sizes = configSettings->readSizes("/split", &ok);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001272 if (ok)
1273 split->setSizes(sizes);
1274 configSettings->endGroup();
1275 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
1276 }
1277}
1278
1279void ConfigSearchWindow::saveSettings(void)
1280{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001281 if (!objectName().isEmpty()) {
1282 configSettings->beginGroup(objectName());
1283 configSettings->setValue("/window x", pos().x());
1284 configSettings->setValue("/window y", pos().y());
1285 configSettings->setValue("/window width", size().width());
1286 configSettings->setValue("/window height", size().height());
1287 configSettings->writeSizes("/split", split->sizes());
1288 configSettings->endGroup();
1289 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001290}
1291
1292void ConfigSearchWindow::search(void)
1293{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001294 struct symbol **p;
1295 struct property *prop;
1296 ConfigItem *lastItem = NULL;
1297
1298 free(result);
1299 list->list->clear();
1300 info->clear();
1301
1302 result = sym_re_search(editField->text().toLatin1());
1303 if (!result)
1304 return;
1305 for (p = result; *p; p++) {
1306 for_all_prompts((*p), prop)
1307 lastItem = new ConfigItem(list->list, lastItem, prop->menu,
1308 menu_is_visible(prop->menu));
1309 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001310}
1311
Linus Torvalds1da177e2005-04-16 15:20:36 -07001312/*
1313 * Construct the complete config widget
1314 */
1315ConfigMainWindow::ConfigMainWindow(void)
Roman Zippelf12aa702006-11-25 11:09:31 -08001316 : searchWindow(0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001317{
1318 QMenuBar* menu;
Boris Barbulovski92119932015-09-22 11:36:16 -07001319 bool ok = true;
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001320 QVariant x, y;
1321 int width, height;
Randy Dunlapa54bb702007-10-20 11:18:47 -07001322 char title[256];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001323
Markus Heidelberg8d90c972009-05-18 01:36:52 +02001324 QDesktopWidget *d = configApp->desktop();
Arnaud Lacombe09548282010-08-18 01:57:13 -04001325 snprintf(title, sizeof(title), "%s%s",
1326 rootmenu.prompt->text,
Michal Marek76a136c2010-09-01 17:39:27 +02001327 ""
Michal Marek76a136c2010-09-01 17:39:27 +02001328 );
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001329 setWindowTitle(title);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001330
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001331 width = configSettings->value("/window width", d->width() - 64).toInt();
1332 height = configSettings->value("/window height", d->height() - 64).toInt();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001333 resize(width, height);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001334 x = configSettings->value("/window x");
1335 y = configSettings->value("/window y");
1336 if ((x.isValid())&&(y.isValid()))
1337 move(x.toInt(), y.toInt());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001338
1339 split1 = new QSplitter(this);
Markus Heidelberg7298b932009-05-18 01:36:50 +02001340 split1->setOrientation(Qt::Horizontal);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001341 setCentralWidget(split1);
1342
Roman Zippel7fc925f2006-06-08 22:12:46 -07001343 menuView = new ConfigView(split1, "menu");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001344 menuList = menuView->list;
1345
1346 split2 = new QSplitter(split1);
Markus Heidelberg7298b932009-05-18 01:36:50 +02001347 split2->setOrientation(Qt::Vertical);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001348
1349 // create config tree
Roman Zippel7fc925f2006-06-08 22:12:46 -07001350 configView = new ConfigView(split2, "config");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001351 configList = configView->list;
1352
Roman Zippel7fc925f2006-06-08 22:12:46 -07001353 helpText = new ConfigInfoView(split2, "help");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001354
1355 setTabOrder(configList, helpText);
1356 configList->setFocus();
1357
1358 menu = menuBar();
Boris Barbulovskib1f8a452015-09-22 11:36:02 -07001359 toolBar = new QToolBar("Tools", this);
Boris Barbulovski29a70162015-09-22 11:36:10 -07001360 addToolBar(toolBar);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001361
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001362 backAction = new QAction(QPixmap(xpm_back), _("Back"), this);
Boris Barbulovski92119932015-09-22 11:36:16 -07001363 connect(backAction, SIGNAL(triggered(bool)), SLOT(goBack()));
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001364 backAction->setEnabled(false);
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001365 QAction *quitAction = new QAction(_("&Quit"), this);
1366 quitAction->setShortcut(Qt::CTRL + Qt::Key_Q);
Boris Barbulovski92119932015-09-22 11:36:16 -07001367 connect(quitAction, SIGNAL(triggered(bool)), SLOT(close()));
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001368 QAction *loadAction = new QAction(QPixmap(xpm_load), _("&Load"), this);
1369 loadAction->setShortcut(Qt::CTRL + Qt::Key_L);
Boris Barbulovski92119932015-09-22 11:36:16 -07001370 connect(loadAction, SIGNAL(triggered(bool)), SLOT(loadConfig()));
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001371 saveAction = new QAction(QPixmap(xpm_save), _("&Save"), this);
1372 saveAction->setShortcut(Qt::CTRL + Qt::Key_S);
Boris Barbulovski92119932015-09-22 11:36:16 -07001373 connect(saveAction, SIGNAL(triggered(bool)), SLOT(saveConfig()));
Karsten Wiese3b354c52006-12-13 00:34:08 -08001374 conf_set_changed_callback(conf_changed);
1375 // Set saveAction's initial state
1376 conf_changed();
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001377 QAction *saveAsAction = new QAction(_("Save &As..."), this);
Boris Barbulovski92119932015-09-22 11:36:16 -07001378 connect(saveAsAction, SIGNAL(triggered(bool)), SLOT(saveConfigAs()));
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001379 QAction *searchAction = new QAction(_("&Find"), this);
1380 searchAction->setShortcut(Qt::CTRL + Qt::Key_F);
Boris Barbulovski92119932015-09-22 11:36:16 -07001381 connect(searchAction, SIGNAL(triggered(bool)), SLOT(searchConfig()));
Boris Barbulovski780505e2015-09-22 11:36:13 -07001382 singleViewAction = new QAction(QPixmap(xpm_single_view), _("Single View"), this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001383 singleViewAction->setCheckable(true);
Boris Barbulovski92119932015-09-22 11:36:16 -07001384 connect(singleViewAction, SIGNAL(triggered(bool)), SLOT(showSingleView()));
Boris Barbulovski780505e2015-09-22 11:36:13 -07001385 splitViewAction = new QAction(QPixmap(xpm_split_view), _("Split View"), this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001386 splitViewAction->setCheckable(true);
Boris Barbulovski92119932015-09-22 11:36:16 -07001387 connect(splitViewAction, SIGNAL(triggered(bool)), SLOT(showSplitView()));
Boris Barbulovski780505e2015-09-22 11:36:13 -07001388 fullViewAction = new QAction(QPixmap(xpm_tree_view), _("Full View"), this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001389 fullViewAction->setCheckable(true);
Boris Barbulovski92119932015-09-22 11:36:16 -07001390 connect(fullViewAction, SIGNAL(triggered(bool)), SLOT(showFullView()));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001391
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001392 QAction *showNameAction = new QAction(_("Show Name"), this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001393 showNameAction->setCheckable(true);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001394 connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool)));
Boris Barbulovski9c862352015-09-22 11:36:12 -07001395 showNameAction->setChecked(configView->showName());
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001396 QAction *showRangeAction = new QAction(_("Show Range"), this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001397 showRangeAction->setCheckable(true);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001398 connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool)));
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001399 QAction *showDataAction = new QAction(_("Show Data"), this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001400 showDataAction->setCheckable(true);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001401 connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool)));
Li Zefan39a48972010-05-10 16:33:41 +08001402
1403 QActionGroup *optGroup = new QActionGroup(this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001404 optGroup->setExclusive(true);
Boris Barbulovski92119932015-09-22 11:36:16 -07001405 connect(optGroup, SIGNAL(triggered(QAction*)), configView,
Li Zefan39a48972010-05-10 16:33:41 +08001406 SLOT(setOptionMode(QAction *)));
Boris Barbulovski92119932015-09-22 11:36:16 -07001407 connect(optGroup, SIGNAL(triggered(QAction *)), menuView,
Li Zefan39a48972010-05-10 16:33:41 +08001408 SLOT(setOptionMode(QAction *)));
1409
Alexander Stein133c5f72010-08-31 17:34:37 +02001410 configView->showNormalAction = new QAction(_("Show Normal Options"), optGroup);
1411 configView->showAllAction = new QAction(_("Show All Options"), optGroup);
1412 configView->showPromptAction = new QAction(_("Show Prompt Options"), optGroup);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001413 configView->showNormalAction->setCheckable(true);
1414 configView->showAllAction->setCheckable(true);
1415 configView->showPromptAction->setCheckable(true);
Li Zefan39a48972010-05-10 16:33:41 +08001416
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001417 QAction *showDebugAction = new QAction( _("Show Debug Info"), this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001418 showDebugAction->setCheckable(true);
Roman Zippel43bf6122006-06-08 22:12:45 -07001419 connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
Boris Barbulovski9c862352015-09-22 11:36:12 -07001420 showDebugAction->setChecked(helpText->showDebug());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001421
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001422 QAction *showIntroAction = new QAction( _("Introduction"), this);
Boris Barbulovski92119932015-09-22 11:36:16 -07001423 connect(showIntroAction, SIGNAL(triggered(bool)), SLOT(showIntro()));
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001424 QAction *showAboutAction = new QAction( _("About"), this);
Boris Barbulovski92119932015-09-22 11:36:16 -07001425 connect(showAboutAction, SIGNAL(triggered(bool)), SLOT(showAbout()));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001426
1427 // init tool bar
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001428 toolBar->addAction(backAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001429 toolBar->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001430 toolBar->addAction(loadAction);
1431 toolBar->addAction(saveAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001432 toolBar->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001433 toolBar->addAction(singleViewAction);
1434 toolBar->addAction(splitViewAction);
1435 toolBar->addAction(fullViewAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001436
1437 // create config menu
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001438 QMenu* config = menu->addMenu(_("&File"));
1439 config->addAction(loadAction);
1440 config->addAction(saveAction);
1441 config->addAction(saveAsAction);
Boris Barbulovski76bede82015-09-22 11:36:07 -07001442 config->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001443 config->addAction(quitAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001444
Shlomi Fish66e7c722007-02-14 00:32:58 -08001445 // create edit menu
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001446 QMenu* editMenu = menu->addMenu(_("&Edit"));
1447 editMenu->addAction(searchAction);
Shlomi Fish66e7c722007-02-14 00:32:58 -08001448
Linus Torvalds1da177e2005-04-16 15:20:36 -07001449 // create options menu
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001450 QMenu* optionMenu = menu->addMenu(_("&Option"));
1451 optionMenu->addAction(showNameAction);
1452 optionMenu->addAction(showRangeAction);
1453 optionMenu->addAction(showDataAction);
Boris Barbulovski76bede82015-09-22 11:36:07 -07001454 optionMenu->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001455 optionMenu->addActions(optGroup->actions());
Boris Barbulovski76bede82015-09-22 11:36:07 -07001456 optionMenu->addSeparator();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001457
1458 // create help menu
Boris Barbulovski76bede82015-09-22 11:36:07 -07001459 menu->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001460 QMenu* helpMenu = menu->addMenu(_("&Help"));
1461 helpMenu->addAction(showIntroAction);
1462 helpMenu->addAction(showAboutAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001463
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001464 connect(configList, SIGNAL(menuChanged(struct menu *)),
1465 helpText, SLOT(setInfo(struct menu *)));
1466 connect(configList, SIGNAL(menuSelected(struct menu *)),
1467 SLOT(changeMenu(struct menu *)));
1468 connect(configList, SIGNAL(parentSelected()),
1469 SLOT(goBack()));
1470 connect(menuList, SIGNAL(menuChanged(struct menu *)),
1471 helpText, SLOT(setInfo(struct menu *)));
1472 connect(menuList, SIGNAL(menuSelected(struct menu *)),
1473 SLOT(changeMenu(struct menu *)));
1474
1475 connect(configList, SIGNAL(gotFocus(struct menu *)),
1476 helpText, SLOT(setInfo(struct menu *)));
1477 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1478 helpText, SLOT(setInfo(struct menu *)));
1479 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1480 SLOT(listFocusChanged(void)));
Roman Zippelb65a47e2006-06-08 22:12:47 -07001481 connect(helpText, SIGNAL(menuSelected(struct menu *)),
1482 SLOT(setMenuLink(struct menu *)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001483
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001484 QString listMode = configSettings->value("/listMode", "symbol").toString();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001485 if (listMode == "single")
1486 showSingleView();
1487 else if (listMode == "full")
1488 showFullView();
1489 else /*if (listMode == "split")*/
1490 showSplitView();
1491
1492 // UI setup done, restore splitter positions
Boris Barbulovski041fbdc2015-09-22 11:36:05 -07001493 QList<int> sizes = configSettings->readSizes("/split1", &ok);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001494 if (ok)
1495 split1->setSizes(sizes);
1496
Roman Zippel7fc925f2006-06-08 22:12:46 -07001497 sizes = configSettings->readSizes("/split2", &ok);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001498 if (ok)
1499 split2->setSizes(sizes);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001500}
1501
Linus Torvalds1da177e2005-04-16 15:20:36 -07001502void ConfigMainWindow::loadConfig(void)
1503{
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001504 QString s = QFileDialog::getOpenFileName(this, "", conf_get_configname());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001505 if (s.isNull())
1506 return;
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -07001507 if (conf_read(QFile::encodeName(s)))
EGRY Gaborc21a2d92008-01-11 23:52:07 +01001508 QMessageBox::information(this, "qconf", _("Unable to load configuration!"));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001509 ConfigView::updateListAll();
1510}
1511
Michal Marekbac6aa82011-05-25 15:10:25 +02001512bool ConfigMainWindow::saveConfig(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001513{
Michal Marekbac6aa82011-05-25 15:10:25 +02001514 if (conf_write(NULL)) {
EGRY Gaborc21a2d92008-01-11 23:52:07 +01001515 QMessageBox::information(this, "qconf", _("Unable to save configuration!"));
Michal Marekbac6aa82011-05-25 15:10:25 +02001516 return false;
1517 }
1518 return true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001519}
1520
1521void ConfigMainWindow::saveConfigAs(void)
1522{
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001523 QString s = QFileDialog::getSaveFileName(this, "", conf_get_configname());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001524 if (s.isNull())
1525 return;
Arnaud Lacombed49e4682011-05-24 14:16:18 -04001526 saveConfig();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001527}
1528
Roman Zippel43bf6122006-06-08 22:12:45 -07001529void ConfigMainWindow::searchConfig(void)
1530{
1531 if (!searchWindow)
Roman Zippel7fc925f2006-06-08 22:12:46 -07001532 searchWindow = new ConfigSearchWindow(this, "search");
Roman Zippel43bf6122006-06-08 22:12:45 -07001533 searchWindow->show();
1534}
1535
Linus Torvalds1da177e2005-04-16 15:20:36 -07001536void ConfigMainWindow::changeMenu(struct menu *menu)
1537{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001538 configList->setRootMenu(menu);
1539 if (configList->rootEntry->parent == &rootmenu)
1540 backAction->setEnabled(false);
1541 else
1542 backAction->setEnabled(true);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001543}
1544
Roman Zippelb65a47e2006-06-08 22:12:47 -07001545void ConfigMainWindow::setMenuLink(struct menu *menu)
1546{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001547 struct menu *parent;
1548 ConfigList* list = NULL;
1549 ConfigItem* item;
1550
1551 if (configList->menuSkip(menu))
1552 return;
1553
1554 switch (configList->mode) {
1555 case singleMode:
1556 list = configList;
1557 parent = menu_get_parent_menu(menu);
1558 if (!parent)
1559 return;
1560 list->setRootMenu(parent);
1561 break;
1562 case symbolMode:
1563 if (menu->flags & MENU_ROOT) {
1564 configList->setRootMenu(menu);
1565 configList->clearSelection();
1566 list = menuList;
1567 } else {
1568 list = configList;
1569 parent = menu_get_parent_menu(menu->parent);
1570 if (!parent)
1571 return;
1572 item = menuList->findConfigItem(parent);
1573 if (item) {
1574 item->setSelected(true);
1575 menuList->scrollToItem(item);
1576 }
1577 list->setRootMenu(parent);
1578 }
1579 break;
1580 case fullMode:
1581 list = configList;
1582 break;
1583 default:
1584 break;
1585 }
1586
1587 if (list) {
1588 item = list->findConfigItem(menu);
1589 if (item) {
1590 item->setSelected(true);
1591 list->scrollToItem(item);
1592 list->setFocus();
1593 }
1594 }
Roman Zippelb65a47e2006-06-08 22:12:47 -07001595}
1596
Linus Torvalds1da177e2005-04-16 15:20:36 -07001597void ConfigMainWindow::listFocusChanged(void)
1598{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001599 if (menuList->mode == menuMode)
1600 configList->clearSelection();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001601}
1602
1603void ConfigMainWindow::goBack(void)
1604{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001605 ConfigItem* item;
1606
1607 configList->setParentMenu();
1608 if (configList->rootEntry == &rootmenu)
1609 backAction->setEnabled(false);
1610 item = (ConfigItem*)menuList->selectedItems().first();
1611 while (item) {
1612 if (item->menu == configList->rootEntry) {
1613 item->setSelected(true);
1614 break;
1615 }
1616 item = (ConfigItem*)item->parent();
1617 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001618}
1619
1620void ConfigMainWindow::showSingleView(void)
1621{
Boris Barbulovski780505e2015-09-22 11:36:13 -07001622 singleViewAction->setEnabled(false);
1623 singleViewAction->setChecked(true);
1624 splitViewAction->setEnabled(true);
1625 splitViewAction->setChecked(false);
1626 fullViewAction->setEnabled(true);
1627 fullViewAction->setChecked(false);
1628
Linus Torvalds1da177e2005-04-16 15:20:36 -07001629 menuView->hide();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001630 menuList->setRootMenu(0);
1631 configList->mode = singleMode;
1632 if (configList->rootEntry == &rootmenu)
1633 configList->updateListAll();
1634 else
1635 configList->setRootMenu(&rootmenu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001636 configList->setFocus();
1637}
1638
1639void ConfigMainWindow::showSplitView(void)
1640{
Boris Barbulovski780505e2015-09-22 11:36:13 -07001641 singleViewAction->setEnabled(true);
1642 singleViewAction->setChecked(false);
1643 splitViewAction->setEnabled(false);
1644 splitViewAction->setChecked(true);
1645 fullViewAction->setEnabled(true);
1646 fullViewAction->setChecked(false);
1647
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001648 configList->mode = symbolMode;
1649 if (configList->rootEntry == &rootmenu)
1650 configList->updateListAll();
1651 else
1652 configList->setRootMenu(&rootmenu);
1653 configList->setAllOpen(true);
1654 configApp->processEvents();
1655 menuList->mode = menuMode;
1656 menuList->setRootMenu(&rootmenu);
1657 menuList->setAllOpen(true);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001658 menuView->show();
1659 menuList->setFocus();
1660}
1661
1662void ConfigMainWindow::showFullView(void)
1663{
Boris Barbulovski780505e2015-09-22 11:36:13 -07001664 singleViewAction->setEnabled(true);
1665 singleViewAction->setChecked(false);
1666 splitViewAction->setEnabled(true);
1667 splitViewAction->setChecked(false);
1668 fullViewAction->setEnabled(false);
1669 fullViewAction->setChecked(true);
1670
Linus Torvalds1da177e2005-04-16 15:20:36 -07001671 menuView->hide();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001672 menuList->setRootMenu(0);
1673 configList->mode = fullMode;
1674 if (configList->rootEntry == &rootmenu)
1675 configList->updateListAll();
1676 else
1677 configList->setRootMenu(&rootmenu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001678 configList->setFocus();
1679}
1680
Linus Torvalds1da177e2005-04-16 15:20:36 -07001681/*
1682 * ask for saving configuration before quitting
1683 * TODO ask only when something changed
1684 */
1685void ConfigMainWindow::closeEvent(QCloseEvent* e)
1686{
Karsten Wieseb3214292006-12-13 00:34:06 -08001687 if (!conf_get_changed()) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001688 e->accept();
1689 return;
1690 }
EGRY Gaborc21a2d92008-01-11 23:52:07 +01001691 QMessageBox mb("qconf", _("Save configuration?"), QMessageBox::Warning,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001692 QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape);
EGRY Gaborc21a2d92008-01-11 23:52:07 +01001693 mb.setButtonText(QMessageBox::Yes, _("&Save Changes"));
1694 mb.setButtonText(QMessageBox::No, _("&Discard Changes"));
1695 mb.setButtonText(QMessageBox::Cancel, _("Cancel Exit"));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001696 switch (mb.exec()) {
1697 case QMessageBox::Yes:
Michal Marekbac6aa82011-05-25 15:10:25 +02001698 if (saveConfig())
1699 e->accept();
1700 else
1701 e->ignore();
1702 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001703 case QMessageBox::No:
1704 e->accept();
1705 break;
1706 case QMessageBox::Cancel:
1707 e->ignore();
1708 break;
1709 }
1710}
1711
1712void ConfigMainWindow::showIntro(void)
1713{
Arnaud Lacombe652cf982010-08-14 23:51:40 -04001714 static const QString str = _("Welcome to the qconf graphical configuration tool.\n\n"
Linus Torvalds1da177e2005-04-16 15:20:36 -07001715 "For each option, a blank box indicates the feature is disabled, a check\n"
1716 "indicates it is enabled, and a dot indicates that it is to be compiled\n"
1717 "as a module. Clicking on the box will cycle through the three states.\n\n"
1718 "If you do not see an option (e.g., a device driver) that you believe\n"
1719 "should be present, try turning on Show All Options under the Options menu.\n"
1720 "Although there is no cross reference yet to help you figure out what other\n"
1721 "options must be enabled to support the option you are interested in, you can\n"
1722 "still view the help of a grayed-out option.\n\n"
1723 "Toggling Show Debug Info under the Options menu will show the dependencies,\n"
EGRY Gaborc21a2d92008-01-11 23:52:07 +01001724 "which you can then match by examining other options.\n\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001725
1726 QMessageBox::information(this, "qconf", str);
1727}
1728
1729void ConfigMainWindow::showAbout(void)
1730{
EGRY Gaborc21a2d92008-01-11 23:52:07 +01001731 static const QString str = _("qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n\n"
1732 "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001733
1734 QMessageBox::information(this, "qconf", str);
1735}
1736
1737void ConfigMainWindow::saveSettings(void)
1738{
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001739 configSettings->setValue("/window x", pos().x());
1740 configSettings->setValue("/window y", pos().y());
1741 configSettings->setValue("/window width", size().width());
1742 configSettings->setValue("/window height", size().height());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001743
1744 QString entry;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001745 switch(configList->mode) {
1746 case singleMode :
1747 entry = "single";
1748 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001749
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001750 case symbolMode :
1751 entry = "split";
1752 break;
1753
1754 case fullMode :
1755 entry = "full";
1756 break;
1757
1758 default:
1759 break;
1760 }
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001761 configSettings->setValue("/listMode", entry);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001762
Roman Zippel7fc925f2006-06-08 22:12:46 -07001763 configSettings->writeSizes("/split1", split1->sizes());
1764 configSettings->writeSizes("/split2", split2->sizes());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001765}
1766
Karsten Wiese3b354c52006-12-13 00:34:08 -08001767void ConfigMainWindow::conf_changed(void)
1768{
1769 if (saveAction)
1770 saveAction->setEnabled(conf_get_changed());
1771}
1772
Linus Torvalds1da177e2005-04-16 15:20:36 -07001773void fixup_rootmenu(struct menu *menu)
1774{
1775 struct menu *child;
1776 static int menu_cnt = 0;
1777
1778 menu->flags |= MENU_ROOT;
1779 for (child = menu->list; child; child = child->next) {
1780 if (child->prompt && child->prompt->type == P_MENU) {
1781 menu_cnt++;
1782 fixup_rootmenu(child);
1783 menu_cnt--;
1784 } else if (!menu_cnt)
1785 fixup_rootmenu(child);
1786 }
1787}
1788
1789static const char *progname;
1790
1791static void usage(void)
1792{
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001793 printf(_("%s [-s] <config>\n").toLatin1().constData(), progname);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001794 exit(0);
1795}
1796
1797int main(int ac, char** av)
1798{
1799 ConfigMainWindow* v;
1800 const char *name;
1801
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -07001802 bindtextdomain(PACKAGE, LOCALEDIR);
1803 textdomain(PACKAGE);
1804
Linus Torvalds1da177e2005-04-16 15:20:36 -07001805 progname = av[0];
1806 configApp = new QApplication(ac, av);
1807 if (ac > 1 && av[1][0] == '-') {
1808 switch (av[1][1]) {
Michal Marek0a1f00a2015-04-08 13:30:42 +02001809 case 's':
1810 conf_set_message_callback(NULL);
1811 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001812 case 'h':
1813 case '?':
1814 usage();
1815 }
1816 name = av[2];
1817 } else
1818 name = av[1];
1819 if (!name)
1820 usage();
1821
1822 conf_parse(name);
1823 fixup_rootmenu(&rootmenu);
1824 conf_read(NULL);
1825 //zconfdump(stdout);
1826
Roman Zippel7fc925f2006-06-08 22:12:46 -07001827 configSettings = new ConfigSettings();
1828 configSettings->beginGroup("/kconfig/qconf");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001829 v = new ConfigMainWindow();
1830
1831 //zconfdump(stdout);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001832 configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit()));
1833 configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings()));
Roman Zippel43bf6122006-06-08 22:12:45 -07001834 v->show();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001835 configApp->exec();
1836
Roman Zippel7fc925f2006-06-08 22:12:46 -07001837 configSettings->endGroup();
1838 delete configSettings;
1839
Linus Torvalds1da177e2005-04-16 15:20:36 -07001840 return 0;
1841}