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>
8 #include <qdesktopwidget.h>
12 #include <qsplitter.h>
13 #include <qlistview.h>
14 #include <qtextbrowser.h>
15 #include <qlineedit.h>
17 #include <qpushbutton.h>
19 #include <qmessagebox.h>
22 #include <qfiledialog.h>
23 #include <qdragobject.h>
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()));
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 QStringList::Iterator it;
63 for (it = entryList.begin(); it != entryList.end(); ++it)
64 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->optMode == normalOpt) {
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 showName(false), showRange(false), showData(false), optMode(normalOpt),
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 showName = configSettings->readBoolEntry("/showName", false);
340 showRange = configSettings->readBoolEntry("/showRange", false);
341 showData = configSettings->readBoolEntry("/showData", false);
342 optMode = (enum optionMode)configSettings->readNumEntry("/optionMode", 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 bool ConfigList::menuSkip(struct menu *menu)
356 if (optMode == normalOpt && menu_is_visible(menu))
358 if (optMode == promptOpt && menu_has_prompt(menu))
360 if (optMode == allOpt)
365 void ConfigList::reinit(void)
367 removeColumn(dataColIdx);
368 removeColumn(yesColIdx);
369 removeColumn(modColIdx);
370 removeColumn(noColIdx);
371 removeColumn(nameColIdx);
374 addColumn(nameColIdx, _("Name"));
376 addColumn(noColIdx, "N");
377 addColumn(modColIdx, "M");
378 addColumn(yesColIdx, "Y");
381 addColumn(dataColIdx, _("Value"));
386 void ConfigList::saveSettings(void)
389 configSettings->beginGroup(name());
390 configSettings->writeEntry("/showName", showName);
391 configSettings->writeEntry("/showRange", showRange);
392 configSettings->writeEntry("/showData", showData);
393 configSettings->writeEntry("/optionMode", (int)optMode);
394 configSettings->endGroup();
398 ConfigItem* ConfigList::findConfigItem(struct menu *menu)
400 ConfigItem* item = (ConfigItem*)menu->data;
402 for (; item; item = item->nextItem) {
403 if (this == item->listView())
410 void ConfigList::updateSelection(void)
415 ConfigItem* item = (ConfigItem*)selectedItem();
420 emit menuChanged(menu);
423 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
424 if (mode == menuMode && type == P_MENU)
425 emit menuSelected(menu);
428 void ConfigList::updateList(ConfigItem* item)
430 ConfigItem* last = 0;
433 if (mode != listMode)
435 QListViewItemIterator it(this);
438 for (; it.current(); ++it) {
439 item = (ConfigItem*)it.current();
442 item->testUpdateMenu(menu_is_visible(item->menu));
447 if (rootEntry != &rootmenu && (mode == singleMode ||
448 (mode == symbolMode && rootEntry->parent != &rootmenu))) {
451 item = new ConfigItem(this, 0, true);
454 if ((mode == singleMode || (mode == symbolMode && !(rootEntry->flags & MENU_ROOT))) &&
455 rootEntry->sym && rootEntry->prompt) {
456 item = last ? last->nextSibling() : firstChild();
458 item = new ConfigItem(this, last, rootEntry, true);
460 item->testUpdateMenu(true);
462 updateMenuList(item, rootEntry);
467 updateMenuList(this, rootEntry);
471 void ConfigList::setValue(ConfigItem* item, tristate val)
477 sym = item->menu ? item->menu->sym : 0;
481 type = sym_get_type(sym);
485 oldval = sym_get_tristate_value(sym);
487 if (!sym_set_tristate_value(sym, val))
489 if (oldval == no && item->menu->list)
491 parent()->updateList(item);
496 void ConfigList::changeValue(ConfigItem* item)
500 int type, oldexpr, newexpr;
507 if (item->menu->list)
508 item->setOpen(!item->isOpen());
512 type = sym_get_type(sym);
516 oldexpr = sym_get_tristate_value(sym);
517 newexpr = sym_toggle_tristate_value(sym);
518 if (item->menu->list) {
519 if (oldexpr == newexpr)
520 item->setOpen(!item->isOpen());
521 else if (oldexpr == no)
524 if (oldexpr != newexpr)
525 parent()->updateList(item);
530 #if QT_VERSION >= 300
531 if (colMap[dataColIdx] >= 0)
532 item->startRename(colMap[dataColIdx]);
535 parent()->lineEdit->show(item);
540 void ConfigList::setRootMenu(struct menu *menu)
544 if (rootEntry == menu)
546 type = menu && menu->prompt ? menu->prompt->type : P_UNKNOWN;
549 updateMenuList(this, 0);
552 setSelected(currentItem(), hasFocus());
553 ensureItemVisible(currentItem());
556 void ConfigList::setParentMenu(void)
559 struct menu *oldroot;
562 if (rootEntry == &rootmenu)
564 setRootMenu(menu_get_parent_menu(rootEntry->parent));
566 QListViewItemIterator it(this);
567 for (; (item = (ConfigItem*)it.current()); it++) {
568 if (item->menu == oldroot) {
569 setCurrentItem(item);
570 ensureItemVisible(item);
577 * update all the children of a menu entry
578 * removes/adds the entries from the parent widget as necessary
580 * parent: either the menu list widget or a menu entry widget
581 * menu: entry to be updated
584 void ConfigList::updateMenuList(P* parent, struct menu* menu)
593 while ((item = parent->firstChild()))
598 last = parent->firstChild();
599 if (last && !last->goParent)
601 for (child = menu->list; child; child = child->next) {
602 item = last ? last->nextSibling() : parent->firstChild();
603 type = child->prompt ? child->prompt->type : P_UNKNOWN;
607 if (!(child->flags & MENU_ROOT))
611 if (child->flags & MENU_ROOT)
618 visible = menu_is_visible(child);
619 if (!menuSkip(child)) {
620 if (!child->sym && !child->list && !child->prompt)
622 if (!item || item->menu != child)
623 item = new ConfigItem(parent, last, child, visible);
625 item->testUpdateMenu(visible);
627 if (mode == fullMode || mode == menuMode || type != P_MENU)
628 updateMenuList(item, child);
630 updateMenuList(item, 0);
635 if (item && item->menu == child) {
636 last = parent->firstChild();
639 else while (last->nextSibling() != item)
640 last = last->nextSibling();
646 void ConfigList::keyPressEvent(QKeyEvent* ev)
648 QListViewItem* i = currentItem();
653 if (ev->key() == Qt::Key_Escape && mode != fullMode && mode != listMode) {
654 emit parentSelected();
660 Parent::keyPressEvent(ev);
663 item = (ConfigItem*)i;
668 if (item->goParent) {
669 emit parentSelected();
675 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
676 if (type == P_MENU && rootEntry != menu &&
677 mode != fullMode && mode != menuMode) {
678 emit menuSelected(menu);
694 Parent::keyPressEvent(ev);
700 void ConfigList::contentsMousePressEvent(QMouseEvent* e)
702 //QPoint p(contentsToViewport(e->pos()));
703 //printf("contentsMousePressEvent: %d,%d\n", p.x(), p.y());
704 Parent::contentsMousePressEvent(e);
707 void ConfigList::contentsMouseReleaseEvent(QMouseEvent* e)
709 QPoint p(contentsToViewport(e->pos()));
710 ConfigItem* item = (ConfigItem*)itemAt(p);
712 enum prop_type ptype;
720 x = header()->offset() + p.x();
721 idx = colRevMap[header()->sectionAt(x)];
724 pm = item->pixmap(promptColIdx);
726 int off = header()->sectionPos(0) + itemMargin() +
727 treeStepSize() * (item->depth() + (rootIsDecorated() ? 1 : 0));
728 if (x >= off && x < off + pm->width()) {
729 if (item->goParent) {
730 emit parentSelected();
734 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
735 if (ptype == P_MENU && rootEntry != menu &&
736 mode != fullMode && mode != menuMode)
737 emit menuSelected(menu);
758 //printf("contentsMouseReleaseEvent: %d,%d\n", p.x(), p.y());
759 Parent::contentsMouseReleaseEvent(e);
762 void ConfigList::contentsMouseMoveEvent(QMouseEvent* e)
764 //QPoint p(contentsToViewport(e->pos()));
765 //printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y());
766 Parent::contentsMouseMoveEvent(e);
769 void ConfigList::contentsMouseDoubleClickEvent(QMouseEvent* e)
771 QPoint p(contentsToViewport(e->pos()));
772 ConfigItem* item = (ConfigItem*)itemAt(p);
774 enum prop_type ptype;
778 if (item->goParent) {
779 emit parentSelected();
785 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
786 if (ptype == P_MENU && (mode == singleMode || mode == symbolMode))
787 emit menuSelected(menu);
792 //printf("contentsMouseDoubleClickEvent: %d,%d\n", p.x(), p.y());
793 Parent::contentsMouseDoubleClickEvent(e);
796 void ConfigList::focusInEvent(QFocusEvent *e)
798 struct menu *menu = NULL;
800 Parent::focusInEvent(e);
802 ConfigItem* item = (ConfigItem *)currentItem();
804 setSelected(item, TRUE);
810 void ConfigList::contextMenuEvent(QContextMenuEvent *e)
812 if (e->y() <= header()->geometry().bottom()) {
816 headerPopup = new QPopupMenu(this);
817 action = new QAction(NULL, _("Show Name"), 0, this);
818 action->setToggleAction(TRUE);
819 connect(action, SIGNAL(toggled(bool)),
820 parent(), SLOT(setShowName(bool)));
821 connect(parent(), SIGNAL(showNameChanged(bool)),
822 action, SLOT(setOn(bool)));
823 action->setOn(showName);
824 action->addTo(headerPopup);
825 action = new QAction(NULL, _("Show Range"), 0, this);
826 action->setToggleAction(TRUE);
827 connect(action, SIGNAL(toggled(bool)),
828 parent(), SLOT(setShowRange(bool)));
829 connect(parent(), SIGNAL(showRangeChanged(bool)),
830 action, SLOT(setOn(bool)));
831 action->setOn(showRange);
832 action->addTo(headerPopup);
833 action = new QAction(NULL, _("Show Data"), 0, this);
834 action->setToggleAction(TRUE);
835 connect(action, SIGNAL(toggled(bool)),
836 parent(), SLOT(setShowData(bool)));
837 connect(parent(), SIGNAL(showDataChanged(bool)),
838 action, SLOT(setOn(bool)));
839 action->setOn(showData);
840 action->addTo(headerPopup);
842 headerPopup->exec(e->globalPos());
848 ConfigView*ConfigView::viewList;
849 QAction *ConfigView::showNormalAction;
850 QAction *ConfigView::showAllAction;
851 QAction *ConfigView::showPromptAction;
853 ConfigView::ConfigView(QWidget* parent, const char *name)
854 : Parent(parent, name)
856 list = new ConfigList(this, name);
857 lineEdit = new ConfigLineEdit(this);
860 this->nextView = viewList;
864 ConfigView::~ConfigView(void)
868 for (vp = &viewList; *vp; vp = &(*vp)->nextView) {
876 void ConfigView::setOptionMode(QAction *act)
878 if (act == showNormalAction)
879 list->optMode = normalOpt;
880 else if (act == showAllAction)
881 list->optMode = allOpt;
883 list->optMode = promptOpt;
885 list->updateListAll();
888 void ConfigView::setShowName(bool b)
890 if (list->showName != b) {
893 emit showNameChanged(b);
897 void ConfigView::setShowRange(bool b)
899 if (list->showRange != b) {
902 emit showRangeChanged(b);
906 void ConfigView::setShowData(bool b)
908 if (list->showData != b) {
911 emit showDataChanged(b);
915 void ConfigList::setAllOpen(bool open)
917 QListViewItemIterator it(this);
919 for (; it.current(); it++)
920 it.current()->setOpen(open);
923 void ConfigView::updateList(ConfigItem* item)
927 for (v = viewList; v; v = v->nextView)
928 v->list->updateList(item);
931 void ConfigView::updateListAll(void)
935 for (v = viewList; v; v = v->nextView)
936 v->list->updateListAll();
939 ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name)
940 : Parent(parent, name), sym(0), menu(0)
943 configSettings->beginGroup(name);
944 _showDebug = configSettings->readBoolEntry("/showDebug", false);
945 configSettings->endGroup();
946 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
950 void ConfigInfoView::saveSettings(void)
953 configSettings->beginGroup(name());
954 configSettings->writeEntry("/showDebug", showDebug());
955 configSettings->endGroup();
959 void ConfigInfoView::setShowDebug(bool b)
961 if (_showDebug != b) {
967 emit showDebugChanged(b);
971 void ConfigInfoView::setInfo(struct menu *m)
983 void ConfigInfoView::symbolInfo(void)
987 str += "<big>Symbol: <b>";
988 str += print_filter(sym->name);
989 str += "</b></big><br><br>value: ";
990 str += print_filter(sym_get_string_value(sym));
991 str += "<br>visibility: ";
992 str += sym->visible == yes ? "y" : sym->visible == mod ? "m" : "n";
994 str += debug_info(sym);
999 void ConfigInfoView::menuInfo(void)
1002 QString head, debug, help;
1008 head += print_filter(_(menu->prompt->text));
1009 head += "</b></big>";
1013 head += QString().sprintf("<a href=\"s%p\">", sym);
1014 head += print_filter(sym->name);
1019 } else if (sym->name) {
1022 head += QString().sprintf("<a href=\"s%p\">", sym);
1023 head += print_filter(sym->name);
1026 head += "</b></big>";
1031 debug = debug_info(sym);
1033 struct gstr help_gstr = str_new();
1034 menu_get_ext_help(menu, &help_gstr);
1035 help = print_filter(str_get(&help_gstr));
1036 str_free(&help_gstr);
1037 } else if (menu->prompt) {
1039 head += print_filter(_(menu->prompt->text));
1040 head += "</b></big><br><br>";
1042 if (menu->prompt->visible.expr) {
1043 debug += " dep: ";
1044 expr_print(menu->prompt->visible.expr, expr_print_help, &debug, E_NONE);
1045 debug += "<br><br>";
1050 debug += QString().sprintf("defined at %s:%d<br><br>", menu->file->name, menu->lineno);
1052 setText(head + debug + help);
1055 QString ConfigInfoView::debug_info(struct symbol *sym)
1060 debug += print_filter(sym_type_name(sym->type));
1061 if (sym_is_choice(sym))
1062 debug += " (choice)";
1064 if (sym->rev_dep.expr) {
1065 debug += "reverse dep: ";
1066 expr_print(sym->rev_dep.expr, expr_print_help, &debug, E_NONE);
1069 for (struct property *prop = sym->prop; prop; prop = prop->next) {
1070 switch (prop->type) {
1073 debug += QString().sprintf("prompt: <a href=\"m%p\">", prop->menu);
1074 debug += print_filter(_(prop->text));
1075 debug += "</a><br>";
1081 debug += prop_get_type_name(prop->type);
1083 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1087 if (sym_is_choice(sym)) {
1088 debug += "choice: ";
1089 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1094 debug += "unknown property: ";
1095 debug += prop_get_type_name(prop->type);
1098 if (prop->visible.expr) {
1099 debug += " dep: ";
1100 expr_print(prop->visible.expr, expr_print_help, &debug, E_NONE);
1109 QString ConfigInfoView::print_filter(const QString &str)
1111 QRegExp re("[<>&\"\\n]");
1113 for (int i = 0; (i = res.find(re, i)) >= 0;) {
1114 switch (res[i].latin1()) {
1116 res.replace(i, 1, "<");
1120 res.replace(i, 1, ">");
1124 res.replace(i, 1, "&");
1128 res.replace(i, 1, """);
1132 res.replace(i, 1, "<br>");
1140 void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char *str)
1142 QString* text = reinterpret_cast<QString*>(data);
1143 QString str2 = print_filter(str);
1145 if (sym && sym->name && !(sym->flags & SYMBOL_CONST)) {
1146 *text += QString().sprintf("<a href=\"s%p\">", sym);
1153 QPopupMenu* ConfigInfoView::createPopupMenu(const QPoint& pos)
1155 QPopupMenu* popup = Parent::createPopupMenu(pos);
1156 QAction* action = new QAction(NULL, _("Show Debug Info"), 0, popup);
1157 action->setToggleAction(TRUE);
1158 connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
1159 connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool)));
1160 action->setOn(showDebug());
1161 popup->insertSeparator();
1162 action->addTo(popup);
1166 void ConfigInfoView::contentsContextMenuEvent(QContextMenuEvent *e)
1168 Parent::contentsContextMenuEvent(e);
1171 ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow* parent, const char *name)
1172 : Parent(parent, name), result(NULL)
1174 setCaption("Search Config");
1176 QVBoxLayout* layout1 = new QVBoxLayout(this, 11, 6);
1177 QHBoxLayout* layout2 = new QHBoxLayout(0, 0, 6);
1178 layout2->addWidget(new QLabel(_("Find:"), this));
1179 editField = new QLineEdit(this);
1180 connect(editField, SIGNAL(returnPressed()), SLOT(search()));
1181 layout2->addWidget(editField);
1182 searchButton = new QPushButton(_("Search"), this);
1183 searchButton->setAutoDefault(FALSE);
1184 connect(searchButton, SIGNAL(clicked()), SLOT(search()));
1185 layout2->addWidget(searchButton);
1186 layout1->addLayout(layout2);
1188 split = new QSplitter(this);
1189 split->setOrientation(Qt::Vertical);
1190 list = new ConfigView(split, name);
1191 list->list->mode = listMode;
1192 info = new ConfigInfoView(split, name);
1193 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1194 info, SLOT(setInfo(struct menu *)));
1195 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1196 parent, SLOT(setMenuLink(struct menu *)));
1198 layout1->addWidget(split);
1201 int x, y, width, height;
1204 configSettings->beginGroup(name);
1205 width = configSettings->readNumEntry("/window width", parent->width() / 2);
1206 height = configSettings->readNumEntry("/window height", parent->height() / 2);
1207 resize(width, height);
1208 x = configSettings->readNumEntry("/window x", 0, &ok);
1210 y = configSettings->readNumEntry("/window y", 0, &ok);
1213 QValueList<int> sizes = configSettings->readSizes("/split", &ok);
1215 split->setSizes(sizes);
1216 configSettings->endGroup();
1217 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
1221 void ConfigSearchWindow::saveSettings(void)
1224 configSettings->beginGroup(name());
1225 configSettings->writeEntry("/window x", pos().x());
1226 configSettings->writeEntry("/window y", pos().y());
1227 configSettings->writeEntry("/window width", size().width());
1228 configSettings->writeEntry("/window height", size().height());
1229 configSettings->writeSizes("/split", split->sizes());
1230 configSettings->endGroup();
1234 void ConfigSearchWindow::search(void)
1237 struct property *prop;
1238 ConfigItem *lastItem = NULL;
1241 list->list->clear();
1244 result = sym_re_search(editField->text().latin1());
1247 for (p = result; *p; p++) {
1248 for_all_prompts((*p), prop)
1249 lastItem = new ConfigItem(list->list, lastItem, prop->menu,
1250 menu_is_visible(prop->menu));
1255 * Construct the complete config widget
1257 ConfigMainWindow::ConfigMainWindow(void)
1262 int x, y, width, height;
1265 QDesktopWidget *d = configApp->desktop();
1266 snprintf(title, sizeof(title), _("Linux Kernel v%s Configuration"),
1267 getenv("KERNELVERSION"));
1270 width = configSettings->readNumEntry("/window width", d->width() - 64);
1271 height = configSettings->readNumEntry("/window height", d->height() - 64);
1272 resize(width, height);
1273 x = configSettings->readNumEntry("/window x", 0, &ok);
1275 y = configSettings->readNumEntry("/window y", 0, &ok);
1279 split1 = new QSplitter(this);
1280 split1->setOrientation(Qt::Horizontal);
1281 setCentralWidget(split1);
1283 menuView = new ConfigView(split1, "menu");
1284 menuList = menuView->list;
1286 split2 = new QSplitter(split1);
1287 split2->setOrientation(Qt::Vertical);
1289 // create config tree
1290 configView = new ConfigView(split2, "config");
1291 configList = configView->list;
1293 helpText = new ConfigInfoView(split2, "help");
1294 helpText->setTextFormat(Qt::RichText);
1296 setTabOrder(configList, helpText);
1297 configList->setFocus();
1300 toolBar = new QToolBar("Tools", this);
1302 backAction = new QAction("Back", QPixmap(xpm_back), _("Back"), 0, this);
1303 connect(backAction, SIGNAL(activated()), SLOT(goBack()));
1304 backAction->setEnabled(FALSE);
1305 QAction *quitAction = new QAction("Quit", _("&Quit"), Qt::CTRL + Qt::Key_Q, this);
1306 connect(quitAction, SIGNAL(activated()), SLOT(close()));
1307 QAction *loadAction = new QAction("Load", QPixmap(xpm_load), _("&Load"), Qt::CTRL + Qt::Key_L, this);
1308 connect(loadAction, SIGNAL(activated()), SLOT(loadConfig()));
1309 saveAction = new QAction("Save", QPixmap(xpm_save), _("&Save"), Qt::CTRL + Qt::Key_S, this);
1310 connect(saveAction, SIGNAL(activated()), SLOT(saveConfig()));
1311 conf_set_changed_callback(conf_changed);
1312 // Set saveAction's initial state
1314 QAction *saveAsAction = new QAction("Save As...", _("Save &As..."), 0, this);
1315 connect(saveAsAction, SIGNAL(activated()), SLOT(saveConfigAs()));
1316 QAction *searchAction = new QAction("Find", _("&Find"), Qt::CTRL + Qt::Key_F, this);
1317 connect(searchAction, SIGNAL(activated()), SLOT(searchConfig()));
1318 QAction *singleViewAction = new QAction("Single View", QPixmap(xpm_single_view), _("Single View"), 0, this);
1319 connect(singleViewAction, SIGNAL(activated()), SLOT(showSingleView()));
1320 QAction *splitViewAction = new QAction("Split View", QPixmap(xpm_split_view), _("Split View"), 0, this);
1321 connect(splitViewAction, SIGNAL(activated()), SLOT(showSplitView()));
1322 QAction *fullViewAction = new QAction("Full View", QPixmap(xpm_tree_view), _("Full View"), 0, this);
1323 connect(fullViewAction, SIGNAL(activated()), SLOT(showFullView()));
1325 QAction *showNameAction = new QAction(NULL, _("Show Name"), 0, this);
1326 showNameAction->setToggleAction(TRUE);
1327 connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool)));
1328 connect(configView, SIGNAL(showNameChanged(bool)), showNameAction, SLOT(setOn(bool)));
1329 showNameAction->setOn(configView->showName());
1330 QAction *showRangeAction = new QAction(NULL, _("Show Range"), 0, this);
1331 showRangeAction->setToggleAction(TRUE);
1332 connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool)));
1333 connect(configView, SIGNAL(showRangeChanged(bool)), showRangeAction, SLOT(setOn(bool)));
1334 showRangeAction->setOn(configList->showRange);
1335 QAction *showDataAction = new QAction(NULL, _("Show Data"), 0, this);
1336 showDataAction->setToggleAction(TRUE);
1337 connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool)));
1338 connect(configView, SIGNAL(showDataChanged(bool)), showDataAction, SLOT(setOn(bool)));
1339 showDataAction->setOn(configList->showData);
1341 QActionGroup *optGroup = new QActionGroup(this);
1342 optGroup->setExclusive(TRUE);
1343 connect(optGroup, SIGNAL(selected(QAction *)), configView,
1344 SLOT(setOptionMode(QAction *)));
1345 connect(optGroup, SIGNAL(selected(QAction *)), menuView,
1346 SLOT(setOptionMode(QAction *)));
1348 configView->showNormalAction = new QAction(NULL, _("Show Normal Options"), 0, optGroup);
1349 configView->showAllAction = new QAction(NULL, _("Show All Options"), 0, optGroup);
1350 configView->showPromptAction = new QAction(NULL, _("Show Prompt Options"), 0, optGroup);
1351 configView->showNormalAction->setToggleAction(TRUE);
1352 configView->showNormalAction->setOn(configList->optMode == normalOpt);
1353 configView->showAllAction->setToggleAction(TRUE);
1354 configView->showAllAction->setOn(configList->optMode == allOpt);
1355 configView->showPromptAction->setToggleAction(TRUE);
1356 configView->showPromptAction->setOn(configList->optMode == promptOpt);
1358 QAction *showDebugAction = new QAction(NULL, _("Show Debug Info"), 0, this);
1359 showDebugAction->setToggleAction(TRUE);
1360 connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
1361 connect(helpText, SIGNAL(showDebugChanged(bool)), showDebugAction, SLOT(setOn(bool)));
1362 showDebugAction->setOn(helpText->showDebug());
1364 QAction *showIntroAction = new QAction(NULL, _("Introduction"), 0, this);
1365 connect(showIntroAction, SIGNAL(activated()), SLOT(showIntro()));
1366 QAction *showAboutAction = new QAction(NULL, _("About"), 0, this);
1367 connect(showAboutAction, SIGNAL(activated()), SLOT(showAbout()));
1370 backAction->addTo(toolBar);
1371 toolBar->addSeparator();
1372 loadAction->addTo(toolBar);
1373 saveAction->addTo(toolBar);
1374 toolBar->addSeparator();
1375 singleViewAction->addTo(toolBar);
1376 splitViewAction->addTo(toolBar);
1377 fullViewAction->addTo(toolBar);
1379 // create config menu
1380 QPopupMenu* config = new QPopupMenu(this);
1381 menu->insertItem(_("&File"), config);
1382 loadAction->addTo(config);
1383 saveAction->addTo(config);
1384 saveAsAction->addTo(config);
1385 config->insertSeparator();
1386 quitAction->addTo(config);
1389 QPopupMenu* editMenu = new QPopupMenu(this);
1390 menu->insertItem(_("&Edit"), editMenu);
1391 searchAction->addTo(editMenu);
1393 // create options menu
1394 QPopupMenu* optionMenu = new QPopupMenu(this);
1395 menu->insertItem(_("&Option"), optionMenu);
1396 showNameAction->addTo(optionMenu);
1397 showRangeAction->addTo(optionMenu);
1398 showDataAction->addTo(optionMenu);
1399 optionMenu->insertSeparator();
1400 optGroup->addTo(optionMenu);
1401 optionMenu->insertSeparator();
1402 showDebugAction->addTo(optionMenu);
1405 QPopupMenu* helpMenu = new QPopupMenu(this);
1406 menu->insertSeparator();
1407 menu->insertItem(_("&Help"), helpMenu);
1408 showIntroAction->addTo(helpMenu);
1409 showAboutAction->addTo(helpMenu);
1411 connect(configList, SIGNAL(menuChanged(struct menu *)),
1412 helpText, SLOT(setInfo(struct menu *)));
1413 connect(configList, SIGNAL(menuSelected(struct menu *)),
1414 SLOT(changeMenu(struct menu *)));
1415 connect(configList, SIGNAL(parentSelected()),
1417 connect(menuList, SIGNAL(menuChanged(struct menu *)),
1418 helpText, SLOT(setInfo(struct menu *)));
1419 connect(menuList, SIGNAL(menuSelected(struct menu *)),
1420 SLOT(changeMenu(struct menu *)));
1422 connect(configList, SIGNAL(gotFocus(struct menu *)),
1423 helpText, SLOT(setInfo(struct menu *)));
1424 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1425 helpText, SLOT(setInfo(struct menu *)));
1426 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1427 SLOT(listFocusChanged(void)));
1428 connect(helpText, SIGNAL(menuSelected(struct menu *)),
1429 SLOT(setMenuLink(struct menu *)));
1431 QString listMode = configSettings->readEntry("/listMode", "symbol");
1432 if (listMode == "single")
1434 else if (listMode == "full")
1436 else /*if (listMode == "split")*/
1439 // UI setup done, restore splitter positions
1440 QValueList<int> sizes = configSettings->readSizes("/split1", &ok);
1442 split1->setSizes(sizes);
1444 sizes = configSettings->readSizes("/split2", &ok);
1446 split2->setSizes(sizes);
1449 void ConfigMainWindow::loadConfig(void)
1451 QString s = QFileDialog::getOpenFileName(conf_get_configname(), NULL, this);
1454 if (conf_read(QFile::encodeName(s)))
1455 QMessageBox::information(this, "qconf", _("Unable to load configuration!"));
1456 ConfigView::updateListAll();
1459 void ConfigMainWindow::saveConfig(void)
1461 if (conf_write(NULL))
1462 QMessageBox::information(this, "qconf", _("Unable to save configuration!"));
1465 void ConfigMainWindow::saveConfigAs(void)
1467 QString s = QFileDialog::getSaveFileName(conf_get_configname(), NULL, this);
1470 if (conf_write(QFile::encodeName(s)))
1471 QMessageBox::information(this, "qconf", _("Unable to save configuration!"));
1474 void ConfigMainWindow::searchConfig(void)
1477 searchWindow = new ConfigSearchWindow(this, "search");
1478 searchWindow->show();
1481 void ConfigMainWindow::changeMenu(struct menu *menu)
1483 configList->setRootMenu(menu);
1484 if (configList->rootEntry->parent == &rootmenu)
1485 backAction->setEnabled(FALSE);
1487 backAction->setEnabled(TRUE);
1490 void ConfigMainWindow::setMenuLink(struct menu *menu)
1492 struct menu *parent;
1493 ConfigList* list = NULL;
1496 if (configList->menuSkip(menu))
1499 switch (configList->mode) {
1502 parent = menu_get_parent_menu(menu);
1505 list->setRootMenu(parent);
1508 if (menu->flags & MENU_ROOT) {
1509 configList->setRootMenu(menu);
1510 configList->clearSelection();
1514 parent = menu_get_parent_menu(menu->parent);
1517 item = menuList->findConfigItem(parent);
1519 menuList->setSelected(item, TRUE);
1520 menuList->ensureItemVisible(item);
1522 list->setRootMenu(parent);
1533 item = list->findConfigItem(menu);
1535 list->setSelected(item, TRUE);
1536 list->ensureItemVisible(item);
1542 void ConfigMainWindow::listFocusChanged(void)
1544 if (menuList->mode == menuMode)
1545 configList->clearSelection();
1548 void ConfigMainWindow::goBack(void)
1552 configList->setParentMenu();
1553 if (configList->rootEntry == &rootmenu)
1554 backAction->setEnabled(FALSE);
1555 item = (ConfigItem*)menuList->selectedItem();
1557 if (item->menu == configList->rootEntry) {
1558 menuList->setSelected(item, TRUE);
1561 item = (ConfigItem*)item->parent();
1565 void ConfigMainWindow::showSingleView(void)
1568 menuList->setRootMenu(0);
1569 configList->mode = singleMode;
1570 if (configList->rootEntry == &rootmenu)
1571 configList->updateListAll();
1573 configList->setRootMenu(&rootmenu);
1574 configList->setAllOpen(TRUE);
1575 configList->setFocus();
1578 void ConfigMainWindow::showSplitView(void)
1580 configList->mode = symbolMode;
1581 if (configList->rootEntry == &rootmenu)
1582 configList->updateListAll();
1584 configList->setRootMenu(&rootmenu);
1585 configList->setAllOpen(TRUE);
1586 configApp->processEvents();
1587 menuList->mode = menuMode;
1588 menuList->setRootMenu(&rootmenu);
1589 menuList->setAllOpen(TRUE);
1591 menuList->setFocus();
1594 void ConfigMainWindow::showFullView(void)
1597 menuList->setRootMenu(0);
1598 configList->mode = fullMode;
1599 if (configList->rootEntry == &rootmenu)
1600 configList->updateListAll();
1602 configList->setRootMenu(&rootmenu);
1603 configList->setAllOpen(FALSE);
1604 configList->setFocus();
1608 * ask for saving configuration before quitting
1609 * TODO ask only when something changed
1611 void ConfigMainWindow::closeEvent(QCloseEvent* e)
1613 if (!conf_get_changed()) {
1617 QMessageBox mb("qconf", _("Save configuration?"), QMessageBox::Warning,
1618 QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape);
1619 mb.setButtonText(QMessageBox::Yes, _("&Save Changes"));
1620 mb.setButtonText(QMessageBox::No, _("&Discard Changes"));
1621 mb.setButtonText(QMessageBox::Cancel, _("Cancel Exit"));
1622 switch (mb.exec()) {
1623 case QMessageBox::Yes:
1625 case QMessageBox::No:
1628 case QMessageBox::Cancel:
1634 void ConfigMainWindow::showIntro(void)
1636 static const QString str = _("Welcome to the qconf graphical kernel configuration tool for Linux.\n\n"
1637 "For each option, a blank box indicates the feature is disabled, a check\n"
1638 "indicates it is enabled, and a dot indicates that it is to be compiled\n"
1639 "as a module. Clicking on the box will cycle through the three states.\n\n"
1640 "If you do not see an option (e.g., a device driver) that you believe\n"
1641 "should be present, try turning on Show All Options under the Options menu.\n"
1642 "Although there is no cross reference yet to help you figure out what other\n"
1643 "options must be enabled to support the option you are interested in, you can\n"
1644 "still view the help of a grayed-out option.\n\n"
1645 "Toggling Show Debug Info under the Options menu will show the dependencies,\n"
1646 "which you can then match by examining other options.\n\n");
1648 QMessageBox::information(this, "qconf", str);
1651 void ConfigMainWindow::showAbout(void)
1653 static const QString str = _("qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n\n"
1654 "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n");
1656 QMessageBox::information(this, "qconf", str);
1659 void ConfigMainWindow::saveSettings(void)
1661 configSettings->writeEntry("/window x", pos().x());
1662 configSettings->writeEntry("/window y", pos().y());
1663 configSettings->writeEntry("/window width", size().width());
1664 configSettings->writeEntry("/window height", size().height());
1667 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;