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