blob: 9edb9c5416641d72e46dcc56dd3f9e15d593052e [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
202 //int i = list->mapIdx(dataColIdx);
203 //if (i >= 0)
204 // setRenameEnabled(i, true);
205 setText(dataColIdx, data);
206 if (type == S_STRING)
207 prompt = QString("%1: %2").arg(prompt).arg(data);
208 else
209 prompt = QString("(%2) %1").arg(prompt).arg(data);
210 break;
211 }
212 if (!sym_has_value(sym) && visible)
213 prompt += _(" (NEW)");
214set_prompt:
215 setText(promptColIdx, prompt);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700216}
217
218void ConfigItem::testUpdateMenu(bool v)
219{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700220 ConfigItem* i;
221
222 visible = v;
223 if (!menu)
224 return;
225
226 sym_calc_value(menu->sym);
227 if (menu->flags & MENU_CHANGED) {
228 /* the menu entry changed, so update all list items */
229 menu->flags &= ~MENU_CHANGED;
230 for (i = (ConfigItem*)menu->data; i; i = i->nextItem)
231 i->updateMenu();
232 } else if (listView()->updateAll)
233 updateMenu();
Boris Barbulovski59e56442015-09-22 11:36:18 -0700234}
235
236
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700237/*
238 * construct a menu entry
239 */
240void ConfigItem::init(void)
241{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700242 if (menu) {
243 ConfigList* list = listView();
244 nextItem = (ConfigItem*)menu->data;
245 menu->data = this;
246
247 if (list->mode != fullMode)
248 setExpanded(true);
249 sym_calc_value(menu->sym);
250 }
251 updateMenu();
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700252}
253
254/*
255 * destruct a menu entry
256 */
257ConfigItem::~ConfigItem(void)
258{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700259 if (menu) {
260 ConfigItem** ip = (ConfigItem**)&menu->data;
261 for (; *ip; ip = &(*ip)->nextItem) {
262 if (*ip == this) {
263 *ip = nextItem;
264 break;
265 }
266 }
267 }
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700268}
269
Roman Zippel43bf6122006-06-08 22:12:45 -0700270ConfigLineEdit::ConfigLineEdit(ConfigView* parent)
271 : Parent(parent)
272{
Boris Barbulovskic14fa5e2015-09-22 11:36:21 -0700273 connect(this, SIGNAL(editingFinished()), SLOT(hide()));
Roman Zippel43bf6122006-06-08 22:12:45 -0700274}
275
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700276void ConfigLineEdit::show(ConfigItem* i)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700277{
278 item = i;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700279 if (sym_get_string_value(item->menu->sym))
280 setText(QString::fromLocal8Bit(sym_get_string_value(item->menu->sym)));
281 else
282 setText(QString::null);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700283 Parent::show();
284 setFocus();
285}
286
287void ConfigLineEdit::keyPressEvent(QKeyEvent* e)
288{
289 switch (e->key()) {
Markus Heidelbergfbb86372009-05-18 01:36:51 +0200290 case Qt::Key_Escape:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700291 break;
Markus Heidelbergfbb86372009-05-18 01:36:51 +0200292 case Qt::Key_Return:
293 case Qt::Key_Enter:
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700294 sym_set_string_value(item->menu->sym, text().toLatin1());
Linus Torvalds1da177e2005-04-16 15:20:36 -0700295 parent()->updateList(item);
296 break;
297 default:
298 Parent::keyPressEvent(e);
299 return;
300 }
301 e->accept();
302 parent()->list->setFocus();
303 hide();
304}
305
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700306ConfigList::ConfigList(ConfigView* p, const char *name)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700307 : Parent(p),
308 updateAll(false),
309 symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no),
310 choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no),
311 menuPix(xpm_menu), menuInvPix(xpm_menu_inv), menuBackPix(xpm_menuback), voidPix(xpm_void),
Boris Barbulovskidbf62932015-09-22 11:36:26 -0700312 showName(false), showRange(false), showData(false), mode(singleMode), optMode(normalOpt),
Boris Barbulovski59e56442015-09-22 11:36:18 -0700313 rootEntry(0), headerPopup(0)
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700314{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700315 int i;
316
317 setObjectName(name);
Boris Barbulovskia5225e92015-09-22 11:36:29 -0700318 setSortingEnabled(false);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700319 setRootIsDecorated(true);
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();
453 return;
454 }
455update:
456 updateMenuList(this, rootEntry);
457 update();
Boris Barbulovski59e56442015-09-22 11:36:18 -0700458}
459
460void ConfigList::setValue(ConfigItem* item, tristate val)
461{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700462 struct symbol* sym;
463 int type;
464 tristate oldval;
465
466 sym = item->menu ? item->menu->sym : 0;
467 if (!sym)
468 return;
469
470 type = sym_get_type(sym);
471 switch (type) {
472 case S_BOOLEAN:
473 case S_TRISTATE:
474 oldval = sym_get_tristate_value(sym);
475
476 if (!sym_set_tristate_value(sym, val))
477 return;
478 if (oldval == no && item->menu->list)
479 item->setExpanded(true);
480 parent()->updateList(item);
481 break;
482 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700483}
484
485void ConfigList::changeValue(ConfigItem* item)
486{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700487 struct symbol* sym;
488 struct menu* menu;
489 int type, oldexpr, newexpr;
490
491 menu = item->menu;
492 if (!menu)
493 return;
494 sym = menu->sym;
495 if (!sym) {
496 if (item->menu->list)
497 item->setExpanded(!item->isExpanded());
498 return;
499 }
500
501 type = sym_get_type(sym);
502 switch (type) {
503 case S_BOOLEAN:
504 case S_TRISTATE:
505 oldexpr = sym_get_tristate_value(sym);
506 newexpr = sym_toggle_tristate_value(sym);
507 if (item->menu->list) {
508 if (oldexpr == newexpr)
509 item->setExpanded(!item->isExpanded());
510 else if (oldexpr == no)
511 item->setExpanded(true);
512 }
513 if (oldexpr != newexpr)
514 parent()->updateList(item);
515 break;
516 case S_INT:
517 case S_HEX:
518 case S_STRING:
519 break;
520 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700521}
522
523void ConfigList::setRootMenu(struct menu *menu)
524{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700525 enum prop_type type;
526
527 if (rootEntry == menu)
528 return;
529 type = menu && menu->prompt ? menu->prompt->type : P_UNKNOWN;
530 if (type != P_MENU)
531 return;
532 updateMenuList(this, 0);
533 rootEntry = menu;
534 updateListAll();
535 if (currentItem()) {
536 currentItem()->setSelected(hasFocus());
537 scrollToItem(currentItem());
538 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700539}
540
541void ConfigList::setParentMenu(void)
542{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700543 ConfigItem* item;
544 struct menu *oldroot;
545
546 oldroot = rootEntry;
547 if (rootEntry == &rootmenu)
548 return;
549 setRootMenu(menu_get_parent_menu(rootEntry->parent));
550
551 QTreeWidgetItemIterator it(this);
552 while (*it) {
553 item = (ConfigItem *)(*it);
554 if (item->menu == oldroot) {
555 setCurrentItem(item);
556 scrollToItem(item);
557 break;
558 }
559
560 ++it;
561 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700562}
563
564/*
565 * update all the children of a menu entry
566 * removes/adds the entries from the parent widget as necessary
567 *
568 * parent: either the menu list widget or a menu entry widget
569 * menu: entry to be updated
570 */
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700571void ConfigList::updateMenuList(ConfigItem *parent, struct menu* menu)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700572{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700573 struct menu* child;
574 ConfigItem* item;
575 ConfigItem* last;
576 bool visible;
577 enum prop_type type;
578
579 if (!menu) {
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700580 while (parent->childCount() > 0)
581 {
582 delete parent->takeChild(0);
583 }
584
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700585 return;
586 }
587
588 last = parent->firstChild();
589 if (last && !last->goParent)
590 last = 0;
591 for (child = menu->list; child; child = child->next) {
592 item = last ? last->nextSibling() : parent->firstChild();
593 type = child->prompt ? child->prompt->type : P_UNKNOWN;
594
595 switch (mode) {
596 case menuMode:
597 if (!(child->flags & MENU_ROOT))
598 goto hide;
599 break;
600 case symbolMode:
601 if (child->flags & MENU_ROOT)
602 goto hide;
603 break;
604 default:
605 break;
606 }
607
608 visible = menu_is_visible(child);
609 if (!menuSkip(child)) {
610 if (!child->sym && !child->list && !child->prompt)
611 continue;
612 if (!item || item->menu != child)
613 item = new ConfigItem(parent, last, child, visible);
614 else
615 item->testUpdateMenu(visible);
616
617 if (mode == fullMode || mode == menuMode || type != P_MENU)
618 updateMenuList(item, child);
619 else
620 updateMenuList(item, 0);
621 last = item;
622 continue;
623 }
624 hide:
625 if (item && item->menu == child) {
626 last = parent->firstChild();
627 if (last == item)
628 last = 0;
629 else while (last->nextSibling() != item)
630 last = last->nextSibling();
631 delete item;
632 }
633 }
Boris Barbulovski59e56442015-09-22 11:36:18 -0700634}
635
Boris Barbulovski5c6f1552015-09-22 11:36:27 -0700636void ConfigList::updateMenuList(ConfigList *parent, struct menu* menu)
637{
638 struct menu* child;
639 ConfigItem* item;
640 ConfigItem* last;
641 bool visible;
642 enum prop_type type;
643
644 if (!menu) {
645 while (parent->topLevelItemCount() > 0)
646 {
647 delete parent->takeTopLevelItem(0);
648 }
649
650 return;
651 }
652
653 last = (ConfigItem*)parent->topLevelItem(0);
654 if (last && !last->goParent)
655 last = 0;
656 for (child = menu->list; child; child = child->next) {
657 item = last ? last->nextSibling() : (ConfigItem*)parent->topLevelItem(0);
658 type = child->prompt ? child->prompt->type : P_UNKNOWN;
659
660 switch (mode) {
661 case menuMode:
662 if (!(child->flags & MENU_ROOT))
663 goto hide;
664 break;
665 case symbolMode:
666 if (child->flags & MENU_ROOT)
667 goto hide;
668 break;
669 default:
670 break;
671 }
672
673 visible = menu_is_visible(child);
674 if (!menuSkip(child)) {
675 if (!child->sym && !child->list && !child->prompt)
676 continue;
677 if (!item || item->menu != child)
678 item = new ConfigItem(parent, last, child, visible);
679 else
680 item->testUpdateMenu(visible);
681
682 if (mode == fullMode || mode == menuMode || type != P_MENU)
683 updateMenuList(item, child);
684 else
685 updateMenuList(item, 0);
686 last = item;
687 continue;
688 }
689 hide:
690 if (item && item->menu == child) {
691 last = (ConfigItem*)parent->topLevelItem(0);
692 if (last == item)
693 last = 0;
694 else while (last->nextSibling() != item)
695 last = last->nextSibling();
696 delete item;
697 }
698 }
699}
700
Boris Barbulovski59e56442015-09-22 11:36:18 -0700701void ConfigList::keyPressEvent(QKeyEvent* ev)
702{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700703 QTreeWidgetItem* i = currentItem();
704 ConfigItem* item;
705 struct menu *menu;
706 enum prop_type type;
707
708 if (ev->key() == Qt::Key_Escape && mode != fullMode && mode != listMode) {
709 emit parentSelected();
710 ev->accept();
711 return;
712 }
713
714 if (!i) {
715 Parent::keyPressEvent(ev);
716 return;
717 }
718 item = (ConfigItem*)i;
719
720 switch (ev->key()) {
721 case Qt::Key_Return:
722 case Qt::Key_Enter:
723 if (item->goParent) {
724 emit parentSelected();
725 break;
726 }
727 menu = item->menu;
728 if (!menu)
729 break;
730 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
731 if (type == P_MENU && rootEntry != menu &&
732 mode != fullMode && mode != menuMode) {
733 emit menuSelected(menu);
734 break;
735 }
736 case Qt::Key_Space:
737 changeValue(item);
738 break;
739 case Qt::Key_N:
740 setValue(item, no);
741 break;
742 case Qt::Key_M:
743 setValue(item, mod);
744 break;
745 case Qt::Key_Y:
746 setValue(item, yes);
747 break;
748 default:
749 Parent::keyPressEvent(ev);
750 return;
751 }
752 ev->accept();
Boris Barbulovski59e56442015-09-22 11:36:18 -0700753}
754
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700755void ConfigList::mousePressEvent(QMouseEvent* e)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700756{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700757 //QPoint p(contentsToViewport(e->pos()));
758 //printf("contentsMousePressEvent: %d,%d\n", p.x(), p.y());
759 Parent::mousePressEvent(e);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700760}
761
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700762void ConfigList::mouseReleaseEvent(QMouseEvent* e)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700763{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700764 QPoint p = e->pos();
765 ConfigItem* item = (ConfigItem*)itemAt(p);
766 struct menu *menu;
767 enum prop_type ptype;
768 QIcon icon;
769 int idx, x;
770
771 if (!item)
772 goto skip;
773
774 menu = item->menu;
775 x = header()->offset() + p.x();
776 idx = header()->sectionPosition(x);
777 switch (idx) {
778 case promptColIdx:
779 icon = item->pixmap(promptColIdx);
780 break;
781 case noColIdx:
782 setValue(item, no);
783 break;
784 case modColIdx:
785 setValue(item, mod);
786 break;
787 case yesColIdx:
788 setValue(item, yes);
789 break;
790 case dataColIdx:
791 changeValue(item);
792 break;
793 }
794
795skip:
796 //printf("contentsMouseReleaseEvent: %d,%d\n", p.x(), p.y());
797 Parent::mouseReleaseEvent(e);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700798}
799
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700800void ConfigList::mouseMoveEvent(QMouseEvent* e)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700801{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700802 //QPoint p(contentsToViewport(e->pos()));
803 //printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y());
804 Parent::mouseMoveEvent(e);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700805}
806
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700807void ConfigList::mouseDoubleClickEvent(QMouseEvent* e)
Boris Barbulovski59e56442015-09-22 11:36:18 -0700808{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700809 QPoint p = e->pos(); // TODO: Check if this works(was contentsToViewport).
810 ConfigItem* item = (ConfigItem*)itemAt(p);
811 struct menu *menu;
812 enum prop_type ptype;
813
814 if (!item)
815 goto skip;
816 if (item->goParent) {
817 emit parentSelected();
818 goto skip;
819 }
820 menu = item->menu;
821 if (!menu)
822 goto skip;
823 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
824 if (ptype == P_MENU && (mode == singleMode || mode == symbolMode))
825 emit menuSelected(menu);
826 else if (menu->sym)
827 changeValue(item);
828
829skip:
830 //printf("contentsMouseDoubleClickEvent: %d,%d\n", p.x(), p.y());
831 Parent::mouseDoubleClickEvent(e);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700832}
833
834void ConfigList::focusInEvent(QFocusEvent *e)
835{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700836 struct menu *menu = NULL;
837
838 Parent::focusInEvent(e);
839
840 ConfigItem* item = (ConfigItem *)currentItem();
841 if (item) {
842 item->setSelected(true);
843 menu = item->menu;
844 }
845 emit gotFocus(menu);
Boris Barbulovski59e56442015-09-22 11:36:18 -0700846}
847
848void ConfigList::contextMenuEvent(QContextMenuEvent *e)
849{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700850 if (e->y() <= header()->geometry().bottom()) {
851 if (!headerPopup) {
852 QAction *action;
853
854 headerPopup = new QMenu(this);
855 action = new QAction(_("Show Name"), this);
856 action->setCheckable(true);
857 connect(action, SIGNAL(toggled(bool)),
858 parent(), SLOT(setShowName(bool)));
859 connect(parent(), SIGNAL(showNameChanged(bool)),
860 action, SLOT(setOn(bool)));
861 action->setChecked(showName);
862 headerPopup->addAction(action);
863 action = new QAction(_("Show Range"), this);
864 action->setCheckable(true);
865 connect(action, SIGNAL(toggled(bool)),
866 parent(), SLOT(setShowRange(bool)));
867 connect(parent(), SIGNAL(showRangeChanged(bool)),
868 action, SLOT(setOn(bool)));
869 action->setChecked(showRange);
870 headerPopup->addAction(action);
871 action = new QAction(_("Show Data"), this);
872 action->setCheckable(true);
873 connect(action, SIGNAL(toggled(bool)),
874 parent(), SLOT(setShowData(bool)));
875 connect(parent(), SIGNAL(showDataChanged(bool)),
876 action, SLOT(setOn(bool)));
877 action->setChecked(showData);
878 headerPopup->addAction(action);
879 }
880 headerPopup->exec(e->globalPos());
881 e->accept();
882 } else
883 e->ignore();
Boris Barbulovski59e56442015-09-22 11:36:18 -0700884}
885
Li Zefan39a48972010-05-10 16:33:41 +0800886ConfigView*ConfigView::viewList;
887QAction *ConfigView::showNormalAction;
888QAction *ConfigView::showAllAction;
889QAction *ConfigView::showPromptAction;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700890
Roman Zippel7fc925f2006-06-08 22:12:46 -0700891ConfigView::ConfigView(QWidget* parent, const char *name)
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -0700892 : Parent(parent)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700893{
Boris Barbulovski9bd36ed2015-09-22 11:36:22 -0700894 setObjectName(name);
Boris Barbulovski29a70162015-09-22 11:36:10 -0700895 QVBoxLayout *verticalLayout = new QVBoxLayout(this);
Boris Barbulovski92298b42015-09-22 11:36:11 -0700896 verticalLayout->setContentsMargins(0, 0, 0, 0);
Boris Barbulovski29a70162015-09-22 11:36:10 -0700897
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700898 list = new ConfigList(this);
Boris Barbulovski29a70162015-09-22 11:36:10 -0700899 verticalLayout->addWidget(list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700900 lineEdit = new ConfigLineEdit(this);
901 lineEdit->hide();
Boris Barbulovski29a70162015-09-22 11:36:10 -0700902 verticalLayout->addWidget(lineEdit);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700903
904 this->nextView = viewList;
905 viewList = this;
906}
907
908ConfigView::~ConfigView(void)
909{
910 ConfigView** vp;
911
912 for (vp = &viewList; *vp; vp = &(*vp)->nextView) {
913 if (*vp == this) {
914 *vp = nextView;
915 break;
916 }
917 }
918}
919
Li Zefan39a48972010-05-10 16:33:41 +0800920void ConfigView::setOptionMode(QAction *act)
Roman Zippel7fc925f2006-06-08 22:12:46 -0700921{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700922 if (act == showNormalAction)
923 list->optMode = normalOpt;
924 else if (act == showAllAction)
925 list->optMode = allOpt;
926 else
927 list->optMode = promptOpt;
928
929 list->updateListAll();
Roman Zippel7fc925f2006-06-08 22:12:46 -0700930}
931
932void ConfigView::setShowName(bool b)
933{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700934 if (list->showName != b) {
935 list->showName = b;
936 list->reinit();
937 emit showNameChanged(b);
938 }
Roman Zippel7fc925f2006-06-08 22:12:46 -0700939}
940
941void ConfigView::setShowRange(bool b)
942{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700943 if (list->showRange != b) {
944 list->showRange = b;
945 list->reinit();
946 emit showRangeChanged(b);
947 }
Roman Zippel7fc925f2006-06-08 22:12:46 -0700948}
949
950void ConfigView::setShowData(bool b)
951{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700952 if (list->showData != b) {
953 list->showData = b;
954 list->reinit();
955 emit showDataChanged(b);
956 }
957}
958
959void ConfigList::setAllOpen(bool open)
960{
961 QTreeWidgetItemIterator it(this);
962
963 while (*it) {
964 (*it)->setExpanded(open);
965
966 ++it;
967 }
Roman Zippel7fc925f2006-06-08 22:12:46 -0700968}
969
Boris Barbulovski1019f1a2015-09-22 11:36:17 -0700970void ConfigView::updateList(ConfigItem* item)
Roman Zippel7fc925f2006-06-08 22:12:46 -0700971{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700972 ConfigView* v;
973
974 for (v = viewList; v; v = v->nextView)
975 v->list->updateList(item);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700976}
977
978void ConfigView::updateListAll(void)
979{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700980 ConfigView* v;
981
982 for (v = viewList; v; v = v->nextView)
983 v->list->updateListAll();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700984}
985
Roman Zippel43bf6122006-06-08 22:12:45 -0700986ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name)
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -0700987 : Parent(parent), sym(0), _menu(0)
Roman Zippel43bf6122006-06-08 22:12:45 -0700988{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -0700989 setObjectName(name);
990
991
992 if (!objectName().isEmpty()) {
993 configSettings->beginGroup(objectName());
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -0700994 _showDebug = configSettings->value("/showDebug", false).toBool();
Roman Zippel7fc925f2006-06-08 22:12:46 -0700995 configSettings->endGroup();
996 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
997 }
998}
999
1000void ConfigInfoView::saveSettings(void)
1001{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001002 if (!objectName().isEmpty()) {
1003 configSettings->beginGroup(objectName());
1004 configSettings->setValue("/showDebug", showDebug());
1005 configSettings->endGroup();
1006 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001007}
1008
1009void ConfigInfoView::setShowDebug(bool b)
1010{
1011 if (_showDebug != b) {
1012 _showDebug = b;
Alexander Stein133c5f72010-08-31 17:34:37 +02001013 if (_menu)
Roman Zippel43bf6122006-06-08 22:12:45 -07001014 menuInfo();
Roman Zippelab45d192006-06-08 22:12:47 -07001015 else if (sym)
1016 symbolInfo();
Roman Zippel43bf6122006-06-08 22:12:45 -07001017 emit showDebugChanged(b);
1018 }
1019}
1020
1021void ConfigInfoView::setInfo(struct menu *m)
1022{
Alexander Stein133c5f72010-08-31 17:34:37 +02001023 if (_menu == m)
Roman Zippelb65a47e2006-06-08 22:12:47 -07001024 return;
Alexander Stein133c5f72010-08-31 17:34:37 +02001025 _menu = m;
Roman Zippel6fa1da82007-01-10 23:15:31 -08001026 sym = NULL;
Alexander Stein133c5f72010-08-31 17:34:37 +02001027 if (!_menu)
Roman Zippel43bf6122006-06-08 22:12:45 -07001028 clear();
Roman Zippel6fa1da82007-01-10 23:15:31 -08001029 else
Roman Zippel43bf6122006-06-08 22:12:45 -07001030 menuInfo();
1031}
1032
Roman Zippelab45d192006-06-08 22:12:47 -07001033void ConfigInfoView::symbolInfo(void)
1034{
1035 QString str;
1036
1037 str += "<big>Symbol: <b>";
1038 str += print_filter(sym->name);
1039 str += "</b></big><br><br>value: ";
1040 str += print_filter(sym_get_string_value(sym));
1041 str += "<br>visibility: ";
1042 str += sym->visible == yes ? "y" : sym->visible == mod ? "m" : "n";
1043 str += "<br>";
1044 str += debug_info(sym);
1045
1046 setText(str);
1047}
1048
Roman Zippel43bf6122006-06-08 22:12:45 -07001049void ConfigInfoView::menuInfo(void)
1050{
1051 struct symbol* sym;
1052 QString head, debug, help;
1053
Alexander Stein133c5f72010-08-31 17:34:37 +02001054 sym = _menu->sym;
Roman Zippel43bf6122006-06-08 22:12:45 -07001055 if (sym) {
Alexander Stein133c5f72010-08-31 17:34:37 +02001056 if (_menu->prompt) {
Roman Zippel43bf6122006-06-08 22:12:45 -07001057 head += "<big><b>";
Alexander Stein133c5f72010-08-31 17:34:37 +02001058 head += print_filter(_(_menu->prompt->text));
Roman Zippel43bf6122006-06-08 22:12:45 -07001059 head += "</b></big>";
1060 if (sym->name) {
1061 head += " (";
Roman Zippelab45d192006-06-08 22:12:47 -07001062 if (showDebug())
1063 head += QString().sprintf("<a href=\"s%p\">", sym);
Roman Zippel43bf6122006-06-08 22:12:45 -07001064 head += print_filter(sym->name);
Roman Zippelab45d192006-06-08 22:12:47 -07001065 if (showDebug())
1066 head += "</a>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001067 head += ")";
1068 }
1069 } else if (sym->name) {
1070 head += "<big><b>";
Roman Zippelab45d192006-06-08 22:12:47 -07001071 if (showDebug())
1072 head += QString().sprintf("<a href=\"s%p\">", sym);
Roman Zippel43bf6122006-06-08 22:12:45 -07001073 head += print_filter(sym->name);
Roman Zippelab45d192006-06-08 22:12:47 -07001074 if (showDebug())
1075 head += "</a>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001076 head += "</b></big>";
1077 }
1078 head += "<br><br>";
1079
1080 if (showDebug())
1081 debug = debug_info(sym);
1082
Cheng Renquand74c15f2009-07-12 16:11:47 +08001083 struct gstr help_gstr = str_new();
Alexander Stein133c5f72010-08-31 17:34:37 +02001084 menu_get_ext_help(_menu, &help_gstr);
Cheng Renquand74c15f2009-07-12 16:11:47 +08001085 help = print_filter(str_get(&help_gstr));
1086 str_free(&help_gstr);
Alexander Stein133c5f72010-08-31 17:34:37 +02001087 } else if (_menu->prompt) {
Roman Zippel43bf6122006-06-08 22:12:45 -07001088 head += "<big><b>";
Alexander Stein133c5f72010-08-31 17:34:37 +02001089 head += print_filter(_(_menu->prompt->text));
Roman Zippel43bf6122006-06-08 22:12:45 -07001090 head += "</b></big><br><br>";
1091 if (showDebug()) {
Alexander Stein133c5f72010-08-31 17:34:37 +02001092 if (_menu->prompt->visible.expr) {
Roman Zippel43bf6122006-06-08 22:12:45 -07001093 debug += "&nbsp;&nbsp;dep: ";
Alexander Stein133c5f72010-08-31 17:34:37 +02001094 expr_print(_menu->prompt->visible.expr, expr_print_help, &debug, E_NONE);
Roman Zippel43bf6122006-06-08 22:12:45 -07001095 debug += "<br><br>";
1096 }
1097 }
1098 }
1099 if (showDebug())
Alexander Stein133c5f72010-08-31 17:34:37 +02001100 debug += QString().sprintf("defined at %s:%d<br><br>", _menu->file->name, _menu->lineno);
Roman Zippel43bf6122006-06-08 22:12:45 -07001101
1102 setText(head + debug + help);
1103}
1104
1105QString ConfigInfoView::debug_info(struct symbol *sym)
1106{
1107 QString debug;
1108
1109 debug += "type: ";
1110 debug += print_filter(sym_type_name(sym->type));
1111 if (sym_is_choice(sym))
1112 debug += " (choice)";
1113 debug += "<br>";
1114 if (sym->rev_dep.expr) {
1115 debug += "reverse dep: ";
1116 expr_print(sym->rev_dep.expr, expr_print_help, &debug, E_NONE);
1117 debug += "<br>";
1118 }
1119 for (struct property *prop = sym->prop; prop; prop = prop->next) {
1120 switch (prop->type) {
1121 case P_PROMPT:
1122 case P_MENU:
Roman Zippelab45d192006-06-08 22:12:47 -07001123 debug += QString().sprintf("prompt: <a href=\"m%p\">", prop->menu);
Roman Zippel43bf6122006-06-08 22:12:45 -07001124 debug += print_filter(_(prop->text));
Roman Zippelab45d192006-06-08 22:12:47 -07001125 debug += "</a><br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001126 break;
1127 case P_DEFAULT:
Roman Zippel93449082008-01-14 04:50:54 +01001128 case P_SELECT:
1129 case P_RANGE:
1130 case P_ENV:
1131 debug += prop_get_type_name(prop->type);
1132 debug += ": ";
Roman Zippel43bf6122006-06-08 22:12:45 -07001133 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1134 debug += "<br>";
1135 break;
1136 case P_CHOICE:
1137 if (sym_is_choice(sym)) {
1138 debug += "choice: ";
1139 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1140 debug += "<br>";
1141 }
1142 break;
Roman Zippel43bf6122006-06-08 22:12:45 -07001143 default:
1144 debug += "unknown property: ";
1145 debug += prop_get_type_name(prop->type);
1146 debug += "<br>";
1147 }
1148 if (prop->visible.expr) {
1149 debug += "&nbsp;&nbsp;&nbsp;&nbsp;dep: ";
1150 expr_print(prop->visible.expr, expr_print_help, &debug, E_NONE);
1151 debug += "<br>";
1152 }
1153 }
1154 debug += "<br>";
1155
1156 return debug;
1157}
1158
1159QString ConfigInfoView::print_filter(const QString &str)
1160{
1161 QRegExp re("[<>&\"\\n]");
1162 QString res = str;
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001163 for (int i = 0; (i = res.indexOf(re, i)) >= 0;) {
1164 switch (res[i].toLatin1()) {
Roman Zippel43bf6122006-06-08 22:12:45 -07001165 case '<':
1166 res.replace(i, 1, "&lt;");
1167 i += 4;
1168 break;
1169 case '>':
1170 res.replace(i, 1, "&gt;");
1171 i += 4;
1172 break;
1173 case '&':
1174 res.replace(i, 1, "&amp;");
1175 i += 5;
1176 break;
1177 case '"':
1178 res.replace(i, 1, "&quot;");
1179 i += 6;
1180 break;
1181 case '\n':
1182 res.replace(i, 1, "<br>");
1183 i += 4;
1184 break;
1185 }
1186 }
1187 return res;
1188}
1189
Roman Zippelab45d192006-06-08 22:12:47 -07001190void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char *str)
Roman Zippel43bf6122006-06-08 22:12:45 -07001191{
Roman Zippelab45d192006-06-08 22:12:47 -07001192 QString* text = reinterpret_cast<QString*>(data);
1193 QString str2 = print_filter(str);
1194
1195 if (sym && sym->name && !(sym->flags & SYMBOL_CONST)) {
1196 *text += QString().sprintf("<a href=\"s%p\">", sym);
1197 *text += str2;
1198 *text += "</a>";
1199 } else
1200 *text += str2;
Roman Zippel43bf6122006-06-08 22:12:45 -07001201}
1202
Boris Barbulovski924bbb52015-09-22 11:36:06 -07001203QMenu* ConfigInfoView::createStandardContextMenu(const QPoint & pos)
Roman Zippel7fc925f2006-06-08 22:12:46 -07001204{
Boris Barbulovski924bbb52015-09-22 11:36:06 -07001205 QMenu* popup = Parent::createStandardContextMenu(pos);
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001206 QAction* action = new QAction(_("Show Debug Info"), popup);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001207 action->setCheckable(true);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001208 connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
1209 connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool)));
Boris Barbulovski9c862352015-09-22 11:36:12 -07001210 action->setChecked(showDebug());
Boris Barbulovski924bbb52015-09-22 11:36:06 -07001211 popup->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001212 popup->addAction(action);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001213 return popup;
1214}
1215
Boris Barbulovski924bbb52015-09-22 11:36:06 -07001216void ConfigInfoView::contextMenuEvent(QContextMenuEvent *e)
Roman Zippel7fc925f2006-06-08 22:12:46 -07001217{
Boris Barbulovski924bbb52015-09-22 11:36:06 -07001218 Parent::contextMenuEvent(e);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001219}
1220
Marco Costalba63431e72006-10-05 19:12:59 +02001221ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow* parent, const char *name)
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001222 : Parent(parent), result(NULL)
Roman Zippel43bf6122006-06-08 22:12:45 -07001223{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001224 setObjectName(name);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001225 setWindowTitle("Search Config");
Roman Zippel43bf6122006-06-08 22:12:45 -07001226
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001227 QVBoxLayout* layout1 = new QVBoxLayout(this);
1228 layout1->setContentsMargins(11, 11, 11, 11);
1229 layout1->setSpacing(6);
1230 QHBoxLayout* layout2 = new QHBoxLayout(0);
1231 layout2->setContentsMargins(0, 0, 0, 0);
1232 layout2->setSpacing(6);
EGRY Gaborc21a2d92008-01-11 23:52:07 +01001233 layout2->addWidget(new QLabel(_("Find:"), this));
Roman Zippel43bf6122006-06-08 22:12:45 -07001234 editField = new QLineEdit(this);
1235 connect(editField, SIGNAL(returnPressed()), SLOT(search()));
1236 layout2->addWidget(editField);
EGRY Gaborc21a2d92008-01-11 23:52:07 +01001237 searchButton = new QPushButton(_("Search"), this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001238 searchButton->setAutoDefault(false);
Roman Zippel43bf6122006-06-08 22:12:45 -07001239 connect(searchButton, SIGNAL(clicked()), SLOT(search()));
1240 layout2->addWidget(searchButton);
1241 layout1->addLayout(layout2);
1242
Roman Zippel7fc925f2006-06-08 22:12:46 -07001243 split = new QSplitter(this);
Markus Heidelberg7298b932009-05-18 01:36:50 +02001244 split->setOrientation(Qt::Vertical);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001245 list = new ConfigView(split, name);
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001246 list->list->mode = listMode;
Roman Zippel7fc925f2006-06-08 22:12:46 -07001247 info = new ConfigInfoView(split, name);
Roman Zippel43bf6122006-06-08 22:12:45 -07001248 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1249 info, SLOT(setInfo(struct menu *)));
Marco Costalba63431e72006-10-05 19:12:59 +02001250 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1251 parent, SLOT(setMenuLink(struct menu *)));
1252
Roman Zippel43bf6122006-06-08 22:12:45 -07001253 layout1->addWidget(split);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001254
1255 if (name) {
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001256 QVariant x, y;
1257 int width, height;
Roman Zippel7fc925f2006-06-08 22:12:46 -07001258 bool ok;
1259
1260 configSettings->beginGroup(name);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001261 width = configSettings->value("/window width", parent->width() / 2).toInt();
1262 height = configSettings->value("/window height", parent->height() / 2).toInt();
Roman Zippel7fc925f2006-06-08 22:12:46 -07001263 resize(width, height);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001264 x = configSettings->value("/window x");
1265 y = configSettings->value("/window y");
1266 if ((x.isValid())&&(y.isValid()))
1267 move(x.toInt(), y.toInt());
Boris Barbulovski041fbdc2015-09-22 11:36:05 -07001268 QList<int> sizes = configSettings->readSizes("/split", &ok);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001269 if (ok)
1270 split->setSizes(sizes);
1271 configSettings->endGroup();
1272 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
1273 }
1274}
1275
1276void ConfigSearchWindow::saveSettings(void)
1277{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001278 if (!objectName().isEmpty()) {
1279 configSettings->beginGroup(objectName());
1280 configSettings->setValue("/window x", pos().x());
1281 configSettings->setValue("/window y", pos().y());
1282 configSettings->setValue("/window width", size().width());
1283 configSettings->setValue("/window height", size().height());
1284 configSettings->writeSizes("/split", split->sizes());
1285 configSettings->endGroup();
1286 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001287}
1288
1289void ConfigSearchWindow::search(void)
1290{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001291 struct symbol **p;
1292 struct property *prop;
1293 ConfigItem *lastItem = NULL;
1294
1295 free(result);
1296 list->list->clear();
1297 info->clear();
1298
1299 result = sym_re_search(editField->text().toLatin1());
1300 if (!result)
1301 return;
1302 for (p = result; *p; p++) {
1303 for_all_prompts((*p), prop)
1304 lastItem = new ConfigItem(list->list, lastItem, prop->menu,
1305 menu_is_visible(prop->menu));
1306 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001307}
1308
Linus Torvalds1da177e2005-04-16 15:20:36 -07001309/*
1310 * Construct the complete config widget
1311 */
1312ConfigMainWindow::ConfigMainWindow(void)
Roman Zippelf12aa702006-11-25 11:09:31 -08001313 : searchWindow(0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001314{
1315 QMenuBar* menu;
Boris Barbulovski92119932015-09-22 11:36:16 -07001316 bool ok = true;
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001317 QVariant x, y;
1318 int width, height;
Randy Dunlapa54bb702007-10-20 11:18:47 -07001319 char title[256];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001320
Markus Heidelberg8d90c972009-05-18 01:36:52 +02001321 QDesktopWidget *d = configApp->desktop();
Arnaud Lacombe09548282010-08-18 01:57:13 -04001322 snprintf(title, sizeof(title), "%s%s",
1323 rootmenu.prompt->text,
Michal Marek76a136c2010-09-01 17:39:27 +02001324 ""
Michal Marek76a136c2010-09-01 17:39:27 +02001325 );
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001326 setWindowTitle(title);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001327
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001328 width = configSettings->value("/window width", d->width() - 64).toInt();
1329 height = configSettings->value("/window height", d->height() - 64).toInt();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001330 resize(width, height);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001331 x = configSettings->value("/window x");
1332 y = configSettings->value("/window y");
1333 if ((x.isValid())&&(y.isValid()))
1334 move(x.toInt(), y.toInt());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001335
1336 split1 = new QSplitter(this);
Markus Heidelberg7298b932009-05-18 01:36:50 +02001337 split1->setOrientation(Qt::Horizontal);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001338 setCentralWidget(split1);
1339
Roman Zippel7fc925f2006-06-08 22:12:46 -07001340 menuView = new ConfigView(split1, "menu");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001341 menuList = menuView->list;
1342
1343 split2 = new QSplitter(split1);
Markus Heidelberg7298b932009-05-18 01:36:50 +02001344 split2->setOrientation(Qt::Vertical);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001345
1346 // create config tree
Roman Zippel7fc925f2006-06-08 22:12:46 -07001347 configView = new ConfigView(split2, "config");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001348 configList = configView->list;
1349
Roman Zippel7fc925f2006-06-08 22:12:46 -07001350 helpText = new ConfigInfoView(split2, "help");
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001351 //helpText->setTextFormat(Qt::RichText);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001352
1353 setTabOrder(configList, helpText);
1354 configList->setFocus();
1355
1356 menu = menuBar();
Boris Barbulovskib1f8a452015-09-22 11:36:02 -07001357 toolBar = new QToolBar("Tools", this);
Boris Barbulovski29a70162015-09-22 11:36:10 -07001358 addToolBar(toolBar);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001359
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001360 backAction = new QAction(QPixmap(xpm_back), _("Back"), this);
Boris Barbulovski92119932015-09-22 11:36:16 -07001361 connect(backAction, SIGNAL(triggered(bool)), SLOT(goBack()));
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001362 backAction->setEnabled(false);
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001363 QAction *quitAction = new QAction(_("&Quit"), this);
1364 quitAction->setShortcut(Qt::CTRL + Qt::Key_Q);
Boris Barbulovski92119932015-09-22 11:36:16 -07001365 connect(quitAction, SIGNAL(triggered(bool)), SLOT(close()));
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001366 QAction *loadAction = new QAction(QPixmap(xpm_load), _("&Load"), this);
1367 loadAction->setShortcut(Qt::CTRL + Qt::Key_L);
Boris Barbulovski92119932015-09-22 11:36:16 -07001368 connect(loadAction, SIGNAL(triggered(bool)), SLOT(loadConfig()));
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001369 saveAction = new QAction(QPixmap(xpm_save), _("&Save"), this);
1370 saveAction->setShortcut(Qt::CTRL + Qt::Key_S);
Boris Barbulovski92119932015-09-22 11:36:16 -07001371 connect(saveAction, SIGNAL(triggered(bool)), SLOT(saveConfig()));
Karsten Wiese3b354c52006-12-13 00:34:08 -08001372 conf_set_changed_callback(conf_changed);
1373 // Set saveAction's initial state
1374 conf_changed();
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001375 QAction *saveAsAction = new QAction(_("Save &As..."), this);
Boris Barbulovski92119932015-09-22 11:36:16 -07001376 connect(saveAsAction, SIGNAL(triggered(bool)), SLOT(saveConfigAs()));
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001377 QAction *searchAction = new QAction(_("&Find"), this);
1378 searchAction->setShortcut(Qt::CTRL + Qt::Key_F);
Boris Barbulovski92119932015-09-22 11:36:16 -07001379 connect(searchAction, SIGNAL(triggered(bool)), SLOT(searchConfig()));
Boris Barbulovski780505e2015-09-22 11:36:13 -07001380 singleViewAction = new QAction(QPixmap(xpm_single_view), _("Single View"), this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001381 singleViewAction->setCheckable(true);
Boris Barbulovski92119932015-09-22 11:36:16 -07001382 connect(singleViewAction, SIGNAL(triggered(bool)), SLOT(showSingleView()));
Boris Barbulovski780505e2015-09-22 11:36:13 -07001383 splitViewAction = new QAction(QPixmap(xpm_split_view), _("Split View"), this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001384 splitViewAction->setCheckable(true);
Boris Barbulovski92119932015-09-22 11:36:16 -07001385 connect(splitViewAction, SIGNAL(triggered(bool)), SLOT(showSplitView()));
Boris Barbulovski780505e2015-09-22 11:36:13 -07001386 fullViewAction = new QAction(QPixmap(xpm_tree_view), _("Full View"), this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001387 fullViewAction->setCheckable(true);
Boris Barbulovski92119932015-09-22 11:36:16 -07001388 connect(fullViewAction, SIGNAL(triggered(bool)), SLOT(showFullView()));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001389
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001390 QAction *showNameAction = new QAction(_("Show Name"), this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001391 showNameAction->setCheckable(true);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001392 connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool)));
Boris Barbulovski9c862352015-09-22 11:36:12 -07001393 showNameAction->setChecked(configView->showName());
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001394 QAction *showRangeAction = new QAction(_("Show Range"), this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001395 showRangeAction->setCheckable(true);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001396 connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool)));
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001397 QAction *showDataAction = new QAction(_("Show Data"), this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001398 showDataAction->setCheckable(true);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001399 connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool)));
Li Zefan39a48972010-05-10 16:33:41 +08001400
1401 QActionGroup *optGroup = new QActionGroup(this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001402 optGroup->setExclusive(true);
Boris Barbulovski92119932015-09-22 11:36:16 -07001403 connect(optGroup, SIGNAL(triggered(QAction*)), configView,
Li Zefan39a48972010-05-10 16:33:41 +08001404 SLOT(setOptionMode(QAction *)));
Boris Barbulovski92119932015-09-22 11:36:16 -07001405 connect(optGroup, SIGNAL(triggered(QAction *)), menuView,
Li Zefan39a48972010-05-10 16:33:41 +08001406 SLOT(setOptionMode(QAction *)));
1407
Alexander Stein133c5f72010-08-31 17:34:37 +02001408 configView->showNormalAction = new QAction(_("Show Normal Options"), optGroup);
1409 configView->showAllAction = new QAction(_("Show All Options"), optGroup);
1410 configView->showPromptAction = new QAction(_("Show Prompt Options"), optGroup);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001411 configView->showNormalAction->setCheckable(true);
1412 configView->showAllAction->setCheckable(true);
1413 configView->showPromptAction->setCheckable(true);
Li Zefan39a48972010-05-10 16:33:41 +08001414
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001415 QAction *showDebugAction = new QAction( _("Show Debug Info"), this);
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001416 showDebugAction->setCheckable(true);
Roman Zippel43bf6122006-06-08 22:12:45 -07001417 connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
Boris Barbulovski9c862352015-09-22 11:36:12 -07001418 showDebugAction->setChecked(helpText->showDebug());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001419
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001420 QAction *showIntroAction = new QAction( _("Introduction"), this);
Boris Barbulovski92119932015-09-22 11:36:16 -07001421 connect(showIntroAction, SIGNAL(triggered(bool)), SLOT(showIntro()));
Boris Barbulovski85eaf282015-09-22 11:36:03 -07001422 QAction *showAboutAction = new QAction( _("About"), this);
Boris Barbulovski92119932015-09-22 11:36:16 -07001423 connect(showAboutAction, SIGNAL(triggered(bool)), SLOT(showAbout()));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001424
1425 // init tool bar
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001426 toolBar->addAction(backAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001427 toolBar->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001428 toolBar->addAction(loadAction);
1429 toolBar->addAction(saveAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001430 toolBar->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001431 toolBar->addAction(singleViewAction);
1432 toolBar->addAction(splitViewAction);
1433 toolBar->addAction(fullViewAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001434
1435 // create config menu
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001436 QMenu* config = menu->addMenu(_("&File"));
1437 config->addAction(loadAction);
1438 config->addAction(saveAction);
1439 config->addAction(saveAsAction);
Boris Barbulovski76bede82015-09-22 11:36:07 -07001440 config->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001441 config->addAction(quitAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001442
Shlomi Fish66e7c722007-02-14 00:32:58 -08001443 // create edit menu
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001444 QMenu* editMenu = menu->addMenu(_("&Edit"));
1445 editMenu->addAction(searchAction);
Shlomi Fish66e7c722007-02-14 00:32:58 -08001446
Linus Torvalds1da177e2005-04-16 15:20:36 -07001447 // create options menu
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001448 QMenu* optionMenu = menu->addMenu(_("&Option"));
1449 optionMenu->addAction(showNameAction);
1450 optionMenu->addAction(showRangeAction);
1451 optionMenu->addAction(showDataAction);
Boris Barbulovski76bede82015-09-22 11:36:07 -07001452 optionMenu->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001453 optionMenu->addActions(optGroup->actions());
Boris Barbulovski76bede82015-09-22 11:36:07 -07001454 optionMenu->addSeparator();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001455
1456 // create help menu
Boris Barbulovski76bede82015-09-22 11:36:07 -07001457 menu->addSeparator();
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001458 QMenu* helpMenu = menu->addMenu(_("&Help"));
1459 helpMenu->addAction(showIntroAction);
1460 helpMenu->addAction(showAboutAction);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001461
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001462 connect(configList, SIGNAL(menuChanged(struct menu *)),
1463 helpText, SLOT(setInfo(struct menu *)));
1464 connect(configList, SIGNAL(menuSelected(struct menu *)),
1465 SLOT(changeMenu(struct menu *)));
1466 connect(configList, SIGNAL(parentSelected()),
1467 SLOT(goBack()));
1468 connect(menuList, SIGNAL(menuChanged(struct menu *)),
1469 helpText, SLOT(setInfo(struct menu *)));
1470 connect(menuList, SIGNAL(menuSelected(struct menu *)),
1471 SLOT(changeMenu(struct menu *)));
1472
1473 connect(configList, SIGNAL(gotFocus(struct menu *)),
1474 helpText, SLOT(setInfo(struct menu *)));
1475 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1476 helpText, SLOT(setInfo(struct menu *)));
1477 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1478 SLOT(listFocusChanged(void)));
Roman Zippelb65a47e2006-06-08 22:12:47 -07001479 connect(helpText, SIGNAL(menuSelected(struct menu *)),
1480 SLOT(setMenuLink(struct menu *)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001481
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001482 QString listMode = configSettings->value("/listMode", "symbol").toString();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001483 if (listMode == "single")
1484 showSingleView();
1485 else if (listMode == "full")
1486 showFullView();
1487 else /*if (listMode == "split")*/
1488 showSplitView();
1489
1490 // UI setup done, restore splitter positions
Boris Barbulovski041fbdc2015-09-22 11:36:05 -07001491 QList<int> sizes = configSettings->readSizes("/split1", &ok);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001492 if (ok)
1493 split1->setSizes(sizes);
1494
Roman Zippel7fc925f2006-06-08 22:12:46 -07001495 sizes = configSettings->readSizes("/split2", &ok);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001496 if (ok)
1497 split2->setSizes(sizes);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001498}
1499
Linus Torvalds1da177e2005-04-16 15:20:36 -07001500void ConfigMainWindow::loadConfig(void)
1501{
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001502 QString s = QFileDialog::getOpenFileName(this, "", conf_get_configname());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001503 if (s.isNull())
1504 return;
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -07001505 if (conf_read(QFile::encodeName(s)))
EGRY Gaborc21a2d92008-01-11 23:52:07 +01001506 QMessageBox::information(this, "qconf", _("Unable to load configuration!"));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001507 ConfigView::updateListAll();
1508}
1509
Michal Marekbac6aa82011-05-25 15:10:25 +02001510bool ConfigMainWindow::saveConfig(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001511{
Michal Marekbac6aa82011-05-25 15:10:25 +02001512 if (conf_write(NULL)) {
EGRY Gaborc21a2d92008-01-11 23:52:07 +01001513 QMessageBox::information(this, "qconf", _("Unable to save configuration!"));
Michal Marekbac6aa82011-05-25 15:10:25 +02001514 return false;
1515 }
1516 return true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001517}
1518
1519void ConfigMainWindow::saveConfigAs(void)
1520{
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001521 QString s = QFileDialog::getSaveFileName(this, "", conf_get_configname());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001522 if (s.isNull())
1523 return;
Arnaud Lacombed49e4682011-05-24 14:16:18 -04001524 saveConfig();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001525}
1526
Roman Zippel43bf6122006-06-08 22:12:45 -07001527void ConfigMainWindow::searchConfig(void)
1528{
1529 if (!searchWindow)
Roman Zippel7fc925f2006-06-08 22:12:46 -07001530 searchWindow = new ConfigSearchWindow(this, "search");
Roman Zippel43bf6122006-06-08 22:12:45 -07001531 searchWindow->show();
1532}
1533
Linus Torvalds1da177e2005-04-16 15:20:36 -07001534void ConfigMainWindow::changeMenu(struct menu *menu)
1535{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001536 configList->setRootMenu(menu);
1537 if (configList->rootEntry->parent == &rootmenu)
1538 backAction->setEnabled(false);
1539 else
1540 backAction->setEnabled(true);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001541}
1542
Roman Zippelb65a47e2006-06-08 22:12:47 -07001543void ConfigMainWindow::setMenuLink(struct menu *menu)
1544{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001545 struct menu *parent;
1546 ConfigList* list = NULL;
1547 ConfigItem* item;
1548
1549 if (configList->menuSkip(menu))
1550 return;
1551
1552 switch (configList->mode) {
1553 case singleMode:
1554 list = configList;
1555 parent = menu_get_parent_menu(menu);
1556 if (!parent)
1557 return;
1558 list->setRootMenu(parent);
1559 break;
1560 case symbolMode:
1561 if (menu->flags & MENU_ROOT) {
1562 configList->setRootMenu(menu);
1563 configList->clearSelection();
1564 list = menuList;
1565 } else {
1566 list = configList;
1567 parent = menu_get_parent_menu(menu->parent);
1568 if (!parent)
1569 return;
1570 item = menuList->findConfigItem(parent);
1571 if (item) {
1572 item->setSelected(true);
1573 menuList->scrollToItem(item);
1574 }
1575 list->setRootMenu(parent);
1576 }
1577 break;
1578 case fullMode:
1579 list = configList;
1580 break;
1581 default:
1582 break;
1583 }
1584
1585 if (list) {
1586 item = list->findConfigItem(menu);
1587 if (item) {
1588 item->setSelected(true);
1589 list->scrollToItem(item);
1590 list->setFocus();
1591 }
1592 }
Roman Zippelb65a47e2006-06-08 22:12:47 -07001593}
1594
Linus Torvalds1da177e2005-04-16 15:20:36 -07001595void ConfigMainWindow::listFocusChanged(void)
1596{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001597 if (menuList->mode == menuMode)
1598 configList->clearSelection();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001599}
1600
1601void ConfigMainWindow::goBack(void)
1602{
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001603 ConfigItem* item;
1604
1605 configList->setParentMenu();
1606 if (configList->rootEntry == &rootmenu)
1607 backAction->setEnabled(false);
1608 item = (ConfigItem*)menuList->selectedItems().first();
1609 while (item) {
1610 if (item->menu == configList->rootEntry) {
1611 item->setSelected(true);
1612 break;
1613 }
1614 item = (ConfigItem*)item->parent();
1615 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001616}
1617
1618void ConfigMainWindow::showSingleView(void)
1619{
Boris Barbulovski780505e2015-09-22 11:36:13 -07001620 singleViewAction->setEnabled(false);
1621 singleViewAction->setChecked(true);
1622 splitViewAction->setEnabled(true);
1623 splitViewAction->setChecked(false);
1624 fullViewAction->setEnabled(true);
1625 fullViewAction->setChecked(false);
1626
Linus Torvalds1da177e2005-04-16 15:20:36 -07001627 menuView->hide();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001628 menuList->setRootMenu(0);
1629 configList->mode = singleMode;
1630 if (configList->rootEntry == &rootmenu)
1631 configList->updateListAll();
1632 else
1633 configList->setRootMenu(&rootmenu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001634 configList->setFocus();
1635}
1636
1637void ConfigMainWindow::showSplitView(void)
1638{
Boris Barbulovski780505e2015-09-22 11:36:13 -07001639 singleViewAction->setEnabled(true);
1640 singleViewAction->setChecked(false);
1641 splitViewAction->setEnabled(false);
1642 splitViewAction->setChecked(true);
1643 fullViewAction->setEnabled(true);
1644 fullViewAction->setChecked(false);
1645
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001646 configList->mode = symbolMode;
1647 if (configList->rootEntry == &rootmenu)
1648 configList->updateListAll();
1649 else
1650 configList->setRootMenu(&rootmenu);
1651 configList->setAllOpen(true);
1652 configApp->processEvents();
1653 menuList->mode = menuMode;
1654 menuList->setRootMenu(&rootmenu);
1655 menuList->setAllOpen(true);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001656 menuView->show();
1657 menuList->setFocus();
1658}
1659
1660void ConfigMainWindow::showFullView(void)
1661{
Boris Barbulovski780505e2015-09-22 11:36:13 -07001662 singleViewAction->setEnabled(true);
1663 singleViewAction->setChecked(false);
1664 splitViewAction->setEnabled(true);
1665 splitViewAction->setChecked(false);
1666 fullViewAction->setEnabled(false);
1667 fullViewAction->setChecked(true);
1668
Linus Torvalds1da177e2005-04-16 15:20:36 -07001669 menuView->hide();
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001670 menuList->setRootMenu(0);
1671 configList->mode = fullMode;
1672 if (configList->rootEntry == &rootmenu)
1673 configList->updateListAll();
1674 else
1675 configList->setRootMenu(&rootmenu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001676 configList->setFocus();
1677}
1678
Linus Torvalds1da177e2005-04-16 15:20:36 -07001679/*
1680 * ask for saving configuration before quitting
1681 * TODO ask only when something changed
1682 */
1683void ConfigMainWindow::closeEvent(QCloseEvent* e)
1684{
Karsten Wieseb3214292006-12-13 00:34:06 -08001685 if (!conf_get_changed()) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001686 e->accept();
1687 return;
1688 }
EGRY Gaborc21a2d92008-01-11 23:52:07 +01001689 QMessageBox mb("qconf", _("Save configuration?"), QMessageBox::Warning,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001690 QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape);
EGRY Gaborc21a2d92008-01-11 23:52:07 +01001691 mb.setButtonText(QMessageBox::Yes, _("&Save Changes"));
1692 mb.setButtonText(QMessageBox::No, _("&Discard Changes"));
1693 mb.setButtonText(QMessageBox::Cancel, _("Cancel Exit"));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001694 switch (mb.exec()) {
1695 case QMessageBox::Yes:
Michal Marekbac6aa82011-05-25 15:10:25 +02001696 if (saveConfig())
1697 e->accept();
1698 else
1699 e->ignore();
1700 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001701 case QMessageBox::No:
1702 e->accept();
1703 break;
1704 case QMessageBox::Cancel:
1705 e->ignore();
1706 break;
1707 }
1708}
1709
1710void ConfigMainWindow::showIntro(void)
1711{
Arnaud Lacombe652cf982010-08-14 23:51:40 -04001712 static const QString str = _("Welcome to the qconf graphical configuration tool.\n\n"
Linus Torvalds1da177e2005-04-16 15:20:36 -07001713 "For each option, a blank box indicates the feature is disabled, a check\n"
1714 "indicates it is enabled, and a dot indicates that it is to be compiled\n"
1715 "as a module. Clicking on the box will cycle through the three states.\n\n"
1716 "If you do not see an option (e.g., a device driver) that you believe\n"
1717 "should be present, try turning on Show All Options under the Options menu.\n"
1718 "Although there is no cross reference yet to help you figure out what other\n"
1719 "options must be enabled to support the option you are interested in, you can\n"
1720 "still view the help of a grayed-out option.\n\n"
1721 "Toggling Show Debug Info under the Options menu will show the dependencies,\n"
EGRY Gaborc21a2d92008-01-11 23:52:07 +01001722 "which you can then match by examining other options.\n\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001723
1724 QMessageBox::information(this, "qconf", str);
1725}
1726
1727void ConfigMainWindow::showAbout(void)
1728{
EGRY Gaborc21a2d92008-01-11 23:52:07 +01001729 static const QString str = _("qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n\n"
1730 "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001731
1732 QMessageBox::information(this, "qconf", str);
1733}
1734
1735void ConfigMainWindow::saveSettings(void)
1736{
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001737 configSettings->setValue("/window x", pos().x());
1738 configSettings->setValue("/window y", pos().y());
1739 configSettings->setValue("/window width", size().width());
1740 configSettings->setValue("/window height", size().height());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001741
1742 QString entry;
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001743 switch(configList->mode) {
1744 case singleMode :
1745 entry = "single";
1746 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001747
Boris Barbulovskid5d973c2015-09-22 11:36:19 -07001748 case symbolMode :
1749 entry = "split";
1750 break;
1751
1752 case fullMode :
1753 entry = "full";
1754 break;
1755
1756 default:
1757 break;
1758 }
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001759 configSettings->setValue("/listMode", entry);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001760
Roman Zippel7fc925f2006-06-08 22:12:46 -07001761 configSettings->writeSizes("/split1", split1->sizes());
1762 configSettings->writeSizes("/split2", split2->sizes());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001763}
1764
Karsten Wiese3b354c52006-12-13 00:34:08 -08001765void ConfigMainWindow::conf_changed(void)
1766{
1767 if (saveAction)
1768 saveAction->setEnabled(conf_get_changed());
1769}
1770
Linus Torvalds1da177e2005-04-16 15:20:36 -07001771void fixup_rootmenu(struct menu *menu)
1772{
1773 struct menu *child;
1774 static int menu_cnt = 0;
1775
1776 menu->flags |= MENU_ROOT;
1777 for (child = menu->list; child; child = child->next) {
1778 if (child->prompt && child->prompt->type == P_MENU) {
1779 menu_cnt++;
1780 fixup_rootmenu(child);
1781 menu_cnt--;
1782 } else if (!menu_cnt)
1783 fixup_rootmenu(child);
1784 }
1785}
1786
1787static const char *progname;
1788
1789static void usage(void)
1790{
Boris Barbulovski68ccb7e2015-09-22 11:36:15 -07001791 printf(_("%s [-s] <config>\n").toLatin1().constData(), progname);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001792 exit(0);
1793}
1794
1795int main(int ac, char** av)
1796{
1797 ConfigMainWindow* v;
1798 const char *name;
1799
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -07001800 bindtextdomain(PACKAGE, LOCALEDIR);
1801 textdomain(PACKAGE);
1802
Linus Torvalds1da177e2005-04-16 15:20:36 -07001803 progname = av[0];
1804 configApp = new QApplication(ac, av);
1805 if (ac > 1 && av[1][0] == '-') {
1806 switch (av[1][1]) {
Michal Marek0a1f00a2015-04-08 13:30:42 +02001807 case 's':
1808 conf_set_message_callback(NULL);
1809 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001810 case 'h':
1811 case '?':
1812 usage();
1813 }
1814 name = av[2];
1815 } else
1816 name = av[1];
1817 if (!name)
1818 usage();
1819
1820 conf_parse(name);
1821 fixup_rootmenu(&rootmenu);
1822 conf_read(NULL);
1823 //zconfdump(stdout);
1824
Roman Zippel7fc925f2006-06-08 22:12:46 -07001825 configSettings = new ConfigSettings();
1826 configSettings->beginGroup("/kconfig/qconf");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001827 v = new ConfigMainWindow();
1828
1829 //zconfdump(stdout);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001830 configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit()));
1831 configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings()));
Roman Zippel43bf6122006-06-08 22:12:45 -07001832 v->show();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001833 configApp->exec();
1834
Roman Zippel7fc925f2006-06-08 22:12:46 -07001835 configSettings->endGroup();
1836 delete configSettings;
1837
Linus Torvalds1da177e2005-04-16 15:20:36 -07001838 return 0;
1839}