2 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
3 * Released under the terms of the GNU GPL v2.0.
11 #include <qtextbrowser.h>
14 #include <QFileDialog>
17 #include <qapplication.h>
18 #include <qdesktopwidget.h>
21 #include <qsplitter.h>
22 #include <qlineedit.h>
24 #include <qpushbutton.h>
26 #include <qmessagebox.h>
43 static QApplication *configApp;
44 static ConfigSettings *configSettings;
46 QAction *ConfigMainWindow::saveAction;
48 static inline QString qgettext(const char* str)
50 return QString::fromLocal8Bit(gettext(str));
53 static inline QString qgettext(const QString& str)
55 return QString::fromLocal8Bit(gettext(str.latin1()));
58 ConfigSettings::ConfigSettings()
59 : QSettings("kernel.org", "qconf")
64 * Reads a list of integer values from the application settings.
66 QList<int> ConfigSettings::readSizes(const QString& key, bool *ok)
69 QStringList entryList = readListEntry(key, ok);
70 QStringList::Iterator it;
72 for (it = entryList.begin(); it != entryList.end(); ++it)
73 result.push_back((*it).toInt());
79 * Writes a list of integer values to the application settings.
81 bool ConfigSettings::writeSizes(const QString& key, const QList<int>& value)
83 QStringList stringList;
84 QList<int>::ConstIterator it;
86 for (it = value.begin(); it != value.end(); ++it)
87 stringList.push_back(QString::number(*it));
88 return writeEntry(key, stringList);
94 * TODO check the value
96 void ConfigItem::okRename(int col)
98 Parent::okRename(col);
99 sym_set_string_value(menu->sym, text(dataColIdx).latin1());
100 listView()->updateList(this);
104 * update the displayed of a menu entry
106 void ConfigItem::updateMenu(void)
110 struct property *prop;
117 setPixmap(promptColIdx, list->menuBackPix);
124 prompt = _(menu_get_prompt(menu));
126 if (prop) switch (prop->type) {
128 if (list->mode == singleMode || list->mode == symbolMode) {
129 /* a menuconfig entry is displayed differently
130 * depending whether it's at the view root or a child.
132 if (sym && list->rootEntry == menu)
134 setPixmap(promptColIdx, list->menuPix);
138 setPixmap(promptColIdx, 0);
142 setPixmap(promptColIdx, 0);
150 setText(nameColIdx, QString::fromLocal8Bit(sym->name));
152 type = sym_get_type(sym);
158 if (!sym_is_changable(sym) && list->optMode == normalOpt) {
159 setPixmap(promptColIdx, 0);
160 setText(noColIdx, QString::null);
161 setText(modColIdx, QString::null);
162 setText(yesColIdx, QString::null);
165 expr = sym_get_tristate_value(sym);
168 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
169 setPixmap(promptColIdx, list->choiceYesPix);
171 setPixmap(promptColIdx, list->symbolYesPix);
172 setText(yesColIdx, "Y");
176 setPixmap(promptColIdx, list->symbolModPix);
177 setText(modColIdx, "M");
181 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
182 setPixmap(promptColIdx, list->choiceNoPix);
184 setPixmap(promptColIdx, list->symbolNoPix);
185 setText(noColIdx, "N");
190 setText(noColIdx, sym_tristate_within_range(sym, no) ? "_" : 0);
192 setText(modColIdx, sym_tristate_within_range(sym, mod) ? "_" : 0);
194 setText(yesColIdx, sym_tristate_within_range(sym, yes) ? "_" : 0);
196 setText(dataColIdx, QChar(ch));
203 data = sym_get_string_value(sym);
205 int i = list->mapIdx(dataColIdx);
207 setRenameEnabled(i, TRUE);
208 setText(dataColIdx, data);
209 if (type == S_STRING)
210 prompt = QString("%1: %2").arg(prompt).arg(data);
212 prompt = QString("(%2) %1").arg(prompt).arg(data);
215 if (!sym_has_value(sym) && visible)
216 prompt += _(" (NEW)");
218 setText(promptColIdx, prompt);
221 void ConfigItem::testUpdateMenu(bool v)
229 sym_calc_value(menu->sym);
230 if (menu->flags & MENU_CHANGED) {
231 /* the menu entry changed, so update all list items */
232 menu->flags &= ~MENU_CHANGED;
233 for (i = (ConfigItem*)menu->data; i; i = i->nextItem)
235 } else if (listView()->updateAll)
239 void ConfigItem::paintCell(QPainter* p, const QColorGroup& cg, int column, int width, int align)
241 ConfigList* list = listView();
244 if (isSelected() && !list->hasFocus() && list->mode == menuMode)
245 Parent::paintCell(p, list->inactivedColorGroup, column, width, align);
247 Parent::paintCell(p, cg, column, width, align);
249 Parent::paintCell(p, list->disabledColorGroup, column, width, align);
253 * construct a menu entry
255 void ConfigItem::init(void)
258 ConfigList* list = listView();
259 nextItem = (ConfigItem*)menu->data;
262 if (list->mode != fullMode)
264 sym_calc_value(menu->sym);
270 * destruct a menu entry
272 ConfigItem::~ConfigItem(void)
275 ConfigItem** ip = (ConfigItem**)&menu->data;
276 for (; *ip; ip = &(*ip)->nextItem) {
285 ConfigLineEdit::ConfigLineEdit(ConfigView* parent)
288 connect(this, SIGNAL(lostFocus()), SLOT(hide()));
291 void ConfigLineEdit::show(ConfigItem* i)
294 if (sym_get_string_value(item->menu->sym))
295 setText(QString::fromLocal8Bit(sym_get_string_value(item->menu->sym)));
297 setText(QString::null);
302 void ConfigLineEdit::keyPressEvent(QKeyEvent* e)
309 sym_set_string_value(item->menu->sym, text().latin1());
310 parent()->updateList(item);
313 Parent::keyPressEvent(e);
317 parent()->list->setFocus();
321 ConfigList::ConfigList(ConfigView* p, const char *name)
324 symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no),
325 choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no),
326 menuPix(xpm_menu), menuInvPix(xpm_menu_inv), menuBackPix(xpm_menuback), voidPix(xpm_void),
327 showName(false), showRange(false), showData(false), optMode(normalOpt),
328 rootEntry(0), headerPopup(0)
333 setRootIsDecorated(TRUE);
334 disabledColorGroup = palette().active();
335 disabledColorGroup.setColor(QColorGroup::Text, palette().disabled().text());
336 inactivedColorGroup = palette().active();
337 inactivedColorGroup.setColor(QColorGroup::Highlight, palette().disabled().highlight());
339 connect(this, SIGNAL(selectionChanged(void)),
340 SLOT(updateSelection(void)));
343 configSettings->beginGroup(name);
344 showName = configSettings->readBoolEntry("/showName", false);
345 showRange = configSettings->readBoolEntry("/showRange", false);
346 showData = configSettings->readBoolEntry("/showData", false);
347 optMode = (enum optionMode)configSettings->readNumEntry("/optionMode", false);
348 configSettings->endGroup();
349 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
352 for (i = 0; i < colNr; i++)
353 colMap[i] = colRevMap[i] = -1;
354 addColumn(promptColIdx, _("Option"));
359 bool ConfigList::menuSkip(struct menu *menu)
361 if (optMode == normalOpt && menu_is_visible(menu))
363 if (optMode == promptOpt && menu_has_prompt(menu))
365 if (optMode == allOpt)
370 void ConfigList::reinit(void)
372 removeColumn(dataColIdx);
373 removeColumn(yesColIdx);
374 removeColumn(modColIdx);
375 removeColumn(noColIdx);
376 removeColumn(nameColIdx);
379 addColumn(nameColIdx, _("Name"));
381 addColumn(noColIdx, "N");
382 addColumn(modColIdx, "M");
383 addColumn(yesColIdx, "Y");
386 addColumn(dataColIdx, _("Value"));
391 void ConfigList::saveSettings(void)
394 configSettings->beginGroup(name());
395 configSettings->writeEntry("/showName", showName);
396 configSettings->writeEntry("/showRange", showRange);
397 configSettings->writeEntry("/showData", showData);
398 configSettings->writeEntry("/optionMode", (int)optMode);
399 configSettings->endGroup();
403 ConfigItem* ConfigList::findConfigItem(struct menu *menu)
405 ConfigItem* item = (ConfigItem*)menu->data;
407 for (; item; item = item->nextItem) {
408 if (this == item->listView())
415 void ConfigList::updateSelection(void)
420 ConfigItem* item = (ConfigItem*)selectedItem();
425 emit menuChanged(menu);
428 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
429 if (mode == menuMode && type == P_MENU)
430 emit menuSelected(menu);
433 void ConfigList::updateList(ConfigItem* item)
435 ConfigItem* last = 0;
438 if (mode != listMode)
440 Q3ListViewItemIterator it(this);
443 for (; it.current(); ++it) {
444 item = (ConfigItem*)it.current();
447 item->testUpdateMenu(menu_is_visible(item->menu));
452 if (rootEntry != &rootmenu && (mode == singleMode ||
453 (mode == symbolMode && rootEntry->parent != &rootmenu))) {
456 item = new ConfigItem(this, 0, true);
459 if ((mode == singleMode || (mode == symbolMode && !(rootEntry->flags & MENU_ROOT))) &&
460 rootEntry->sym && rootEntry->prompt) {
461 item = last ? last->nextSibling() : firstChild();
463 item = new ConfigItem(this, last, rootEntry, true);
465 item->testUpdateMenu(true);
467 updateMenuList(item, rootEntry);
472 updateMenuList(this, rootEntry);
476 void ConfigList::setValue(ConfigItem* item, tristate val)
482 sym = item->menu ? item->menu->sym : 0;
486 type = sym_get_type(sym);
490 oldval = sym_get_tristate_value(sym);
492 if (!sym_set_tristate_value(sym, val))
494 if (oldval == no && item->menu->list)
496 parent()->updateList(item);
501 void ConfigList::changeValue(ConfigItem* item)
505 int type, oldexpr, newexpr;
512 if (item->menu->list)
513 item->setOpen(!item->isOpen());
517 type = sym_get_type(sym);
521 oldexpr = sym_get_tristate_value(sym);
522 newexpr = sym_toggle_tristate_value(sym);
523 if (item->menu->list) {
524 if (oldexpr == newexpr)
525 item->setOpen(!item->isOpen());
526 else if (oldexpr == no)
529 if (oldexpr != newexpr)
530 parent()->updateList(item);
535 if (colMap[dataColIdx] >= 0)
536 item->startRename(colMap[dataColIdx]);
538 parent()->lineEdit->show(item);
543 void ConfigList::setRootMenu(struct menu *menu)
547 if (rootEntry == menu)
549 type = menu && menu->prompt ? menu->prompt->type : P_UNKNOWN;
552 updateMenuList(this, 0);
555 setSelected(currentItem(), hasFocus());
556 ensureItemVisible(currentItem());
559 void ConfigList::setParentMenu(void)
562 struct menu *oldroot;
565 if (rootEntry == &rootmenu)
567 setRootMenu(menu_get_parent_menu(rootEntry->parent));
569 Q3ListViewItemIterator it(this);
570 for (; (item = (ConfigItem*)it.current()); it++) {
571 if (item->menu == oldroot) {
572 setCurrentItem(item);
573 ensureItemVisible(item);
580 * update all the children of a menu entry
581 * removes/adds the entries from the parent widget as necessary
583 * parent: either the menu list widget or a menu entry widget
584 * menu: entry to be updated
587 void ConfigList::updateMenuList(P* parent, struct menu* menu)
596 while ((item = parent->firstChild()))
601 last = parent->firstChild();
602 if (last && !last->goParent)
604 for (child = menu->list; child; child = child->next) {
605 item = last ? last->nextSibling() : parent->firstChild();
606 type = child->prompt ? child->prompt->type : P_UNKNOWN;
610 if (!(child->flags & MENU_ROOT))
614 if (child->flags & MENU_ROOT)
621 visible = menu_is_visible(child);
622 if (!menuSkip(child)) {
623 if (!child->sym && !child->list && !child->prompt)
625 if (!item || item->menu != child)
626 item = new ConfigItem(parent, last, child, visible);
628 item->testUpdateMenu(visible);
630 if (mode == fullMode || mode == menuMode || type != P_MENU)
631 updateMenuList(item, child);
633 updateMenuList(item, 0);
638 if (item && item->menu == child) {
639 last = parent->firstChild();
642 else while (last->nextSibling() != item)
643 last = last->nextSibling();
649 void ConfigList::keyPressEvent(QKeyEvent* ev)
651 Q3ListViewItem* i = currentItem();
656 if (ev->key() == Qt::Key_Escape && mode != fullMode && mode != listMode) {
657 emit parentSelected();
663 Parent::keyPressEvent(ev);
666 item = (ConfigItem*)i;
671 if (item->goParent) {
672 emit parentSelected();
678 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
679 if (type == P_MENU && rootEntry != menu &&
680 mode != fullMode && mode != menuMode) {
681 emit menuSelected(menu);
697 Parent::keyPressEvent(ev);
703 void ConfigList::contentsMousePressEvent(QMouseEvent* e)
705 //QPoint p(contentsToViewport(e->pos()));
706 //printf("contentsMousePressEvent: %d,%d\n", p.x(), p.y());
707 Parent::contentsMousePressEvent(e);
710 void ConfigList::contentsMouseReleaseEvent(QMouseEvent* e)
712 QPoint p(contentsToViewport(e->pos()));
713 ConfigItem* item = (ConfigItem*)itemAt(p);
715 enum prop_type ptype;
723 x = header()->offset() + p.x();
724 idx = colRevMap[header()->sectionAt(x)];
727 pm = item->pixmap(promptColIdx);
729 int off = header()->sectionPos(0) + itemMargin() +
730 treeStepSize() * (item->depth() + (rootIsDecorated() ? 1 : 0));
731 if (x >= off && x < off + pm->width()) {
732 if (item->goParent) {
733 emit parentSelected();
737 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
738 if (ptype == P_MENU && rootEntry != menu &&
739 mode != fullMode && mode != menuMode)
740 emit menuSelected(menu);
761 //printf("contentsMouseReleaseEvent: %d,%d\n", p.x(), p.y());
762 Parent::contentsMouseReleaseEvent(e);
765 void ConfigList::contentsMouseMoveEvent(QMouseEvent* e)
767 //QPoint p(contentsToViewport(e->pos()));
768 //printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y());
769 Parent::contentsMouseMoveEvent(e);
772 void ConfigList::contentsMouseDoubleClickEvent(QMouseEvent* e)
774 QPoint p(contentsToViewport(e->pos()));
775 ConfigItem* item = (ConfigItem*)itemAt(p);
777 enum prop_type ptype;
781 if (item->goParent) {
782 emit parentSelected();
788 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
789 if (ptype == P_MENU && (mode == singleMode || mode == symbolMode))
790 emit menuSelected(menu);
795 //printf("contentsMouseDoubleClickEvent: %d,%d\n", p.x(), p.y());
796 Parent::contentsMouseDoubleClickEvent(e);
799 void ConfigList::focusInEvent(QFocusEvent *e)
801 struct menu *menu = NULL;
803 Parent::focusInEvent(e);
805 ConfigItem* item = (ConfigItem *)currentItem();
807 setSelected(item, TRUE);
813 void ConfigList::contextMenuEvent(QContextMenuEvent *e)
815 if (e->y() <= header()->geometry().bottom()) {
819 headerPopup = new QMenu(this);
820 action = new QAction(_("Show Name"), this);
821 action->setToggleAction(TRUE);
822 connect(action, SIGNAL(toggled(bool)),
823 parent(), SLOT(setShowName(bool)));
824 connect(parent(), SIGNAL(showNameChanged(bool)),
825 action, SLOT(setOn(bool)));
826 action->setOn(showName);
827 action->addTo(headerPopup);
828 action = new QAction(_("Show Range"), this);
829 action->setToggleAction(TRUE);
830 connect(action, SIGNAL(toggled(bool)),
831 parent(), SLOT(setShowRange(bool)));
832 connect(parent(), SIGNAL(showRangeChanged(bool)),
833 action, SLOT(setOn(bool)));
834 action->setOn(showRange);
835 action->addTo(headerPopup);
836 action = new QAction( _("Show Data"), this);
837 action->setToggleAction(TRUE);
838 connect(action, SIGNAL(toggled(bool)),
839 parent(), SLOT(setShowData(bool)));
840 connect(parent(), SIGNAL(showDataChanged(bool)),
841 action, SLOT(setOn(bool)));
842 action->setOn(showData);
843 action->addTo(headerPopup);
845 headerPopup->exec(e->globalPos());
851 ConfigView*ConfigView::viewList;
852 QAction *ConfigView::showNormalAction;
853 QAction *ConfigView::showAllAction;
854 QAction *ConfigView::showPromptAction;
856 ConfigView::ConfigView(QWidget* parent, const char *name)
857 : Parent(parent, name)
859 list = new ConfigList(this, name);
860 lineEdit = new ConfigLineEdit(this);
863 this->nextView = viewList;
867 ConfigView::~ConfigView(void)
871 for (vp = &viewList; *vp; vp = &(*vp)->nextView) {
879 void ConfigView::setOptionMode(QAction *act)
881 if (act == showNormalAction)
882 list->optMode = normalOpt;
883 else if (act == showAllAction)
884 list->optMode = allOpt;
886 list->optMode = promptOpt;
888 list->updateListAll();
891 void ConfigView::setShowName(bool b)
893 if (list->showName != b) {
896 emit showNameChanged(b);
900 void ConfigView::setShowRange(bool b)
902 if (list->showRange != b) {
905 emit showRangeChanged(b);
909 void ConfigView::setShowData(bool b)
911 if (list->showData != b) {
914 emit showDataChanged(b);
918 void ConfigList::setAllOpen(bool open)
920 Q3ListViewItemIterator it(this);
922 for (; it.current(); it++)
923 it.current()->setOpen(open);
926 void ConfigView::updateList(ConfigItem* item)
930 for (v = viewList; v; v = v->nextView)
931 v->list->updateList(item);
934 void ConfigView::updateListAll(void)
938 for (v = viewList; v; v = v->nextView)
939 v->list->updateListAll();
942 ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name)
943 : Parent(parent, name), sym(0), _menu(0)
946 configSettings->beginGroup(name);
947 _showDebug = configSettings->readBoolEntry("/showDebug", false);
948 configSettings->endGroup();
949 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
953 void ConfigInfoView::saveSettings(void)
956 configSettings->beginGroup(name());
957 configSettings->writeEntry("/showDebug", showDebug());
958 configSettings->endGroup();
962 void ConfigInfoView::setShowDebug(bool b)
964 if (_showDebug != b) {
970 emit showDebugChanged(b);
974 void ConfigInfoView::setInfo(struct menu *m)
986 void ConfigInfoView::symbolInfo(void)
990 str += "<big>Symbol: <b>";
991 str += print_filter(sym->name);
992 str += "</b></big><br><br>value: ";
993 str += print_filter(sym_get_string_value(sym));
994 str += "<br>visibility: ";
995 str += sym->visible == yes ? "y" : sym->visible == mod ? "m" : "n";
997 str += debug_info(sym);
1002 void ConfigInfoView::menuInfo(void)
1005 QString head, debug, help;
1009 if (_menu->prompt) {
1011 head += print_filter(_(_menu->prompt->text));
1012 head += "</b></big>";
1016 head += QString().sprintf("<a href=\"s%p\">", sym);
1017 head += print_filter(sym->name);
1022 } else if (sym->name) {
1025 head += QString().sprintf("<a href=\"s%p\">", sym);
1026 head += print_filter(sym->name);
1029 head += "</b></big>";
1034 debug = debug_info(sym);
1036 struct gstr help_gstr = str_new();
1037 menu_get_ext_help(_menu, &help_gstr);
1038 help = print_filter(str_get(&help_gstr));
1039 str_free(&help_gstr);
1040 } else if (_menu->prompt) {
1042 head += print_filter(_(_menu->prompt->text));
1043 head += "</b></big><br><br>";
1045 if (_menu->prompt->visible.expr) {
1046 debug += " dep: ";
1047 expr_print(_menu->prompt->visible.expr, expr_print_help, &debug, E_NONE);
1048 debug += "<br><br>";
1053 debug += QString().sprintf("defined at %s:%d<br><br>", _menu->file->name, _menu->lineno);
1055 setText(head + debug + help);
1058 QString ConfigInfoView::debug_info(struct symbol *sym)
1063 debug += print_filter(sym_type_name(sym->type));
1064 if (sym_is_choice(sym))
1065 debug += " (choice)";
1067 if (sym->rev_dep.expr) {
1068 debug += "reverse dep: ";
1069 expr_print(sym->rev_dep.expr, expr_print_help, &debug, E_NONE);
1072 for (struct property *prop = sym->prop; prop; prop = prop->next) {
1073 switch (prop->type) {
1076 debug += QString().sprintf("prompt: <a href=\"m%p\">", prop->menu);
1077 debug += print_filter(_(prop->text));
1078 debug += "</a><br>";
1084 debug += prop_get_type_name(prop->type);
1086 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1090 if (sym_is_choice(sym)) {
1091 debug += "choice: ";
1092 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1097 debug += "unknown property: ";
1098 debug += prop_get_type_name(prop->type);
1101 if (prop->visible.expr) {
1102 debug += " dep: ";
1103 expr_print(prop->visible.expr, expr_print_help, &debug, E_NONE);
1112 QString ConfigInfoView::print_filter(const QString &str)
1114 QRegExp re("[<>&\"\\n]");
1116 for (int i = 0; (i = res.find(re, i)) >= 0;) {
1117 switch (res[i].latin1()) {
1119 res.replace(i, 1, "<");
1123 res.replace(i, 1, ">");
1127 res.replace(i, 1, "&");
1131 res.replace(i, 1, """);
1135 res.replace(i, 1, "<br>");
1143 void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char *str)
1145 QString* text = reinterpret_cast<QString*>(data);
1146 QString str2 = print_filter(str);
1148 if (sym && sym->name && !(sym->flags & SYMBOL_CONST)) {
1149 *text += QString().sprintf("<a href=\"s%p\">", sym);
1156 QMenu* ConfigInfoView::createStandardContextMenu(const QPoint & pos)
1158 QMenu* popup = Parent::createStandardContextMenu(pos);
1159 QAction* action = new QAction(_("Show Debug Info"), popup);
1160 action->setToggleAction(TRUE);
1161 connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
1162 connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool)));
1163 action->setOn(showDebug());
1164 popup->addSeparator();
1165 action->addTo(popup);
1169 void ConfigInfoView::contextMenuEvent(QContextMenuEvent *e)
1171 Parent::contextMenuEvent(e);
1174 ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow* parent, const char *name)
1175 : Parent(parent, name), result(NULL)
1177 setCaption("Search Config");
1179 QVBoxLayout* layout1 = new QVBoxLayout(this, 11, 6);
1180 QHBoxLayout* layout2 = new QHBoxLayout(0, 0, 6);
1181 layout2->addWidget(new QLabel(_("Find:"), this));
1182 editField = new QLineEdit(this);
1183 connect(editField, SIGNAL(returnPressed()), SLOT(search()));
1184 layout2->addWidget(editField);
1185 searchButton = new QPushButton(_("Search"), this);
1186 searchButton->setAutoDefault(FALSE);
1187 connect(searchButton, SIGNAL(clicked()), SLOT(search()));
1188 layout2->addWidget(searchButton);
1189 layout1->addLayout(layout2);
1191 split = new QSplitter(this);
1192 split->setOrientation(Qt::Vertical);
1193 list = new ConfigView(split, name);
1194 list->list->mode = listMode;
1195 info = new ConfigInfoView(split, name);
1196 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1197 info, SLOT(setInfo(struct menu *)));
1198 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1199 parent, SLOT(setMenuLink(struct menu *)));
1201 layout1->addWidget(split);
1204 int x, y, width, height;
1207 configSettings->beginGroup(name);
1208 width = configSettings->readNumEntry("/window width", parent->width() / 2);
1209 height = configSettings->readNumEntry("/window height", parent->height() / 2);
1210 resize(width, height);
1211 x = configSettings->readNumEntry("/window x", 0, &ok);
1213 y = configSettings->readNumEntry("/window y", 0, &ok);
1216 QList<int> sizes = configSettings->readSizes("/split", &ok);
1218 split->setSizes(sizes);
1219 configSettings->endGroup();
1220 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
1224 void ConfigSearchWindow::saveSettings(void)
1227 configSettings->beginGroup(name());
1228 configSettings->writeEntry("/window x", pos().x());
1229 configSettings->writeEntry("/window y", pos().y());
1230 configSettings->writeEntry("/window width", size().width());
1231 configSettings->writeEntry("/window height", size().height());
1232 configSettings->writeSizes("/split", split->sizes());
1233 configSettings->endGroup();
1237 void ConfigSearchWindow::search(void)
1240 struct property *prop;
1241 ConfigItem *lastItem = NULL;
1244 list->list->clear();
1247 result = sym_re_search(editField->text().latin1());
1250 for (p = result; *p; p++) {
1251 for_all_prompts((*p), prop)
1252 lastItem = new ConfigItem(list->list, lastItem, prop->menu,
1253 menu_is_visible(prop->menu));
1258 * Construct the complete config widget
1260 ConfigMainWindow::ConfigMainWindow(void)
1265 int x, y, width, height;
1268 QDesktopWidget *d = configApp->desktop();
1269 snprintf(title, sizeof(title), "%s%s",
1270 rootmenu.prompt->text,
1275 width = configSettings->readNumEntry("/window width", d->width() - 64);
1276 height = configSettings->readNumEntry("/window height", d->height() - 64);
1277 resize(width, height);
1278 x = configSettings->readNumEntry("/window x", 0, &ok);
1280 y = configSettings->readNumEntry("/window y", 0, &ok);
1284 split1 = new QSplitter(this);
1285 split1->setOrientation(Qt::Horizontal);
1286 setCentralWidget(split1);
1288 menuView = new ConfigView(split1, "menu");
1289 menuList = menuView->list;
1291 split2 = new QSplitter(split1);
1292 split2->setOrientation(Qt::Vertical);
1294 // create config tree
1295 configView = new ConfigView(split2, "config");
1296 configList = configView->list;
1298 helpText = new ConfigInfoView(split2, "help");
1299 helpText->setTextFormat(Qt::RichText);
1301 setTabOrder(configList, helpText);
1302 configList->setFocus();
1305 toolBar = new QToolBar("Tools", this);
1307 backAction = new QAction(QPixmap(xpm_back), _("Back"), this);
1308 connect(backAction, SIGNAL(activated()), SLOT(goBack()));
1309 backAction->setEnabled(FALSE);
1310 QAction *quitAction = new QAction(_("&Quit"), this);
1311 quitAction->setShortcut(Qt::CTRL + Qt::Key_Q);
1312 connect(quitAction, SIGNAL(activated()), SLOT(close()));
1313 QAction *loadAction = new QAction(QPixmap(xpm_load), _("&Load"), this);
1314 loadAction->setShortcut(Qt::CTRL + Qt::Key_L);
1315 connect(loadAction, SIGNAL(activated()), SLOT(loadConfig()));
1316 saveAction = new QAction(QPixmap(xpm_save), _("&Save"), this);
1317 saveAction->setShortcut(Qt::CTRL + Qt::Key_S);
1318 connect(saveAction, SIGNAL(activated()), SLOT(saveConfig()));
1319 conf_set_changed_callback(conf_changed);
1320 // Set saveAction's initial state
1322 QAction *saveAsAction = new QAction(_("Save &As..."), this);
1323 connect(saveAsAction, SIGNAL(activated()), SLOT(saveConfigAs()));
1324 QAction *searchAction = new QAction(_("&Find"), this);
1325 searchAction->setShortcut(Qt::CTRL + Qt::Key_F);
1326 connect(searchAction, SIGNAL(activated()), SLOT(searchConfig()));
1327 QAction *singleViewAction = new QAction(QPixmap(xpm_single_view), _("Single View"), this);
1328 connect(singleViewAction, SIGNAL(activated()), SLOT(showSingleView()));
1329 QAction *splitViewAction = new QAction(QPixmap(xpm_split_view), _("Split View"), this);
1330 connect(splitViewAction, SIGNAL(activated()), SLOT(showSplitView()));
1331 QAction *fullViewAction = new QAction(QPixmap(xpm_tree_view), _("Full View"), this);
1332 connect(fullViewAction, SIGNAL(activated()), SLOT(showFullView()));
1334 QAction *showNameAction = new QAction(_("Show Name"), this);
1335 showNameAction->setToggleAction(TRUE);
1336 connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool)));
1337 connect(configView, SIGNAL(showNameChanged(bool)), showNameAction, SLOT(setOn(bool)));
1338 showNameAction->setOn(configView->showName());
1339 QAction *showRangeAction = new QAction(_("Show Range"), this);
1340 showRangeAction->setToggleAction(TRUE);
1341 connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool)));
1342 connect(configView, SIGNAL(showRangeChanged(bool)), showRangeAction, SLOT(setOn(bool)));
1343 showRangeAction->setOn(configList->showRange);
1344 QAction *showDataAction = new QAction(_("Show Data"), this);
1345 showDataAction->setToggleAction(TRUE);
1346 connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool)));
1347 connect(configView, SIGNAL(showDataChanged(bool)), showDataAction, SLOT(setOn(bool)));
1348 showDataAction->setOn(configList->showData);
1350 QActionGroup *optGroup = new QActionGroup(this);
1351 optGroup->setExclusive(TRUE);
1352 connect(optGroup, SIGNAL(selected(QAction *)), configView,
1353 SLOT(setOptionMode(QAction *)));
1354 connect(optGroup, SIGNAL(selected(QAction *)), menuView,
1355 SLOT(setOptionMode(QAction *)));
1357 configView->showNormalAction = new QAction(_("Show Normal Options"), optGroup);
1358 configView->showAllAction = new QAction(_("Show All Options"), optGroup);
1359 configView->showPromptAction = new QAction(_("Show Prompt Options"), optGroup);
1360 configView->showNormalAction->setToggleAction(TRUE);
1361 configView->showNormalAction->setOn(configList->optMode == normalOpt);
1362 configView->showAllAction->setToggleAction(TRUE);
1363 configView->showAllAction->setOn(configList->optMode == allOpt);
1364 configView->showPromptAction->setToggleAction(TRUE);
1365 configView->showPromptAction->setOn(configList->optMode == promptOpt);
1367 QAction *showDebugAction = new QAction( _("Show Debug Info"), this);
1368 showDebugAction->setToggleAction(TRUE);
1369 connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
1370 connect(helpText, SIGNAL(showDebugChanged(bool)), showDebugAction, SLOT(setOn(bool)));
1371 showDebugAction->setOn(helpText->showDebug());
1373 QAction *showIntroAction = new QAction( _("Introduction"), this);
1374 connect(showIntroAction, SIGNAL(activated()), SLOT(showIntro()));
1375 QAction *showAboutAction = new QAction( _("About"), this);
1376 connect(showAboutAction, SIGNAL(activated()), SLOT(showAbout()));
1379 backAction->addTo(toolBar);
1380 toolBar->addSeparator();
1381 loadAction->addTo(toolBar);
1382 saveAction->addTo(toolBar);
1383 toolBar->addSeparator();
1384 singleViewAction->addTo(toolBar);
1385 splitViewAction->addTo(toolBar);
1386 fullViewAction->addTo(toolBar);
1388 // create config menu
1389 QMenu* config = new QMenu(this);
1390 menu->insertItem(_("&File"), config);
1391 loadAction->addTo(config);
1392 saveAction->addTo(config);
1393 saveAsAction->addTo(config);
1394 config->addSeparator();
1395 quitAction->addTo(config);
1398 QMenu* editMenu = new QMenu(this);
1399 menu->insertItem(_("&Edit"), editMenu);
1400 searchAction->addTo(editMenu);
1402 // create options menu
1403 QMenu* optionMenu = new QMenu(this);
1404 menu->insertItem(_("&Option"), optionMenu);
1405 showNameAction->addTo(optionMenu);
1406 showRangeAction->addTo(optionMenu);
1407 showDataAction->addTo(optionMenu);
1408 optionMenu->addSeparator();
1409 optGroup->addTo(optionMenu);
1410 optionMenu->addSeparator();
1413 QMenu* helpMenu = new QMenu(this);
1414 menu->addSeparator();
1415 menu->insertItem(_("&Help"), helpMenu);
1416 showIntroAction->addTo(helpMenu);
1417 showAboutAction->addTo(helpMenu);
1419 connect(configList, SIGNAL(menuChanged(struct menu *)),
1420 helpText, SLOT(setInfo(struct menu *)));
1421 connect(configList, SIGNAL(menuSelected(struct menu *)),
1422 SLOT(changeMenu(struct menu *)));
1423 connect(configList, SIGNAL(parentSelected()),
1425 connect(menuList, SIGNAL(menuChanged(struct menu *)),
1426 helpText, SLOT(setInfo(struct menu *)));
1427 connect(menuList, SIGNAL(menuSelected(struct menu *)),
1428 SLOT(changeMenu(struct menu *)));
1430 connect(configList, SIGNAL(gotFocus(struct menu *)),
1431 helpText, SLOT(setInfo(struct menu *)));
1432 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1433 helpText, SLOT(setInfo(struct menu *)));
1434 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1435 SLOT(listFocusChanged(void)));
1436 connect(helpText, SIGNAL(menuSelected(struct menu *)),
1437 SLOT(setMenuLink(struct menu *)));
1439 QString listMode = configSettings->readEntry("/listMode", "symbol");
1440 if (listMode == "single")
1442 else if (listMode == "full")
1444 else /*if (listMode == "split")*/
1447 // UI setup done, restore splitter positions
1448 QList<int> sizes = configSettings->readSizes("/split1", &ok);
1450 split1->setSizes(sizes);
1452 sizes = configSettings->readSizes("/split2", &ok);
1454 split2->setSizes(sizes);
1457 void ConfigMainWindow::loadConfig(void)
1459 QString s = QFileDialog::getOpenFileName(conf_get_configname(), NULL, this);
1462 if (conf_read(QFile::encodeName(s)))
1463 QMessageBox::information(this, "qconf", _("Unable to load configuration!"));
1464 ConfigView::updateListAll();
1467 bool ConfigMainWindow::saveConfig(void)
1469 if (conf_write(NULL)) {
1470 QMessageBox::information(this, "qconf", _("Unable to save configuration!"));
1476 void ConfigMainWindow::saveConfigAs(void)
1478 QString s = QFileDialog::getSaveFileName(conf_get_configname(), NULL, this);
1484 void ConfigMainWindow::searchConfig(void)
1487 searchWindow = new ConfigSearchWindow(this, "search");
1488 searchWindow->show();
1491 void ConfigMainWindow::changeMenu(struct menu *menu)
1493 configList->setRootMenu(menu);
1494 if (configList->rootEntry->parent == &rootmenu)
1495 backAction->setEnabled(FALSE);
1497 backAction->setEnabled(TRUE);
1500 void ConfigMainWindow::setMenuLink(struct menu *menu)
1502 struct menu *parent;
1503 ConfigList* list = NULL;
1506 if (configList->menuSkip(menu))
1509 switch (configList->mode) {
1512 parent = menu_get_parent_menu(menu);
1515 list->setRootMenu(parent);
1518 if (menu->flags & MENU_ROOT) {
1519 configList->setRootMenu(menu);
1520 configList->clearSelection();
1524 parent = menu_get_parent_menu(menu->parent);
1527 item = menuList->findConfigItem(parent);
1529 menuList->setSelected(item, TRUE);
1530 menuList->ensureItemVisible(item);
1532 list->setRootMenu(parent);
1543 item = list->findConfigItem(menu);
1545 list->setSelected(item, TRUE);
1546 list->ensureItemVisible(item);
1552 void ConfigMainWindow::listFocusChanged(void)
1554 if (menuList->mode == menuMode)
1555 configList->clearSelection();
1558 void ConfigMainWindow::goBack(void)
1562 configList->setParentMenu();
1563 if (configList->rootEntry == &rootmenu)
1564 backAction->setEnabled(FALSE);
1565 item = (ConfigItem*)menuList->selectedItem();
1567 if (item->menu == configList->rootEntry) {
1568 menuList->setSelected(item, TRUE);
1571 item = (ConfigItem*)item->parent();
1575 void ConfigMainWindow::showSingleView(void)
1578 menuList->setRootMenu(0);
1579 configList->mode = singleMode;
1580 if (configList->rootEntry == &rootmenu)
1581 configList->updateListAll();
1583 configList->setRootMenu(&rootmenu);
1584 configList->setAllOpen(TRUE);
1585 configList->setFocus();
1588 void ConfigMainWindow::showSplitView(void)
1590 configList->mode = symbolMode;
1591 if (configList->rootEntry == &rootmenu)
1592 configList->updateListAll();
1594 configList->setRootMenu(&rootmenu);
1595 configList->setAllOpen(TRUE);
1596 configApp->processEvents();
1597 menuList->mode = menuMode;
1598 menuList->setRootMenu(&rootmenu);
1599 menuList->setAllOpen(TRUE);
1601 menuList->setFocus();
1604 void ConfigMainWindow::showFullView(void)
1607 menuList->setRootMenu(0);
1608 configList->mode = fullMode;
1609 if (configList->rootEntry == &rootmenu)
1610 configList->updateListAll();
1612 configList->setRootMenu(&rootmenu);
1613 configList->setAllOpen(FALSE);
1614 configList->setFocus();
1618 * ask for saving configuration before quitting
1619 * TODO ask only when something changed
1621 void ConfigMainWindow::closeEvent(QCloseEvent* e)
1623 if (!conf_get_changed()) {
1627 QMessageBox mb("qconf", _("Save configuration?"), QMessageBox::Warning,
1628 QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape);
1629 mb.setButtonText(QMessageBox::Yes, _("&Save Changes"));
1630 mb.setButtonText(QMessageBox::No, _("&Discard Changes"));
1631 mb.setButtonText(QMessageBox::Cancel, _("Cancel Exit"));
1632 switch (mb.exec()) {
1633 case QMessageBox::Yes:
1639 case QMessageBox::No:
1642 case QMessageBox::Cancel:
1648 void ConfigMainWindow::showIntro(void)
1650 static const QString str = _("Welcome to the qconf graphical configuration tool.\n\n"
1651 "For each option, a blank box indicates the feature is disabled, a check\n"
1652 "indicates it is enabled, and a dot indicates that it is to be compiled\n"
1653 "as a module. Clicking on the box will cycle through the three states.\n\n"
1654 "If you do not see an option (e.g., a device driver) that you believe\n"
1655 "should be present, try turning on Show All Options under the Options menu.\n"
1656 "Although there is no cross reference yet to help you figure out what other\n"
1657 "options must be enabled to support the option you are interested in, you can\n"
1658 "still view the help of a grayed-out option.\n\n"
1659 "Toggling Show Debug Info under the Options menu will show the dependencies,\n"
1660 "which you can then match by examining other options.\n\n");
1662 QMessageBox::information(this, "qconf", str);
1665 void ConfigMainWindow::showAbout(void)
1667 static const QString str = _("qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n\n"
1668 "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n");
1670 QMessageBox::information(this, "qconf", str);
1673 void ConfigMainWindow::saveSettings(void)
1675 configSettings->writeEntry("/window x", pos().x());
1676 configSettings->writeEntry("/window y", pos().y());
1677 configSettings->writeEntry("/window width", size().width());
1678 configSettings->writeEntry("/window height", size().height());
1681 switch(configList->mode) {
1697 configSettings->writeEntry("/listMode", entry);
1699 configSettings->writeSizes("/split1", split1->sizes());
1700 configSettings->writeSizes("/split2", split2->sizes());
1703 void ConfigMainWindow::conf_changed(void)
1706 saveAction->setEnabled(conf_get_changed());
1709 void fixup_rootmenu(struct menu *menu)
1712 static int menu_cnt = 0;
1714 menu->flags |= MENU_ROOT;
1715 for (child = menu->list; child; child = child->next) {
1716 if (child->prompt && child->prompt->type == P_MENU) {
1718 fixup_rootmenu(child);
1720 } else if (!menu_cnt)
1721 fixup_rootmenu(child);
1725 static const char *progname;
1727 static void usage(void)
1729 printf(_("%s [-s] <config>\n"), progname);
1733 int main(int ac, char** av)
1735 ConfigMainWindow* v;
1738 bindtextdomain(PACKAGE, LOCALEDIR);
1739 textdomain(PACKAGE);
1742 configApp = new QApplication(ac, av);
1743 if (ac > 1 && av[1][0] == '-') {
1746 conf_set_message_callback(NULL);
1759 fixup_rootmenu(&rootmenu);
1761 //zconfdump(stdout);
1763 configSettings = new ConfigSettings();
1764 configSettings->beginGroup("/kconfig/qconf");
1765 v = new ConfigMainWindow();
1767 //zconfdump(stdout);
1768 configApp->setMainWidget(v);
1769 configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit()));
1770 configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings()));
1774 configSettings->endGroup();
1775 delete configSettings;