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