]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - scripts/kconfig/qconf.cc
powerpc/mm/radix: Only need the Nest MMU workaround for R -> RW transition
[mirror_ubuntu-bionic-kernel.git] / scripts / kconfig / qconf.cc
CommitLineData
1da177e4
LT
1/*
2 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
b4ff1de3 3 * Copyright (C) 2015 Boris Barbulovski <bbarbulovski@gmail.com>
1da177e4
LT
4 * Released under the terms of the GNU GPL v2.0.
5 */
6
133c5f7c
AS
7#include <qglobal.h>
8
b1f8a45b 9#include <QMainWindow>
041fbdc2 10#include <QList>
924bbb53 11#include <qtextbrowser.h>
85eaf28a 12#include <QAction>
bea00771 13#include <QFileDialog>
76bede87 14#include <QMenu>
133c5f7c
AS
15
16#include <qapplication.h>
8d90c97e 17#include <qdesktopwidget.h>
1da177e4 18#include <qtoolbar.h>
43bf612a 19#include <qlayout.h>
1da177e4 20#include <qsplitter.h>
1da177e4 21#include <qlineedit.h>
43bf612a
RZ
22#include <qlabel.h>
23#include <qpushbutton.h>
1da177e4
LT
24#include <qmenubar.h>
25#include <qmessagebox.h>
1da177e4 26#include <qregexp.h>
133c5f7c 27#include <qevent.h>
1da177e4
LT
28
29#include <stdlib.h>
30
31#include "lkc.h"
32#include "qconf.h"
33
34#include "qconf.moc"
35#include "images.c"
36
3b9fa093
ACM
37#ifdef _
38# undef _
39# define _ qgettext
40#endif
41
1da177e4 42static QApplication *configApp;
7fc925fd 43static ConfigSettings *configSettings;
1da177e4 44
85eaf28a 45QAction *ConfigMainWindow::saveAction;
3b354c55 46
3b9fa093
ACM
47static inline QString qgettext(const char* str)
48{
43bf612a 49 return QString::fromLocal8Bit(gettext(str));
3b9fa093
ACM
50}
51
52static inline QString qgettext(const QString& str)
53{
68ccb7ef 54 return QString::fromLocal8Bit(gettext(str.toLatin1()));
3b9fa093
ACM
55}
56
00d4f8fc
BH
57ConfigSettings::ConfigSettings()
58 : QSettings("kernel.org", "qconf")
59{
60}
61
1da177e4
LT
62/**
63 * Reads a list of integer values from the application settings.
64 */
041fbdc2 65QList<int> ConfigSettings::readSizes(const QString& key, bool *ok)
1da177e4 66{
041fbdc2 67 QList<int> result;
c1f96f09 68
83c3a1ba
BB
69 if (contains(key))
70 {
71 QStringList entryList = value(key).toStringList();
72 QStringList::Iterator it;
73
74 for (it = entryList.begin(); it != entryList.end(); ++it)
75 result.push_back((*it).toInt());
76
77 *ok = true;
78 }
79 else
80 *ok = false;
1da177e4
LT
81
82 return result;
83}
84
85/**
86 * Writes a list of integer values to the application settings.
87 */
041fbdc2 88bool ConfigSettings::writeSizes(const QString& key, const QList<int>& value)
1da177e4
LT
89{
90 QStringList stringList;
041fbdc2 91 QList<int>::ConstIterator it;
1da177e4
LT
92
93 for (it = value.begin(); it != value.end(); ++it)
94 stringList.push_back(QString::number(*it));
68ccb7ef 95 setValue(key, stringList);
59e56440 96
68ccb7ef 97 return true;
1da177e4 98}
1da177e4 99
59e56440
BB
100
101/*
102 * set the new data
103 * TODO check the value
104 */
105void ConfigItem::okRename(int col)
106{
107}
108
109/*
110 * update the displayed of a menu entry
111 */
112void ConfigItem::updateMenu(void)
113{
d5d973c3
BB
114 ConfigList* list;
115 struct symbol* sym;
116 struct property *prop;
117 QString prompt;
118 int type;
119 tristate expr;
120
121 list = listView();
122 if (goParent) {
123 setPixmap(promptColIdx, list->menuBackPix);
124 prompt = "..";
125 goto set_prompt;
126 }
127
128 sym = menu->sym;
129 prop = menu->prompt;
130 prompt = _(menu_get_prompt(menu));
131
132 if (prop) switch (prop->type) {
133 case P_MENU:
134 if (list->mode == singleMode || list->mode == symbolMode) {
135 /* a menuconfig entry is displayed differently
136 * depending whether it's at the view root or a child.
137 */
138 if (sym && list->rootEntry == menu)
139 break;
140 setPixmap(promptColIdx, list->menuPix);
141 } else {
142 if (sym)
143 break;
144 setPixmap(promptColIdx, QIcon());
145 }
146 goto set_prompt;
147 case P_COMMENT:
148 setPixmap(promptColIdx, QIcon());
149 goto set_prompt;
150 default:
151 ;
152 }
153 if (!sym)
154 goto set_prompt;
155
156 setText(nameColIdx, QString::fromLocal8Bit(sym->name));
157
158 type = sym_get_type(sym);
159 switch (type) {
160 case S_BOOLEAN:
161 case S_TRISTATE:
162 char ch;
163
164 if (!sym_is_changable(sym) && list->optMode == normalOpt) {
165 setPixmap(promptColIdx, QIcon());
166 setText(noColIdx, QString::null);
167 setText(modColIdx, QString::null);
168 setText(yesColIdx, QString::null);
169 break;
170 }
171 expr = sym_get_tristate_value(sym);
172 switch (expr) {
173 case yes:
174 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
175 setPixmap(promptColIdx, list->choiceYesPix);
176 else
177 setPixmap(promptColIdx, list->symbolYesPix);
178 setText(yesColIdx, "Y");
179 ch = 'Y';
180 break;
181 case mod:
182 setPixmap(promptColIdx, list->symbolModPix);
183 setText(modColIdx, "M");
184 ch = 'M';
185 break;
186 default:
187 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
188 setPixmap(promptColIdx, list->choiceNoPix);
189 else
190 setPixmap(promptColIdx, list->symbolNoPix);
191 setText(noColIdx, "N");
192 ch = 'N';
193 break;
194 }
195 if (expr != no)
196 setText(noColIdx, sym_tristate_within_range(sym, no) ? "_" : 0);
197 if (expr != mod)
198 setText(modColIdx, sym_tristate_within_range(sym, mod) ? "_" : 0);
199 if (expr != yes)
200 setText(yesColIdx, sym_tristate_within_range(sym, yes) ? "_" : 0);
201
202 setText(dataColIdx, QChar(ch));
203 break;
204 case S_INT:
205 case S_HEX:
206 case S_STRING:
207 const char* data;
208
209 data = sym_get_string_value(sym);
210
d5d973c3
BB
211 setText(dataColIdx, data);
212 if (type == S_STRING)
213 prompt = QString("%1: %2").arg(prompt).arg(data);
214 else
215 prompt = QString("(%2) %1").arg(prompt).arg(data);
216 break;
217 }
218 if (!sym_has_value(sym) && visible)
219 prompt += _(" (NEW)");
220set_prompt:
221 setText(promptColIdx, prompt);
59e56440
BB
222}
223
224void ConfigItem::testUpdateMenu(bool v)
225{
d5d973c3
BB
226 ConfigItem* i;
227
228 visible = v;
229 if (!menu)
230 return;
231
232 sym_calc_value(menu->sym);
233 if (menu->flags & MENU_CHANGED) {
234 /* the menu entry changed, so update all list items */
235 menu->flags &= ~MENU_CHANGED;
236 for (i = (ConfigItem*)menu->data; i; i = i->nextItem)
237 i->updateMenu();
238 } else if (listView()->updateAll)
239 updateMenu();
59e56440
BB
240}
241
242
1019f1a5
BB
243/*
244 * construct a menu entry
245 */
246void ConfigItem::init(void)
247{
d5d973c3
BB
248 if (menu) {
249 ConfigList* list = listView();
250 nextItem = (ConfigItem*)menu->data;
251 menu->data = this;
252
253 if (list->mode != fullMode)
254 setExpanded(true);
255 sym_calc_value(menu->sym);
256 }
257 updateMenu();
1019f1a5
BB
258}
259
260/*
261 * destruct a menu entry
262 */
263ConfigItem::~ConfigItem(void)
264{
d5d973c3
BB
265 if (menu) {
266 ConfigItem** ip = (ConfigItem**)&menu->data;
267 for (; *ip; ip = &(*ip)->nextItem) {
268 if (*ip == this) {
269 *ip = nextItem;
270 break;
271 }
272 }
273 }
1019f1a5
BB
274}
275
43bf612a
RZ
276ConfigLineEdit::ConfigLineEdit(ConfigView* parent)
277 : Parent(parent)
278{
c14fa5e1 279 connect(this, SIGNAL(editingFinished()), SLOT(hide()));
43bf612a
RZ
280}
281
1019f1a5 282void ConfigLineEdit::show(ConfigItem* i)
1da177e4
LT
283{
284 item = i;
d5d973c3
BB
285 if (sym_get_string_value(item->menu->sym))
286 setText(QString::fromLocal8Bit(sym_get_string_value(item->menu->sym)));
287 else
288 setText(QString::null);
1da177e4
LT
289 Parent::show();
290 setFocus();
291}
292
293void ConfigLineEdit::keyPressEvent(QKeyEvent* e)
294{
295 switch (e->key()) {
fbb86374 296 case Qt::Key_Escape:
1da177e4 297 break;
fbb86374
MH
298 case Qt::Key_Return:
299 case Qt::Key_Enter:
d5d973c3 300 sym_set_string_value(item->menu->sym, text().toLatin1());
1da177e4
LT
301 parent()->updateList(item);
302 break;
303 default:
304 Parent::keyPressEvent(e);
305 return;
306 }
307 e->accept();
308 parent()->list->setFocus();
309 hide();
310}
311
1019f1a5 312ConfigList::ConfigList(ConfigView* p, const char *name)
59e56440
BB
313 : Parent(p),
314 updateAll(false),
315 symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no),
316 choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no),
317 menuPix(xpm_menu), menuInvPix(xpm_menu_inv), menuBackPix(xpm_menuback), voidPix(xpm_void),
dbf62933 318 showName(false), showRange(false), showData(false), mode(singleMode), optMode(normalOpt),
59e56440
BB
319 rootEntry(0), headerPopup(0)
320{
d5d973c3
BB
321 int i;
322
323 setObjectName(name);
a5225e9b 324 setSortingEnabled(false);
d5d973c3
BB
325 setRootIsDecorated(true);
326
f999cc06
BB
327 setVerticalScrollMode(ScrollPerPixel);
328 setHorizontalScrollMode(ScrollPerPixel);
329
a52cb321
BB
330 setHeaderLabels(QStringList() << _("Option") << _("Name") << "N" << "M" << "Y" << _("Value"));
331
c14fa5e1 332 connect(this, SIGNAL(itemSelectionChanged(void)),
d5d973c3
BB
333 SLOT(updateSelection(void)));
334
335 if (name) {
336 configSettings->beginGroup(name);
337 showName = configSettings->value("/showName", false).toBool();
338 showRange = configSettings->value("/showRange", false).toBool();
339 showData = configSettings->value("/showData", false).toBool();
340 optMode = (enum optionMode)configSettings->value("/optionMode", 0).toInt();
341 configSettings->endGroup();
342 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
343 }
344
345 addColumn(promptColIdx);
346
347 reinit();
348}
349
350bool ConfigList::menuSkip(struct menu *menu)
351{
352 if (optMode == normalOpt && menu_is_visible(menu))
353 return false;
354 if (optMode == promptOpt && menu_has_prompt(menu))
355 return false;
356 if (optMode == allOpt)
357 return false;
358 return true;
59e56440
BB
359}
360
361void ConfigList::reinit(void)
362{
d5d973c3
BB
363 removeColumn(dataColIdx);
364 removeColumn(yesColIdx);
365 removeColumn(modColIdx);
366 removeColumn(noColIdx);
367 removeColumn(nameColIdx);
368
369 if (showName)
370 addColumn(nameColIdx);
371 if (showRange) {
372 addColumn(noColIdx);
373 addColumn(modColIdx);
374 addColumn(yesColIdx);
375 }
376 if (showData)
377 addColumn(dataColIdx);
378
379 updateListAll();
59e56440
BB
380}
381
382void ConfigList::saveSettings(void)
383{
d5d973c3
BB
384 if (!objectName().isEmpty()) {
385 configSettings->beginGroup(objectName());
386 configSettings->setValue("/showName", showName);
387 configSettings->setValue("/showRange", showRange);
388 configSettings->setValue("/showData", showData);
389 configSettings->setValue("/optionMode", (int)optMode);
390 configSettings->endGroup();
391 }
59e56440
BB
392}
393
394ConfigItem* ConfigList::findConfigItem(struct menu *menu)
395{
d5d973c3
BB
396 ConfigItem* item = (ConfigItem*)menu->data;
397
398 for (; item; item = item->nextItem) {
399 if (this == item->listView())
400 break;
401 }
402
403 return item;
59e56440
BB
404}
405
406void ConfigList::updateSelection(void)
407{
d5d973c3
BB
408 struct menu *menu;
409 enum prop_type type;
410
be596aaa
BB
411 if (selectedItems().count() == 0)
412 return;
413
d5d973c3
BB
414 ConfigItem* item = (ConfigItem*)selectedItems().first();
415 if (!item)
416 return;
417
418 menu = item->menu;
419 emit menuChanged(menu);
420 if (!menu)
421 return;
422 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
423 if (mode == menuMode && type == P_MENU)
424 emit menuSelected(menu);
59e56440
BB
425}
426
427void ConfigList::updateList(ConfigItem* item)
428{
d5d973c3
BB
429 ConfigItem* last = 0;
430
431 if (!rootEntry) {
432 if (mode != listMode)
433 goto update;
434 QTreeWidgetItemIterator it(this);
435 ConfigItem* item;
436
437 while (*it) {
438 item = (ConfigItem*)(*it);
439 if (!item->menu)
440 continue;
441 item->testUpdateMenu(menu_is_visible(item->menu));
442
443 ++it;
444 }
445 return;
446 }
447
448 if (rootEntry != &rootmenu && (mode == singleMode ||
449 (mode == symbolMode && rootEntry->parent != &rootmenu))) {
ee7298fb 450 item = (ConfigItem *)topLevelItem(0);
d5d973c3
BB
451 if (!item)
452 item = new ConfigItem(this, 0, true);
453 last = item;
454 }
455 if ((mode == singleMode || (mode == symbolMode && !(rootEntry->flags & MENU_ROOT))) &&
456 rootEntry->sym && rootEntry->prompt) {
457 item = last ? last->nextSibling() : firstChild();
458 if (!item)
459 item = new ConfigItem(this, last, rootEntry, true);
460 else
461 item->testUpdateMenu(true);
462
463 updateMenuList(item, rootEntry);
464 update();
f999cc06 465 resizeColumnToContents(0);
d5d973c3
BB
466 return;
467 }
468update:
469 updateMenuList(this, rootEntry);
470 update();
f999cc06 471 resizeColumnToContents(0);
59e56440
BB
472}
473
474void ConfigList::setValue(ConfigItem* item, tristate val)
475{
d5d973c3
BB
476 struct symbol* sym;
477 int type;
478 tristate oldval;
479
480 sym = item->menu ? item->menu->sym : 0;
481 if (!sym)
482 return;
483
484 type = sym_get_type(sym);
485 switch (type) {
486 case S_BOOLEAN:
487 case S_TRISTATE:
488 oldval = sym_get_tristate_value(sym);
489
490 if (!sym_set_tristate_value(sym, val))
491 return;
492 if (oldval == no && item->menu->list)
493 item->setExpanded(true);
494 parent()->updateList(item);
495 break;
496 }
59e56440
BB
497}
498
499void ConfigList::changeValue(ConfigItem* item)
500{
d5d973c3
BB
501 struct symbol* sym;
502 struct menu* menu;
503 int type, oldexpr, newexpr;
504
505 menu = item->menu;
506 if (!menu)
507 return;
508 sym = menu->sym;
509 if (!sym) {
510 if (item->menu->list)
511 item->setExpanded(!item->isExpanded());
512 return;
513 }
514
515 type = sym_get_type(sym);
516 switch (type) {
517 case S_BOOLEAN:
518 case S_TRISTATE:
519 oldexpr = sym_get_tristate_value(sym);
520 newexpr = sym_toggle_tristate_value(sym);
521 if (item->menu->list) {
522 if (oldexpr == newexpr)
523 item->setExpanded(!item->isExpanded());
524 else if (oldexpr == no)
525 item->setExpanded(true);
526 }
527 if (oldexpr != newexpr)
528 parent()->updateList(item);
529 break;
530 case S_INT:
531 case S_HEX:
532 case S_STRING:
e336b9f1 533 parent()->lineEdit->show(item);
d5d973c3
BB
534 break;
535 }
59e56440
BB
536}
537
538void ConfigList::setRootMenu(struct menu *menu)
539{
d5d973c3
BB
540 enum prop_type type;
541
542 if (rootEntry == menu)
543 return;
544 type = menu && menu->prompt ? menu->prompt->type : P_UNKNOWN;
545 if (type != P_MENU)
546 return;
547 updateMenuList(this, 0);
548 rootEntry = menu;
549 updateListAll();
550 if (currentItem()) {
551 currentItem()->setSelected(hasFocus());
552 scrollToItem(currentItem());
553 }
59e56440
BB
554}
555
556void ConfigList::setParentMenu(void)
557{
d5d973c3
BB
558 ConfigItem* item;
559 struct menu *oldroot;
560
561 oldroot = rootEntry;
562 if (rootEntry == &rootmenu)
563 return;
564 setRootMenu(menu_get_parent_menu(rootEntry->parent));
565
566 QTreeWidgetItemIterator it(this);
567 while (*it) {
568 item = (ConfigItem *)(*it);
569 if (item->menu == oldroot) {
570 setCurrentItem(item);
571 scrollToItem(item);
572 break;
573 }
574
575 ++it;
576 }
59e56440
BB
577}
578
579/*
580 * update all the children of a menu entry
581 * removes/adds the entries from the parent widget as necessary
582 *
583 * parent: either the menu list widget or a menu entry widget
584 * menu: entry to be updated
585 */
5c6f1554 586void ConfigList::updateMenuList(ConfigItem *parent, struct menu* menu)
59e56440 587{
d5d973c3
BB
588 struct menu* child;
589 ConfigItem* item;
590 ConfigItem* last;
591 bool visible;
592 enum prop_type type;
593
594 if (!menu) {
5c6f1554
BB
595 while (parent->childCount() > 0)
596 {
597 delete parent->takeChild(0);
598 }
599
d5d973c3
BB
600 return;
601 }
602
603 last = parent->firstChild();
604 if (last && !last->goParent)
605 last = 0;
606 for (child = menu->list; child; child = child->next) {
607 item = last ? last->nextSibling() : parent->firstChild();
608 type = child->prompt ? child->prompt->type : P_UNKNOWN;
609
610 switch (mode) {
611 case menuMode:
612 if (!(child->flags & MENU_ROOT))
613 goto hide;
614 break;
615 case symbolMode:
616 if (child->flags & MENU_ROOT)
617 goto hide;
618 break;
619 default:
620 break;
621 }
622
623 visible = menu_is_visible(child);
624 if (!menuSkip(child)) {
625 if (!child->sym && !child->list && !child->prompt)
626 continue;
627 if (!item || item->menu != child)
628 item = new ConfigItem(parent, last, child, visible);
629 else
630 item->testUpdateMenu(visible);
631
632 if (mode == fullMode || mode == menuMode || type != P_MENU)
633 updateMenuList(item, child);
634 else
635 updateMenuList(item, 0);
636 last = item;
637 continue;
638 }
639 hide:
640 if (item && item->menu == child) {
641 last = parent->firstChild();
642 if (last == item)
643 last = 0;
644 else while (last->nextSibling() != item)
645 last = last->nextSibling();
646 delete item;
647 }
648 }
59e56440
BB
649}
650
5c6f1554
BB
651void ConfigList::updateMenuList(ConfigList *parent, struct menu* menu)
652{
653 struct menu* child;
654 ConfigItem* item;
655 ConfigItem* last;
656 bool visible;
657 enum prop_type type;
658
659 if (!menu) {
660 while (parent->topLevelItemCount() > 0)
661 {
662 delete parent->takeTopLevelItem(0);
663 }
664
665 return;
666 }
667
668 last = (ConfigItem*)parent->topLevelItem(0);
669 if (last && !last->goParent)
670 last = 0;
671 for (child = menu->list; child; child = child->next) {
672 item = last ? last->nextSibling() : (ConfigItem*)parent->topLevelItem(0);
673 type = child->prompt ? child->prompt->type : P_UNKNOWN;
674
675 switch (mode) {
676 case menuMode:
677 if (!(child->flags & MENU_ROOT))
678 goto hide;
679 break;
680 case symbolMode:
681 if (child->flags & MENU_ROOT)
682 goto hide;
683 break;
684 default:
685 break;
686 }
687
688 visible = menu_is_visible(child);
689 if (!menuSkip(child)) {
690 if (!child->sym && !child->list && !child->prompt)
691 continue;
692 if (!item || item->menu != child)
693 item = new ConfigItem(parent, last, child, visible);
694 else
695 item->testUpdateMenu(visible);
696
697 if (mode == fullMode || mode == menuMode || type != P_MENU)
698 updateMenuList(item, child);
699 else
700 updateMenuList(item, 0);
701 last = item;
702 continue;
703 }
704 hide:
705 if (item && item->menu == child) {
706 last = (ConfigItem*)parent->topLevelItem(0);
707 if (last == item)
708 last = 0;
709 else while (last->nextSibling() != item)
710 last = last->nextSibling();
711 delete item;
712 }
713 }
714}
715
59e56440
BB
716void ConfigList::keyPressEvent(QKeyEvent* ev)
717{
d5d973c3
BB
718 QTreeWidgetItem* i = currentItem();
719 ConfigItem* item;
720 struct menu *menu;
721 enum prop_type type;
722
723 if (ev->key() == Qt::Key_Escape && mode != fullMode && mode != listMode) {
724 emit parentSelected();
725 ev->accept();
726 return;
727 }
728
729 if (!i) {
730 Parent::keyPressEvent(ev);
731 return;
732 }
733 item = (ConfigItem*)i;
734
735 switch (ev->key()) {
736 case Qt::Key_Return:
737 case Qt::Key_Enter:
738 if (item->goParent) {
739 emit parentSelected();
740 break;
741 }
742 menu = item->menu;
743 if (!menu)
744 break;
745 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
746 if (type == P_MENU && rootEntry != menu &&
747 mode != fullMode && mode != menuMode) {
748 emit menuSelected(menu);
749 break;
750 }
751 case Qt::Key_Space:
752 changeValue(item);
753 break;
754 case Qt::Key_N:
755 setValue(item, no);
756 break;
757 case Qt::Key_M:
758 setValue(item, mod);
759 break;
760 case Qt::Key_Y:
761 setValue(item, yes);
762 break;
763 default:
764 Parent::keyPressEvent(ev);
765 return;
766 }
767 ev->accept();
59e56440
BB
768}
769
d5d973c3 770void ConfigList::mousePressEvent(QMouseEvent* e)
1019f1a5 771{
d5d973c3
BB
772 //QPoint p(contentsToViewport(e->pos()));
773 //printf("contentsMousePressEvent: %d,%d\n", p.x(), p.y());
774 Parent::mousePressEvent(e);
1019f1a5 775}
59e56440 776
d5d973c3 777void ConfigList::mouseReleaseEvent(QMouseEvent* e)
59e56440 778{
d5d973c3
BB
779 QPoint p = e->pos();
780 ConfigItem* item = (ConfigItem*)itemAt(p);
781 struct menu *menu;
782 enum prop_type ptype;
783 QIcon icon;
784 int idx, x;
785
786 if (!item)
787 goto skip;
788
789 menu = item->menu;
790 x = header()->offset() + p.x();
76d53cbb 791 idx = header()->logicalIndexAt(x);
d5d973c3
BB
792 switch (idx) {
793 case promptColIdx:
794 icon = item->pixmap(promptColIdx);
76d53cbb
BB
795 if (!icon.isNull()) {
796 int off = header()->sectionPosition(0) + visualRect(indexAt(p)).x() + 4; // 4 is Hardcoded image offset. There might be a way to do it properly.
797 if (x >= off && x < off + icon.availableSizes().first().width()) {
798 if (item->goParent) {
799 emit parentSelected();
800 break;
801 } else if (!menu)
802 break;
803 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
804 if (ptype == P_MENU && rootEntry != menu &&
805 mode != fullMode && mode != menuMode)
806 emit menuSelected(menu);
807 else
808 changeValue(item);
809 }
810 }
d5d973c3
BB
811 break;
812 case noColIdx:
813 setValue(item, no);
814 break;
815 case modColIdx:
816 setValue(item, mod);
817 break;
818 case yesColIdx:
819 setValue(item, yes);
820 break;
821 case dataColIdx:
822 changeValue(item);
823 break;
824 }
825
826skip:
827 //printf("contentsMouseReleaseEvent: %d,%d\n", p.x(), p.y());
828 Parent::mouseReleaseEvent(e);
59e56440
BB
829}
830
d5d973c3 831void ConfigList::mouseMoveEvent(QMouseEvent* e)
59e56440 832{
d5d973c3
BB
833 //QPoint p(contentsToViewport(e->pos()));
834 //printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y());
835 Parent::mouseMoveEvent(e);
59e56440
BB
836}
837
d5d973c3 838void ConfigList::mouseDoubleClickEvent(QMouseEvent* e)
59e56440 839{
d5d973c3
BB
840 QPoint p = e->pos(); // TODO: Check if this works(was contentsToViewport).
841 ConfigItem* item = (ConfigItem*)itemAt(p);
842 struct menu *menu;
843 enum prop_type ptype;
844
845 if (!item)
846 goto skip;
847 if (item->goParent) {
848 emit parentSelected();
849 goto skip;
850 }
851 menu = item->menu;
852 if (!menu)
853 goto skip;
854 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
855 if (ptype == P_MENU && (mode == singleMode || mode == symbolMode))
856 emit menuSelected(menu);
857 else if (menu->sym)
858 changeValue(item);
859
860skip:
861 //printf("contentsMouseDoubleClickEvent: %d,%d\n", p.x(), p.y());
862 Parent::mouseDoubleClickEvent(e);
59e56440
BB
863}
864
865void ConfigList::focusInEvent(QFocusEvent *e)
866{
d5d973c3
BB
867 struct menu *menu = NULL;
868
869 Parent::focusInEvent(e);
870
871 ConfigItem* item = (ConfigItem *)currentItem();
872 if (item) {
873 item->setSelected(true);
874 menu = item->menu;
875 }
876 emit gotFocus(menu);
59e56440
BB
877}
878
879void ConfigList::contextMenuEvent(QContextMenuEvent *e)
880{
d5d973c3
BB
881 if (e->y() <= header()->geometry().bottom()) {
882 if (!headerPopup) {
883 QAction *action;
884
885 headerPopup = new QMenu(this);
886 action = new QAction(_("Show Name"), this);
887 action->setCheckable(true);
888 connect(action, SIGNAL(toggled(bool)),
889 parent(), SLOT(setShowName(bool)));
890 connect(parent(), SIGNAL(showNameChanged(bool)),
891 action, SLOT(setOn(bool)));
892 action->setChecked(showName);
893 headerPopup->addAction(action);
894 action = new QAction(_("Show Range"), this);
895 action->setCheckable(true);
896 connect(action, SIGNAL(toggled(bool)),
897 parent(), SLOT(setShowRange(bool)));
898 connect(parent(), SIGNAL(showRangeChanged(bool)),
899 action, SLOT(setOn(bool)));
900 action->setChecked(showRange);
901 headerPopup->addAction(action);
902 action = new QAction(_("Show Data"), this);
903 action->setCheckable(true);
904 connect(action, SIGNAL(toggled(bool)),
905 parent(), SLOT(setShowData(bool)));
906 connect(parent(), SIGNAL(showDataChanged(bool)),
907 action, SLOT(setOn(bool)));
908 action->setChecked(showData);
909 headerPopup->addAction(action);
910 }
911 headerPopup->exec(e->globalPos());
912 e->accept();
913 } else
914 e->ignore();
59e56440
BB
915}
916
39a4897c
LZ
917ConfigView*ConfigView::viewList;
918QAction *ConfigView::showNormalAction;
919QAction *ConfigView::showAllAction;
920QAction *ConfigView::showPromptAction;
1da177e4 921
7fc925fd 922ConfigView::ConfigView(QWidget* parent, const char *name)
68ccb7ef 923 : Parent(parent)
1da177e4 924{
9bd36ed3 925 setObjectName(name);
29a70168 926 QVBoxLayout *verticalLayout = new QVBoxLayout(this);
92298b49 927 verticalLayout->setContentsMargins(0, 0, 0, 0);
29a70168 928
1019f1a5 929 list = new ConfigList(this);
29a70168 930 verticalLayout->addWidget(list);
1da177e4
LT
931 lineEdit = new ConfigLineEdit(this);
932 lineEdit->hide();
29a70168 933 verticalLayout->addWidget(lineEdit);
1da177e4
LT
934
935 this->nextView = viewList;
936 viewList = this;
937}
938
939ConfigView::~ConfigView(void)
940{
941 ConfigView** vp;
942
943 for (vp = &viewList; *vp; vp = &(*vp)->nextView) {
944 if (*vp == this) {
945 *vp = nextView;
946 break;
947 }
948 }
949}
950
39a4897c 951void ConfigView::setOptionMode(QAction *act)
7fc925fd 952{
d5d973c3
BB
953 if (act == showNormalAction)
954 list->optMode = normalOpt;
955 else if (act == showAllAction)
956 list->optMode = allOpt;
957 else
958 list->optMode = promptOpt;
959
960 list->updateListAll();
7fc925fd
RZ
961}
962
963void ConfigView::setShowName(bool b)
964{
d5d973c3
BB
965 if (list->showName != b) {
966 list->showName = b;
967 list->reinit();
968 emit showNameChanged(b);
969 }
7fc925fd
RZ
970}
971
972void ConfigView::setShowRange(bool b)
973{
d5d973c3
BB
974 if (list->showRange != b) {
975 list->showRange = b;
976 list->reinit();
977 emit showRangeChanged(b);
978 }
7fc925fd
RZ
979}
980
981void ConfigView::setShowData(bool b)
982{
d5d973c3
BB
983 if (list->showData != b) {
984 list->showData = b;
985 list->reinit();
986 emit showDataChanged(b);
987 }
988}
989
990void ConfigList::setAllOpen(bool open)
991{
992 QTreeWidgetItemIterator it(this);
993
994 while (*it) {
995 (*it)->setExpanded(open);
996
997 ++it;
998 }
7fc925fd
RZ
999}
1000
1019f1a5 1001void ConfigView::updateList(ConfigItem* item)
1da177e4 1002{
d5d973c3
BB
1003 ConfigView* v;
1004
1005 for (v = viewList; v; v = v->nextView)
1006 v->list->updateList(item);
1da177e4
LT
1007}
1008
1009void ConfigView::updateListAll(void)
1010{
d5d973c3
BB
1011 ConfigView* v;
1012
1013 for (v = viewList; v; v = v->nextView)
1014 v->list->updateListAll();
1da177e4
LT
1015}
1016
43bf612a 1017ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name)
68ccb7ef 1018 : Parent(parent), sym(0), _menu(0)
43bf612a 1019{
d5d973c3
BB
1020 setObjectName(name);
1021
1022
1023 if (!objectName().isEmpty()) {
1024 configSettings->beginGroup(objectName());
e039303f 1025 setShowDebug(configSettings->value("/showDebug", false).toBool());
7fc925fd
RZ
1026 configSettings->endGroup();
1027 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
1028 }
1029}
1030
1031void ConfigInfoView::saveSettings(void)
1032{
d5d973c3
BB
1033 if (!objectName().isEmpty()) {
1034 configSettings->beginGroup(objectName());
1035 configSettings->setValue("/showDebug", showDebug());
1036 configSettings->endGroup();
1037 }
43bf612a
RZ
1038}
1039
1040void ConfigInfoView::setShowDebug(bool b)
1041{
1042 if (_showDebug != b) {
1043 _showDebug = b;
133c5f7c 1044 if (_menu)
43bf612a 1045 menuInfo();
ab45d190
RZ
1046 else if (sym)
1047 symbolInfo();
43bf612a
RZ
1048 emit showDebugChanged(b);
1049 }
1050}
1051
1052void ConfigInfoView::setInfo(struct menu *m)
1053{
133c5f7c 1054 if (_menu == m)
b65a47e1 1055 return;
133c5f7c 1056 _menu = m;
6fa1da8e 1057 sym = NULL;
133c5f7c 1058 if (!_menu)
43bf612a 1059 clear();
6fa1da8e 1060 else
43bf612a
RZ
1061 menuInfo();
1062}
1063
ab45d190
RZ
1064void ConfigInfoView::symbolInfo(void)
1065{
1066 QString str;
1067
1068 str += "<big>Symbol: <b>";
1069 str += print_filter(sym->name);
1070 str += "</b></big><br><br>value: ";
1071 str += print_filter(sym_get_string_value(sym));
1072 str += "<br>visibility: ";
1073 str += sym->visible == yes ? "y" : sym->visible == mod ? "m" : "n";
1074 str += "<br>";
1075 str += debug_info(sym);
1076
1077 setText(str);
1078}
1079
43bf612a
RZ
1080void ConfigInfoView::menuInfo(void)
1081{
1082 struct symbol* sym;
1083 QString head, debug, help;
1084
133c5f7c 1085 sym = _menu->sym;
43bf612a 1086 if (sym) {
133c5f7c 1087 if (_menu->prompt) {
43bf612a 1088 head += "<big><b>";
133c5f7c 1089 head += print_filter(_(_menu->prompt->text));
43bf612a
RZ
1090 head += "</b></big>";
1091 if (sym->name) {
1092 head += " (";
ab45d190
RZ
1093 if (showDebug())
1094 head += QString().sprintf("<a href=\"s%p\">", sym);
43bf612a 1095 head += print_filter(sym->name);
ab45d190
RZ
1096 if (showDebug())
1097 head += "</a>";
43bf612a
RZ
1098 head += ")";
1099 }
1100 } else if (sym->name) {
1101 head += "<big><b>";
ab45d190
RZ
1102 if (showDebug())
1103 head += QString().sprintf("<a href=\"s%p\">", sym);
43bf612a 1104 head += print_filter(sym->name);
ab45d190
RZ
1105 if (showDebug())
1106 head += "</a>";
43bf612a
RZ
1107 head += "</b></big>";
1108 }
1109 head += "<br><br>";
1110
1111 if (showDebug())
1112 debug = debug_info(sym);
1113
d74c15f3 1114 struct gstr help_gstr = str_new();
133c5f7c 1115 menu_get_ext_help(_menu, &help_gstr);
d74c15f3
CR
1116 help = print_filter(str_get(&help_gstr));
1117 str_free(&help_gstr);
133c5f7c 1118 } else if (_menu->prompt) {
43bf612a 1119 head += "<big><b>";
133c5f7c 1120 head += print_filter(_(_menu->prompt->text));
43bf612a
RZ
1121 head += "</b></big><br><br>";
1122 if (showDebug()) {
133c5f7c 1123 if (_menu->prompt->visible.expr) {
43bf612a 1124 debug += "&nbsp;&nbsp;dep: ";
133c5f7c 1125 expr_print(_menu->prompt->visible.expr, expr_print_help, &debug, E_NONE);
43bf612a
RZ
1126 debug += "<br><br>";
1127 }
1128 }
1129 }
1130 if (showDebug())
133c5f7c 1131 debug += QString().sprintf("defined at %s:%d<br><br>", _menu->file->name, _menu->lineno);
43bf612a
RZ
1132
1133 setText(head + debug + help);
1134}
1135
1136QString ConfigInfoView::debug_info(struct symbol *sym)
1137{
1138 QString debug;
1139
1140 debug += "type: ";
1141 debug += print_filter(sym_type_name(sym->type));
1142 if (sym_is_choice(sym))
1143 debug += " (choice)";
1144 debug += "<br>";
1145 if (sym->rev_dep.expr) {
1146 debug += "reverse dep: ";
1147 expr_print(sym->rev_dep.expr, expr_print_help, &debug, E_NONE);
1148 debug += "<br>";
1149 }
1150 for (struct property *prop = sym->prop; prop; prop = prop->next) {
1151 switch (prop->type) {
1152 case P_PROMPT:
1153 case P_MENU:
ab45d190 1154 debug += QString().sprintf("prompt: <a href=\"m%p\">", prop->menu);
43bf612a 1155 debug += print_filter(_(prop->text));
ab45d190 1156 debug += "</a><br>";
43bf612a
RZ
1157 break;
1158 case P_DEFAULT:
93449082
RZ
1159 case P_SELECT:
1160 case P_RANGE:
1161 case P_ENV:
1162 debug += prop_get_type_name(prop->type);
1163 debug += ": ";
43bf612a
RZ
1164 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1165 debug += "<br>";
1166 break;
1167 case P_CHOICE:
1168 if (sym_is_choice(sym)) {
1169 debug += "choice: ";
1170 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1171 debug += "<br>";
1172 }
1173 break;
43bf612a
RZ
1174 default:
1175 debug += "unknown property: ";
1176 debug += prop_get_type_name(prop->type);
1177 debug += "<br>";
1178 }
1179 if (prop->visible.expr) {
1180 debug += "&nbsp;&nbsp;&nbsp;&nbsp;dep: ";
1181 expr_print(prop->visible.expr, expr_print_help, &debug, E_NONE);
1182 debug += "<br>";
1183 }
1184 }
1185 debug += "<br>";
1186
1187 return debug;
1188}
1189
1190QString ConfigInfoView::print_filter(const QString &str)
1191{
1192 QRegExp re("[<>&\"\\n]");
1193 QString res = str;
68ccb7ef
BB
1194 for (int i = 0; (i = res.indexOf(re, i)) >= 0;) {
1195 switch (res[i].toLatin1()) {
43bf612a
RZ
1196 case '<':
1197 res.replace(i, 1, "&lt;");
1198 i += 4;
1199 break;
1200 case '>':
1201 res.replace(i, 1, "&gt;");
1202 i += 4;
1203 break;
1204 case '&':
1205 res.replace(i, 1, "&amp;");
1206 i += 5;
1207 break;
1208 case '"':
1209 res.replace(i, 1, "&quot;");
1210 i += 6;
1211 break;
1212 case '\n':
1213 res.replace(i, 1, "<br>");
1214 i += 4;
1215 break;
1216 }
1217 }
1218 return res;
1219}
1220
ab45d190 1221void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char *str)
43bf612a 1222{
ab45d190
RZ
1223 QString* text = reinterpret_cast<QString*>(data);
1224 QString str2 = print_filter(str);
1225
1226 if (sym && sym->name && !(sym->flags & SYMBOL_CONST)) {
1227 *text += QString().sprintf("<a href=\"s%p\">", sym);
1228 *text += str2;
1229 *text += "</a>";
1230 } else
1231 *text += str2;
43bf612a
RZ
1232}
1233
924bbb53 1234QMenu* ConfigInfoView::createStandardContextMenu(const QPoint & pos)
7fc925fd 1235{
924bbb53 1236 QMenu* popup = Parent::createStandardContextMenu(pos);
85eaf28a 1237 QAction* action = new QAction(_("Show Debug Info"), popup);
68ccb7ef 1238 action->setCheckable(true);
7fc925fd
RZ
1239 connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
1240 connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool)));
9c86235a 1241 action->setChecked(showDebug());
924bbb53 1242 popup->addSeparator();
68ccb7ef 1243 popup->addAction(action);
7fc925fd
RZ
1244 return popup;
1245}
1246
924bbb53 1247void ConfigInfoView::contextMenuEvent(QContextMenuEvent *e)
7fc925fd 1248{
924bbb53 1249 Parent::contextMenuEvent(e);
7fc925fd
RZ
1250}
1251
63431e75 1252ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow* parent, const char *name)
68ccb7ef 1253 : Parent(parent), result(NULL)
43bf612a 1254{
d5d973c3 1255 setObjectName(name);
68ccb7ef 1256 setWindowTitle("Search Config");
43bf612a 1257
68ccb7ef
BB
1258 QVBoxLayout* layout1 = new QVBoxLayout(this);
1259 layout1->setContentsMargins(11, 11, 11, 11);
1260 layout1->setSpacing(6);
1261 QHBoxLayout* layout2 = new QHBoxLayout(0);
1262 layout2->setContentsMargins(0, 0, 0, 0);
1263 layout2->setSpacing(6);
c21a2d95 1264 layout2->addWidget(new QLabel(_("Find:"), this));
43bf612a
RZ
1265 editField = new QLineEdit(this);
1266 connect(editField, SIGNAL(returnPressed()), SLOT(search()));
1267 layout2->addWidget(editField);
c21a2d95 1268 searchButton = new QPushButton(_("Search"), this);
68ccb7ef 1269 searchButton->setAutoDefault(false);
43bf612a
RZ
1270 connect(searchButton, SIGNAL(clicked()), SLOT(search()));
1271 layout2->addWidget(searchButton);
1272 layout1->addLayout(layout2);
1273
7fc925fd 1274 split = new QSplitter(this);
7298b936 1275 split->setOrientation(Qt::Vertical);
7fc925fd 1276 list = new ConfigView(split, name);
d5d973c3 1277 list->list->mode = listMode;
7fc925fd 1278 info = new ConfigInfoView(split, name);
43bf612a
RZ
1279 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1280 info, SLOT(setInfo(struct menu *)));
63431e75
MC
1281 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1282 parent, SLOT(setMenuLink(struct menu *)));
1283
43bf612a 1284 layout1->addWidget(split);
7fc925fd
RZ
1285
1286 if (name) {
68ccb7ef
BB
1287 QVariant x, y;
1288 int width, height;
7fc925fd
RZ
1289 bool ok;
1290
1291 configSettings->beginGroup(name);
68ccb7ef
BB
1292 width = configSettings->value("/window width", parent->width() / 2).toInt();
1293 height = configSettings->value("/window height", parent->height() / 2).toInt();
7fc925fd 1294 resize(width, height);
68ccb7ef
BB
1295 x = configSettings->value("/window x");
1296 y = configSettings->value("/window y");
1297 if ((x.isValid())&&(y.isValid()))
1298 move(x.toInt(), y.toInt());
041fbdc2 1299 QList<int> sizes = configSettings->readSizes("/split", &ok);
7fc925fd
RZ
1300 if (ok)
1301 split->setSizes(sizes);
1302 configSettings->endGroup();
1303 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
1304 }
1305}
1306
1307void ConfigSearchWindow::saveSettings(void)
1308{
d5d973c3
BB
1309 if (!objectName().isEmpty()) {
1310 configSettings->beginGroup(objectName());
1311 configSettings->setValue("/window x", pos().x());
1312 configSettings->setValue("/window y", pos().y());
1313 configSettings->setValue("/window width", size().width());
1314 configSettings->setValue("/window height", size().height());
1315 configSettings->writeSizes("/split", split->sizes());
1316 configSettings->endGroup();
1317 }
43bf612a
RZ
1318}
1319
1320void ConfigSearchWindow::search(void)
1321{
d5d973c3
BB
1322 struct symbol **p;
1323 struct property *prop;
1324 ConfigItem *lastItem = NULL;
1325
1326 free(result);
1327 list->list->clear();
1328 info->clear();
1329
1330 result = sym_re_search(editField->text().toLatin1());
1331 if (!result)
1332 return;
1333 for (p = result; *p; p++) {
1334 for_all_prompts((*p), prop)
1335 lastItem = new ConfigItem(list->list, lastItem, prop->menu,
1336 menu_is_visible(prop->menu));
1337 }
43bf612a
RZ
1338}
1339
1da177e4
LT
1340/*
1341 * Construct the complete config widget
1342 */
1343ConfigMainWindow::ConfigMainWindow(void)
f12aa704 1344 : searchWindow(0)
1da177e4
LT
1345{
1346 QMenuBar* menu;
92119937 1347 bool ok = true;
68ccb7ef
BB
1348 QVariant x, y;
1349 int width, height;
a54bb701 1350 char title[256];
1da177e4 1351
8d90c97e 1352 QDesktopWidget *d = configApp->desktop();
0954828f
AL
1353 snprintf(title, sizeof(title), "%s%s",
1354 rootmenu.prompt->text,
76a136c4 1355 ""
76a136c4 1356 );
68ccb7ef 1357 setWindowTitle(title);
1da177e4 1358
68ccb7ef
BB
1359 width = configSettings->value("/window width", d->width() - 64).toInt();
1360 height = configSettings->value("/window height", d->height() - 64).toInt();
1da177e4 1361 resize(width, height);
68ccb7ef
BB
1362 x = configSettings->value("/window x");
1363 y = configSettings->value("/window y");
1364 if ((x.isValid())&&(y.isValid()))
1365 move(x.toInt(), y.toInt());
1da177e4
LT
1366
1367 split1 = new QSplitter(this);
7298b936 1368 split1->setOrientation(Qt::Horizontal);
1da177e4
LT
1369 setCentralWidget(split1);
1370
7fc925fd 1371 menuView = new ConfigView(split1, "menu");
1da177e4
LT
1372 menuList = menuView->list;
1373
1374 split2 = new QSplitter(split1);
7298b936 1375 split2->setOrientation(Qt::Vertical);
1da177e4
LT
1376
1377 // create config tree
7fc925fd 1378 configView = new ConfigView(split2, "config");
1da177e4
LT
1379 configList = configView->list;
1380
7fc925fd 1381 helpText = new ConfigInfoView(split2, "help");
1da177e4
LT
1382
1383 setTabOrder(configList, helpText);
1384 configList->setFocus();
1385
1386 menu = menuBar();
b1f8a45b 1387 toolBar = new QToolBar("Tools", this);
29a70168 1388 addToolBar(toolBar);
1da177e4 1389
85eaf28a 1390 backAction = new QAction(QPixmap(xpm_back), _("Back"), this);
92119937 1391 connect(backAction, SIGNAL(triggered(bool)), SLOT(goBack()));
68ccb7ef 1392 backAction->setEnabled(false);
85eaf28a
BB
1393 QAction *quitAction = new QAction(_("&Quit"), this);
1394 quitAction->setShortcut(Qt::CTRL + Qt::Key_Q);
92119937 1395 connect(quitAction, SIGNAL(triggered(bool)), SLOT(close()));
85eaf28a
BB
1396 QAction *loadAction = new QAction(QPixmap(xpm_load), _("&Load"), this);
1397 loadAction->setShortcut(Qt::CTRL + Qt::Key_L);
92119937 1398 connect(loadAction, SIGNAL(triggered(bool)), SLOT(loadConfig()));
85eaf28a
BB
1399 saveAction = new QAction(QPixmap(xpm_save), _("&Save"), this);
1400 saveAction->setShortcut(Qt::CTRL + Qt::Key_S);
92119937 1401 connect(saveAction, SIGNAL(triggered(bool)), SLOT(saveConfig()));
3b354c55
KW
1402 conf_set_changed_callback(conf_changed);
1403 // Set saveAction's initial state
1404 conf_changed();
85eaf28a 1405 QAction *saveAsAction = new QAction(_("Save &As..."), this);
92119937 1406 connect(saveAsAction, SIGNAL(triggered(bool)), SLOT(saveConfigAs()));
85eaf28a
BB
1407 QAction *searchAction = new QAction(_("&Find"), this);
1408 searchAction->setShortcut(Qt::CTRL + Qt::Key_F);
92119937 1409 connect(searchAction, SIGNAL(triggered(bool)), SLOT(searchConfig()));
780505e3 1410 singleViewAction = new QAction(QPixmap(xpm_single_view), _("Single View"), this);
68ccb7ef 1411 singleViewAction->setCheckable(true);
92119937 1412 connect(singleViewAction, SIGNAL(triggered(bool)), SLOT(showSingleView()));
780505e3 1413 splitViewAction = new QAction(QPixmap(xpm_split_view), _("Split View"), this);
68ccb7ef 1414 splitViewAction->setCheckable(true);
92119937 1415 connect(splitViewAction, SIGNAL(triggered(bool)), SLOT(showSplitView()));
780505e3 1416 fullViewAction = new QAction(QPixmap(xpm_tree_view), _("Full View"), this);
68ccb7ef 1417 fullViewAction->setCheckable(true);
92119937 1418 connect(fullViewAction, SIGNAL(triggered(bool)), SLOT(showFullView()));
1da177e4 1419
85eaf28a 1420 QAction *showNameAction = new QAction(_("Show Name"), this);
68ccb7ef 1421 showNameAction->setCheckable(true);
7fc925fd 1422 connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool)));
9c86235a 1423 showNameAction->setChecked(configView->showName());
85eaf28a 1424 QAction *showRangeAction = new QAction(_("Show Range"), this);
68ccb7ef 1425 showRangeAction->setCheckable(true);
7fc925fd 1426 connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool)));
85eaf28a 1427 QAction *showDataAction = new QAction(_("Show Data"), this);
68ccb7ef 1428 showDataAction->setCheckable(true);
7fc925fd 1429 connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool)));
39a4897c
LZ
1430
1431 QActionGroup *optGroup = new QActionGroup(this);
68ccb7ef 1432 optGroup->setExclusive(true);
92119937 1433 connect(optGroup, SIGNAL(triggered(QAction*)), configView,
39a4897c 1434 SLOT(setOptionMode(QAction *)));
92119937 1435 connect(optGroup, SIGNAL(triggered(QAction *)), menuView,
39a4897c
LZ
1436 SLOT(setOptionMode(QAction *)));
1437
133c5f7c
AS
1438 configView->showNormalAction = new QAction(_("Show Normal Options"), optGroup);
1439 configView->showAllAction = new QAction(_("Show All Options"), optGroup);
1440 configView->showPromptAction = new QAction(_("Show Prompt Options"), optGroup);
68ccb7ef
BB
1441 configView->showNormalAction->setCheckable(true);
1442 configView->showAllAction->setCheckable(true);
1443 configView->showPromptAction->setCheckable(true);
39a4897c 1444
85eaf28a 1445 QAction *showDebugAction = new QAction( _("Show Debug Info"), this);
68ccb7ef 1446 showDebugAction->setCheckable(true);
43bf612a 1447 connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
9c86235a 1448 showDebugAction->setChecked(helpText->showDebug());
1da177e4 1449
85eaf28a 1450 QAction *showIntroAction = new QAction( _("Introduction"), this);
92119937 1451 connect(showIntroAction, SIGNAL(triggered(bool)), SLOT(showIntro()));
85eaf28a 1452 QAction *showAboutAction = new QAction( _("About"), this);
92119937 1453 connect(showAboutAction, SIGNAL(triggered(bool)), SLOT(showAbout()));
1da177e4
LT
1454
1455 // init tool bar
68ccb7ef 1456 toolBar->addAction(backAction);
1da177e4 1457 toolBar->addSeparator();
68ccb7ef
BB
1458 toolBar->addAction(loadAction);
1459 toolBar->addAction(saveAction);
1da177e4 1460 toolBar->addSeparator();
68ccb7ef
BB
1461 toolBar->addAction(singleViewAction);
1462 toolBar->addAction(splitViewAction);
1463 toolBar->addAction(fullViewAction);
1da177e4
LT
1464
1465 // create config menu
68ccb7ef
BB
1466 QMenu* config = menu->addMenu(_("&File"));
1467 config->addAction(loadAction);
1468 config->addAction(saveAction);
1469 config->addAction(saveAsAction);
76bede87 1470 config->addSeparator();
68ccb7ef 1471 config->addAction(quitAction);
1da177e4 1472
66e7c723 1473 // create edit menu
68ccb7ef
BB
1474 QMenu* editMenu = menu->addMenu(_("&Edit"));
1475 editMenu->addAction(searchAction);
66e7c723 1476
1da177e4 1477 // create options menu
68ccb7ef
BB
1478 QMenu* optionMenu = menu->addMenu(_("&Option"));
1479 optionMenu->addAction(showNameAction);
1480 optionMenu->addAction(showRangeAction);
1481 optionMenu->addAction(showDataAction);
76bede87 1482 optionMenu->addSeparator();
68ccb7ef 1483 optionMenu->addActions(optGroup->actions());
76bede87 1484 optionMenu->addSeparator();
e039303f 1485 optionMenu->addAction(showDebugAction);
1da177e4
LT
1486
1487 // create help menu
76bede87 1488 menu->addSeparator();
68ccb7ef
BB
1489 QMenu* helpMenu = menu->addMenu(_("&Help"));
1490 helpMenu->addAction(showIntroAction);
1491 helpMenu->addAction(showAboutAction);
1da177e4 1492
d5d973c3
BB
1493 connect(configList, SIGNAL(menuChanged(struct menu *)),
1494 helpText, SLOT(setInfo(struct menu *)));
1495 connect(configList, SIGNAL(menuSelected(struct menu *)),
1496 SLOT(changeMenu(struct menu *)));
1497 connect(configList, SIGNAL(parentSelected()),
1498 SLOT(goBack()));
1499 connect(menuList, SIGNAL(menuChanged(struct menu *)),
1500 helpText, SLOT(setInfo(struct menu *)));
1501 connect(menuList, SIGNAL(menuSelected(struct menu *)),
1502 SLOT(changeMenu(struct menu *)));
1503
1504 connect(configList, SIGNAL(gotFocus(struct menu *)),
1505 helpText, SLOT(setInfo(struct menu *)));
1506 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1507 helpText, SLOT(setInfo(struct menu *)));
1508 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1509 SLOT(listFocusChanged(void)));
b65a47e1
RZ
1510 connect(helpText, SIGNAL(menuSelected(struct menu *)),
1511 SLOT(setMenuLink(struct menu *)));
1da177e4 1512
68ccb7ef 1513 QString listMode = configSettings->value("/listMode", "symbol").toString();
1da177e4
LT
1514 if (listMode == "single")
1515 showSingleView();
1516 else if (listMode == "full")
1517 showFullView();
1518 else /*if (listMode == "split")*/
1519 showSplitView();
1520
1521 // UI setup done, restore splitter positions
041fbdc2 1522 QList<int> sizes = configSettings->readSizes("/split1", &ok);
1da177e4
LT
1523 if (ok)
1524 split1->setSizes(sizes);
1525
7fc925fd 1526 sizes = configSettings->readSizes("/split2", &ok);
1da177e4
LT
1527 if (ok)
1528 split2->setSizes(sizes);
1da177e4
LT
1529}
1530
1da177e4
LT
1531void ConfigMainWindow::loadConfig(void)
1532{
68ccb7ef 1533 QString s = QFileDialog::getOpenFileName(this, "", conf_get_configname());
1da177e4
LT
1534 if (s.isNull())
1535 return;
3b9fa093 1536 if (conf_read(QFile::encodeName(s)))
c21a2d95 1537 QMessageBox::information(this, "qconf", _("Unable to load configuration!"));
1da177e4
LT
1538 ConfigView::updateListAll();
1539}
1540
bac6aa86 1541bool ConfigMainWindow::saveConfig(void)
1da177e4 1542{
bac6aa86 1543 if (conf_write(NULL)) {
c21a2d95 1544 QMessageBox::information(this, "qconf", _("Unable to save configuration!"));
bac6aa86
MM
1545 return false;
1546 }
1547 return true;
1da177e4
LT
1548}
1549
1550void ConfigMainWindow::saveConfigAs(void)
1551{
68ccb7ef 1552 QString s = QFileDialog::getSaveFileName(this, "", conf_get_configname());
1da177e4
LT
1553 if (s.isNull())
1554 return;
d49e4687 1555 saveConfig();
1da177e4
LT
1556}
1557
43bf612a
RZ
1558void ConfigMainWindow::searchConfig(void)
1559{
1560 if (!searchWindow)
7fc925fd 1561 searchWindow = new ConfigSearchWindow(this, "search");
43bf612a
RZ
1562 searchWindow->show();
1563}
1564
1da177e4
LT
1565void ConfigMainWindow::changeMenu(struct menu *menu)
1566{
d5d973c3
BB
1567 configList->setRootMenu(menu);
1568 if (configList->rootEntry->parent == &rootmenu)
1569 backAction->setEnabled(false);
1570 else
1571 backAction->setEnabled(true);
1da177e4
LT
1572}
1573
b65a47e1 1574void ConfigMainWindow::setMenuLink(struct menu *menu)
1da177e4 1575{
d5d973c3
BB
1576 struct menu *parent;
1577 ConfigList* list = NULL;
1578 ConfigItem* item;
1579
1580 if (configList->menuSkip(menu))
1581 return;
1582
1583 switch (configList->mode) {
1584 case singleMode:
1585 list = configList;
1586 parent = menu_get_parent_menu(menu);
1587 if (!parent)
1588 return;
1589 list->setRootMenu(parent);
1590 break;
1591 case symbolMode:
1592 if (menu->flags & MENU_ROOT) {
1593 configList->setRootMenu(menu);
1594 configList->clearSelection();
1595 list = menuList;
1596 } else {
1597 list = configList;
1598 parent = menu_get_parent_menu(menu->parent);
1599 if (!parent)
1600 return;
1601 item = menuList->findConfigItem(parent);
1602 if (item) {
1603 item->setSelected(true);
1604 menuList->scrollToItem(item);
1605 }
1606 list->setRootMenu(parent);
1607 }
1608 break;
1609 case fullMode:
1610 list = configList;
1611 break;
1612 default:
1613 break;
1614 }
1615
1616 if (list) {
1617 item = list->findConfigItem(menu);
1618 if (item) {
1619 item->setSelected(true);
1620 list->scrollToItem(item);
1621 list->setFocus();
1622 }
1623 }
1da177e4
LT
1624}
1625
b65a47e1
RZ
1626void ConfigMainWindow::listFocusChanged(void)
1627{
d5d973c3
BB
1628 if (menuList->mode == menuMode)
1629 configList->clearSelection();
b65a47e1
RZ
1630}
1631
1da177e4
LT
1632void ConfigMainWindow::goBack(void)
1633{
5df9da9d 1634 ConfigItem* item, *oldSelection;
d5d973c3
BB
1635
1636 configList->setParentMenu();
1637 if (configList->rootEntry == &rootmenu)
1638 backAction->setEnabled(false);
be596aaa
BB
1639
1640 if (menuList->selectedItems().count() == 0)
1641 return;
1642
d5d973c3 1643 item = (ConfigItem*)menuList->selectedItems().first();
5df9da9d 1644 oldSelection = item;
d5d973c3
BB
1645 while (item) {
1646 if (item->menu == configList->rootEntry) {
5df9da9d 1647 oldSelection->setSelected(false);
d5d973c3
BB
1648 item->setSelected(true);
1649 break;
1650 }
1651 item = (ConfigItem*)item->parent();
1652 }
1da177e4
LT
1653}
1654
1655void ConfigMainWindow::showSingleView(void)
1656{
780505e3
BB
1657 singleViewAction->setEnabled(false);
1658 singleViewAction->setChecked(true);
1659 splitViewAction->setEnabled(true);
1660 splitViewAction->setChecked(false);
1661 fullViewAction->setEnabled(true);
1662 fullViewAction->setChecked(false);
1663
1da177e4 1664 menuView->hide();
d5d973c3
BB
1665 menuList->setRootMenu(0);
1666 configList->mode = singleMode;
1667 if (configList->rootEntry == &rootmenu)
1668 configList->updateListAll();
1669 else
1670 configList->setRootMenu(&rootmenu);
1da177e4
LT
1671 configList->setFocus();
1672}
1673
1674void ConfigMainWindow::showSplitView(void)
1675{
780505e3
BB
1676 singleViewAction->setEnabled(true);
1677 singleViewAction->setChecked(false);
1678 splitViewAction->setEnabled(false);
1679 splitViewAction->setChecked(true);
1680 fullViewAction->setEnabled(true);
1681 fullViewAction->setChecked(false);
1682
d5d973c3
BB
1683 configList->mode = symbolMode;
1684 if (configList->rootEntry == &rootmenu)
1685 configList->updateListAll();
1686 else
1687 configList->setRootMenu(&rootmenu);
1688 configList->setAllOpen(true);
1689 configApp->processEvents();
1690 menuList->mode = menuMode;
1691 menuList->setRootMenu(&rootmenu);
1692 menuList->setAllOpen(true);
1da177e4
LT
1693 menuView->show();
1694 menuList->setFocus();
1695}
1696
1697void ConfigMainWindow::showFullView(void)
1698{
780505e3
BB
1699 singleViewAction->setEnabled(true);
1700 singleViewAction->setChecked(false);
1701 splitViewAction->setEnabled(true);
1702 splitViewAction->setChecked(false);
1703 fullViewAction->setEnabled(false);
1704 fullViewAction->setChecked(true);
1705
1da177e4 1706 menuView->hide();
d5d973c3
BB
1707 menuList->setRootMenu(0);
1708 configList->mode = fullMode;
1709 if (configList->rootEntry == &rootmenu)
1710 configList->updateListAll();
1711 else
1712 configList->setRootMenu(&rootmenu);
1da177e4
LT
1713 configList->setFocus();
1714}
1715
1da177e4
LT
1716/*
1717 * ask for saving configuration before quitting
1718 * TODO ask only when something changed
1719 */
1720void ConfigMainWindow::closeEvent(QCloseEvent* e)
1721{
b3214293 1722 if (!conf_get_changed()) {
1da177e4
LT
1723 e->accept();
1724 return;
1725 }
c21a2d95 1726 QMessageBox mb("qconf", _("Save configuration?"), QMessageBox::Warning,
1da177e4 1727 QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape);
c21a2d95
EG
1728 mb.setButtonText(QMessageBox::Yes, _("&Save Changes"));
1729 mb.setButtonText(QMessageBox::No, _("&Discard Changes"));
1730 mb.setButtonText(QMessageBox::Cancel, _("Cancel Exit"));
1da177e4
LT
1731 switch (mb.exec()) {
1732 case QMessageBox::Yes:
bac6aa86
MM
1733 if (saveConfig())
1734 e->accept();
1735 else
1736 e->ignore();
1737 break;
1da177e4
LT
1738 case QMessageBox::No:
1739 e->accept();
1740 break;
1741 case QMessageBox::Cancel:
1742 e->ignore();
1743 break;
1744 }
1745}
1746
1747void ConfigMainWindow::showIntro(void)
1748{
652cf982 1749 static const QString str = _("Welcome to the qconf graphical configuration tool.\n\n"
1da177e4
LT
1750 "For each option, a blank box indicates the feature is disabled, a check\n"
1751 "indicates it is enabled, and a dot indicates that it is to be compiled\n"
1752 "as a module. Clicking on the box will cycle through the three states.\n\n"
1753 "If you do not see an option (e.g., a device driver) that you believe\n"
1754 "should be present, try turning on Show All Options under the Options menu.\n"
1755 "Although there is no cross reference yet to help you figure out what other\n"
1756 "options must be enabled to support the option you are interested in, you can\n"
1757 "still view the help of a grayed-out option.\n\n"
1758 "Toggling Show Debug Info under the Options menu will show the dependencies,\n"
c21a2d95 1759 "which you can then match by examining other options.\n\n");
1da177e4
LT
1760
1761 QMessageBox::information(this, "qconf", str);
1762}
1763
1764void ConfigMainWindow::showAbout(void)
1765{
b4ff1de3
BB
1766 static const QString str = _("qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n"
1767 "Copyright (C) 2015 Boris Barbulovski <bbarbulovski@gmail.com>.\n\n"
c21a2d95 1768 "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n");
1da177e4
LT
1769
1770 QMessageBox::information(this, "qconf", str);
1771}
1772
1773void ConfigMainWindow::saveSettings(void)
1774{
68ccb7ef
BB
1775 configSettings->setValue("/window x", pos().x());
1776 configSettings->setValue("/window y", pos().y());
1777 configSettings->setValue("/window width", size().width());
1778 configSettings->setValue("/window height", size().height());
1da177e4
LT
1779
1780 QString entry;
d5d973c3
BB
1781 switch(configList->mode) {
1782 case singleMode :
1783 entry = "single";
1784 break;
1785
1786 case symbolMode :
1787 entry = "split";
1788 break;
1789
1790 case fullMode :
1791 entry = "full";
1792 break;
98403a91 1793
d5d973c3
BB
1794 default:
1795 break;
1796 }
68ccb7ef 1797 configSettings->setValue("/listMode", entry);
1da177e4 1798
7fc925fd
RZ
1799 configSettings->writeSizes("/split1", split1->sizes());
1800 configSettings->writeSizes("/split2", split2->sizes());
1da177e4
LT
1801}
1802
3b354c55
KW
1803void ConfigMainWindow::conf_changed(void)
1804{
1805 if (saveAction)
1806 saveAction->setEnabled(conf_get_changed());
1807}
1808
1da177e4
LT
1809void fixup_rootmenu(struct menu *menu)
1810{
1811 struct menu *child;
1812 static int menu_cnt = 0;
1813
1814 menu->flags |= MENU_ROOT;
1815 for (child = menu->list; child; child = child->next) {
1816 if (child->prompt && child->prompt->type == P_MENU) {
1817 menu_cnt++;
1818 fixup_rootmenu(child);
1819 menu_cnt--;
1820 } else if (!menu_cnt)
1821 fixup_rootmenu(child);
1822 }
1823}
1824
1825static const char *progname;
1826
1827static void usage(void)
1828{
68ccb7ef 1829 printf(_("%s [-s] <config>\n").toLatin1().constData(), progname);
1da177e4
LT
1830 exit(0);
1831}
1832
1833int main(int ac, char** av)
1834{
1835 ConfigMainWindow* v;
1836 const char *name;
1837
3b9fa093
ACM
1838 bindtextdomain(PACKAGE, LOCALEDIR);
1839 textdomain(PACKAGE);
1840
1da177e4
LT
1841 progname = av[0];
1842 configApp = new QApplication(ac, av);
1843 if (ac > 1 && av[1][0] == '-') {
1844 switch (av[1][1]) {
0a1f00a1
MM
1845 case 's':
1846 conf_set_message_callback(NULL);
1847 break;
1da177e4
LT
1848 case 'h':
1849 case '?':
1850 usage();
1851 }
1852 name = av[2];
1853 } else
1854 name = av[1];
1855 if (!name)
1856 usage();
1857
1858 conf_parse(name);
1859 fixup_rootmenu(&rootmenu);
1860 conf_read(NULL);
1861 //zconfdump(stdout);
1862
7fc925fd
RZ
1863 configSettings = new ConfigSettings();
1864 configSettings->beginGroup("/kconfig/qconf");
1da177e4
LT
1865 v = new ConfigMainWindow();
1866
1867 //zconfdump(stdout);
1da177e4
LT
1868 configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit()));
1869 configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings()));
43bf612a 1870 v->show();
1da177e4
LT
1871 configApp->exec();
1872
7fc925fd
RZ
1873 configSettings->endGroup();
1874 delete configSettings;
5b61c7bd
CB
1875 delete v;
1876 delete configApp;
7fc925fd 1877
1da177e4
LT
1878 return 0;
1879}