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