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 static inline QString qgettext(const char* str)
43 return QString::fromLocal8Bit(gettext(str));
46 static inline QString qgettext(const QString& str)
48 return QString::fromLocal8Bit(gettext(str.latin1()));
52 * Reads a list of integer values from the application settings.
54 QValueList<int> ConfigSettings::readSizes(const QString& key, bool *ok)
56 QValueList<int> result;
57 QStringList entryList = readListEntry(key, ok);
59 QStringList::Iterator it;
60 for (it = entryList.begin(); it != entryList.end(); ++it)
61 result.push_back((*it).toInt());
68 * Writes a list of integer values to the application settings.
70 bool ConfigSettings::writeSizes(const QString& key, const QValueList<int>& value)
72 QStringList stringList;
73 QValueList<int>::ConstIterator it;
75 for (it = value.begin(); it != value.end(); ++it)
76 stringList.push_back(QString::number(*it));
77 return writeEntry(key, stringList);
84 * TODO check the value
86 void ConfigItem::okRename(int col)
88 Parent::okRename(col);
89 sym_set_string_value(menu->sym, text(dataColIdx).latin1());
94 * update the displayed of a menu entry
96 void ConfigItem::updateMenu(void)
100 struct property *prop;
107 setPixmap(promptColIdx, list->menuBackPix);
114 prompt = QString::fromLocal8Bit(menu_get_prompt(menu));
116 if (prop) switch (prop->type) {
118 if (list->mode == singleMode || list->mode == symbolMode) {
119 /* a menuconfig entry is displayed differently
120 * depending whether it's at the view root or a child.
122 if (sym && list->rootEntry == menu)
124 setPixmap(promptColIdx, list->menuPix);
128 setPixmap(promptColIdx, 0);
132 setPixmap(promptColIdx, 0);
140 setText(nameColIdx, QString::fromLocal8Bit(sym->name));
142 type = sym_get_type(sym);
148 if (!sym_is_changable(sym) && !list->showAll) {
149 setPixmap(promptColIdx, 0);
150 setText(noColIdx, QString::null);
151 setText(modColIdx, QString::null);
152 setText(yesColIdx, QString::null);
155 expr = sym_get_tristate_value(sym);
158 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
159 setPixmap(promptColIdx, list->choiceYesPix);
161 setPixmap(promptColIdx, list->symbolYesPix);
162 setText(yesColIdx, "Y");
166 setPixmap(promptColIdx, list->symbolModPix);
167 setText(modColIdx, "M");
171 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
172 setPixmap(promptColIdx, list->choiceNoPix);
174 setPixmap(promptColIdx, list->symbolNoPix);
175 setText(noColIdx, "N");
180 setText(noColIdx, sym_tristate_within_range(sym, no) ? "_" : 0);
182 setText(modColIdx, sym_tristate_within_range(sym, mod) ? "_" : 0);
184 setText(yesColIdx, sym_tristate_within_range(sym, yes) ? "_" : 0);
186 setText(dataColIdx, QChar(ch));
193 data = sym_get_string_value(sym);
195 #if QT_VERSION >= 300
196 int i = list->mapIdx(dataColIdx);
198 setRenameEnabled(i, TRUE);
200 setText(dataColIdx, data);
201 if (type == S_STRING)
202 prompt = QString("%1: %2").arg(prompt).arg(data);
204 prompt = QString("(%2) %1").arg(prompt).arg(data);
207 if (!sym_has_value(sym) && visible)
210 setText(promptColIdx, prompt);
213 void ConfigItem::testUpdateMenu(bool v)
221 sym_calc_value(menu->sym);
222 if (menu->flags & MENU_CHANGED) {
223 /* the menu entry changed, so update all list items */
224 menu->flags &= ~MENU_CHANGED;
225 for (i = (ConfigItem*)menu->data; i; i = i->nextItem)
227 } else if (listView()->updateAll)
231 void ConfigItem::paintCell(QPainter* p, const QColorGroup& cg, int column, int width, int align)
233 ConfigList* list = listView();
236 if (isSelected() && !list->hasFocus() && list->mode == menuMode)
237 Parent::paintCell(p, list->inactivedColorGroup, column, width, align);
239 Parent::paintCell(p, cg, column, width, align);
241 Parent::paintCell(p, list->disabledColorGroup, column, width, align);
245 * construct a menu entry
247 void ConfigItem::init(void)
250 ConfigList* list = listView();
251 nextItem = (ConfigItem*)menu->data;
254 if (list->mode != fullMode)
256 sym_calc_value(menu->sym);
262 * destruct a menu entry
264 ConfigItem::~ConfigItem(void)
267 ConfigItem** ip = (ConfigItem**)&menu->data;
268 for (; *ip; ip = &(*ip)->nextItem) {
277 ConfigLineEdit::ConfigLineEdit(ConfigView* parent)
280 connect(this, SIGNAL(lostFocus()), SLOT(hide()));
283 void ConfigLineEdit::show(ConfigItem* i)
286 if (sym_get_string_value(item->menu->sym))
287 setText(QString::fromLocal8Bit(sym_get_string_value(item->menu->sym)));
289 setText(QString::null);
294 void ConfigLineEdit::keyPressEvent(QKeyEvent* e)
301 sym_set_string_value(item->menu->sym, text().latin1());
302 parent()->updateList(item);
305 Parent::keyPressEvent(e);
309 parent()->list->setFocus();
313 ConfigList::ConfigList(ConfigView* p, const char *name)
316 symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no),
317 choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no),
318 menuPix(xpm_menu), menuInvPix(xpm_menu_inv), menuBackPix(xpm_menuback), voidPix(xpm_void),
319 showAll(false), showName(false), showRange(false), showData(false),
320 rootEntry(0), headerPopup(0)
325 setRootIsDecorated(TRUE);
326 disabledColorGroup = palette().active();
327 disabledColorGroup.setColor(QColorGroup::Text, palette().disabled().text());
328 inactivedColorGroup = palette().active();
329 inactivedColorGroup.setColor(QColorGroup::Highlight, palette().disabled().highlight());
331 connect(this, SIGNAL(selectionChanged(void)),
332 SLOT(updateSelection(void)));
335 configSettings->beginGroup(name);
336 showAll = configSettings->readBoolEntry("/showAll", false);
337 showName = configSettings->readBoolEntry("/showName", false);
338 showRange = configSettings->readBoolEntry("/showRange", false);
339 showData = configSettings->readBoolEntry("/showData", false);
340 configSettings->endGroup();
341 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
344 for (i = 0; i < colNr; i++)
345 colMap[i] = colRevMap[i] = -1;
346 addColumn(promptColIdx, "Option");
351 void ConfigList::reinit(void)
353 removeColumn(dataColIdx);
354 removeColumn(yesColIdx);
355 removeColumn(modColIdx);
356 removeColumn(noColIdx);
357 removeColumn(nameColIdx);
360 addColumn(nameColIdx, "Name");
362 addColumn(noColIdx, "N");
363 addColumn(modColIdx, "M");
364 addColumn(yesColIdx, "Y");
367 addColumn(dataColIdx, "Value");
372 void ConfigList::saveSettings(void)
375 configSettings->beginGroup(name());
376 configSettings->writeEntry("/showName", showName);
377 configSettings->writeEntry("/showRange", showRange);
378 configSettings->writeEntry("/showData", showData);
379 configSettings->writeEntry("/showAll", showAll);
380 configSettings->endGroup();
384 void ConfigList::updateSelection(void)
389 ConfigItem* item = (ConfigItem*)selectedItem();
394 emit menuChanged(menu);
397 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
398 if (mode == menuMode && type == P_MENU)
399 emit menuSelected(menu);
402 void ConfigList::updateList(ConfigItem* item)
404 ConfigItem* last = 0;
407 if (mode != listMode)
409 QListViewItemIterator it(this);
412 for (; it.current(); ++it) {
413 item = (ConfigItem*)it.current();
416 item->testUpdateMenu(menu_is_visible(item->menu));
421 if (rootEntry != &rootmenu && (mode == singleMode ||
422 (mode == symbolMode && rootEntry->parent != &rootmenu))) {
425 item = new ConfigItem(this, 0, true);
428 if ((mode == singleMode || (mode == symbolMode && !(rootEntry->flags & MENU_ROOT))) &&
429 rootEntry->sym && rootEntry->prompt) {
430 item = last ? last->nextSibling() : firstChild();
432 item = new ConfigItem(this, last, rootEntry, true);
434 item->testUpdateMenu(true);
436 updateMenuList(item, rootEntry);
441 updateMenuList(this, rootEntry);
445 void ConfigList::setValue(ConfigItem* item, tristate val)
451 sym = item->menu ? item->menu->sym : 0;
455 type = sym_get_type(sym);
459 oldval = sym_get_tristate_value(sym);
461 if (!sym_set_tristate_value(sym, val))
463 if (oldval == no && item->menu->list)
465 parent()->updateList(item);
470 void ConfigList::changeValue(ConfigItem* item)
474 int type, oldexpr, newexpr;
481 if (item->menu->list)
482 item->setOpen(!item->isOpen());
486 type = sym_get_type(sym);
490 oldexpr = sym_get_tristate_value(sym);
491 newexpr = sym_toggle_tristate_value(sym);
492 if (item->menu->list) {
493 if (oldexpr == newexpr)
494 item->setOpen(!item->isOpen());
495 else if (oldexpr == no)
498 if (oldexpr != newexpr)
499 parent()->updateList(item);
504 #if QT_VERSION >= 300
505 if (colMap[dataColIdx] >= 0)
506 item->startRename(colMap[dataColIdx]);
509 parent()->lineEdit->show(item);
514 void ConfigList::setRootMenu(struct menu *menu)
518 if (rootEntry == menu)
520 type = menu && menu->prompt ? menu->prompt->type : P_UNKNOWN;
523 updateMenuList(this, 0);
526 setSelected(currentItem(), hasFocus());
529 void ConfigList::setParentMenu(void)
532 struct menu *oldroot;
535 if (rootEntry == &rootmenu)
537 setRootMenu(menu_get_parent_menu(rootEntry->parent));
539 QListViewItemIterator it(this);
540 for (; (item = (ConfigItem*)it.current()); it++) {
541 if (item->menu == oldroot) {
542 setCurrentItem(item);
543 ensureItemVisible(item);
550 * update all the children of a menu entry
551 * removes/adds the entries from the parent widget as necessary
553 * parent: either the menu list widget or a menu entry widget
554 * menu: entry to be updated
557 void ConfigList::updateMenuList(P* parent, struct menu* menu)
566 while ((item = parent->firstChild()))
571 last = parent->firstChild();
572 if (last && !last->goParent)
574 for (child = menu->list; child; child = child->next) {
575 item = last ? last->nextSibling() : parent->firstChild();
576 type = child->prompt ? child->prompt->type : P_UNKNOWN;
580 if (!(child->flags & MENU_ROOT))
584 if (child->flags & MENU_ROOT)
591 visible = menu_is_visible(child);
592 if (showAll || visible) {
593 if (!item || item->menu != child)
594 item = new ConfigItem(parent, last, child, visible);
596 item->testUpdateMenu(visible);
598 if (mode == fullMode || mode == menuMode || type != P_MENU)
599 updateMenuList(item, child);
601 updateMenuList(item, 0);
606 if (item && item->menu == child) {
607 last = parent->firstChild();
610 else while (last->nextSibling() != item)
611 last = last->nextSibling();
617 void ConfigList::keyPressEvent(QKeyEvent* ev)
619 QListViewItem* i = currentItem();
624 if (ev->key() == Key_Escape && mode != fullMode && mode != listMode) {
625 emit parentSelected();
631 Parent::keyPressEvent(ev);
634 item = (ConfigItem*)i;
639 if (item->goParent) {
640 emit parentSelected();
646 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
647 if (type == P_MENU && rootEntry != menu &&
648 mode != fullMode && mode != menuMode) {
649 emit menuSelected(menu);
665 Parent::keyPressEvent(ev);
671 void ConfigList::contentsMousePressEvent(QMouseEvent* e)
673 //QPoint p(contentsToViewport(e->pos()));
674 //printf("contentsMousePressEvent: %d,%d\n", p.x(), p.y());
675 Parent::contentsMousePressEvent(e);
678 void ConfigList::contentsMouseReleaseEvent(QMouseEvent* e)
680 QPoint p(contentsToViewport(e->pos()));
681 ConfigItem* item = (ConfigItem*)itemAt(p);
683 enum prop_type ptype;
691 x = header()->offset() + p.x();
692 idx = colRevMap[header()->sectionAt(x)];
695 pm = item->pixmap(promptColIdx);
697 int off = header()->sectionPos(0) + itemMargin() +
698 treeStepSize() * (item->depth() + (rootIsDecorated() ? 1 : 0));
699 if (x >= off && x < off + pm->width()) {
700 if (item->goParent) {
701 emit parentSelected();
705 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
706 if (ptype == P_MENU && rootEntry != menu &&
707 mode != fullMode && mode != menuMode)
708 emit menuSelected(menu);
729 //printf("contentsMouseReleaseEvent: %d,%d\n", p.x(), p.y());
730 Parent::contentsMouseReleaseEvent(e);
733 void ConfigList::contentsMouseMoveEvent(QMouseEvent* e)
735 //QPoint p(contentsToViewport(e->pos()));
736 //printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y());
737 Parent::contentsMouseMoveEvent(e);
740 void ConfigList::contentsMouseDoubleClickEvent(QMouseEvent* e)
742 QPoint p(contentsToViewport(e->pos()));
743 ConfigItem* item = (ConfigItem*)itemAt(p);
745 enum prop_type ptype;
749 if (item->goParent) {
750 emit parentSelected();
756 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
757 if (ptype == P_MENU && (mode == singleMode || mode == symbolMode))
758 emit menuSelected(menu);
763 //printf("contentsMouseDoubleClickEvent: %d,%d\n", p.x(), p.y());
764 Parent::contentsMouseDoubleClickEvent(e);
767 void ConfigList::focusInEvent(QFocusEvent *e)
769 Parent::focusInEvent(e);
771 QListViewItem* item = currentItem();
775 setSelected(item, TRUE);
779 void ConfigList::contextMenuEvent(QContextMenuEvent *e)
781 if (e->y() <= header()->geometry().bottom()) {
785 headerPopup = new QPopupMenu(this);
786 action = new QAction("Show Name", 0, this);
787 action->setToggleAction(TRUE);
788 connect(action, SIGNAL(toggled(bool)),
789 parent(), SLOT(setShowName(bool)));
790 connect(parent(), SIGNAL(showNameChanged(bool)),
791 action, SLOT(setOn(bool)));
792 action->setOn(showName);
793 action->addTo(headerPopup);
794 action = new QAction("Show Range", 0, this);
795 action->setToggleAction(TRUE);
796 connect(action, SIGNAL(toggled(bool)),
797 parent(), SLOT(setShowRange(bool)));
798 connect(parent(), SIGNAL(showRangeChanged(bool)),
799 action, SLOT(setOn(bool)));
800 action->setOn(showRange);
801 action->addTo(headerPopup);
802 action = new QAction("Show Data", 0, this);
803 action->setToggleAction(TRUE);
804 connect(action, SIGNAL(toggled(bool)),
805 parent(), SLOT(setShowData(bool)));
806 connect(parent(), SIGNAL(showDataChanged(bool)),
807 action, SLOT(setOn(bool)));
808 action->setOn(showData);
809 action->addTo(headerPopup);
811 headerPopup->exec(e->globalPos());
817 ConfigView* ConfigView::viewList;
819 ConfigView::ConfigView(QWidget* parent, const char *name)
820 : Parent(parent, name)
822 list = new ConfigList(this, name);
823 lineEdit = new ConfigLineEdit(this);
826 this->nextView = viewList;
830 ConfigView::~ConfigView(void)
834 for (vp = &viewList; *vp; vp = &(*vp)->nextView) {
842 void ConfigView::setShowAll(bool b)
844 if (list->showAll != b) {
846 list->updateListAll();
847 emit showAllChanged(b);
851 void ConfigView::setShowName(bool b)
853 if (list->showName != b) {
856 emit showNameChanged(b);
860 void ConfigView::setShowRange(bool b)
862 if (list->showRange != b) {
865 emit showRangeChanged(b);
869 void ConfigView::setShowData(bool b)
871 if (list->showData != b) {
874 emit showDataChanged(b);
878 void ConfigList::setAllOpen(bool open)
880 QListViewItemIterator it(this);
882 for (; it.current(); it++)
883 it.current()->setOpen(open);
886 void ConfigView::updateList(ConfigItem* item)
890 for (v = viewList; v; v = v->nextView)
891 v->list->updateList(item);
894 void ConfigView::updateListAll(void)
898 for (v = viewList; v; v = v->nextView)
899 v->list->updateListAll();
902 ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name)
903 : Parent(parent, name), menu(0)
906 configSettings->beginGroup(name);
907 _showDebug = configSettings->readBoolEntry("/showDebug", false);
908 configSettings->endGroup();
909 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
913 void ConfigInfoView::saveSettings(void)
916 configSettings->beginGroup(name());
917 configSettings->writeEntry("/showDebug", showDebug());
918 configSettings->endGroup();
922 void ConfigInfoView::setShowDebug(bool b)
924 if (_showDebug != b) {
930 emit showDebugChanged(b);
934 void ConfigInfoView::setInfo(struct menu *m)
943 void ConfigInfoView::setSource(const QString& name)
945 const char *p = name.latin1();
954 if (sscanf(p, "m%p", &m) == 1 && menu != m) {
962 if (sscanf(p, "s%p", &s) == 1 && sym != s) {
970 void ConfigInfoView::symbolInfo(void)
974 str += "<big>Symbol: <b>";
975 str += print_filter(sym->name);
976 str += "</b></big><br><br>value: ";
977 str += print_filter(sym_get_string_value(sym));
978 str += "<br>visibility: ";
979 str += sym->visible == yes ? "y" : sym->visible == mod ? "m" : "n";
981 str += debug_info(sym);
986 void ConfigInfoView::menuInfo(void)
989 QString head, debug, help;
995 head += print_filter(_(menu->prompt->text));
996 head += "</b></big>";
1000 head += QString().sprintf("<a href=\"s%p\">", sym);
1001 head += print_filter(sym->name);
1006 } else if (sym->name) {
1009 head += QString().sprintf("<a href=\"s%p\">", sym);
1010 head += print_filter(sym->name);
1013 head += "</b></big>";
1018 debug = debug_info(sym);
1020 help = print_filter(_(sym->help));
1021 } else if (menu->prompt) {
1023 head += print_filter(_(menu->prompt->text));
1024 head += "</b></big><br><br>";
1026 if (menu->prompt->visible.expr) {
1027 debug += " dep: ";
1028 expr_print(menu->prompt->visible.expr, expr_print_help, &debug, E_NONE);
1029 debug += "<br><br>";
1034 debug += QString().sprintf("defined at %s:%d<br><br>", menu->file->name, menu->lineno);
1036 setText(head + debug + help);
1039 QString ConfigInfoView::debug_info(struct symbol *sym)
1044 debug += print_filter(sym_type_name(sym->type));
1045 if (sym_is_choice(sym))
1046 debug += " (choice)";
1048 if (sym->rev_dep.expr) {
1049 debug += "reverse dep: ";
1050 expr_print(sym->rev_dep.expr, expr_print_help, &debug, E_NONE);
1053 for (struct property *prop = sym->prop; prop; prop = prop->next) {
1054 switch (prop->type) {
1057 debug += QString().sprintf("prompt: <a href=\"m%p\">", prop->menu);
1058 debug += print_filter(_(prop->text));
1059 debug += "</a><br>";
1062 debug += "default: ";
1063 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1067 if (sym_is_choice(sym)) {
1068 debug += "choice: ";
1069 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1074 debug += "select: ";
1075 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1080 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1084 debug += "unknown property: ";
1085 debug += prop_get_type_name(prop->type);
1088 if (prop->visible.expr) {
1089 debug += " dep: ";
1090 expr_print(prop->visible.expr, expr_print_help, &debug, E_NONE);
1099 QString ConfigInfoView::print_filter(const QString &str)
1101 QRegExp re("[<>&\"\\n]");
1103 for (int i = 0; (i = res.find(re, i)) >= 0;) {
1104 switch (res[i].latin1()) {
1106 res.replace(i, 1, "<");
1110 res.replace(i, 1, ">");
1114 res.replace(i, 1, "&");
1118 res.replace(i, 1, """);
1122 res.replace(i, 1, "<br>");
1130 void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char *str)
1132 QString* text = reinterpret_cast<QString*>(data);
1133 QString str2 = print_filter(str);
1135 if (sym && sym->name && !(sym->flags & SYMBOL_CONST)) {
1136 *text += QString().sprintf("<a href=\"s%p\">", sym);
1143 QPopupMenu* ConfigInfoView::createPopupMenu(const QPoint& pos)
1145 QPopupMenu* popup = Parent::createPopupMenu(pos);
1146 QAction* action = new QAction("Show Debug Info", 0, popup);
1147 action->setToggleAction(TRUE);
1148 connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
1149 connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool)));
1150 action->setOn(showDebug());
1151 popup->insertSeparator();
1152 action->addTo(popup);
1156 void ConfigInfoView::contentsContextMenuEvent(QContextMenuEvent *e)
1158 Parent::contentsContextMenuEvent(e);
1161 ConfigSearchWindow::ConfigSearchWindow(QWidget* parent, const char *name)
1162 : Parent(parent, name), result(NULL)
1164 setCaption("Search Config");
1166 QVBoxLayout* layout1 = new QVBoxLayout(this, 11, 6);
1167 QHBoxLayout* layout2 = new QHBoxLayout(0, 0, 6);
1168 layout2->addWidget(new QLabel("Find:", this));
1169 editField = new QLineEdit(this);
1170 connect(editField, SIGNAL(returnPressed()), SLOT(search()));
1171 layout2->addWidget(editField);
1172 searchButton = new QPushButton("Search", this);
1173 searchButton->setAutoDefault(FALSE);
1174 connect(searchButton, SIGNAL(clicked()), SLOT(search()));
1175 layout2->addWidget(searchButton);
1176 layout1->addLayout(layout2);
1178 split = new QSplitter(this);
1179 split->setOrientation(QSplitter::Vertical);
1180 list = new ConfigView(split, name);
1181 list->list->mode = listMode;
1182 info = new ConfigInfoView(split, name);
1183 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1184 info, SLOT(setInfo(struct menu *)));
1185 layout1->addWidget(split);
1188 int x, y, width, height;
1191 configSettings->beginGroup(name);
1192 width = configSettings->readNumEntry("/window width", parent->width() / 2);
1193 height = configSettings->readNumEntry("/window height", parent->height() / 2);
1194 resize(width, height);
1195 x = configSettings->readNumEntry("/window x", 0, &ok);
1197 y = configSettings->readNumEntry("/window y", 0, &ok);
1200 QValueList<int> sizes = configSettings->readSizes("/split", &ok);
1202 split->setSizes(sizes);
1203 configSettings->endGroup();
1204 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
1208 void ConfigSearchWindow::saveSettings(void)
1211 configSettings->beginGroup(name());
1212 configSettings->writeEntry("/window x", pos().x());
1213 configSettings->writeEntry("/window y", pos().y());
1214 configSettings->writeEntry("/window width", size().width());
1215 configSettings->writeEntry("/window height", size().height());
1216 configSettings->writeSizes("/split", split->sizes());
1217 configSettings->endGroup();
1221 void ConfigSearchWindow::search(void)
1224 struct property *prop;
1225 ConfigItem *lastItem = NULL;
1228 list->list->clear();
1230 result = sym_re_search(editField->text().latin1());
1233 for (p = result; *p; p++) {
1234 for_all_prompts((*p), prop)
1235 lastItem = new ConfigItem(list->list, lastItem, prop->menu,
1236 menu_is_visible(prop->menu));
1241 * Construct the complete config widget
1243 ConfigMainWindow::ConfigMainWindow(void)
1247 int x, y, width, height;
1249 QWidget *d = configApp->desktop();
1251 width = configSettings->readNumEntry("/window width", d->width() - 64);
1252 height = configSettings->readNumEntry("/window height", d->height() - 64);
1253 resize(width, height);
1254 x = configSettings->readNumEntry("/window x", 0, &ok);
1256 y = configSettings->readNumEntry("/window y", 0, &ok);
1260 split1 = new QSplitter(this);
1261 split1->setOrientation(QSplitter::Horizontal);
1262 setCentralWidget(split1);
1264 menuView = new ConfigView(split1, "menu");
1265 menuList = menuView->list;
1267 split2 = new QSplitter(split1);
1268 split2->setOrientation(QSplitter::Vertical);
1270 // create config tree
1271 configView = new ConfigView(split2, "config");
1272 configList = configView->list;
1274 helpText = new ConfigInfoView(split2, "help");
1275 helpText->setTextFormat(Qt::RichText);
1277 setTabOrder(configList, helpText);
1278 configList->setFocus();
1281 toolBar = new QToolBar("Tools", this);
1283 backAction = new QAction("Back", QPixmap(xpm_back), "Back", 0, this);
1284 connect(backAction, SIGNAL(activated()), SLOT(goBack()));
1285 backAction->setEnabled(FALSE);
1286 QAction *quitAction = new QAction("Quit", "&Quit", CTRL+Key_Q, this);
1287 connect(quitAction, SIGNAL(activated()), SLOT(close()));
1288 QAction *loadAction = new QAction("Load", QPixmap(xpm_load), "&Load", CTRL+Key_L, this);
1289 connect(loadAction, SIGNAL(activated()), SLOT(loadConfig()));
1290 QAction *saveAction = new QAction("Save", QPixmap(xpm_save), "&Save", CTRL+Key_S, this);
1291 connect(saveAction, SIGNAL(activated()), SLOT(saveConfig()));
1292 QAction *saveAsAction = new QAction("Save As...", "Save &As...", 0, this);
1293 connect(saveAsAction, SIGNAL(activated()), SLOT(saveConfigAs()));
1294 QAction *searchAction = new QAction("Search", "&Search", CTRL+Key_F, this);
1295 connect(searchAction, SIGNAL(activated()), SLOT(searchConfig()));
1296 QAction *singleViewAction = new QAction("Single View", QPixmap(xpm_single_view), "Split View", 0, this);
1297 connect(singleViewAction, SIGNAL(activated()), SLOT(showSingleView()));
1298 QAction *splitViewAction = new QAction("Split View", QPixmap(xpm_split_view), "Split View", 0, this);
1299 connect(splitViewAction, SIGNAL(activated()), SLOT(showSplitView()));
1300 QAction *fullViewAction = new QAction("Full View", QPixmap(xpm_tree_view), "Full View", 0, this);
1301 connect(fullViewAction, SIGNAL(activated()), SLOT(showFullView()));
1303 QAction *showNameAction = new QAction(NULL, "Show Name", 0, this);
1304 showNameAction->setToggleAction(TRUE);
1305 connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool)));
1306 connect(configView, SIGNAL(showNameChanged(bool)), showNameAction, SLOT(setOn(bool)));
1307 showNameAction->setOn(configView->showName());
1308 QAction *showRangeAction = new QAction(NULL, "Show Range", 0, this);
1309 showRangeAction->setToggleAction(TRUE);
1310 connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool)));
1311 connect(configView, SIGNAL(showRangeChanged(bool)), showRangeAction, SLOT(setOn(bool)));
1312 showRangeAction->setOn(configList->showRange);
1313 QAction *showDataAction = new QAction(NULL, "Show Data", 0, this);
1314 showDataAction->setToggleAction(TRUE);
1315 connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool)));
1316 connect(configView, SIGNAL(showDataChanged(bool)), showDataAction, SLOT(setOn(bool)));
1317 showDataAction->setOn(configList->showData);
1318 QAction *showAllAction = new QAction(NULL, "Show All Options", 0, this);
1319 showAllAction->setToggleAction(TRUE);
1320 connect(showAllAction, SIGNAL(toggled(bool)), configView, SLOT(setShowAll(bool)));
1321 connect(showAllAction, SIGNAL(toggled(bool)), menuView, SLOT(setShowAll(bool)));
1322 showAllAction->setOn(configList->showAll);
1323 QAction *showDebugAction = new QAction(NULL, "Show Debug Info", 0, this);
1324 showDebugAction->setToggleAction(TRUE);
1325 connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
1326 connect(helpText, SIGNAL(showDebugChanged(bool)), showDebugAction, SLOT(setOn(bool)));
1327 showDebugAction->setOn(helpText->showDebug());
1329 QAction *showIntroAction = new QAction(NULL, "Introduction", 0, this);
1330 connect(showIntroAction, SIGNAL(activated()), SLOT(showIntro()));
1331 QAction *showAboutAction = new QAction(NULL, "About", 0, this);
1332 connect(showAboutAction, SIGNAL(activated()), SLOT(showAbout()));
1335 backAction->addTo(toolBar);
1336 toolBar->addSeparator();
1337 loadAction->addTo(toolBar);
1338 saveAction->addTo(toolBar);
1339 toolBar->addSeparator();
1340 singleViewAction->addTo(toolBar);
1341 splitViewAction->addTo(toolBar);
1342 fullViewAction->addTo(toolBar);
1344 // create config menu
1345 QPopupMenu* config = new QPopupMenu(this);
1346 menu->insertItem("&File", config);
1347 loadAction->addTo(config);
1348 saveAction->addTo(config);
1349 saveAsAction->addTo(config);
1350 config->insertSeparator();
1351 searchAction->addTo(config);
1352 config->insertSeparator();
1353 quitAction->addTo(config);
1355 // create options menu
1356 QPopupMenu* optionMenu = new QPopupMenu(this);
1357 menu->insertItem("&Option", optionMenu);
1358 showNameAction->addTo(optionMenu);
1359 showRangeAction->addTo(optionMenu);
1360 showDataAction->addTo(optionMenu);
1361 optionMenu->insertSeparator();
1362 showAllAction->addTo(optionMenu);
1363 showDebugAction->addTo(optionMenu);
1366 QPopupMenu* helpMenu = new QPopupMenu(this);
1367 menu->insertSeparator();
1368 menu->insertItem("&Help", helpMenu);
1369 showIntroAction->addTo(helpMenu);
1370 showAboutAction->addTo(helpMenu);
1372 connect(configList, SIGNAL(menuChanged(struct menu *)),
1373 helpText, SLOT(setInfo(struct menu *)));
1374 connect(configList, SIGNAL(menuSelected(struct menu *)),
1375 SLOT(changeMenu(struct menu *)));
1376 connect(configList, SIGNAL(parentSelected()),
1378 connect(menuList, SIGNAL(menuChanged(struct menu *)),
1379 helpText, SLOT(setInfo(struct menu *)));
1380 connect(menuList, SIGNAL(menuSelected(struct menu *)),
1381 SLOT(changeMenu(struct menu *)));
1383 connect(configList, SIGNAL(gotFocus(void)),
1384 SLOT(listFocusChanged(void)));
1385 connect(menuList, SIGNAL(gotFocus(void)),
1386 SLOT(listFocusChanged(void)));
1388 QString listMode = configSettings->readEntry("/listMode", "symbol");
1389 if (listMode == "single")
1391 else if (listMode == "full")
1393 else /*if (listMode == "split")*/
1396 // UI setup done, restore splitter positions
1397 QValueList<int> sizes = configSettings->readSizes("/split1", &ok);
1399 split1->setSizes(sizes);
1401 sizes = configSettings->readSizes("/split2", &ok);
1403 split2->setSizes(sizes);
1407 * display a new help entry as soon as a new menu entry is selected
1409 void ConfigMainWindow::setHelp(QListViewItem* item)
1411 struct menu* menu = 0;
1414 menu = ((ConfigItem*)item)->menu;
1415 helpText->setInfo(menu);
1418 void ConfigMainWindow::loadConfig(void)
1420 QString s = QFileDialog::getOpenFileName(".config", NULL, this);
1423 if (conf_read(QFile::encodeName(s)))
1424 QMessageBox::information(this, "qconf", "Unable to load configuration!");
1425 ConfigView::updateListAll();
1428 void ConfigMainWindow::saveConfig(void)
1430 if (conf_write(NULL))
1431 QMessageBox::information(this, "qconf", "Unable to save configuration!");
1434 void ConfigMainWindow::saveConfigAs(void)
1436 QString s = QFileDialog::getSaveFileName(".config", NULL, this);
1439 if (conf_write(QFile::encodeName(s)))
1440 QMessageBox::information(this, "qconf", "Unable to save configuration!");
1443 void ConfigMainWindow::searchConfig(void)
1446 searchWindow = new ConfigSearchWindow(this, "search");
1447 searchWindow->show();
1450 void ConfigMainWindow::changeMenu(struct menu *menu)
1452 configList->setRootMenu(menu);
1453 backAction->setEnabled(TRUE);
1456 void ConfigMainWindow::listFocusChanged(void)
1458 if (menuList->hasFocus()) {
1459 if (menuList->mode == menuMode)
1460 configList->clearSelection();
1461 setHelp(menuList->selectedItem());
1462 } else if (configList->hasFocus()) {
1463 setHelp(configList->selectedItem());
1467 void ConfigMainWindow::goBack(void)
1471 configList->setParentMenu();
1472 if (configList->rootEntry == &rootmenu)
1473 backAction->setEnabled(FALSE);
1474 item = (ConfigItem*)menuList->selectedItem();
1476 if (item->menu == configList->rootEntry) {
1477 menuList->setSelected(item, TRUE);
1480 item = (ConfigItem*)item->parent();
1484 void ConfigMainWindow::showSingleView(void)
1487 menuList->setRootMenu(0);
1488 configList->mode = singleMode;
1489 if (configList->rootEntry == &rootmenu)
1490 configList->updateListAll();
1492 configList->setRootMenu(&rootmenu);
1493 configList->setAllOpen(TRUE);
1494 configList->setFocus();
1497 void ConfigMainWindow::showSplitView(void)
1499 configList->mode = symbolMode;
1500 if (configList->rootEntry == &rootmenu)
1501 configList->updateListAll();
1503 configList->setRootMenu(&rootmenu);
1504 configList->setAllOpen(TRUE);
1505 configApp->processEvents();
1506 menuList->mode = menuMode;
1507 menuList->setRootMenu(&rootmenu);
1508 menuList->setAllOpen(TRUE);
1510 menuList->setFocus();
1513 void ConfigMainWindow::showFullView(void)
1516 menuList->setRootMenu(0);
1517 configList->mode = fullMode;
1518 if (configList->rootEntry == &rootmenu)
1519 configList->updateListAll();
1521 configList->setRootMenu(&rootmenu);
1522 configList->setAllOpen(FALSE);
1523 configList->setFocus();
1527 * ask for saving configuration before quitting
1528 * TODO ask only when something changed
1530 void ConfigMainWindow::closeEvent(QCloseEvent* e)
1532 if (!sym_change_count) {
1536 QMessageBox mb("qconf", "Save configuration?", QMessageBox::Warning,
1537 QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape);
1538 mb.setButtonText(QMessageBox::Yes, "&Save Changes");
1539 mb.setButtonText(QMessageBox::No, "&Discard Changes");
1540 mb.setButtonText(QMessageBox::Cancel, "Cancel Exit");
1541 switch (mb.exec()) {
1542 case QMessageBox::Yes:
1544 case QMessageBox::No:
1547 case QMessageBox::Cancel:
1553 void ConfigMainWindow::showIntro(void)
1555 static char str[] = "Welcome to the qconf graphical kernel configuration tool for Linux.\n\n"
1556 "For each option, a blank box indicates the feature is disabled, a check\n"
1557 "indicates it is enabled, and a dot indicates that it is to be compiled\n"
1558 "as a module. Clicking on the box will cycle through the three states.\n\n"
1559 "If you do not see an option (e.g., a device driver) that you believe\n"
1560 "should be present, try turning on Show All Options under the Options menu.\n"
1561 "Although there is no cross reference yet to help you figure out what other\n"
1562 "options must be enabled to support the option you are interested in, you can\n"
1563 "still view the help of a grayed-out option.\n\n"
1564 "Toggling Show Debug Info under the Options menu will show the dependencies,\n"
1565 "which you can then match by examining other options.\n\n";
1567 QMessageBox::information(this, "qconf", str);
1570 void ConfigMainWindow::showAbout(void)
1572 static char str[] = "qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n\n"
1573 "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n";
1575 QMessageBox::information(this, "qconf", str);
1578 void ConfigMainWindow::saveSettings(void)
1580 configSettings->writeEntry("/window x", pos().x());
1581 configSettings->writeEntry("/window y", pos().y());
1582 configSettings->writeEntry("/window width", size().width());
1583 configSettings->writeEntry("/window height", size().height());
1586 switch(configList->mode) {
1599 configSettings->writeEntry("/listMode", entry);
1601 configSettings->writeSizes("/split1", split1->sizes());
1602 configSettings->writeSizes("/split2", split2->sizes());
1605 void fixup_rootmenu(struct menu *menu)
1608 static int menu_cnt = 0;
1610 menu->flags |= MENU_ROOT;
1611 for (child = menu->list; child; child = child->next) {
1612 if (child->prompt && child->prompt->type == P_MENU) {
1614 fixup_rootmenu(child);
1616 } else if (!menu_cnt)
1617 fixup_rootmenu(child);
1621 static const char *progname;
1623 static void usage(void)
1625 printf("%s <config>\n", progname);
1629 int main(int ac, char** av)
1631 ConfigMainWindow* v;
1634 bindtextdomain(PACKAGE, LOCALEDIR);
1635 textdomain(PACKAGE);
1637 #ifndef LKC_DIRECT_LINK
1642 configApp = new QApplication(ac, av);
1643 if (ac > 1 && av[1][0] == '-') {
1656 fixup_rootmenu(&rootmenu);
1658 //zconfdump(stdout);
1660 configSettings = new ConfigSettings();
1661 configSettings->beginGroup("/kconfig/qconf");
1662 v = new ConfigMainWindow();
1664 //zconfdump(stdout);
1665 configApp->setMainWidget(v);
1666 configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit()));
1667 configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings()));
1671 configSettings->endGroup();
1672 delete configSettings;