2 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
3 * Released under the terms of the GNU GPL v2.0.
6 #include <qapplication.h>
7 #include <qmainwindow.h>
11 #include <qsplitter.h>
12 #include <qlistview.h>
13 #include <qtextbrowser.h>
14 #include <qlineedit.h>
16 #include <qpushbutton.h>
18 #include <qmessagebox.h>
21 #include <qfiledialog.h>
22 #include <qdragobject.h>
38 static QApplication *configApp;
39 static ConfigSettings *configSettings;
41 QAction *ConfigMainWindow::saveAction;
43 static inline QString qgettext(const char* str)
45 return QString::fromLocal8Bit(gettext(str));
48 static inline QString qgettext(const QString& str)
50 return QString::fromLocal8Bit(gettext(str.latin1()));
54 * Reads a list of integer values from the application settings.
56 QValueList<int> ConfigSettings::readSizes(const QString& key, bool *ok)
58 QValueList<int> result;
59 QStringList entryList = readListEntry(key, ok);
61 QStringList::Iterator it;
62 for (it = entryList.begin(); it != entryList.end(); ++it)
63 result.push_back((*it).toInt());
70 * Writes a list of integer values to the application settings.
72 bool ConfigSettings::writeSizes(const QString& key, const QValueList<int>& value)
74 QStringList stringList;
75 QValueList<int>::ConstIterator it;
77 for (it = value.begin(); it != value.end(); ++it)
78 stringList.push_back(QString::number(*it));
79 return writeEntry(key, stringList);
86 * TODO check the value
88 void ConfigItem::okRename(int col)
90 Parent::okRename(col);
91 sym_set_string_value(menu->sym, text(dataColIdx).latin1());
92 listView()->updateList(this);
97 * update the displayed of a menu entry
99 void ConfigItem::updateMenu(void)
103 struct property *prop;
110 setPixmap(promptColIdx, list->menuBackPix);
117 prompt = _(menu_get_prompt(menu));
119 if (prop) switch (prop->type) {
121 if (list->mode == singleMode || list->mode == symbolMode) {
122 /* a menuconfig entry is displayed differently
123 * depending whether it's at the view root or a child.
125 if (sym && list->rootEntry == menu)
127 setPixmap(promptColIdx, list->menuPix);
131 setPixmap(promptColIdx, 0);
135 setPixmap(promptColIdx, 0);
143 setText(nameColIdx, QString::fromLocal8Bit(sym->name));
145 type = sym_get_type(sym);
151 if (!sym_is_changable(sym) && !list->showAll) {
152 setPixmap(promptColIdx, 0);
153 setText(noColIdx, QString::null);
154 setText(modColIdx, QString::null);
155 setText(yesColIdx, QString::null);
158 expr = sym_get_tristate_value(sym);
161 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
162 setPixmap(promptColIdx, list->choiceYesPix);
164 setPixmap(promptColIdx, list->symbolYesPix);
165 setText(yesColIdx, "Y");
169 setPixmap(promptColIdx, list->symbolModPix);
170 setText(modColIdx, "M");
174 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
175 setPixmap(promptColIdx, list->choiceNoPix);
177 setPixmap(promptColIdx, list->symbolNoPix);
178 setText(noColIdx, "N");
183 setText(noColIdx, sym_tristate_within_range(sym, no) ? "_" : 0);
185 setText(modColIdx, sym_tristate_within_range(sym, mod) ? "_" : 0);
187 setText(yesColIdx, sym_tristate_within_range(sym, yes) ? "_" : 0);
189 setText(dataColIdx, QChar(ch));
196 data = sym_get_string_value(sym);
198 #if QT_VERSION >= 300
199 int i = list->mapIdx(dataColIdx);
201 setRenameEnabled(i, TRUE);
203 setText(dataColIdx, data);
204 if (type == S_STRING)
205 prompt = QString("%1: %2").arg(prompt).arg(data);
207 prompt = QString("(%2) %1").arg(prompt).arg(data);
210 if (!sym_has_value(sym) && visible)
211 prompt += _(" (NEW)");
213 setText(promptColIdx, prompt);
216 void ConfigItem::testUpdateMenu(bool v)
224 sym_calc_value(menu->sym);
225 if (menu->flags & MENU_CHANGED) {
226 /* the menu entry changed, so update all list items */
227 menu->flags &= ~MENU_CHANGED;
228 for (i = (ConfigItem*)menu->data; i; i = i->nextItem)
230 } else if (listView()->updateAll)
234 void ConfigItem::paintCell(QPainter* p, const QColorGroup& cg, int column, int width, int align)
236 ConfigList* list = listView();
239 if (isSelected() && !list->hasFocus() && list->mode == menuMode)
240 Parent::paintCell(p, list->inactivedColorGroup, column, width, align);
242 Parent::paintCell(p, cg, column, width, align);
244 Parent::paintCell(p, list->disabledColorGroup, column, width, align);
248 * construct a menu entry
250 void ConfigItem::init(void)
253 ConfigList* list = listView();
254 nextItem = (ConfigItem*)menu->data;
257 if (list->mode != fullMode)
259 sym_calc_value(menu->sym);
265 * destruct a menu entry
267 ConfigItem::~ConfigItem(void)
270 ConfigItem** ip = (ConfigItem**)&menu->data;
271 for (; *ip; ip = &(*ip)->nextItem) {
280 ConfigLineEdit::ConfigLineEdit(ConfigView* parent)
283 connect(this, SIGNAL(lostFocus()), SLOT(hide()));
286 void ConfigLineEdit::show(ConfigItem* i)
289 if (sym_get_string_value(item->menu->sym))
290 setText(QString::fromLocal8Bit(sym_get_string_value(item->menu->sym)));
292 setText(QString::null);
297 void ConfigLineEdit::keyPressEvent(QKeyEvent* e)
304 sym_set_string_value(item->menu->sym, text().latin1());
305 parent()->updateList(item);
308 Parent::keyPressEvent(e);
312 parent()->list->setFocus();
316 ConfigList::ConfigList(ConfigView* p, const char *name)
319 symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no),
320 choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no),
321 menuPix(xpm_menu), menuInvPix(xpm_menu_inv), menuBackPix(xpm_menuback), voidPix(xpm_void),
322 showAll(false), showName(false), showRange(false), showData(false),
323 rootEntry(0), headerPopup(0)
328 setRootIsDecorated(TRUE);
329 disabledColorGroup = palette().active();
330 disabledColorGroup.setColor(QColorGroup::Text, palette().disabled().text());
331 inactivedColorGroup = palette().active();
332 inactivedColorGroup.setColor(QColorGroup::Highlight, palette().disabled().highlight());
334 connect(this, SIGNAL(selectionChanged(void)),
335 SLOT(updateSelection(void)));
338 configSettings->beginGroup(name);
339 showAll = configSettings->readBoolEntry("/showAll", false);
340 showName = configSettings->readBoolEntry("/showName", false);
341 showRange = configSettings->readBoolEntry("/showRange", false);
342 showData = configSettings->readBoolEntry("/showData", false);
343 configSettings->endGroup();
344 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
347 for (i = 0; i < colNr; i++)
348 colMap[i] = colRevMap[i] = -1;
349 addColumn(promptColIdx, _("Option"));
354 void ConfigList::reinit(void)
356 removeColumn(dataColIdx);
357 removeColumn(yesColIdx);
358 removeColumn(modColIdx);
359 removeColumn(noColIdx);
360 removeColumn(nameColIdx);
363 addColumn(nameColIdx, _("Name"));
365 addColumn(noColIdx, "N");
366 addColumn(modColIdx, "M");
367 addColumn(yesColIdx, "Y");
370 addColumn(dataColIdx, _("Value"));
375 void ConfigList::saveSettings(void)
378 configSettings->beginGroup(name());
379 configSettings->writeEntry("/showName", showName);
380 configSettings->writeEntry("/showRange", showRange);
381 configSettings->writeEntry("/showData", showData);
382 configSettings->writeEntry("/showAll", showAll);
383 configSettings->endGroup();
387 ConfigItem* ConfigList::findConfigItem(struct menu *menu)
389 ConfigItem* item = (ConfigItem*)menu->data;
391 for (; item; item = item->nextItem) {
392 if (this == item->listView())
399 void ConfigList::updateSelection(void)
404 ConfigItem* item = (ConfigItem*)selectedItem();
409 emit menuChanged(menu);
412 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
413 if (mode == menuMode && type == P_MENU)
414 emit menuSelected(menu);
417 void ConfigList::updateList(ConfigItem* item)
419 ConfigItem* last = 0;
422 if (mode != listMode)
424 QListViewItemIterator it(this);
427 for (; it.current(); ++it) {
428 item = (ConfigItem*)it.current();
431 item->testUpdateMenu(menu_is_visible(item->menu));
436 if (rootEntry != &rootmenu && (mode == singleMode ||
437 (mode == symbolMode && rootEntry->parent != &rootmenu))) {
440 item = new ConfigItem(this, 0, true);
443 if ((mode == singleMode || (mode == symbolMode && !(rootEntry->flags & MENU_ROOT))) &&
444 rootEntry->sym && rootEntry->prompt) {
445 item = last ? last->nextSibling() : firstChild();
447 item = new ConfigItem(this, last, rootEntry, true);
449 item->testUpdateMenu(true);
451 updateMenuList(item, rootEntry);
456 updateMenuList(this, rootEntry);
460 void ConfigList::setValue(ConfigItem* item, tristate val)
466 sym = item->menu ? item->menu->sym : 0;
470 type = sym_get_type(sym);
474 oldval = sym_get_tristate_value(sym);
476 if (!sym_set_tristate_value(sym, val))
478 if (oldval == no && item->menu->list)
480 parent()->updateList(item);
485 void ConfigList::changeValue(ConfigItem* item)
489 int type, oldexpr, newexpr;
496 if (item->menu->list)
497 item->setOpen(!item->isOpen());
501 type = sym_get_type(sym);
505 oldexpr = sym_get_tristate_value(sym);
506 newexpr = sym_toggle_tristate_value(sym);
507 if (item->menu->list) {
508 if (oldexpr == newexpr)
509 item->setOpen(!item->isOpen());
510 else if (oldexpr == no)
513 if (oldexpr != newexpr)
514 parent()->updateList(item);
519 #if QT_VERSION >= 300
520 if (colMap[dataColIdx] >= 0)
521 item->startRename(colMap[dataColIdx]);
524 parent()->lineEdit->show(item);
529 void ConfigList::setRootMenu(struct menu *menu)
533 if (rootEntry == menu)
535 type = menu && menu->prompt ? menu->prompt->type : P_UNKNOWN;
538 updateMenuList(this, 0);
541 setSelected(currentItem(), hasFocus());
542 ensureItemVisible(currentItem());
545 void ConfigList::setParentMenu(void)
548 struct menu *oldroot;
551 if (rootEntry == &rootmenu)
553 setRootMenu(menu_get_parent_menu(rootEntry->parent));
555 QListViewItemIterator it(this);
556 for (; (item = (ConfigItem*)it.current()); it++) {
557 if (item->menu == oldroot) {
558 setCurrentItem(item);
559 ensureItemVisible(item);
566 * update all the children of a menu entry
567 * removes/adds the entries from the parent widget as necessary
569 * parent: either the menu list widget or a menu entry widget
570 * menu: entry to be updated
573 void ConfigList::updateMenuList(P* parent, struct menu* menu)
582 while ((item = parent->firstChild()))
587 last = parent->firstChild();
588 if (last && !last->goParent)
590 for (child = menu->list; child; child = child->next) {
591 item = last ? last->nextSibling() : parent->firstChild();
592 type = child->prompt ? child->prompt->type : P_UNKNOWN;
596 if (!(child->flags & MENU_ROOT))
600 if (child->flags & MENU_ROOT)
607 visible = menu_is_visible(child);
608 if (showAll || visible) {
609 if (!child->sym && !child->list && !child->prompt)
611 if (!item || item->menu != child)
612 item = new ConfigItem(parent, last, child, visible);
614 item->testUpdateMenu(visible);
616 if (mode == fullMode || mode == menuMode || type != P_MENU)
617 updateMenuList(item, child);
619 updateMenuList(item, 0);
624 if (item && item->menu == child) {
625 last = parent->firstChild();
628 else while (last->nextSibling() != item)
629 last = last->nextSibling();
635 void ConfigList::keyPressEvent(QKeyEvent* ev)
637 QListViewItem* i = currentItem();
642 if (ev->key() == Key_Escape && mode != fullMode && mode != listMode) {
643 emit parentSelected();
649 Parent::keyPressEvent(ev);
652 item = (ConfigItem*)i;
657 if (item->goParent) {
658 emit parentSelected();
664 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
665 if (type == P_MENU && rootEntry != menu &&
666 mode != fullMode && mode != menuMode) {
667 emit menuSelected(menu);
683 Parent::keyPressEvent(ev);
689 void ConfigList::contentsMousePressEvent(QMouseEvent* e)
691 //QPoint p(contentsToViewport(e->pos()));
692 //printf("contentsMousePressEvent: %d,%d\n", p.x(), p.y());
693 Parent::contentsMousePressEvent(e);
696 void ConfigList::contentsMouseReleaseEvent(QMouseEvent* e)
698 QPoint p(contentsToViewport(e->pos()));
699 ConfigItem* item = (ConfigItem*)itemAt(p);
701 enum prop_type ptype;
709 x = header()->offset() + p.x();
710 idx = colRevMap[header()->sectionAt(x)];
713 pm = item->pixmap(promptColIdx);
715 int off = header()->sectionPos(0) + itemMargin() +
716 treeStepSize() * (item->depth() + (rootIsDecorated() ? 1 : 0));
717 if (x >= off && x < off + pm->width()) {
718 if (item->goParent) {
719 emit parentSelected();
723 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
724 if (ptype == P_MENU && rootEntry != menu &&
725 mode != fullMode && mode != menuMode)
726 emit menuSelected(menu);
747 //printf("contentsMouseReleaseEvent: %d,%d\n", p.x(), p.y());
748 Parent::contentsMouseReleaseEvent(e);
751 void ConfigList::contentsMouseMoveEvent(QMouseEvent* e)
753 //QPoint p(contentsToViewport(e->pos()));
754 //printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y());
755 Parent::contentsMouseMoveEvent(e);
758 void ConfigList::contentsMouseDoubleClickEvent(QMouseEvent* e)
760 QPoint p(contentsToViewport(e->pos()));
761 ConfigItem* item = (ConfigItem*)itemAt(p);
763 enum prop_type ptype;
767 if (item->goParent) {
768 emit parentSelected();
774 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
775 if (ptype == P_MENU && (mode == singleMode || mode == symbolMode))
776 emit menuSelected(menu);
781 //printf("contentsMouseDoubleClickEvent: %d,%d\n", p.x(), p.y());
782 Parent::contentsMouseDoubleClickEvent(e);
785 void ConfigList::focusInEvent(QFocusEvent *e)
787 struct menu *menu = NULL;
789 Parent::focusInEvent(e);
791 ConfigItem* item = (ConfigItem *)currentItem();
793 setSelected(item, TRUE);
799 void ConfigList::contextMenuEvent(QContextMenuEvent *e)
801 if (e->y() <= header()->geometry().bottom()) {
805 headerPopup = new QPopupMenu(this);
806 action = new QAction(NULL, _("Show Name"), 0, this);
807 action->setToggleAction(TRUE);
808 connect(action, SIGNAL(toggled(bool)),
809 parent(), SLOT(setShowName(bool)));
810 connect(parent(), SIGNAL(showNameChanged(bool)),
811 action, SLOT(setOn(bool)));
812 action->setOn(showName);
813 action->addTo(headerPopup);
814 action = new QAction(NULL, _("Show Range"), 0, this);
815 action->setToggleAction(TRUE);
816 connect(action, SIGNAL(toggled(bool)),
817 parent(), SLOT(setShowRange(bool)));
818 connect(parent(), SIGNAL(showRangeChanged(bool)),
819 action, SLOT(setOn(bool)));
820 action->setOn(showRange);
821 action->addTo(headerPopup);
822 action = new QAction(NULL, _("Show Data"), 0, this);
823 action->setToggleAction(TRUE);
824 connect(action, SIGNAL(toggled(bool)),
825 parent(), SLOT(setShowData(bool)));
826 connect(parent(), SIGNAL(showDataChanged(bool)),
827 action, SLOT(setOn(bool)));
828 action->setOn(showData);
829 action->addTo(headerPopup);
831 headerPopup->exec(e->globalPos());
837 ConfigView* ConfigView::viewList;
839 ConfigView::ConfigView(QWidget* parent, const char *name)
840 : Parent(parent, name)
842 list = new ConfigList(this, name);
843 lineEdit = new ConfigLineEdit(this);
846 this->nextView = viewList;
850 ConfigView::~ConfigView(void)
854 for (vp = &viewList; *vp; vp = &(*vp)->nextView) {
862 void ConfigView::setShowAll(bool b)
864 if (list->showAll != b) {
866 list->updateListAll();
867 emit showAllChanged(b);
871 void ConfigView::setShowName(bool b)
873 if (list->showName != b) {
876 emit showNameChanged(b);
880 void ConfigView::setShowRange(bool b)
882 if (list->showRange != b) {
885 emit showRangeChanged(b);
889 void ConfigView::setShowData(bool b)
891 if (list->showData != b) {
894 emit showDataChanged(b);
898 void ConfigList::setAllOpen(bool open)
900 QListViewItemIterator it(this);
902 for (; it.current(); it++)
903 it.current()->setOpen(open);
906 void ConfigView::updateList(ConfigItem* item)
910 for (v = viewList; v; v = v->nextView)
911 v->list->updateList(item);
914 void ConfigView::updateListAll(void)
918 for (v = viewList; v; v = v->nextView)
919 v->list->updateListAll();
922 ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name)
923 : Parent(parent, name), menu(0), sym(0)
926 configSettings->beginGroup(name);
927 _showDebug = configSettings->readBoolEntry("/showDebug", false);
928 configSettings->endGroup();
929 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
933 void ConfigInfoView::saveSettings(void)
936 configSettings->beginGroup(name());
937 configSettings->writeEntry("/showDebug", showDebug());
938 configSettings->endGroup();
942 void ConfigInfoView::setShowDebug(bool b)
944 if (_showDebug != b) {
950 emit showDebugChanged(b);
954 void ConfigInfoView::setInfo(struct menu *m)
966 void ConfigInfoView::setSource(const QString& name)
968 const char *p = name.latin1();
977 if (sscanf(p, "m%p", &m) == 1 && menu != m) {
980 emit menuSelected(menu);
986 if (sscanf(p, "s%p", &s) == 1 && sym != s) {
994 void ConfigInfoView::symbolInfo(void)
998 str += "<big>Symbol: <b>";
999 str += print_filter(sym->name);
1000 str += "</b></big><br><br>value: ";
1001 str += print_filter(sym_get_string_value(sym));
1002 str += "<br>visibility: ";
1003 str += sym->visible == yes ? "y" : sym->visible == mod ? "m" : "n";
1005 str += debug_info(sym);
1010 void ConfigInfoView::menuInfo(void)
1013 QString head, debug, help;
1019 head += print_filter(_(menu->prompt->text));
1020 head += "</b></big>";
1024 head += QString().sprintf("<a href=\"s%p\">", sym);
1025 head += print_filter(sym->name);
1030 } else if (sym->name) {
1033 head += QString().sprintf("<a href=\"s%p\">", sym);
1034 head += print_filter(sym->name);
1037 head += "</b></big>";
1042 debug = debug_info(sym);
1044 help = menu_get_help(menu);
1045 /* Gettextize if the help text not empty */
1047 help = print_filter(menu_get_help(menu));
1049 help = print_filter(_(menu_get_help(menu)));
1050 } else if (menu->prompt) {
1052 head += print_filter(_(menu->prompt->text));
1053 head += "</b></big><br><br>";
1055 if (menu->prompt->visible.expr) {
1056 debug += " dep: ";
1057 expr_print(menu->prompt->visible.expr, expr_print_help, &debug, E_NONE);
1058 debug += "<br><br>";
1063 debug += QString().sprintf("defined at %s:%d<br><br>", menu->file->name, menu->lineno);
1065 setText(head + debug + help);
1068 QString ConfigInfoView::debug_info(struct symbol *sym)
1073 debug += print_filter(sym_type_name(sym->type));
1074 if (sym_is_choice(sym))
1075 debug += " (choice)";
1077 if (sym->rev_dep.expr) {
1078 debug += "reverse dep: ";
1079 expr_print(sym->rev_dep.expr, expr_print_help, &debug, E_NONE);
1082 for (struct property *prop = sym->prop; prop; prop = prop->next) {
1083 switch (prop->type) {
1086 debug += QString().sprintf("prompt: <a href=\"m%p\">", prop->menu);
1087 debug += print_filter(_(prop->text));
1088 debug += "</a><br>";
1091 debug += "default: ";
1092 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1096 if (sym_is_choice(sym)) {
1097 debug += "choice: ";
1098 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1103 debug += "select: ";
1104 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1109 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1113 debug += "unknown property: ";
1114 debug += prop_get_type_name(prop->type);
1117 if (prop->visible.expr) {
1118 debug += " dep: ";
1119 expr_print(prop->visible.expr, expr_print_help, &debug, E_NONE);
1128 QString ConfigInfoView::print_filter(const QString &str)
1130 QRegExp re("[<>&\"\\n]");
1132 for (int i = 0; (i = res.find(re, i)) >= 0;) {
1133 switch (res[i].latin1()) {
1135 res.replace(i, 1, "<");
1139 res.replace(i, 1, ">");
1143 res.replace(i, 1, "&");
1147 res.replace(i, 1, """);
1151 res.replace(i, 1, "<br>");
1159 void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char *str)
1161 QString* text = reinterpret_cast<QString*>(data);
1162 QString str2 = print_filter(str);
1164 if (sym && sym->name && !(sym->flags & SYMBOL_CONST)) {
1165 *text += QString().sprintf("<a href=\"s%p\">", sym);
1172 QPopupMenu* ConfigInfoView::createPopupMenu(const QPoint& pos)
1174 QPopupMenu* popup = Parent::createPopupMenu(pos);
1175 QAction* action = new QAction(NULL, _("Show Debug Info"), 0, popup);
1176 action->setToggleAction(TRUE);
1177 connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
1178 connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool)));
1179 action->setOn(showDebug());
1180 popup->insertSeparator();
1181 action->addTo(popup);
1185 void ConfigInfoView::contentsContextMenuEvent(QContextMenuEvent *e)
1187 Parent::contentsContextMenuEvent(e);
1190 ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow* parent, const char *name)
1191 : Parent(parent, name), result(NULL)
1193 setCaption("Search Config");
1195 QVBoxLayout* layout1 = new QVBoxLayout(this, 11, 6);
1196 QHBoxLayout* layout2 = new QHBoxLayout(0, 0, 6);
1197 layout2->addWidget(new QLabel(_("Find:"), this));
1198 editField = new QLineEdit(this);
1199 connect(editField, SIGNAL(returnPressed()), SLOT(search()));
1200 layout2->addWidget(editField);
1201 searchButton = new QPushButton(_("Search"), this);
1202 searchButton->setAutoDefault(FALSE);
1203 connect(searchButton, SIGNAL(clicked()), SLOT(search()));
1204 layout2->addWidget(searchButton);
1205 layout1->addLayout(layout2);
1207 split = new QSplitter(this);
1208 split->setOrientation(QSplitter::Vertical);
1209 list = new ConfigView(split, name);
1210 list->list->mode = listMode;
1211 info = new ConfigInfoView(split, name);
1212 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1213 info, SLOT(setInfo(struct menu *)));
1214 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1215 parent, SLOT(setMenuLink(struct menu *)));
1217 layout1->addWidget(split);
1220 int x, y, width, height;
1223 configSettings->beginGroup(name);
1224 width = configSettings->readNumEntry("/window width", parent->width() / 2);
1225 height = configSettings->readNumEntry("/window height", parent->height() / 2);
1226 resize(width, height);
1227 x = configSettings->readNumEntry("/window x", 0, &ok);
1229 y = configSettings->readNumEntry("/window y", 0, &ok);
1232 QValueList<int> sizes = configSettings->readSizes("/split", &ok);
1234 split->setSizes(sizes);
1235 configSettings->endGroup();
1236 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
1240 void ConfigSearchWindow::saveSettings(void)
1243 configSettings->beginGroup(name());
1244 configSettings->writeEntry("/window x", pos().x());
1245 configSettings->writeEntry("/window y", pos().y());
1246 configSettings->writeEntry("/window width", size().width());
1247 configSettings->writeEntry("/window height", size().height());
1248 configSettings->writeSizes("/split", split->sizes());
1249 configSettings->endGroup();
1253 void ConfigSearchWindow::search(void)
1256 struct property *prop;
1257 ConfigItem *lastItem = NULL;
1260 list->list->clear();
1263 result = sym_re_search(editField->text().latin1());
1266 for (p = result; *p; p++) {
1267 for_all_prompts((*p), prop)
1268 lastItem = new ConfigItem(list->list, lastItem, prop->menu,
1269 menu_is_visible(prop->menu));
1274 * Construct the complete config widget
1276 ConfigMainWindow::ConfigMainWindow(void)
1281 int x, y, width, height;
1284 QWidget *d = configApp->desktop();
1285 snprintf(title, sizeof(title), _("Linux Kernel v%s Configuration"),
1286 getenv("KERNELVERSION"));
1289 width = configSettings->readNumEntry("/window width", d->width() - 64);
1290 height = configSettings->readNumEntry("/window height", d->height() - 64);
1291 resize(width, height);
1292 x = configSettings->readNumEntry("/window x", 0, &ok);
1294 y = configSettings->readNumEntry("/window y", 0, &ok);
1298 split1 = new QSplitter(this);
1299 split1->setOrientation(QSplitter::Horizontal);
1300 setCentralWidget(split1);
1302 menuView = new ConfigView(split1, "menu");
1303 menuList = menuView->list;
1305 split2 = new QSplitter(split1);
1306 split2->setOrientation(QSplitter::Vertical);
1308 // create config tree
1309 configView = new ConfigView(split2, "config");
1310 configList = configView->list;
1312 helpText = new ConfigInfoView(split2, "help");
1313 helpText->setTextFormat(Qt::RichText);
1315 setTabOrder(configList, helpText);
1316 configList->setFocus();
1319 toolBar = new QToolBar("Tools", this);
1321 backAction = new QAction("Back", QPixmap(xpm_back), _("Back"), 0, this);
1322 connect(backAction, SIGNAL(activated()), SLOT(goBack()));
1323 backAction->setEnabled(FALSE);
1324 QAction *quitAction = new QAction("Quit", _("&Quit"), CTRL+Key_Q, this);
1325 connect(quitAction, SIGNAL(activated()), SLOT(close()));
1326 QAction *loadAction = new QAction("Load", QPixmap(xpm_load), _("&Load"), CTRL+Key_L, this);
1327 connect(loadAction, SIGNAL(activated()), SLOT(loadConfig()));
1328 saveAction = new QAction("Save", QPixmap(xpm_save), _("&Save"), CTRL+Key_S, this);
1329 connect(saveAction, SIGNAL(activated()), SLOT(saveConfig()));
1330 conf_set_changed_callback(conf_changed);
1331 // Set saveAction's initial state
1333 QAction *saveAsAction = new QAction("Save As...", _("Save &As..."), 0, this);
1334 connect(saveAsAction, SIGNAL(activated()), SLOT(saveConfigAs()));
1335 QAction *searchAction = new QAction("Find", _("&Find"), CTRL+Key_F, this);
1336 connect(searchAction, SIGNAL(activated()), SLOT(searchConfig()));
1337 QAction *singleViewAction = new QAction("Single View", QPixmap(xpm_single_view), _("Single View"), 0, this);
1338 connect(singleViewAction, SIGNAL(activated()), SLOT(showSingleView()));
1339 QAction *splitViewAction = new QAction("Split View", QPixmap(xpm_split_view), _("Split View"), 0, this);
1340 connect(splitViewAction, SIGNAL(activated()), SLOT(showSplitView()));
1341 QAction *fullViewAction = new QAction("Full View", QPixmap(xpm_tree_view), _("Full View"), 0, this);
1342 connect(fullViewAction, SIGNAL(activated()), SLOT(showFullView()));
1344 QAction *showNameAction = new QAction(NULL, _("Show Name"), 0, this);
1345 showNameAction->setToggleAction(TRUE);
1346 connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool)));
1347 connect(configView, SIGNAL(showNameChanged(bool)), showNameAction, SLOT(setOn(bool)));
1348 showNameAction->setOn(configView->showName());
1349 QAction *showRangeAction = new QAction(NULL, _("Show Range"), 0, this);
1350 showRangeAction->setToggleAction(TRUE);
1351 connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool)));
1352 connect(configView, SIGNAL(showRangeChanged(bool)), showRangeAction, SLOT(setOn(bool)));
1353 showRangeAction->setOn(configList->showRange);
1354 QAction *showDataAction = new QAction(NULL, _("Show Data"), 0, this);
1355 showDataAction->setToggleAction(TRUE);
1356 connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool)));
1357 connect(configView, SIGNAL(showDataChanged(bool)), showDataAction, SLOT(setOn(bool)));
1358 showDataAction->setOn(configList->showData);
1359 QAction *showAllAction = new QAction(NULL, _("Show All Options"), 0, this);
1360 showAllAction->setToggleAction(TRUE);
1361 connect(showAllAction, SIGNAL(toggled(bool)), configView, SLOT(setShowAll(bool)));
1362 connect(showAllAction, SIGNAL(toggled(bool)), menuView, SLOT(setShowAll(bool)));
1363 showAllAction->setOn(configList->showAll);
1364 QAction *showDebugAction = new QAction(NULL, _("Show Debug Info"), 0, this);
1365 showDebugAction->setToggleAction(TRUE);
1366 connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
1367 connect(helpText, SIGNAL(showDebugChanged(bool)), showDebugAction, SLOT(setOn(bool)));
1368 showDebugAction->setOn(helpText->showDebug());
1370 QAction *showIntroAction = new QAction(NULL, _("Introduction"), 0, this);
1371 connect(showIntroAction, SIGNAL(activated()), SLOT(showIntro()));
1372 QAction *showAboutAction = new QAction(NULL, _("About"), 0, this);
1373 connect(showAboutAction, SIGNAL(activated()), SLOT(showAbout()));
1376 backAction->addTo(toolBar);
1377 toolBar->addSeparator();
1378 loadAction->addTo(toolBar);
1379 saveAction->addTo(toolBar);
1380 toolBar->addSeparator();
1381 singleViewAction->addTo(toolBar);
1382 splitViewAction->addTo(toolBar);
1383 fullViewAction->addTo(toolBar);
1385 // create config menu
1386 QPopupMenu* config = new QPopupMenu(this);
1387 menu->insertItem(_("&File"), config);
1388 loadAction->addTo(config);
1389 saveAction->addTo(config);
1390 saveAsAction->addTo(config);
1391 config->insertSeparator();
1392 quitAction->addTo(config);
1395 QPopupMenu* editMenu = new QPopupMenu(this);
1396 menu->insertItem(_("&Edit"), editMenu);
1397 searchAction->addTo(editMenu);
1399 // create options menu
1400 QPopupMenu* optionMenu = new QPopupMenu(this);
1401 menu->insertItem(_("&Option"), optionMenu);
1402 showNameAction->addTo(optionMenu);
1403 showRangeAction->addTo(optionMenu);
1404 showDataAction->addTo(optionMenu);
1405 optionMenu->insertSeparator();
1406 showAllAction->addTo(optionMenu);
1407 showDebugAction->addTo(optionMenu);
1410 QPopupMenu* helpMenu = new QPopupMenu(this);
1411 menu->insertSeparator();
1412 menu->insertItem(_("&Help"), helpMenu);
1413 showIntroAction->addTo(helpMenu);
1414 showAboutAction->addTo(helpMenu);
1416 connect(configList, SIGNAL(menuChanged(struct menu *)),
1417 helpText, SLOT(setInfo(struct menu *)));
1418 connect(configList, SIGNAL(menuSelected(struct menu *)),
1419 SLOT(changeMenu(struct menu *)));
1420 connect(configList, SIGNAL(parentSelected()),
1422 connect(menuList, SIGNAL(menuChanged(struct menu *)),
1423 helpText, SLOT(setInfo(struct menu *)));
1424 connect(menuList, SIGNAL(menuSelected(struct menu *)),
1425 SLOT(changeMenu(struct menu *)));
1427 connect(configList, SIGNAL(gotFocus(struct menu *)),
1428 helpText, SLOT(setInfo(struct menu *)));
1429 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1430 helpText, SLOT(setInfo(struct menu *)));
1431 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1432 SLOT(listFocusChanged(void)));
1433 connect(helpText, SIGNAL(menuSelected(struct menu *)),
1434 SLOT(setMenuLink(struct menu *)));
1436 QString listMode = configSettings->readEntry("/listMode", "symbol");
1437 if (listMode == "single")
1439 else if (listMode == "full")
1441 else /*if (listMode == "split")*/
1444 // UI setup done, restore splitter positions
1445 QValueList<int> sizes = configSettings->readSizes("/split1", &ok);
1447 split1->setSizes(sizes);
1449 sizes = configSettings->readSizes("/split2", &ok);
1451 split2->setSizes(sizes);
1454 void ConfigMainWindow::loadConfig(void)
1456 QString s = QFileDialog::getOpenFileName(".config", NULL, this);
1459 if (conf_read(QFile::encodeName(s)))
1460 QMessageBox::information(this, "qconf", _("Unable to load configuration!"));
1461 ConfigView::updateListAll();
1464 void ConfigMainWindow::saveConfig(void)
1466 if (conf_write(NULL))
1467 QMessageBox::information(this, "qconf", _("Unable to save configuration!"));
1470 void ConfigMainWindow::saveConfigAs(void)
1472 QString s = QFileDialog::getSaveFileName(".config", NULL, this);
1475 if (conf_write(QFile::encodeName(s)))
1476 QMessageBox::information(this, "qconf", _("Unable to save configuration!"));
1479 void ConfigMainWindow::searchConfig(void)
1482 searchWindow = new ConfigSearchWindow(this, "search");
1483 searchWindow->show();
1486 void ConfigMainWindow::changeMenu(struct menu *menu)
1488 configList->setRootMenu(menu);
1489 if (configList->rootEntry->parent == &rootmenu)
1490 backAction->setEnabled(FALSE);
1492 backAction->setEnabled(TRUE);
1495 void ConfigMainWindow::setMenuLink(struct menu *menu)
1497 struct menu *parent;
1498 ConfigList* list = NULL;
1501 if (!menu_is_visible(menu) && !configView->showAll())
1504 switch (configList->mode) {
1507 parent = menu_get_parent_menu(menu);
1510 list->setRootMenu(parent);
1513 if (menu->flags & MENU_ROOT) {
1514 configList->setRootMenu(menu);
1515 configList->clearSelection();
1519 parent = menu_get_parent_menu(menu->parent);
1522 item = menuList->findConfigItem(parent);
1524 menuList->setSelected(item, TRUE);
1525 menuList->ensureItemVisible(item);
1527 list->setRootMenu(parent);
1536 item = list->findConfigItem(menu);
1538 list->setSelected(item, TRUE);
1539 list->ensureItemVisible(item);
1545 void ConfigMainWindow::listFocusChanged(void)
1547 if (menuList->mode == menuMode)
1548 configList->clearSelection();
1551 void ConfigMainWindow::goBack(void)
1555 configList->setParentMenu();
1556 if (configList->rootEntry == &rootmenu)
1557 backAction->setEnabled(FALSE);
1558 item = (ConfigItem*)menuList->selectedItem();
1560 if (item->menu == configList->rootEntry) {
1561 menuList->setSelected(item, TRUE);
1564 item = (ConfigItem*)item->parent();
1568 void ConfigMainWindow::showSingleView(void)
1571 menuList->setRootMenu(0);
1572 configList->mode = singleMode;
1573 if (configList->rootEntry == &rootmenu)
1574 configList->updateListAll();
1576 configList->setRootMenu(&rootmenu);
1577 configList->setAllOpen(TRUE);
1578 configList->setFocus();
1581 void ConfigMainWindow::showSplitView(void)
1583 configList->mode = symbolMode;
1584 if (configList->rootEntry == &rootmenu)
1585 configList->updateListAll();
1587 configList->setRootMenu(&rootmenu);
1588 configList->setAllOpen(TRUE);
1589 configApp->processEvents();
1590 menuList->mode = menuMode;
1591 menuList->setRootMenu(&rootmenu);
1592 menuList->setAllOpen(TRUE);
1594 menuList->setFocus();
1597 void ConfigMainWindow::showFullView(void)
1600 menuList->setRootMenu(0);
1601 configList->mode = fullMode;
1602 if (configList->rootEntry == &rootmenu)
1603 configList->updateListAll();
1605 configList->setRootMenu(&rootmenu);
1606 configList->setAllOpen(FALSE);
1607 configList->setFocus();
1611 * ask for saving configuration before quitting
1612 * TODO ask only when something changed
1614 void ConfigMainWindow::closeEvent(QCloseEvent* e)
1616 if (!conf_get_changed()) {
1620 QMessageBox mb("qconf", _("Save configuration?"), QMessageBox::Warning,
1621 QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape);
1622 mb.setButtonText(QMessageBox::Yes, _("&Save Changes"));
1623 mb.setButtonText(QMessageBox::No, _("&Discard Changes"));
1624 mb.setButtonText(QMessageBox::Cancel, _("Cancel Exit"));
1625 switch (mb.exec()) {
1626 case QMessageBox::Yes:
1628 case QMessageBox::No:
1631 case QMessageBox::Cancel:
1637 void ConfigMainWindow::showIntro(void)
1639 static const QString str = _("Welcome to the qconf graphical kernel configuration tool for Linux.\n\n"
1640 "For each option, a blank box indicates the feature is disabled, a check\n"
1641 "indicates it is enabled, and a dot indicates that it is to be compiled\n"
1642 "as a module. Clicking on the box will cycle through the three states.\n\n"
1643 "If you do not see an option (e.g., a device driver) that you believe\n"
1644 "should be present, try turning on Show All Options under the Options menu.\n"
1645 "Although there is no cross reference yet to help you figure out what other\n"
1646 "options must be enabled to support the option you are interested in, you can\n"
1647 "still view the help of a grayed-out option.\n\n"
1648 "Toggling Show Debug Info under the Options menu will show the dependencies,\n"
1649 "which you can then match by examining other options.\n\n");
1651 QMessageBox::information(this, "qconf", str);
1654 void ConfigMainWindow::showAbout(void)
1656 static const QString str = _("qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n\n"
1657 "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n");
1659 QMessageBox::information(this, "qconf", str);
1662 void ConfigMainWindow::saveSettings(void)
1664 configSettings->writeEntry("/window x", pos().x());
1665 configSettings->writeEntry("/window y", pos().y());
1666 configSettings->writeEntry("/window width", size().width());
1667 configSettings->writeEntry("/window height", size().height());
1670 switch(configList->mode) {
1683 configSettings->writeEntry("/listMode", entry);
1685 configSettings->writeSizes("/split1", split1->sizes());
1686 configSettings->writeSizes("/split2", split2->sizes());
1689 void ConfigMainWindow::conf_changed(void)
1692 saveAction->setEnabled(conf_get_changed());
1695 void fixup_rootmenu(struct menu *menu)
1698 static int menu_cnt = 0;
1700 menu->flags |= MENU_ROOT;
1701 for (child = menu->list; child; child = child->next) {
1702 if (child->prompt && child->prompt->type == P_MENU) {
1704 fixup_rootmenu(child);
1706 } else if (!menu_cnt)
1707 fixup_rootmenu(child);
1711 static const char *progname;
1713 static void usage(void)
1715 printf(_("%s <config>\n"), progname);
1719 int main(int ac, char** av)
1721 ConfigMainWindow* v;
1724 bindtextdomain(PACKAGE, LOCALEDIR);
1725 textdomain(PACKAGE);
1727 #ifndef LKC_DIRECT_LINK
1732 configApp = new QApplication(ac, av);
1733 if (ac > 1 && av[1][0] == '-') {
1746 fixup_rootmenu(&rootmenu);
1748 //zconfdump(stdout);
1750 configSettings = new ConfigSettings();
1751 configSettings->beginGroup("/kconfig/qconf");
1752 v = new ConfigMainWindow();
1754 //zconfdump(stdout);
1755 configApp->setMainWidget(v);
1756 configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit()));
1757 configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings()));
1761 configSettings->endGroup();
1762 delete configSettings;