blob: e787117c7d853399cc426197f97f408680693abd [file] [log] [blame]
Patrick Georgi0588d192009-08-12 15:00:51 +00001/*
2 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
zbao11a262c2016-01-22 18:54:22 +08003 * Copyright (C) 2015 Boris Barbulovski <bbarbulovski@gmail.com>
Patrick Georgi0588d192009-08-12 15:00:51 +00004 * Released under the terms of the GNU GPL v2.0.
5 */
6
Patrick Georgid5208402014-04-11 20:24:06 +02007#include <qglobal.h>
8
zbao11a262c2016-01-22 18:54:22 +08009#include <QMainWindow>
10#include <QList>
Patrick Georgid5208402014-04-11 20:24:06 +020011#include <qtextbrowser.h>
zbao11a262c2016-01-22 18:54:22 +080012#include <QAction>
13#include <QFileDialog>
14#include <QMenu>
Patrick Georgid5208402014-04-11 20:24:06 +020015
16#include <qapplication.h>
17#include <qdesktopwidget.h>
Patrick Georgi0588d192009-08-12 15:00:51 +000018#include <qtoolbar.h>
19#include <qlayout.h>
Patrick Georgi0588d192009-08-12 15:00:51 +000020#include <qsplitter.h>
Patrick Georgi0588d192009-08-12 15:00:51 +000021#include <qlineedit.h>
22#include <qlabel.h>
23#include <qpushbutton.h>
24#include <qmenubar.h>
25#include <qmessagebox.h>
Patrick Georgi0588d192009-08-12 15:00:51 +000026#include <qregexp.h>
Patrick Georgid5208402014-04-11 20:24:06 +020027#include <qevent.h>
Patrick Georgi0588d192009-08-12 15:00:51 +000028
29#include <stdlib.h>
30
31#include "lkc.h"
32#include "qconf.h"
33
34#include "qconf.moc"
35#include "images.c"
36
37#ifdef _
38# undef _
39# define _ qgettext
40#endif
41
Patrick Georgi44853372015-10-01 17:46:19 +020042int kconfig_warnings = 0;
43
Patrick Georgi0588d192009-08-12 15:00:51 +000044static QApplication *configApp;
45static ConfigSettings *configSettings;
46
zbao11a262c2016-01-22 18:54:22 +080047QAction *ConfigMainWindow::saveAction;
Patrick Georgi0588d192009-08-12 15:00:51 +000048
49static inline QString qgettext(const char* str)
50{
51 return QString::fromLocal8Bit(gettext(str));
52}
53
54static inline QString qgettext(const QString& str)
55{
zbao11a262c2016-01-22 18:54:22 +080056 return QString::fromLocal8Bit(gettext(str.toLatin1()));
Patrick Georgi0588d192009-08-12 15:00:51 +000057}
58
Patrick Georgid5208402014-04-11 20:24:06 +020059ConfigSettings::ConfigSettings()
60 : QSettings("kernel.org", "qconf")
61{
62}
63
Patrick Georgi0588d192009-08-12 15:00:51 +000064/**
65 * Reads a list of integer values from the application settings.
66 */
zbao11a262c2016-01-22 18:54:22 +080067QList<int> ConfigSettings::readSizes(const QString& key, bool *ok)
Patrick Georgi0588d192009-08-12 15:00:51 +000068{
zbao11a262c2016-01-22 18:54:22 +080069 QList<int> result;
70 QStringList entryList = value(key).toStringList();
Patrick Georgid5208402014-04-11 20:24:06 +020071 QStringList::Iterator it;
72
73 for (it = entryList.begin(); it != entryList.end(); ++it)
74 result.push_back((*it).toInt());
Patrick Georgi0588d192009-08-12 15:00:51 +000075
76 return result;
77}
78
79/**
80 * Writes a list of integer values to the application settings.
81 */
zbao11a262c2016-01-22 18:54:22 +080082bool ConfigSettings::writeSizes(const QString& key, const QList<int>& value)
Patrick Georgi0588d192009-08-12 15:00:51 +000083{
84 QStringList stringList;
zbao11a262c2016-01-22 18:54:22 +080085 QList<int>::ConstIterator it;
Patrick Georgi0588d192009-08-12 15:00:51 +000086
87 for (it = value.begin(); it != value.end(); ++it)
88 stringList.push_back(QString::number(*it));
zbao11a262c2016-01-22 18:54:22 +080089 setValue(key, stringList);
90
91 return true;
Patrick Georgi0588d192009-08-12 15:00:51 +000092}
93
94
Patrick Georgi0588d192009-08-12 15:00:51 +000095/*
96 * set the new data
97 * TODO check the value
98 */
99void ConfigItem::okRename(int col)
100{
Patrick Georgi0588d192009-08-12 15:00:51 +0000101}
Patrick Georgi0588d192009-08-12 15:00:51 +0000102
103/*
104 * update the displayed of a menu entry
105 */
106void ConfigItem::updateMenu(void)
107{
108 ConfigList* list;
109 struct symbol* sym;
110 struct property *prop;
111 QString prompt;
112 int type;
113 tristate expr;
114
115 list = listView();
116 if (goParent) {
117 setPixmap(promptColIdx, list->menuBackPix);
118 prompt = "..";
119 goto set_prompt;
120 }
121
122 sym = menu->sym;
123 prop = menu->prompt;
124 prompt = _(menu_get_prompt(menu));
125
126 if (prop) switch (prop->type) {
127 case P_MENU:
128 if (list->mode == singleMode || list->mode == symbolMode) {
129 /* a menuconfig entry is displayed differently
130 * depending whether it's at the view root or a child.
131 */
132 if (sym && list->rootEntry == menu)
133 break;
134 setPixmap(promptColIdx, list->menuPix);
135 } else {
136 if (sym)
137 break;
zbao11a262c2016-01-22 18:54:22 +0800138 setPixmap(promptColIdx, QIcon());
Patrick Georgi0588d192009-08-12 15:00:51 +0000139 }
140 goto set_prompt;
141 case P_COMMENT:
zbao11a262c2016-01-22 18:54:22 +0800142 setPixmap(promptColIdx, QIcon());
Patrick Georgi0588d192009-08-12 15:00:51 +0000143 goto set_prompt;
144 default:
145 ;
146 }
147 if (!sym)
148 goto set_prompt;
149
150 setText(nameColIdx, QString::fromLocal8Bit(sym->name));
151
152 type = sym_get_type(sym);
153 switch (type) {
154 case S_BOOLEAN:
155 case S_TRISTATE:
156 char ch;
157
Patrick Georgid5208402014-04-11 20:24:06 +0200158 if (!sym_is_changable(sym) && list->optMode == normalOpt) {
zbao11a262c2016-01-22 18:54:22 +0800159 setPixmap(promptColIdx, QIcon());
Patrick Georgi0588d192009-08-12 15:00:51 +0000160 setText(noColIdx, QString::null);
161 setText(modColIdx, QString::null);
162 setText(yesColIdx, QString::null);
163 break;
164 }
165 expr = sym_get_tristate_value(sym);
166 switch (expr) {
167 case yes:
168 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
169 setPixmap(promptColIdx, list->choiceYesPix);
170 else
171 setPixmap(promptColIdx, list->symbolYesPix);
172 setText(yesColIdx, "Y");
173 ch = 'Y';
174 break;
175 case mod:
176 setPixmap(promptColIdx, list->symbolModPix);
177 setText(modColIdx, "M");
178 ch = 'M';
179 break;
180 default:
181 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
182 setPixmap(promptColIdx, list->choiceNoPix);
183 else
184 setPixmap(promptColIdx, list->symbolNoPix);
185 setText(noColIdx, "N");
186 ch = 'N';
187 break;
188 }
189 if (expr != no)
190 setText(noColIdx, sym_tristate_within_range(sym, no) ? "_" : 0);
191 if (expr != mod)
192 setText(modColIdx, sym_tristate_within_range(sym, mod) ? "_" : 0);
193 if (expr != yes)
194 setText(yesColIdx, sym_tristate_within_range(sym, yes) ? "_" : 0);
195
196 setText(dataColIdx, QChar(ch));
197 break;
198 case S_INT:
199 case S_HEX:
200 case S_STRING:
201 const char* data;
202
203 data = sym_get_string_value(sym);
204
Patrick Georgi0588d192009-08-12 15:00:51 +0000205 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);
216}
217
218void ConfigItem::testUpdateMenu(bool v)
219{
220 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();
234}
235
Patrick Georgi0588d192009-08-12 15:00:51 +0000236
237/*
238 * construct a menu entry
239 */
240void ConfigItem::init(void)
241{
242 if (menu) {
243 ConfigList* list = listView();
244 nextItem = (ConfigItem*)menu->data;
245 menu->data = this;
246
247 if (list->mode != fullMode)
zbao11a262c2016-01-22 18:54:22 +0800248 setExpanded(true);
Patrick Georgi0588d192009-08-12 15:00:51 +0000249 sym_calc_value(menu->sym);
250 }
251 updateMenu();
252}
253
254/*
255 * destruct a menu entry
256 */
257ConfigItem::~ConfigItem(void)
258{
259 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 }
268}
269
270ConfigLineEdit::ConfigLineEdit(ConfigView* parent)
271 : Parent(parent)
272{
zbao11a262c2016-01-22 18:54:22 +0800273 connect(this, SIGNAL(editingFinished()), SLOT(hide()));
Patrick Georgi0588d192009-08-12 15:00:51 +0000274}
275
276void ConfigLineEdit::show(ConfigItem* i)
277{
278 item = i;
279 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);
283 Parent::show();
284 setFocus();
285}
286
287void ConfigLineEdit::keyPressEvent(QKeyEvent* e)
288{
289 switch (e->key()) {
Patrick Georgid5208402014-04-11 20:24:06 +0200290 case Qt::Key_Escape:
Patrick Georgi0588d192009-08-12 15:00:51 +0000291 break;
Patrick Georgid5208402014-04-11 20:24:06 +0200292 case Qt::Key_Return:
293 case Qt::Key_Enter:
zbao11a262c2016-01-22 18:54:22 +0800294 sym_set_string_value(item->menu->sym, text().toLatin1());
Patrick Georgi0588d192009-08-12 15:00:51 +0000295 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
306ConfigList::ConfigList(ConfigView* p, const char *name)
zbao11a262c2016-01-22 18:54:22 +0800307 : Parent(p),
Patrick Georgi0588d192009-08-12 15:00:51 +0000308 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),
zbao11a262c2016-01-22 18:54:22 +0800312 showName(false), showRange(false), showData(false), mode(singleMode), optMode(normalOpt),
Patrick Georgi0588d192009-08-12 15:00:51 +0000313 rootEntry(0), headerPopup(0)
314{
315 int i;
316
zbao11a262c2016-01-22 18:54:22 +0800317 setObjectName(name);
318 setSortingEnabled(false);
319 setRootIsDecorated(true);
Patrick Georgi0588d192009-08-12 15:00:51 +0000320
zbao11a262c2016-01-22 18:54:22 +0800321 setVerticalScrollMode(ScrollPerPixel);
322 setHorizontalScrollMode(ScrollPerPixel);
323
324 setHeaderLabels(QStringList() << _("Option") << _("Name") << "N" << "M" << "Y" << _("Value"));
325
326 connect(this, SIGNAL(itemSelectionChanged(void)),
Patrick Georgi0588d192009-08-12 15:00:51 +0000327 SLOT(updateSelection(void)));
328
329 if (name) {
330 configSettings->beginGroup(name);
zbao11a262c2016-01-22 18:54:22 +0800331 showName = configSettings->value("/showName", false).toBool();
332 showRange = configSettings->value("/showRange", false).toBool();
333 showData = configSettings->value("/showData", false).toBool();
334 optMode = (enum optionMode)configSettings->value("/optionMode", 0).toInt();
Patrick Georgi0588d192009-08-12 15:00:51 +0000335 configSettings->endGroup();
336 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
337 }
338
zbao11a262c2016-01-22 18:54:22 +0800339 addColumn(promptColIdx);
Patrick Georgi0588d192009-08-12 15:00:51 +0000340
341 reinit();
342}
343
Patrick Georgid5208402014-04-11 20:24:06 +0200344bool ConfigList::menuSkip(struct menu *menu)
345{
346 if (optMode == normalOpt && menu_is_visible(menu))
347 return false;
348 if (optMode == promptOpt && menu_has_prompt(menu))
349 return false;
350 if (optMode == allOpt)
351 return false;
352 return true;
353}
354
Patrick Georgi0588d192009-08-12 15:00:51 +0000355void ConfigList::reinit(void)
356{
357 removeColumn(dataColIdx);
358 removeColumn(yesColIdx);
359 removeColumn(modColIdx);
360 removeColumn(noColIdx);
361 removeColumn(nameColIdx);
362
363 if (showName)
zbao11a262c2016-01-22 18:54:22 +0800364 addColumn(nameColIdx);
Patrick Georgi0588d192009-08-12 15:00:51 +0000365 if (showRange) {
zbao11a262c2016-01-22 18:54:22 +0800366 addColumn(noColIdx);
367 addColumn(modColIdx);
368 addColumn(yesColIdx);
Patrick Georgi0588d192009-08-12 15:00:51 +0000369 }
370 if (showData)
zbao11a262c2016-01-22 18:54:22 +0800371 addColumn(dataColIdx);
Patrick Georgi0588d192009-08-12 15:00:51 +0000372
373 updateListAll();
374}
375
376void ConfigList::saveSettings(void)
377{
zbao11a262c2016-01-22 18:54:22 +0800378 if (!objectName().isEmpty()) {
379 configSettings->beginGroup(objectName());
380 configSettings->setValue("/showName", showName);
381 configSettings->setValue("/showRange", showRange);
382 configSettings->setValue("/showData", showData);
383 configSettings->setValue("/optionMode", (int)optMode);
Patrick Georgi0588d192009-08-12 15:00:51 +0000384 configSettings->endGroup();
385 }
386}
387
388ConfigItem* ConfigList::findConfigItem(struct menu *menu)
389{
390 ConfigItem* item = (ConfigItem*)menu->data;
391
392 for (; item; item = item->nextItem) {
393 if (this == item->listView())
394 break;
395 }
396
397 return item;
398}
399
400void ConfigList::updateSelection(void)
401{
402 struct menu *menu;
403 enum prop_type type;
404
zbao11a262c2016-01-22 18:54:22 +0800405 if (selectedItems().count() == 0)
406 return;
407
408 ConfigItem* item = (ConfigItem*)selectedItems().first();
Patrick Georgi0588d192009-08-12 15:00:51 +0000409 if (!item)
410 return;
411
412 menu = item->menu;
413 emit menuChanged(menu);
414 if (!menu)
415 return;
416 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
417 if (mode == menuMode && type == P_MENU)
418 emit menuSelected(menu);
419}
420
421void ConfigList::updateList(ConfigItem* item)
422{
423 ConfigItem* last = 0;
424
425 if (!rootEntry) {
426 if (mode != listMode)
427 goto update;
zbao11a262c2016-01-22 18:54:22 +0800428 QTreeWidgetItemIterator it(this);
Patrick Georgi0588d192009-08-12 15:00:51 +0000429 ConfigItem* item;
430
zbao11a262c2016-01-22 18:54:22 +0800431 while (*it) {
432 item = (ConfigItem*)(*it);
Patrick Georgi0588d192009-08-12 15:00:51 +0000433 if (!item->menu)
434 continue;
435 item->testUpdateMenu(menu_is_visible(item->menu));
zbao11a262c2016-01-22 18:54:22 +0800436
437 ++it;
Patrick Georgi0588d192009-08-12 15:00:51 +0000438 }
439 return;
440 }
441
442 if (rootEntry != &rootmenu && (mode == singleMode ||
443 (mode == symbolMode && rootEntry->parent != &rootmenu))) {
zbao11a262c2016-01-22 18:54:22 +0800444 item = (ConfigItem *)topLevelItem(0);
Patrick Georgi0588d192009-08-12 15:00:51 +0000445 if (!item)
446 item = new ConfigItem(this, 0, true);
447 last = item;
448 }
449 if ((mode == singleMode || (mode == symbolMode && !(rootEntry->flags & MENU_ROOT))) &&
450 rootEntry->sym && rootEntry->prompt) {
451 item = last ? last->nextSibling() : firstChild();
452 if (!item)
453 item = new ConfigItem(this, last, rootEntry, true);
454 else
455 item->testUpdateMenu(true);
456
457 updateMenuList(item, rootEntry);
zbao11a262c2016-01-22 18:54:22 +0800458 update();
459 resizeColumnToContents(0);
Patrick Georgi0588d192009-08-12 15:00:51 +0000460 return;
461 }
462update:
463 updateMenuList(this, rootEntry);
zbao11a262c2016-01-22 18:54:22 +0800464 update();
465 resizeColumnToContents(0);
Patrick Georgi0588d192009-08-12 15:00:51 +0000466}
467
468void ConfigList::setValue(ConfigItem* item, tristate val)
469{
470 struct symbol* sym;
471 int type;
472 tristate oldval;
473
474 sym = item->menu ? item->menu->sym : 0;
475 if (!sym)
476 return;
477
478 type = sym_get_type(sym);
479 switch (type) {
480 case S_BOOLEAN:
481 case S_TRISTATE:
482 oldval = sym_get_tristate_value(sym);
483
484 if (!sym_set_tristate_value(sym, val))
485 return;
486 if (oldval == no && item->menu->list)
zbao11a262c2016-01-22 18:54:22 +0800487 item->setExpanded(true);
Patrick Georgi0588d192009-08-12 15:00:51 +0000488 parent()->updateList(item);
489 break;
490 }
491}
492
493void ConfigList::changeValue(ConfigItem* item)
494{
495 struct symbol* sym;
496 struct menu* menu;
497 int type, oldexpr, newexpr;
498
499 menu = item->menu;
500 if (!menu)
501 return;
502 sym = menu->sym;
503 if (!sym) {
504 if (item->menu->list)
zbao11a262c2016-01-22 18:54:22 +0800505 item->setExpanded(!item->isExpanded());
Patrick Georgi0588d192009-08-12 15:00:51 +0000506 return;
507 }
508
509 type = sym_get_type(sym);
510 switch (type) {
511 case S_BOOLEAN:
512 case S_TRISTATE:
513 oldexpr = sym_get_tristate_value(sym);
514 newexpr = sym_toggle_tristate_value(sym);
515 if (item->menu->list) {
516 if (oldexpr == newexpr)
zbao11a262c2016-01-22 18:54:22 +0800517 item->setExpanded(!item->isExpanded());
Patrick Georgi0588d192009-08-12 15:00:51 +0000518 else if (oldexpr == no)
zbao11a262c2016-01-22 18:54:22 +0800519 item->setExpanded(true);
Patrick Georgi0588d192009-08-12 15:00:51 +0000520 }
521 if (oldexpr != newexpr)
522 parent()->updateList(item);
523 break;
524 case S_INT:
525 case S_HEX:
526 case S_STRING:
zbao11a262c2016-01-22 18:54:22 +0800527 parent()->lineEdit->show(item);
Patrick Georgi0588d192009-08-12 15:00:51 +0000528 break;
529 }
530}
531
532void ConfigList::setRootMenu(struct menu *menu)
533{
534 enum prop_type type;
535
536 if (rootEntry == menu)
537 return;
538 type = menu && menu->prompt ? menu->prompt->type : P_UNKNOWN;
539 if (type != P_MENU)
540 return;
541 updateMenuList(this, 0);
542 rootEntry = menu;
543 updateListAll();
zbao11a262c2016-01-22 18:54:22 +0800544 if (currentItem()) {
545 currentItem()->setSelected(hasFocus());
546 scrollToItem(currentItem());
547 }
Patrick Georgi0588d192009-08-12 15:00:51 +0000548}
549
550void ConfigList::setParentMenu(void)
551{
552 ConfigItem* item;
553 struct menu *oldroot;
554
555 oldroot = rootEntry;
556 if (rootEntry == &rootmenu)
557 return;
558 setRootMenu(menu_get_parent_menu(rootEntry->parent));
559
zbao11a262c2016-01-22 18:54:22 +0800560 QTreeWidgetItemIterator it(this);
561 while (*it) {
562 item = (ConfigItem *)(*it);
Patrick Georgi0588d192009-08-12 15:00:51 +0000563 if (item->menu == oldroot) {
564 setCurrentItem(item);
zbao11a262c2016-01-22 18:54:22 +0800565 scrollToItem(item);
Patrick Georgi0588d192009-08-12 15:00:51 +0000566 break;
567 }
zbao11a262c2016-01-22 18:54:22 +0800568
569 ++it;
Patrick Georgi0588d192009-08-12 15:00:51 +0000570 }
571}
572
573/*
574 * update all the children of a menu entry
575 * removes/adds the entries from the parent widget as necessary
576 *
577 * parent: either the menu list widget or a menu entry widget
578 * menu: entry to be updated
579 */
zbao11a262c2016-01-22 18:54:22 +0800580void ConfigList::updateMenuList(ConfigItem *parent, struct menu* menu)
Patrick Georgi0588d192009-08-12 15:00:51 +0000581{
582 struct menu* child;
583 ConfigItem* item;
584 ConfigItem* last;
585 bool visible;
586 enum prop_type type;
587
588 if (!menu) {
zbao11a262c2016-01-22 18:54:22 +0800589 while (parent->childCount() > 0)
590 {
591 delete parent->takeChild(0);
592 }
593
Patrick Georgi0588d192009-08-12 15:00:51 +0000594 return;
595 }
596
597 last = parent->firstChild();
598 if (last && !last->goParent)
599 last = 0;
600 for (child = menu->list; child; child = child->next) {
601 item = last ? last->nextSibling() : parent->firstChild();
602 type = child->prompt ? child->prompt->type : P_UNKNOWN;
603
604 switch (mode) {
605 case menuMode:
606 if (!(child->flags & MENU_ROOT))
607 goto hide;
608 break;
609 case symbolMode:
610 if (child->flags & MENU_ROOT)
611 goto hide;
612 break;
613 default:
614 break;
615 }
616
617 visible = menu_is_visible(child);
Patrick Georgid5208402014-04-11 20:24:06 +0200618 if (!menuSkip(child)) {
Patrick Georgi0588d192009-08-12 15:00:51 +0000619 if (!child->sym && !child->list && !child->prompt)
620 continue;
621 if (!item || item->menu != child)
622 item = new ConfigItem(parent, last, child, visible);
623 else
624 item->testUpdateMenu(visible);
625
626 if (mode == fullMode || mode == menuMode || type != P_MENU)
627 updateMenuList(item, child);
628 else
629 updateMenuList(item, 0);
630 last = item;
631 continue;
632 }
633 hide:
634 if (item && item->menu == child) {
635 last = parent->firstChild();
636 if (last == item)
637 last = 0;
638 else while (last->nextSibling() != item)
639 last = last->nextSibling();
640 delete item;
641 }
642 }
643}
644
zbao11a262c2016-01-22 18:54:22 +0800645void ConfigList::updateMenuList(ConfigList *parent, struct menu* menu)
646{
647 struct menu* child;
648 ConfigItem* item;
649 ConfigItem* last;
650 bool visible;
651 enum prop_type type;
652
653 if (!menu) {
654 while (parent->topLevelItemCount() > 0)
655 {
656 delete parent->takeTopLevelItem(0);
657 }
658
659 return;
660 }
661
662 last = (ConfigItem*)parent->topLevelItem(0);
663 if (last && !last->goParent)
664 last = 0;
665 for (child = menu->list; child; child = child->next) {
666 item = last ? last->nextSibling() : (ConfigItem*)parent->topLevelItem(0);
667 type = child->prompt ? child->prompt->type : P_UNKNOWN;
668
669 switch (mode) {
670 case menuMode:
671 if (!(child->flags & MENU_ROOT))
672 goto hide;
673 break;
674 case symbolMode:
675 if (child->flags & MENU_ROOT)
676 goto hide;
677 break;
678 default:
679 break;
680 }
681
682 visible = menu_is_visible(child);
683 if (!menuSkip(child)) {
684 if (!child->sym && !child->list && !child->prompt)
685 continue;
686 if (!item || item->menu != child)
687 item = new ConfigItem(parent, last, child, visible);
688 else
689 item->testUpdateMenu(visible);
690
691 if (mode == fullMode || mode == menuMode || type != P_MENU)
692 updateMenuList(item, child);
693 else
694 updateMenuList(item, 0);
695 last = item;
696 continue;
697 }
698 hide:
699 if (item && item->menu == child) {
700 last = (ConfigItem*)parent->topLevelItem(0);
701 if (last == item)
702 last = 0;
703 else while (last->nextSibling() != item)
704 last = last->nextSibling();
705 delete item;
706 }
707 }
708}
709
Patrick Georgi0588d192009-08-12 15:00:51 +0000710void ConfigList::keyPressEvent(QKeyEvent* ev)
711{
zbao11a262c2016-01-22 18:54:22 +0800712 QTreeWidgetItem* i = currentItem();
Patrick Georgi0588d192009-08-12 15:00:51 +0000713 ConfigItem* item;
714 struct menu *menu;
715 enum prop_type type;
716
Patrick Georgid5208402014-04-11 20:24:06 +0200717 if (ev->key() == Qt::Key_Escape && mode != fullMode && mode != listMode) {
Patrick Georgi0588d192009-08-12 15:00:51 +0000718 emit parentSelected();
719 ev->accept();
720 return;
721 }
722
723 if (!i) {
724 Parent::keyPressEvent(ev);
725 return;
726 }
727 item = (ConfigItem*)i;
728
729 switch (ev->key()) {
Patrick Georgid5208402014-04-11 20:24:06 +0200730 case Qt::Key_Return:
731 case Qt::Key_Enter:
Patrick Georgi0588d192009-08-12 15:00:51 +0000732 if (item->goParent) {
733 emit parentSelected();
734 break;
735 }
736 menu = item->menu;
737 if (!menu)
738 break;
739 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
740 if (type == P_MENU && rootEntry != menu &&
741 mode != fullMode && mode != menuMode) {
742 emit menuSelected(menu);
743 break;
744 }
Patrick Georgid5208402014-04-11 20:24:06 +0200745 case Qt::Key_Space:
Patrick Georgi0588d192009-08-12 15:00:51 +0000746 changeValue(item);
747 break;
Patrick Georgid5208402014-04-11 20:24:06 +0200748 case Qt::Key_N:
Patrick Georgi0588d192009-08-12 15:00:51 +0000749 setValue(item, no);
750 break;
Patrick Georgid5208402014-04-11 20:24:06 +0200751 case Qt::Key_M:
Patrick Georgi0588d192009-08-12 15:00:51 +0000752 setValue(item, mod);
753 break;
Patrick Georgid5208402014-04-11 20:24:06 +0200754 case Qt::Key_Y:
Patrick Georgi0588d192009-08-12 15:00:51 +0000755 setValue(item, yes);
756 break;
757 default:
758 Parent::keyPressEvent(ev);
759 return;
760 }
761 ev->accept();
762}
763
zbao11a262c2016-01-22 18:54:22 +0800764void ConfigList::mousePressEvent(QMouseEvent* e)
Patrick Georgi0588d192009-08-12 15:00:51 +0000765{
766 //QPoint p(contentsToViewport(e->pos()));
767 //printf("contentsMousePressEvent: %d,%d\n", p.x(), p.y());
zbao11a262c2016-01-22 18:54:22 +0800768 Parent::mousePressEvent(e);
Patrick Georgi0588d192009-08-12 15:00:51 +0000769}
770
zbao11a262c2016-01-22 18:54:22 +0800771void ConfigList::mouseReleaseEvent(QMouseEvent* e)
Patrick Georgi0588d192009-08-12 15:00:51 +0000772{
zbao11a262c2016-01-22 18:54:22 +0800773 QPoint p = e->pos();
Patrick Georgi0588d192009-08-12 15:00:51 +0000774 ConfigItem* item = (ConfigItem*)itemAt(p);
775 struct menu *menu;
776 enum prop_type ptype;
zbao11a262c2016-01-22 18:54:22 +0800777 QIcon icon;
Patrick Georgi0588d192009-08-12 15:00:51 +0000778 int idx, x;
779
780 if (!item)
781 goto skip;
782
783 menu = item->menu;
784 x = header()->offset() + p.x();
zbao11a262c2016-01-22 18:54:22 +0800785 idx = header()->logicalIndexAt(x);
Patrick Georgi0588d192009-08-12 15:00:51 +0000786 switch (idx) {
787 case promptColIdx:
zbao11a262c2016-01-22 18:54:22 +0800788 icon = item->pixmap(promptColIdx);
789 if (!icon.isNull()) {
790 int off = header()->sectionPosition(0) + visualRect(indexAt(p)).x() + 4; // 4 is Hardcoded image offset. There might be a way to do it properly.
791 if (x >= off && x < off + icon.availableSizes().first().width()) {
Patrick Georgi0588d192009-08-12 15:00:51 +0000792 if (item->goParent) {
793 emit parentSelected();
794 break;
795 } else if (!menu)
796 break;
797 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
798 if (ptype == P_MENU && rootEntry != menu &&
799 mode != fullMode && mode != menuMode)
800 emit menuSelected(menu);
801 else
802 changeValue(item);
803 }
804 }
805 break;
806 case noColIdx:
807 setValue(item, no);
808 break;
809 case modColIdx:
810 setValue(item, mod);
811 break;
812 case yesColIdx:
813 setValue(item, yes);
814 break;
815 case dataColIdx:
816 changeValue(item);
817 break;
818 }
819
820skip:
821 //printf("contentsMouseReleaseEvent: %d,%d\n", p.x(), p.y());
zbao11a262c2016-01-22 18:54:22 +0800822 Parent::mouseReleaseEvent(e);
Patrick Georgi0588d192009-08-12 15:00:51 +0000823}
824
zbao11a262c2016-01-22 18:54:22 +0800825void ConfigList::mouseMoveEvent(QMouseEvent* e)
Patrick Georgi0588d192009-08-12 15:00:51 +0000826{
827 //QPoint p(contentsToViewport(e->pos()));
828 //printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y());
zbao11a262c2016-01-22 18:54:22 +0800829 Parent::mouseMoveEvent(e);
Patrick Georgi0588d192009-08-12 15:00:51 +0000830}
831
zbao11a262c2016-01-22 18:54:22 +0800832void ConfigList::mouseDoubleClickEvent(QMouseEvent* e)
Patrick Georgi0588d192009-08-12 15:00:51 +0000833{
zbao11a262c2016-01-22 18:54:22 +0800834 QPoint p = e->pos(); // TODO: Check if this works(was contentsToViewport).
Patrick Georgi0588d192009-08-12 15:00:51 +0000835 ConfigItem* item = (ConfigItem*)itemAt(p);
836 struct menu *menu;
837 enum prop_type ptype;
838
839 if (!item)
840 goto skip;
841 if (item->goParent) {
842 emit parentSelected();
843 goto skip;
844 }
845 menu = item->menu;
846 if (!menu)
847 goto skip;
848 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
849 if (ptype == P_MENU && (mode == singleMode || mode == symbolMode))
850 emit menuSelected(menu);
851 else if (menu->sym)
852 changeValue(item);
853
854skip:
855 //printf("contentsMouseDoubleClickEvent: %d,%d\n", p.x(), p.y());
zbao11a262c2016-01-22 18:54:22 +0800856 Parent::mouseDoubleClickEvent(e);
Patrick Georgi0588d192009-08-12 15:00:51 +0000857}
858
859void ConfigList::focusInEvent(QFocusEvent *e)
860{
861 struct menu *menu = NULL;
862
863 Parent::focusInEvent(e);
864
865 ConfigItem* item = (ConfigItem *)currentItem();
866 if (item) {
zbao11a262c2016-01-22 18:54:22 +0800867 item->setSelected(true);
Patrick Georgi0588d192009-08-12 15:00:51 +0000868 menu = item->menu;
869 }
870 emit gotFocus(menu);
871}
872
873void ConfigList::contextMenuEvent(QContextMenuEvent *e)
874{
875 if (e->y() <= header()->geometry().bottom()) {
876 if (!headerPopup) {
zbao11a262c2016-01-22 18:54:22 +0800877 QAction *action;
Patrick Georgi0588d192009-08-12 15:00:51 +0000878
zbao11a262c2016-01-22 18:54:22 +0800879 headerPopup = new QMenu(this);
880 action = new QAction(_("Show Name"), this);
881 action->setCheckable(true);
Patrick Georgi0588d192009-08-12 15:00:51 +0000882 connect(action, SIGNAL(toggled(bool)),
883 parent(), SLOT(setShowName(bool)));
884 connect(parent(), SIGNAL(showNameChanged(bool)),
885 action, SLOT(setOn(bool)));
zbao11a262c2016-01-22 18:54:22 +0800886 action->setChecked(showName);
887 headerPopup->addAction(action);
888 action = new QAction(_("Show Range"), this);
889 action->setCheckable(true);
Patrick Georgi0588d192009-08-12 15:00:51 +0000890 connect(action, SIGNAL(toggled(bool)),
891 parent(), SLOT(setShowRange(bool)));
892 connect(parent(), SIGNAL(showRangeChanged(bool)),
893 action, SLOT(setOn(bool)));
zbao11a262c2016-01-22 18:54:22 +0800894 action->setChecked(showRange);
895 headerPopup->addAction(action);
896 action = new QAction(_("Show Data"), this);
897 action->setCheckable(true);
Patrick Georgi0588d192009-08-12 15:00:51 +0000898 connect(action, SIGNAL(toggled(bool)),
899 parent(), SLOT(setShowData(bool)));
900 connect(parent(), SIGNAL(showDataChanged(bool)),
901 action, SLOT(setOn(bool)));
zbao11a262c2016-01-22 18:54:22 +0800902 action->setChecked(showData);
903 headerPopup->addAction(action);
Patrick Georgi0588d192009-08-12 15:00:51 +0000904 }
905 headerPopup->exec(e->globalPos());
906 e->accept();
907 } else
908 e->ignore();
909}
910
Patrick Georgid5208402014-04-11 20:24:06 +0200911ConfigView*ConfigView::viewList;
912QAction *ConfigView::showNormalAction;
913QAction *ConfigView::showAllAction;
914QAction *ConfigView::showPromptAction;
Patrick Georgi0588d192009-08-12 15:00:51 +0000915
916ConfigView::ConfigView(QWidget* parent, const char *name)
zbao11a262c2016-01-22 18:54:22 +0800917 : Parent(parent)
Patrick Georgi0588d192009-08-12 15:00:51 +0000918{
zbao11a262c2016-01-22 18:54:22 +0800919 setObjectName(name);
920 QVBoxLayout *verticalLayout = new QVBoxLayout(this);
921 verticalLayout->setContentsMargins(0, 0, 0, 0);
922
923 list = new ConfigList(this);
924 verticalLayout->addWidget(list);
Patrick Georgi0588d192009-08-12 15:00:51 +0000925 lineEdit = new ConfigLineEdit(this);
926 lineEdit->hide();
zbao11a262c2016-01-22 18:54:22 +0800927 verticalLayout->addWidget(lineEdit);
Patrick Georgi0588d192009-08-12 15:00:51 +0000928
929 this->nextView = viewList;
930 viewList = this;
931}
932
933ConfigView::~ConfigView(void)
934{
935 ConfigView** vp;
936
937 for (vp = &viewList; *vp; vp = &(*vp)->nextView) {
938 if (*vp == this) {
939 *vp = nextView;
940 break;
941 }
942 }
943}
944
Patrick Georgid5208402014-04-11 20:24:06 +0200945void ConfigView::setOptionMode(QAction *act)
Patrick Georgi0588d192009-08-12 15:00:51 +0000946{
Patrick Georgid5208402014-04-11 20:24:06 +0200947 if (act == showNormalAction)
948 list->optMode = normalOpt;
949 else if (act == showAllAction)
950 list->optMode = allOpt;
951 else
952 list->optMode = promptOpt;
953
954 list->updateListAll();
Patrick Georgi0588d192009-08-12 15:00:51 +0000955}
956
957void ConfigView::setShowName(bool b)
958{
959 if (list->showName != b) {
960 list->showName = b;
961 list->reinit();
962 emit showNameChanged(b);
963 }
964}
965
966void ConfigView::setShowRange(bool b)
967{
968 if (list->showRange != b) {
969 list->showRange = b;
970 list->reinit();
971 emit showRangeChanged(b);
972 }
973}
974
975void ConfigView::setShowData(bool b)
976{
977 if (list->showData != b) {
978 list->showData = b;
979 list->reinit();
980 emit showDataChanged(b);
981 }
982}
983
984void ConfigList::setAllOpen(bool open)
985{
zbao11a262c2016-01-22 18:54:22 +0800986 QTreeWidgetItemIterator it(this);
Patrick Georgi0588d192009-08-12 15:00:51 +0000987
zbao11a262c2016-01-22 18:54:22 +0800988 while (*it) {
989 (*it)->setExpanded(open);
990
991 ++it;
992 }
Patrick Georgi0588d192009-08-12 15:00:51 +0000993}
994
995void ConfigView::updateList(ConfigItem* item)
996{
997 ConfigView* v;
998
999 for (v = viewList; v; v = v->nextView)
1000 v->list->updateList(item);
1001}
1002
1003void ConfigView::updateListAll(void)
1004{
1005 ConfigView* v;
1006
1007 for (v = viewList; v; v = v->nextView)
1008 v->list->updateListAll();
1009}
1010
1011ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name)
zbao11a262c2016-01-22 18:54:22 +08001012 : Parent(parent), sym(0), _menu(0)
Patrick Georgi0588d192009-08-12 15:00:51 +00001013{
zbao11a262c2016-01-22 18:54:22 +08001014 setObjectName(name);
1015
1016
1017 if (!objectName().isEmpty()) {
1018 configSettings->beginGroup(objectName());
1019 _showDebug = configSettings->value("/showDebug", false).toBool();
Patrick Georgi0588d192009-08-12 15:00:51 +00001020 configSettings->endGroup();
1021 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
1022 }
1023}
1024
1025void ConfigInfoView::saveSettings(void)
1026{
zbao11a262c2016-01-22 18:54:22 +08001027 if (!objectName().isEmpty()) {
1028 configSettings->beginGroup(objectName());
1029 configSettings->setValue("/showDebug", showDebug());
Patrick Georgi0588d192009-08-12 15:00:51 +00001030 configSettings->endGroup();
1031 }
1032}
1033
1034void ConfigInfoView::setShowDebug(bool b)
1035{
1036 if (_showDebug != b) {
1037 _showDebug = b;
Patrick Georgid5208402014-04-11 20:24:06 +02001038 if (_menu)
Patrick Georgi0588d192009-08-12 15:00:51 +00001039 menuInfo();
1040 else if (sym)
1041 symbolInfo();
1042 emit showDebugChanged(b);
1043 }
1044}
1045
1046void ConfigInfoView::setInfo(struct menu *m)
1047{
Patrick Georgid5208402014-04-11 20:24:06 +02001048 if (_menu == m)
Patrick Georgi0588d192009-08-12 15:00:51 +00001049 return;
Patrick Georgid5208402014-04-11 20:24:06 +02001050 _menu = m;
Patrick Georgi0588d192009-08-12 15:00:51 +00001051 sym = NULL;
Patrick Georgid5208402014-04-11 20:24:06 +02001052 if (!_menu)
Patrick Georgi0588d192009-08-12 15:00:51 +00001053 clear();
1054 else
1055 menuInfo();
1056}
1057
Patrick Georgi0588d192009-08-12 15:00:51 +00001058void ConfigInfoView::symbolInfo(void)
1059{
1060 QString str;
1061
1062 str += "<big>Symbol: <b>";
1063 str += print_filter(sym->name);
1064 str += "</b></big><br><br>value: ";
1065 str += print_filter(sym_get_string_value(sym));
1066 str += "<br>visibility: ";
1067 str += sym->visible == yes ? "y" : sym->visible == mod ? "m" : "n";
1068 str += "<br>";
1069 str += debug_info(sym);
1070
1071 setText(str);
1072}
1073
1074void ConfigInfoView::menuInfo(void)
1075{
1076 struct symbol* sym;
1077 QString head, debug, help;
1078
Patrick Georgid5208402014-04-11 20:24:06 +02001079 sym = _menu->sym;
Patrick Georgi0588d192009-08-12 15:00:51 +00001080 if (sym) {
Patrick Georgid5208402014-04-11 20:24:06 +02001081 if (_menu->prompt) {
Patrick Georgi0588d192009-08-12 15:00:51 +00001082 head += "<big><b>";
Patrick Georgid5208402014-04-11 20:24:06 +02001083 head += print_filter(_(_menu->prompt->text));
Patrick Georgi0588d192009-08-12 15:00:51 +00001084 head += "</b></big>";
1085 if (sym->name) {
1086 head += " (";
1087 if (showDebug())
1088 head += QString().sprintf("<a href=\"s%p\">", sym);
1089 head += print_filter(sym->name);
1090 if (showDebug())
1091 head += "</a>";
1092 head += ")";
1093 }
1094 } else if (sym->name) {
1095 head += "<big><b>";
1096 if (showDebug())
1097 head += QString().sprintf("<a href=\"s%p\">", sym);
1098 head += print_filter(sym->name);
1099 if (showDebug())
1100 head += "</a>";
1101 head += "</b></big>";
1102 }
1103 head += "<br><br>";
1104
1105 if (showDebug())
1106 debug = debug_info(sym);
1107
Patrick Georgid5208402014-04-11 20:24:06 +02001108 struct gstr help_gstr = str_new();
1109 menu_get_ext_help(_menu, &help_gstr);
1110 help = print_filter(str_get(&help_gstr));
1111 str_free(&help_gstr);
1112 } else if (_menu->prompt) {
Patrick Georgi0588d192009-08-12 15:00:51 +00001113 head += "<big><b>";
Patrick Georgid5208402014-04-11 20:24:06 +02001114 head += print_filter(_(_menu->prompt->text));
Patrick Georgi0588d192009-08-12 15:00:51 +00001115 head += "</b></big><br><br>";
1116 if (showDebug()) {
Patrick Georgid5208402014-04-11 20:24:06 +02001117 if (_menu->prompt->visible.expr) {
Patrick Georgi0588d192009-08-12 15:00:51 +00001118 debug += "&nbsp;&nbsp;dep: ";
Patrick Georgid5208402014-04-11 20:24:06 +02001119 expr_print(_menu->prompt->visible.expr, expr_print_help, &debug, E_NONE);
Patrick Georgi0588d192009-08-12 15:00:51 +00001120 debug += "<br><br>";
1121 }
1122 }
1123 }
1124 if (showDebug())
Patrick Georgid5208402014-04-11 20:24:06 +02001125 debug += QString().sprintf("defined at %s:%d<br><br>", _menu->file->name, _menu->lineno);
Patrick Georgi0588d192009-08-12 15:00:51 +00001126
1127 setText(head + debug + help);
1128}
1129
1130QString ConfigInfoView::debug_info(struct symbol *sym)
1131{
1132 QString debug;
1133
1134 debug += "type: ";
1135 debug += print_filter(sym_type_name(sym->type));
1136 if (sym_is_choice(sym))
1137 debug += " (choice)";
1138 debug += "<br>";
1139 if (sym->rev_dep.expr) {
1140 debug += "reverse dep: ";
1141 expr_print(sym->rev_dep.expr, expr_print_help, &debug, E_NONE);
1142 debug += "<br>";
1143 }
1144 for (struct property *prop = sym->prop; prop; prop = prop->next) {
1145 switch (prop->type) {
1146 case P_PROMPT:
1147 case P_MENU:
1148 debug += QString().sprintf("prompt: <a href=\"m%p\">", prop->menu);
1149 debug += print_filter(_(prop->text));
1150 debug += "</a><br>";
1151 break;
1152 case P_DEFAULT:
1153 case P_SELECT:
1154 case P_RANGE:
1155 case P_ENV:
1156 debug += prop_get_type_name(prop->type);
1157 debug += ": ";
1158 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1159 debug += "<br>";
1160 break;
1161 case P_CHOICE:
1162 if (sym_is_choice(sym)) {
1163 debug += "choice: ";
1164 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1165 debug += "<br>";
1166 }
1167 break;
1168 default:
1169 debug += "unknown property: ";
1170 debug += prop_get_type_name(prop->type);
1171 debug += "<br>";
1172 }
1173 if (prop->visible.expr) {
1174 debug += "&nbsp;&nbsp;&nbsp;&nbsp;dep: ";
1175 expr_print(prop->visible.expr, expr_print_help, &debug, E_NONE);
1176 debug += "<br>";
1177 }
1178 }
1179 debug += "<br>";
1180
1181 return debug;
1182}
1183
1184QString ConfigInfoView::print_filter(const QString &str)
1185{
1186 QRegExp re("[<>&\"\\n]");
1187 QString res = str;
zbao11a262c2016-01-22 18:54:22 +08001188 for (int i = 0; (i = res.indexOf(re, i)) >= 0;) {
1189 switch (res[i].toLatin1()) {
Patrick Georgi0588d192009-08-12 15:00:51 +00001190 case '<':
1191 res.replace(i, 1, "&lt;");
1192 i += 4;
1193 break;
1194 case '>':
1195 res.replace(i, 1, "&gt;");
1196 i += 4;
1197 break;
1198 case '&':
1199 res.replace(i, 1, "&amp;");
1200 i += 5;
1201 break;
1202 case '"':
1203 res.replace(i, 1, "&quot;");
1204 i += 6;
1205 break;
1206 case '\n':
1207 res.replace(i, 1, "<br>");
1208 i += 4;
1209 break;
1210 }
1211 }
1212 return res;
1213}
1214
1215void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char *str)
1216{
1217 QString* text = reinterpret_cast<QString*>(data);
1218 QString str2 = print_filter(str);
1219
1220 if (sym && sym->name && !(sym->flags & SYMBOL_CONST)) {
1221 *text += QString().sprintf("<a href=\"s%p\">", sym);
1222 *text += str2;
1223 *text += "</a>";
1224 } else
1225 *text += str2;
1226}
1227
zbao11a262c2016-01-22 18:54:22 +08001228QMenu* ConfigInfoView::createStandardContextMenu(const QPoint & pos)
Patrick Georgi0588d192009-08-12 15:00:51 +00001229{
zbao11a262c2016-01-22 18:54:22 +08001230 QMenu* popup = Parent::createStandardContextMenu(pos);
1231 QAction* action = new QAction(_("Show Debug Info"), popup);
1232 action->setCheckable(true);
Patrick Georgi0588d192009-08-12 15:00:51 +00001233 connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
1234 connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool)));
zbao11a262c2016-01-22 18:54:22 +08001235 action->setChecked(showDebug());
1236 popup->addSeparator();
1237 popup->addAction(action);
Patrick Georgi0588d192009-08-12 15:00:51 +00001238 return popup;
1239}
1240
zbao11a262c2016-01-22 18:54:22 +08001241void ConfigInfoView::contextMenuEvent(QContextMenuEvent *e)
Patrick Georgi0588d192009-08-12 15:00:51 +00001242{
zbao11a262c2016-01-22 18:54:22 +08001243 Parent::contextMenuEvent(e);
Patrick Georgi0588d192009-08-12 15:00:51 +00001244}
1245
1246ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow* parent, const char *name)
zbao11a262c2016-01-22 18:54:22 +08001247 : Parent(parent), result(NULL)
Patrick Georgi0588d192009-08-12 15:00:51 +00001248{
zbao11a262c2016-01-22 18:54:22 +08001249 setObjectName(name);
1250 setWindowTitle("Search Config");
Patrick Georgi0588d192009-08-12 15:00:51 +00001251
zbao11a262c2016-01-22 18:54:22 +08001252 QVBoxLayout* layout1 = new QVBoxLayout(this);
1253 layout1->setContentsMargins(11, 11, 11, 11);
1254 layout1->setSpacing(6);
1255 QHBoxLayout* layout2 = new QHBoxLayout(0);
1256 layout2->setContentsMargins(0, 0, 0, 0);
1257 layout2->setSpacing(6);
Patrick Georgi0588d192009-08-12 15:00:51 +00001258 layout2->addWidget(new QLabel(_("Find:"), this));
1259 editField = new QLineEdit(this);
1260 connect(editField, SIGNAL(returnPressed()), SLOT(search()));
1261 layout2->addWidget(editField);
1262 searchButton = new QPushButton(_("Search"), this);
zbao11a262c2016-01-22 18:54:22 +08001263 searchButton->setAutoDefault(false);
Patrick Georgi0588d192009-08-12 15:00:51 +00001264 connect(searchButton, SIGNAL(clicked()), SLOT(search()));
1265 layout2->addWidget(searchButton);
1266 layout1->addLayout(layout2);
1267
1268 split = new QSplitter(this);
Patrick Georgid5208402014-04-11 20:24:06 +02001269 split->setOrientation(Qt::Vertical);
Patrick Georgi0588d192009-08-12 15:00:51 +00001270 list = new ConfigView(split, name);
1271 list->list->mode = listMode;
1272 info = new ConfigInfoView(split, name);
1273 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1274 info, SLOT(setInfo(struct menu *)));
1275 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1276 parent, SLOT(setMenuLink(struct menu *)));
1277
1278 layout1->addWidget(split);
1279
1280 if (name) {
zbao11a262c2016-01-22 18:54:22 +08001281 QVariant x, y;
1282 int width, height;
Patrick Georgi0588d192009-08-12 15:00:51 +00001283 bool ok;
1284
1285 configSettings->beginGroup(name);
zbao11a262c2016-01-22 18:54:22 +08001286 width = configSettings->value("/window width", parent->width() / 2).toInt();
1287 height = configSettings->value("/window height", parent->height() / 2).toInt();
Patrick Georgi0588d192009-08-12 15:00:51 +00001288 resize(width, height);
zbao11a262c2016-01-22 18:54:22 +08001289 x = configSettings->value("/window x");
1290 y = configSettings->value("/window y");
1291 if ((x.isValid())&&(y.isValid()))
1292 move(x.toInt(), y.toInt());
1293 QList<int> sizes = configSettings->readSizes("/split", &ok);
Patrick Georgi0588d192009-08-12 15:00:51 +00001294 if (ok)
1295 split->setSizes(sizes);
1296 configSettings->endGroup();
1297 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
1298 }
1299}
1300
1301void ConfigSearchWindow::saveSettings(void)
1302{
zbao11a262c2016-01-22 18:54:22 +08001303 if (!objectName().isEmpty()) {
1304 configSettings->beginGroup(objectName());
1305 configSettings->setValue("/window x", pos().x());
1306 configSettings->setValue("/window y", pos().y());
1307 configSettings->setValue("/window width", size().width());
1308 configSettings->setValue("/window height", size().height());
Patrick Georgi0588d192009-08-12 15:00:51 +00001309 configSettings->writeSizes("/split", split->sizes());
1310 configSettings->endGroup();
1311 }
1312}
1313
1314void ConfigSearchWindow::search(void)
1315{
1316 struct symbol **p;
1317 struct property *prop;
1318 ConfigItem *lastItem = NULL;
1319
1320 free(result);
1321 list->list->clear();
1322 info->clear();
1323
zbao11a262c2016-01-22 18:54:22 +08001324 result = sym_re_search(editField->text().toLatin1());
Patrick Georgi0588d192009-08-12 15:00:51 +00001325 if (!result)
1326 return;
1327 for (p = result; *p; p++) {
1328 for_all_prompts((*p), prop)
1329 lastItem = new ConfigItem(list->list, lastItem, prop->menu,
1330 menu_is_visible(prop->menu));
1331 }
1332}
1333
1334/*
1335 * Construct the complete config widget
1336 */
1337ConfigMainWindow::ConfigMainWindow(void)
1338 : searchWindow(0)
1339{
1340 QMenuBar* menu;
zbao11a262c2016-01-22 18:54:22 +08001341 bool ok = true;
1342 QVariant x, y;
1343 int width, height;
Patrick Georgi0588d192009-08-12 15:00:51 +00001344 char title[256];
1345
Patrick Georgid5208402014-04-11 20:24:06 +02001346 QDesktopWidget *d = configApp->desktop();
1347 snprintf(title, sizeof(title), "%s%s",
1348 rootmenu.prompt->text,
Patrick Georgid5208402014-04-11 20:24:06 +02001349 ""
Patrick Georgid5208402014-04-11 20:24:06 +02001350 );
zbao11a262c2016-01-22 18:54:22 +08001351 setWindowTitle(title);
Patrick Georgi0588d192009-08-12 15:00:51 +00001352
zbao11a262c2016-01-22 18:54:22 +08001353 width = configSettings->value("/window width", d->width() - 64).toInt();
1354 height = configSettings->value("/window height", d->height() - 64).toInt();
Patrick Georgi0588d192009-08-12 15:00:51 +00001355 resize(width, height);
zbao11a262c2016-01-22 18:54:22 +08001356 x = configSettings->value("/window x");
1357 y = configSettings->value("/window y");
1358 if ((x.isValid())&&(y.isValid()))
1359 move(x.toInt(), y.toInt());
Patrick Georgi0588d192009-08-12 15:00:51 +00001360
1361 split1 = new QSplitter(this);
Patrick Georgid5208402014-04-11 20:24:06 +02001362 split1->setOrientation(Qt::Horizontal);
Patrick Georgi0588d192009-08-12 15:00:51 +00001363 setCentralWidget(split1);
1364
1365 menuView = new ConfigView(split1, "menu");
1366 menuList = menuView->list;
1367
1368 split2 = new QSplitter(split1);
Patrick Georgid5208402014-04-11 20:24:06 +02001369 split2->setOrientation(Qt::Vertical);
Patrick Georgi0588d192009-08-12 15:00:51 +00001370
1371 // create config tree
1372 configView = new ConfigView(split2, "config");
1373 configList = configView->list;
1374
1375 helpText = new ConfigInfoView(split2, "help");
Patrick Georgi0588d192009-08-12 15:00:51 +00001376
1377 setTabOrder(configList, helpText);
1378 configList->setFocus();
1379
1380 menu = menuBar();
zbao11a262c2016-01-22 18:54:22 +08001381 toolBar = new QToolBar("Tools", this);
1382 addToolBar(toolBar);
Patrick Georgi0588d192009-08-12 15:00:51 +00001383
zbao11a262c2016-01-22 18:54:22 +08001384 backAction = new QAction(QPixmap(xpm_back), _("Back"), this);
1385 connect(backAction, SIGNAL(triggered(bool)), SLOT(goBack()));
1386 backAction->setEnabled(false);
1387 QAction *quitAction = new QAction(_("&Quit"), this);
1388 quitAction->setShortcut(Qt::CTRL + Qt::Key_Q);
1389 connect(quitAction, SIGNAL(triggered(bool)), SLOT(close()));
1390 QAction *loadAction = new QAction(QPixmap(xpm_load), _("&Load"), this);
1391 loadAction->setShortcut(Qt::CTRL + Qt::Key_L);
1392 connect(loadAction, SIGNAL(triggered(bool)), SLOT(loadConfig()));
1393 saveAction = new QAction(QPixmap(xpm_save), _("&Save"), this);
1394 saveAction->setShortcut(Qt::CTRL + Qt::Key_S);
1395 connect(saveAction, SIGNAL(triggered(bool)), SLOT(saveConfig()));
Patrick Georgi0588d192009-08-12 15:00:51 +00001396 conf_set_changed_callback(conf_changed);
1397 // Set saveAction's initial state
1398 conf_changed();
zbao11a262c2016-01-22 18:54:22 +08001399 QAction *saveAsAction = new QAction(_("Save &As..."), this);
1400 connect(saveAsAction, SIGNAL(triggered(bool)), SLOT(saveConfigAs()));
1401 QAction *searchAction = new QAction(_("&Find"), this);
1402 searchAction->setShortcut(Qt::CTRL + Qt::Key_F);
1403 connect(searchAction, SIGNAL(triggered(bool)), SLOT(searchConfig()));
1404 singleViewAction = new QAction(QPixmap(xpm_single_view), _("Single View"), this);
1405 singleViewAction->setCheckable(true);
1406 connect(singleViewAction, SIGNAL(triggered(bool)), SLOT(showSingleView()));
1407 splitViewAction = new QAction(QPixmap(xpm_split_view), _("Split View"), this);
1408 splitViewAction->setCheckable(true);
1409 connect(splitViewAction, SIGNAL(triggered(bool)), SLOT(showSplitView()));
1410 fullViewAction = new QAction(QPixmap(xpm_tree_view), _("Full View"), this);
1411 fullViewAction->setCheckable(true);
1412 connect(fullViewAction, SIGNAL(triggered(bool)), SLOT(showFullView()));
Patrick Georgi0588d192009-08-12 15:00:51 +00001413
zbao11a262c2016-01-22 18:54:22 +08001414 QAction *showNameAction = new QAction(_("Show Name"), this);
1415 showNameAction->setCheckable(true);
Patrick Georgi0588d192009-08-12 15:00:51 +00001416 connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool)));
zbao11a262c2016-01-22 18:54:22 +08001417 showNameAction->setChecked(configView->showName());
1418 QAction *showRangeAction = new QAction(_("Show Range"), this);
1419 showRangeAction->setCheckable(true);
Patrick Georgi0588d192009-08-12 15:00:51 +00001420 connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool)));
zbao11a262c2016-01-22 18:54:22 +08001421 QAction *showDataAction = new QAction(_("Show Data"), this);
1422 showDataAction->setCheckable(true);
Patrick Georgi0588d192009-08-12 15:00:51 +00001423 connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool)));
Patrick Georgid5208402014-04-11 20:24:06 +02001424
1425 QActionGroup *optGroup = new QActionGroup(this);
zbao11a262c2016-01-22 18:54:22 +08001426 optGroup->setExclusive(true);
1427 connect(optGroup, SIGNAL(triggered(QAction*)), configView,
Patrick Georgid5208402014-04-11 20:24:06 +02001428 SLOT(setOptionMode(QAction *)));
zbao11a262c2016-01-22 18:54:22 +08001429 connect(optGroup, SIGNAL(triggered(QAction *)), menuView,
Patrick Georgid5208402014-04-11 20:24:06 +02001430 SLOT(setOptionMode(QAction *)));
1431
Patrick Georgid5208402014-04-11 20:24:06 +02001432 configView->showNormalAction = new QAction(_("Show Normal Options"), optGroup);
1433 configView->showAllAction = new QAction(_("Show All Options"), optGroup);
1434 configView->showPromptAction = new QAction(_("Show Prompt Options"), optGroup);
zbao11a262c2016-01-22 18:54:22 +08001435 configView->showNormalAction->setCheckable(true);
1436 configView->showAllAction->setCheckable(true);
1437 configView->showPromptAction->setCheckable(true);
Patrick Georgid5208402014-04-11 20:24:06 +02001438
zbao11a262c2016-01-22 18:54:22 +08001439 QAction *showDebugAction = new QAction( _("Show Debug Info"), this);
1440 showDebugAction->setCheckable(true);
Patrick Georgi0588d192009-08-12 15:00:51 +00001441 connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
zbao11a262c2016-01-22 18:54:22 +08001442 showDebugAction->setChecked(helpText->showDebug());
Patrick Georgi0588d192009-08-12 15:00:51 +00001443
zbao11a262c2016-01-22 18:54:22 +08001444 QAction *showIntroAction = new QAction( _("Introduction"), this);
1445 connect(showIntroAction, SIGNAL(triggered(bool)), SLOT(showIntro()));
1446 QAction *showAboutAction = new QAction( _("About"), this);
1447 connect(showAboutAction, SIGNAL(triggered(bool)), SLOT(showAbout()));
Patrick Georgi0588d192009-08-12 15:00:51 +00001448
1449 // init tool bar
zbao11a262c2016-01-22 18:54:22 +08001450 toolBar->addAction(backAction);
Patrick Georgi0588d192009-08-12 15:00:51 +00001451 toolBar->addSeparator();
zbao11a262c2016-01-22 18:54:22 +08001452 toolBar->addAction(loadAction);
1453 toolBar->addAction(saveAction);
Patrick Georgi0588d192009-08-12 15:00:51 +00001454 toolBar->addSeparator();
zbao11a262c2016-01-22 18:54:22 +08001455 toolBar->addAction(singleViewAction);
1456 toolBar->addAction(splitViewAction);
1457 toolBar->addAction(fullViewAction);
Patrick Georgi0588d192009-08-12 15:00:51 +00001458
1459 // create config menu
zbao11a262c2016-01-22 18:54:22 +08001460 QMenu* config = menu->addMenu(_("&File"));
1461 config->addAction(loadAction);
1462 config->addAction(saveAction);
1463 config->addAction(saveAsAction);
1464 config->addSeparator();
1465 config->addAction(quitAction);
Patrick Georgi0588d192009-08-12 15:00:51 +00001466
1467 // create edit menu
zbao11a262c2016-01-22 18:54:22 +08001468 QMenu* editMenu = menu->addMenu(_("&Edit"));
1469 editMenu->addAction(searchAction);
Patrick Georgi0588d192009-08-12 15:00:51 +00001470
1471 // create options menu
zbao11a262c2016-01-22 18:54:22 +08001472 QMenu* optionMenu = menu->addMenu(_("&Option"));
1473 optionMenu->addAction(showNameAction);
1474 optionMenu->addAction(showRangeAction);
1475 optionMenu->addAction(showDataAction);
1476 optionMenu->addSeparator();
1477 optionMenu->addActions(optGroup->actions());
1478 optionMenu->addSeparator();
Patrick Georgi0588d192009-08-12 15:00:51 +00001479
1480 // create help menu
zbao11a262c2016-01-22 18:54:22 +08001481 menu->addSeparator();
1482 QMenu* helpMenu = menu->addMenu(_("&Help"));
1483 helpMenu->addAction(showIntroAction);
1484 helpMenu->addAction(showAboutAction);
Patrick Georgi0588d192009-08-12 15:00:51 +00001485
1486 connect(configList, SIGNAL(menuChanged(struct menu *)),
1487 helpText, SLOT(setInfo(struct menu *)));
1488 connect(configList, SIGNAL(menuSelected(struct menu *)),
1489 SLOT(changeMenu(struct menu *)));
1490 connect(configList, SIGNAL(parentSelected()),
1491 SLOT(goBack()));
1492 connect(menuList, SIGNAL(menuChanged(struct menu *)),
1493 helpText, SLOT(setInfo(struct menu *)));
1494 connect(menuList, SIGNAL(menuSelected(struct menu *)),
1495 SLOT(changeMenu(struct menu *)));
1496
1497 connect(configList, SIGNAL(gotFocus(struct menu *)),
1498 helpText, SLOT(setInfo(struct menu *)));
1499 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1500 helpText, SLOT(setInfo(struct menu *)));
1501 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1502 SLOT(listFocusChanged(void)));
1503 connect(helpText, SIGNAL(menuSelected(struct menu *)),
1504 SLOT(setMenuLink(struct menu *)));
1505
zbao11a262c2016-01-22 18:54:22 +08001506 QString listMode = configSettings->value("/listMode", "symbol").toString();
Patrick Georgi0588d192009-08-12 15:00:51 +00001507 if (listMode == "single")
1508 showSingleView();
1509 else if (listMode == "full")
1510 showFullView();
1511 else /*if (listMode == "split")*/
1512 showSplitView();
1513
1514 // UI setup done, restore splitter positions
zbao11a262c2016-01-22 18:54:22 +08001515 QList<int> sizes = configSettings->readSizes("/split1", &ok);
Patrick Georgi0588d192009-08-12 15:00:51 +00001516 if (ok)
1517 split1->setSizes(sizes);
1518
1519 sizes = configSettings->readSizes("/split2", &ok);
1520 if (ok)
1521 split2->setSizes(sizes);
1522}
1523
1524void ConfigMainWindow::loadConfig(void)
1525{
zbao11a262c2016-01-22 18:54:22 +08001526 QString s = QFileDialog::getOpenFileName(this, "", conf_get_configname());
Patrick Georgi0588d192009-08-12 15:00:51 +00001527 if (s.isNull())
1528 return;
1529 if (conf_read(QFile::encodeName(s)))
1530 QMessageBox::information(this, "qconf", _("Unable to load configuration!"));
1531 ConfigView::updateListAll();
1532}
1533
Patrick Georgid5208402014-04-11 20:24:06 +02001534bool ConfigMainWindow::saveConfig(void)
Patrick Georgi0588d192009-08-12 15:00:51 +00001535{
Patrick Georgid5208402014-04-11 20:24:06 +02001536 if (conf_write(NULL)) {
Patrick Georgi0588d192009-08-12 15:00:51 +00001537 QMessageBox::information(this, "qconf", _("Unable to save configuration!"));
Patrick Georgid5208402014-04-11 20:24:06 +02001538 return false;
1539 }
1540 return true;
Patrick Georgi0588d192009-08-12 15:00:51 +00001541}
1542
1543void ConfigMainWindow::saveConfigAs(void)
1544{
zbao11a262c2016-01-22 18:54:22 +08001545 QString s = QFileDialog::getSaveFileName(this, "", conf_get_configname());
Patrick Georgi0588d192009-08-12 15:00:51 +00001546 if (s.isNull())
1547 return;
Patrick Georgid5208402014-04-11 20:24:06 +02001548 saveConfig();
Patrick Georgi0588d192009-08-12 15:00:51 +00001549}
1550
1551void ConfigMainWindow::searchConfig(void)
1552{
1553 if (!searchWindow)
1554 searchWindow = new ConfigSearchWindow(this, "search");
1555 searchWindow->show();
1556}
1557
1558void ConfigMainWindow::changeMenu(struct menu *menu)
1559{
1560 configList->setRootMenu(menu);
1561 if (configList->rootEntry->parent == &rootmenu)
zbao11a262c2016-01-22 18:54:22 +08001562 backAction->setEnabled(false);
Patrick Georgi0588d192009-08-12 15:00:51 +00001563 else
zbao11a262c2016-01-22 18:54:22 +08001564 backAction->setEnabled(true);
Patrick Georgi0588d192009-08-12 15:00:51 +00001565}
1566
1567void ConfigMainWindow::setMenuLink(struct menu *menu)
1568{
1569 struct menu *parent;
1570 ConfigList* list = NULL;
1571 ConfigItem* item;
1572
Patrick Georgid5208402014-04-11 20:24:06 +02001573 if (configList->menuSkip(menu))
Patrick Georgi0588d192009-08-12 15:00:51 +00001574 return;
1575
1576 switch (configList->mode) {
1577 case singleMode:
1578 list = configList;
1579 parent = menu_get_parent_menu(menu);
1580 if (!parent)
1581 return;
1582 list->setRootMenu(parent);
1583 break;
1584 case symbolMode:
1585 if (menu->flags & MENU_ROOT) {
1586 configList->setRootMenu(menu);
1587 configList->clearSelection();
1588 list = menuList;
1589 } else {
1590 list = configList;
1591 parent = menu_get_parent_menu(menu->parent);
1592 if (!parent)
1593 return;
1594 item = menuList->findConfigItem(parent);
1595 if (item) {
zbao11a262c2016-01-22 18:54:22 +08001596 item->setSelected(true);
1597 menuList->scrollToItem(item);
Patrick Georgi0588d192009-08-12 15:00:51 +00001598 }
1599 list->setRootMenu(parent);
1600 }
1601 break;
1602 case fullMode:
1603 list = configList;
1604 break;
Patrick Georgid5208402014-04-11 20:24:06 +02001605 default:
1606 break;
Patrick Georgi0588d192009-08-12 15:00:51 +00001607 }
1608
1609 if (list) {
1610 item = list->findConfigItem(menu);
1611 if (item) {
zbao11a262c2016-01-22 18:54:22 +08001612 item->setSelected(true);
1613 list->scrollToItem(item);
Patrick Georgi0588d192009-08-12 15:00:51 +00001614 list->setFocus();
1615 }
1616 }
1617}
1618
1619void ConfigMainWindow::listFocusChanged(void)
1620{
1621 if (menuList->mode == menuMode)
1622 configList->clearSelection();
1623}
1624
1625void ConfigMainWindow::goBack(void)
1626{
zbao11a262c2016-01-22 18:54:22 +08001627 ConfigItem* item, *oldSelection;
Patrick Georgi0588d192009-08-12 15:00:51 +00001628
1629 configList->setParentMenu();
1630 if (configList->rootEntry == &rootmenu)
zbao11a262c2016-01-22 18:54:22 +08001631 backAction->setEnabled(false);
1632
1633 if (menuList->selectedItems().count() == 0)
1634 return;
1635
1636 item = (ConfigItem*)menuList->selectedItems().first();
1637 oldSelection = item;
Patrick Georgi0588d192009-08-12 15:00:51 +00001638 while (item) {
1639 if (item->menu == configList->rootEntry) {
zbao11a262c2016-01-22 18:54:22 +08001640 oldSelection->setSelected(false);
1641 item->setSelected(true);
Patrick Georgi0588d192009-08-12 15:00:51 +00001642 break;
1643 }
1644 item = (ConfigItem*)item->parent();
1645 }
1646}
1647
1648void ConfigMainWindow::showSingleView(void)
1649{
zbao11a262c2016-01-22 18:54:22 +08001650 singleViewAction->setEnabled(false);
1651 singleViewAction->setChecked(true);
1652 splitViewAction->setEnabled(true);
1653 splitViewAction->setChecked(false);
1654 fullViewAction->setEnabled(true);
1655 fullViewAction->setChecked(false);
1656
Patrick Georgi0588d192009-08-12 15:00:51 +00001657 menuView->hide();
1658 menuList->setRootMenu(0);
1659 configList->mode = singleMode;
1660 if (configList->rootEntry == &rootmenu)
1661 configList->updateListAll();
1662 else
1663 configList->setRootMenu(&rootmenu);
Patrick Georgi0588d192009-08-12 15:00:51 +00001664 configList->setFocus();
1665}
1666
1667void ConfigMainWindow::showSplitView(void)
1668{
zbao11a262c2016-01-22 18:54:22 +08001669 singleViewAction->setEnabled(true);
1670 singleViewAction->setChecked(false);
1671 splitViewAction->setEnabled(false);
1672 splitViewAction->setChecked(true);
1673 fullViewAction->setEnabled(true);
1674 fullViewAction->setChecked(false);
1675
Patrick Georgi0588d192009-08-12 15:00:51 +00001676 configList->mode = symbolMode;
1677 if (configList->rootEntry == &rootmenu)
1678 configList->updateListAll();
1679 else
1680 configList->setRootMenu(&rootmenu);
zbao11a262c2016-01-22 18:54:22 +08001681 configList->setAllOpen(true);
Patrick Georgi0588d192009-08-12 15:00:51 +00001682 configApp->processEvents();
1683 menuList->mode = menuMode;
1684 menuList->setRootMenu(&rootmenu);
zbao11a262c2016-01-22 18:54:22 +08001685 menuList->setAllOpen(true);
Patrick Georgi0588d192009-08-12 15:00:51 +00001686 menuView->show();
1687 menuList->setFocus();
1688}
1689
1690void ConfigMainWindow::showFullView(void)
1691{
zbao11a262c2016-01-22 18:54:22 +08001692 singleViewAction->setEnabled(true);
1693 singleViewAction->setChecked(false);
1694 splitViewAction->setEnabled(true);
1695 splitViewAction->setChecked(false);
1696 fullViewAction->setEnabled(false);
1697 fullViewAction->setChecked(true);
1698
Patrick Georgi0588d192009-08-12 15:00:51 +00001699 menuView->hide();
1700 menuList->setRootMenu(0);
1701 configList->mode = fullMode;
1702 if (configList->rootEntry == &rootmenu)
1703 configList->updateListAll();
1704 else
1705 configList->setRootMenu(&rootmenu);
Patrick Georgi0588d192009-08-12 15:00:51 +00001706 configList->setFocus();
1707}
1708
1709/*
1710 * ask for saving configuration before quitting
1711 * TODO ask only when something changed
1712 */
1713void ConfigMainWindow::closeEvent(QCloseEvent* e)
1714{
1715 if (!conf_get_changed()) {
1716 e->accept();
1717 return;
1718 }
1719 QMessageBox mb("qconf", _("Save configuration?"), QMessageBox::Warning,
1720 QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape);
1721 mb.setButtonText(QMessageBox::Yes, _("&Save Changes"));
1722 mb.setButtonText(QMessageBox::No, _("&Discard Changes"));
1723 mb.setButtonText(QMessageBox::Cancel, _("Cancel Exit"));
1724 switch (mb.exec()) {
1725 case QMessageBox::Yes:
Patrick Georgid5208402014-04-11 20:24:06 +02001726 if (saveConfig())
1727 e->accept();
1728 else
1729 e->ignore();
1730 break;
Patrick Georgi0588d192009-08-12 15:00:51 +00001731 case QMessageBox::No:
1732 e->accept();
1733 break;
1734 case QMessageBox::Cancel:
1735 e->ignore();
1736 break;
1737 }
1738}
1739
1740void ConfigMainWindow::showIntro(void)
1741{
Patrick Georgid5208402014-04-11 20:24:06 +02001742 static const QString str = _("Welcome to the qconf graphical configuration tool.\n\n"
Patrick Georgi0588d192009-08-12 15:00:51 +00001743 "For each option, a blank box indicates the feature is disabled, a check\n"
1744 "indicates it is enabled, and a dot indicates that it is to be compiled\n"
1745 "as a module. Clicking on the box will cycle through the three states.\n\n"
1746 "If you do not see an option (e.g., a device driver) that you believe\n"
1747 "should be present, try turning on Show All Options under the Options menu.\n"
1748 "Although there is no cross reference yet to help you figure out what other\n"
1749 "options must be enabled to support the option you are interested in, you can\n"
1750 "still view the help of a grayed-out option.\n\n"
1751 "Toggling Show Debug Info under the Options menu will show the dependencies,\n"
1752 "which you can then match by examining other options.\n\n");
1753
1754 QMessageBox::information(this, "qconf", str);
1755}
1756
1757void ConfigMainWindow::showAbout(void)
1758{
zbao11a262c2016-01-22 18:54:22 +08001759 static const QString str = _("qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n"
1760 "Copyright (C) 2015 Boris Barbulovski <bbarbulovski@gmail.com>.\n\n"
Patrick Georgi0588d192009-08-12 15:00:51 +00001761 "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n");
1762
1763 QMessageBox::information(this, "qconf", str);
1764}
1765
1766void ConfigMainWindow::saveSettings(void)
1767{
zbao11a262c2016-01-22 18:54:22 +08001768 configSettings->setValue("/window x", pos().x());
1769 configSettings->setValue("/window y", pos().y());
1770 configSettings->setValue("/window width", size().width());
1771 configSettings->setValue("/window height", size().height());
Patrick Georgi0588d192009-08-12 15:00:51 +00001772
1773 QString entry;
1774 switch(configList->mode) {
1775 case singleMode :
1776 entry = "single";
1777 break;
1778
1779 case symbolMode :
1780 entry = "split";
1781 break;
1782
1783 case fullMode :
1784 entry = "full";
1785 break;
Patrick Georgid5208402014-04-11 20:24:06 +02001786
1787 default:
1788 break;
Patrick Georgi0588d192009-08-12 15:00:51 +00001789 }
zbao11a262c2016-01-22 18:54:22 +08001790 configSettings->setValue("/listMode", entry);
Patrick Georgi0588d192009-08-12 15:00:51 +00001791
1792 configSettings->writeSizes("/split1", split1->sizes());
1793 configSettings->writeSizes("/split2", split2->sizes());
1794}
1795
1796void ConfigMainWindow::conf_changed(void)
1797{
1798 if (saveAction)
1799 saveAction->setEnabled(conf_get_changed());
1800}
1801
1802void fixup_rootmenu(struct menu *menu)
1803{
1804 struct menu *child;
1805 static int menu_cnt = 0;
1806
1807 menu->flags |= MENU_ROOT;
1808 for (child = menu->list; child; child = child->next) {
1809 if (child->prompt && child->prompt->type == P_MENU) {
1810 menu_cnt++;
1811 fixup_rootmenu(child);
1812 menu_cnt--;
1813 } else if (!menu_cnt)
1814 fixup_rootmenu(child);
1815 }
1816}
1817
1818static const char *progname;
1819
1820static void usage(void)
1821{
zbao11a262c2016-01-22 18:54:22 +08001822 printf(_("%s [-s] <config>\n").toLatin1().constData(), progname);
Patrick Georgi0588d192009-08-12 15:00:51 +00001823 exit(0);
1824}
1825
1826int main(int ac, char** av)
1827{
1828 ConfigMainWindow* v;
1829 const char *name;
1830
1831 bindtextdomain(PACKAGE, LOCALEDIR);
1832 textdomain(PACKAGE);
1833
Patrick Georgi0588d192009-08-12 15:00:51 +00001834 progname = av[0];
1835 configApp = new QApplication(ac, av);
1836 if (ac > 1 && av[1][0] == '-') {
1837 switch (av[1][1]) {
zbao11a262c2016-01-22 18:54:22 +08001838 case 's':
1839 conf_set_message_callback(NULL);
1840 break;
Patrick Georgi0588d192009-08-12 15:00:51 +00001841 case 'h':
1842 case '?':
1843 usage();
1844 }
1845 name = av[2];
1846 } else
1847 name = av[1];
1848 if (!name)
1849 usage();
1850
1851 conf_parse(name);
1852 fixup_rootmenu(&rootmenu);
1853 conf_read(NULL);
1854 //zconfdump(stdout);
1855
1856 configSettings = new ConfigSettings();
1857 configSettings->beginGroup("/kconfig/qconf");
1858 v = new ConfigMainWindow();
1859
1860 //zconfdump(stdout);
Patrick Georgi0588d192009-08-12 15:00:51 +00001861 configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit()));
1862 configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings()));
1863 v->show();
1864 configApp->exec();
1865
1866 configSettings->endGroup();
1867 delete configSettings;
1868
1869 return 0;
1870}