2 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
3 * Released under the terms of the GNU GPL v2.0.
6 #include <qapplication.h>
7 #include <qmainwindow.h>
11 #include <qsplitter.h>
12 #include <qlistview.h>
13 #include <qtextbrowser.h>
14 #include <qlineedit.h>
16 #include <qpushbutton.h>
18 #include <qmessagebox.h>
21 #include <qfiledialog.h>
22 #include <qdragobject.h>
38 static QApplication *configApp;
39 static ConfigSettings *configSettings;
41 QAction *ConfigMainWindow::saveAction;
43 static inline QString qgettext(const char* str)
45 return QString::fromLocal8Bit(gettext(str));
48 static inline QString qgettext(const QString& str)
50 return QString::fromLocal8Bit(gettext(str.latin1()));
54 * Reads a list of integer values from the application settings.
56 QValueList<int> ConfigSettings::readSizes(const QString& key, bool *ok)
58 QValueList<int> result;
59 QStringList entryList = readListEntry(key, ok);
61 QStringList::Iterator it;
62 for (it = entryList.begin(); it != entryList.end(); ++it)
63 result.push_back((*it).toInt());
70 * Writes a list of integer values to the application settings.
72 bool ConfigSettings::writeSizes(const QString& key, const QValueList<int>& value)
74 QStringList stringList;
75 QValueList<int>::ConstIterator it;
77 for (it = value.begin(); it != value.end(); ++it)
78 stringList.push_back(QString::number(*it));
79 return writeEntry(key, stringList);
86 * TODO check the value
88 void ConfigItem::okRename(int col)
90 Parent::okRename(col);
91 sym_set_string_value(menu->sym, text(dataColIdx).latin1());
92 listView()->updateList(this);
97 * update the displayed of a menu entry
99 void ConfigItem::updateMenu(void)
103 struct property *prop;
110 setPixmap(promptColIdx, list->menuBackPix);
117 prompt = QString::fromLocal8Bit(menu_get_prompt(menu));
119 if (prop) switch (prop->type) {
121 if (list->mode == singleMode || list->mode == symbolMode) {
122 /* a menuconfig entry is displayed differently
123 * depending whether it's at the view root or a child.
125 if (sym && list->rootEntry == menu)
127 setPixmap(promptColIdx, list->menuPix);
131 setPixmap(promptColIdx, 0);
135 setPixmap(promptColIdx, 0);
143 setText(nameColIdx, QString::fromLocal8Bit(sym->name));
145 type = sym_get_type(sym);
151 if (!sym_is_changable(sym) && !list->showAll) {
152 setPixmap(promptColIdx, 0);
153 setText(noColIdx, QString::null);
154 setText(modColIdx, QString::null);
155 setText(yesColIdx, QString::null);
158 expr = sym_get_tristate_value(sym);
161 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
162 setPixmap(promptColIdx, list->choiceYesPix);
164 setPixmap(promptColIdx, list->symbolYesPix);
165 setText(yesColIdx, "Y");
169 setPixmap(promptColIdx, list->symbolModPix);
170 setText(modColIdx, "M");
174 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
175 setPixmap(promptColIdx, list->choiceNoPix);
177 setPixmap(promptColIdx, list->symbolNoPix);
178 setText(noColIdx, "N");
183 setText(noColIdx, sym_tristate_within_range(sym, no) ? "_" : 0);
185 setText(modColIdx, sym_tristate_within_range(sym, mod) ? "_" : 0);
187 setText(yesColIdx, sym_tristate_within_range(sym, yes) ? "_" : 0);
189 setText(dataColIdx, QChar(ch));
196 data = sym_get_string_value(sym);
198 #if QT_VERSION >= 300
199 int i = list->mapIdx(dataColIdx);
201 setRenameEnabled(i, TRUE);
203 setText(dataColIdx, data);
204 if (type == S_STRING)
205 prompt = QString("%1: %2").arg(prompt).arg(data);
207 prompt = QString("(%2) %1").arg(prompt).arg(data);
210 if (!sym_has_value(sym) && visible)
213 setText(promptColIdx, prompt);
216 void ConfigItem::testUpdateMenu(bool v)
224 sym_calc_value(menu->sym);
225 if (menu->flags & MENU_CHANGED) {
226 /* the menu entry changed, so update all list items */
227 menu->flags &= ~MENU_CHANGED;
228 for (i = (ConfigItem*)menu->data; i; i = i->nextItem)
230 } else if (listView()->updateAll)
234 void ConfigItem::paintCell(QPainter* p, const QColorGroup& cg, int column, int width, int align)
236 ConfigList* list = listView();
239 if (isSelected() && !list->hasFocus() && list->mode == menuMode)
240 Parent::paintCell(p, list->inactivedColorGroup, column, width, align);
242 Parent::paintCell(p, cg, column, width, align);
244 Parent::paintCell(p, list->disabledColorGroup, column, width, align);
248 * construct a menu entry
250 void ConfigItem::init(void)
253 ConfigList* list = listView();
254 nextItem = (ConfigItem*)menu->data;
257 if (list->mode != fullMode)
259 sym_calc_value(menu->sym);
265 * destruct a menu entry
267 ConfigItem::~ConfigItem(void)
270 ConfigItem** ip = (ConfigItem**)&menu->data;
271 for (; *ip; ip = &(*ip)->nextItem) {
280 ConfigLineEdit::ConfigLineEdit(ConfigView* parent)
283 connect(this, SIGNAL(lostFocus()), SLOT(hide()));
286 void ConfigLineEdit::show(ConfigItem* i)
289 if (sym_get_string_value(item->menu->sym))
290 setText(QString::fromLocal8Bit(sym_get_string_value(item->menu->sym)));
292 setText(QString::null);
297 void ConfigLineEdit::keyPressEvent(QKeyEvent* e)
304 sym_set_string_value(item->menu->sym, text().latin1());
305 parent()->updateList(item);
308 Parent::keyPressEvent(e);
312 parent()->list->setFocus();
316 ConfigList::ConfigList(ConfigView* p, const char *name)
319 symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no),
320 choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no),
321 menuPix(xpm_menu), menuInvPix(xpm_menu_inv), menuBackPix(xpm_menuback), voidPix(xpm_void),
322 showAll(false), showName(false), showRange(false), showData(false),
323 rootEntry(0), headerPopup(0)
328 setRootIsDecorated(TRUE);
329 disabledColorGroup = palette().active();
330 disabledColorGroup.setColor(QColorGroup::Text, palette().disabled().text());
331 inactivedColorGroup = palette().active();
332 inactivedColorGroup.setColor(QColorGroup::Highlight, palette().disabled().highlight());
334 connect(this, SIGNAL(selectionChanged(void)),
335 SLOT(updateSelection(void)));
338 configSettings->beginGroup(name);
339 showAll = configSettings->readBoolEntry("/showAll", false);
340 showName = configSettings->readBoolEntry("/showName", false);
341 showRange = configSettings->readBoolEntry("/showRange", false);
342 showData = configSettings->readBoolEntry("/showData", false);
343 configSettings->endGroup();
344 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
347 for (i = 0; i < colNr; i++)
348 colMap[i] = colRevMap[i] = -1;
349 addColumn(promptColIdx, "Option");
354 void ConfigList::reinit(void)
356 removeColumn(dataColIdx);
357 removeColumn(yesColIdx);
358 removeColumn(modColIdx);
359 removeColumn(noColIdx);
360 removeColumn(nameColIdx);
363 addColumn(nameColIdx, "Name");
365 addColumn(noColIdx, "N");
366 addColumn(modColIdx, "M");
367 addColumn(yesColIdx, "Y");
370 addColumn(dataColIdx, "Value");
375 void ConfigList::saveSettings(void)
378 configSettings->beginGroup(name());
379 configSettings->writeEntry("/showName", showName);
380 configSettings->writeEntry("/showRange", showRange);
381 configSettings->writeEntry("/showData", showData);
382 configSettings->writeEntry("/showAll", showAll);
383 configSettings->endGroup();
387 ConfigItem* ConfigList::findConfigItem(struct menu *menu)
389 ConfigItem* item = (ConfigItem*)menu->data;
391 for (; item; item = item->nextItem) {
392 if (this == item->listView())
399 void ConfigList::updateSelection(void)
404 ConfigItem* item = (ConfigItem*)selectedItem();
409 emit menuChanged(menu);
412 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
413 if (mode == menuMode && type == P_MENU)
414 emit menuSelected(menu);
417 void ConfigList::updateList(ConfigItem* item)
419 ConfigItem* last = 0;
422 if (mode != listMode)
424 QListViewItemIterator it(this);
427 for (; it.current(); ++it) {
428 item = (ConfigItem*)it.current();
431 item->testUpdateMenu(menu_is_visible(item->menu));
436 if (rootEntry != &rootmenu && (mode == singleMode ||
437 (mode == symbolMode && rootEntry->parent != &rootmenu))) {
440 item = new ConfigItem(this, 0, true);
443 if ((mode == singleMode || (mode == symbolMode && !(rootEntry->flags & MENU_ROOT))) &&
444 rootEntry->sym && rootEntry->prompt) {
445 item = last ? last->nextSibling() : firstChild();
447 item = new ConfigItem(this, last, rootEntry, true);
449 item->testUpdateMenu(true);
451 updateMenuList(item, rootEntry);
456 updateMenuList(this, rootEntry);
460 void ConfigList::setValue(ConfigItem* item, tristate val)
466 sym = item->menu ? item->menu->sym : 0;
470 type = sym_get_type(sym);
474 oldval = sym_get_tristate_value(sym);
476 if (!sym_set_tristate_value(sym, val))
478 if (oldval == no && item->menu->list)
480 parent()->updateList(item);
485 void ConfigList::changeValue(ConfigItem* item)
489 int type, oldexpr, newexpr;
496 if (item->menu->list)
497 item->setOpen(!item->isOpen());
501 type = sym_get_type(sym);
505 oldexpr = sym_get_tristate_value(sym);
506 newexpr = sym_toggle_tristate_value(sym);
507 if (item->menu->list) {
508 if (oldexpr == newexpr)
509 item->setOpen(!item->isOpen());
510 else if (oldexpr == no)
513 if (oldexpr != newexpr)
514 parent()->updateList(item);
519 #if QT_VERSION >= 300
520 if (colMap[dataColIdx] >= 0)
521 item->startRename(colMap[dataColIdx]);
524 parent()->lineEdit->show(item);
529 void ConfigList::setRootMenu(struct menu *menu)
533 if (rootEntry == menu)
535 type = menu && menu->prompt ? menu->prompt->type : P_UNKNOWN;
538 updateMenuList(this, 0);
541 setSelected(currentItem(), hasFocus());
542 ensureItemVisible(currentItem());
545 void ConfigList::setParentMenu(void)
548 struct menu *oldroot;
551 if (rootEntry == &rootmenu)
553 setRootMenu(menu_get_parent_menu(rootEntry->parent));
555 QListViewItemIterator it(this);
556 for (; (item = (ConfigItem*)it.current()); it++) {
557 if (item->menu == oldroot) {
558 setCurrentItem(item);
559 ensureItemVisible(item);
566 * update all the children of a menu entry
567 * removes/adds the entries from the parent widget as necessary
569 * parent: either the menu list widget or a menu entry widget
570 * menu: entry to be updated
573 void ConfigList::updateMenuList(P* parent, struct menu* menu)
582 while ((item = parent->firstChild()))
587 last = parent->firstChild();
588 if (last && !last->goParent)
590 for (child = menu->list; child; child = child->next) {
591 item = last ? last->nextSibling() : parent->firstChild();
592 type = child->prompt ? child->prompt->type : P_UNKNOWN;
596 if (!(child->flags & MENU_ROOT))
600 if (child->flags & MENU_ROOT)
607 visible = menu_is_visible(child);
608 if (showAll || visible) {
609 if (!item || item->menu != child)
610 item = new ConfigItem(parent, last, child, visible);
612 item->testUpdateMenu(visible);
614 if (mode == fullMode || mode == menuMode || type != P_MENU)
615 updateMenuList(item, child);
617 updateMenuList(item, 0);
622 if (item && item->menu == child) {
623 last = parent->firstChild();
626 else while (last->nextSibling() != item)
627 last = last->nextSibling();
633 void ConfigList::keyPressEvent(QKeyEvent* ev)
635 QListViewItem* i = currentItem();
640 if (ev->key() == Key_Escape && mode != fullMode && mode != listMode) {
641 emit parentSelected();
647 Parent::keyPressEvent(ev);
650 item = (ConfigItem*)i;
655 if (item->goParent) {
656 emit parentSelected();
662 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
663 if (type == P_MENU && rootEntry != menu &&
664 mode != fullMode && mode != menuMode) {
665 emit menuSelected(menu);
681 Parent::keyPressEvent(ev);
687 void ConfigList::contentsMousePressEvent(QMouseEvent* e)
689 //QPoint p(contentsToViewport(e->pos()));
690 //printf("contentsMousePressEvent: %d,%d\n", p.x(), p.y());
691 Parent::contentsMousePressEvent(e);
694 void ConfigList::contentsMouseReleaseEvent(QMouseEvent* e)
696 QPoint p(contentsToViewport(e->pos()));
697 ConfigItem* item = (ConfigItem*)itemAt(p);
699 enum prop_type ptype;
707 x = header()->offset() + p.x();
708 idx = colRevMap[header()->sectionAt(x)];
711 pm = item->pixmap(promptColIdx);
713 int off = header()->sectionPos(0) + itemMargin() +
714 treeStepSize() * (item->depth() + (rootIsDecorated() ? 1 : 0));
715 if (x >= off && x < off + pm->width()) {
716 if (item->goParent) {
717 emit parentSelected();
721 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
722 if (ptype == P_MENU && rootEntry != menu &&
723 mode != fullMode && mode != menuMode)
724 emit menuSelected(menu);
745 //printf("contentsMouseReleaseEvent: %d,%d\n", p.x(), p.y());
746 Parent::contentsMouseReleaseEvent(e);
749 void ConfigList::contentsMouseMoveEvent(QMouseEvent* e)
751 //QPoint p(contentsToViewport(e->pos()));
752 //printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y());
753 Parent::contentsMouseMoveEvent(e);
756 void ConfigList::contentsMouseDoubleClickEvent(QMouseEvent* e)
758 QPoint p(contentsToViewport(e->pos()));
759 ConfigItem* item = (ConfigItem*)itemAt(p);
761 enum prop_type ptype;
765 if (item->goParent) {
766 emit parentSelected();
772 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
773 if (ptype == P_MENU && (mode == singleMode || mode == symbolMode))
774 emit menuSelected(menu);
779 //printf("contentsMouseDoubleClickEvent: %d,%d\n", p.x(), p.y());
780 Parent::contentsMouseDoubleClickEvent(e);
783 void ConfigList::focusInEvent(QFocusEvent *e)
785 struct menu *menu = NULL;
787 Parent::focusInEvent(e);
789 ConfigItem* item = (ConfigItem *)currentItem();
791 setSelected(item, TRUE);
797 void ConfigList::contextMenuEvent(QContextMenuEvent *e)
799 if (e->y() <= header()->geometry().bottom()) {
803 headerPopup = new QPopupMenu(this);
804 action = new QAction(NULL, "Show Name", 0, this);
805 action->setToggleAction(TRUE);
806 connect(action, SIGNAL(toggled(bool)),
807 parent(), SLOT(setShowName(bool)));
808 connect(parent(), SIGNAL(showNameChanged(bool)),
809 action, SLOT(setOn(bool)));
810 action->setOn(showName);
811 action->addTo(headerPopup);
812 action = new QAction(NULL, "Show Range", 0, this);
813 action->setToggleAction(TRUE);
814 connect(action, SIGNAL(toggled(bool)),
815 parent(), SLOT(setShowRange(bool)));
816 connect(parent(), SIGNAL(showRangeChanged(bool)),
817 action, SLOT(setOn(bool)));
818 action->setOn(showRange);
819 action->addTo(headerPopup);
820 action = new QAction(NULL, "Show Data", 0, this);
821 action->setToggleAction(TRUE);
822 connect(action, SIGNAL(toggled(bool)),
823 parent(), SLOT(setShowData(bool)));
824 connect(parent(), SIGNAL(showDataChanged(bool)),
825 action, SLOT(setOn(bool)));
826 action->setOn(showData);
827 action->addTo(headerPopup);
829 headerPopup->exec(e->globalPos());
835 ConfigView* ConfigView::viewList;
837 ConfigView::ConfigView(QWidget* parent, const char *name)
838 : Parent(parent, name)
840 list = new ConfigList(this, name);
841 lineEdit = new ConfigLineEdit(this);
844 this->nextView = viewList;
848 ConfigView::~ConfigView(void)
852 for (vp = &viewList; *vp; vp = &(*vp)->nextView) {
860 void ConfigView::setShowAll(bool b)
862 if (list->showAll != b) {
864 list->updateListAll();
865 emit showAllChanged(b);
869 void ConfigView::setShowName(bool b)
871 if (list->showName != b) {
874 emit showNameChanged(b);
878 void ConfigView::setShowRange(bool b)
880 if (list->showRange != b) {
883 emit showRangeChanged(b);
887 void ConfigView::setShowData(bool b)
889 if (list->showData != b) {
892 emit showDataChanged(b);
896 void ConfigList::setAllOpen(bool open)
898 QListViewItemIterator it(this);
900 for (; it.current(); it++)
901 it.current()->setOpen(open);
904 void ConfigView::updateList(ConfigItem* item)
908 for (v = viewList; v; v = v->nextView)
909 v->list->updateList(item);
912 void ConfigView::updateListAll(void)
916 for (v = viewList; v; v = v->nextView)
917 v->list->updateListAll();
920 ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name)
921 : Parent(parent, name), menu(0), sym(0)
924 configSettings->beginGroup(name);
925 _showDebug = configSettings->readBoolEntry("/showDebug", false);
926 configSettings->endGroup();
927 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
931 void ConfigInfoView::saveSettings(void)
934 configSettings->beginGroup(name());
935 configSettings->writeEntry("/showDebug", showDebug());
936 configSettings->endGroup();
940 void ConfigInfoView::setShowDebug(bool b)
942 if (_showDebug != b) {
948 emit showDebugChanged(b);
952 void ConfigInfoView::setInfo(struct menu *m)
964 void ConfigInfoView::setSource(const QString& name)
966 const char *p = name.latin1();
975 if (sscanf(p, "m%p", &m) == 1 && menu != m) {
978 emit menuSelected(menu);
984 if (sscanf(p, "s%p", &s) == 1 && sym != s) {
992 void ConfigInfoView::symbolInfo(void)
996 str += "<big>Symbol: <b>";
997 str += print_filter(sym->name);
998 str += "</b></big><br><br>value: ";
999 str += print_filter(sym_get_string_value(sym));
1000 str += "<br>visibility: ";
1001 str += sym->visible == yes ? "y" : sym->visible == mod ? "m" : "n";
1003 str += debug_info(sym);
1008 void ConfigInfoView::menuInfo(void)
1011 QString head, debug, help;
1017 head += print_filter(_(menu->prompt->text));
1018 head += "</b></big>";
1022 head += QString().sprintf("<a href=\"s%p\">", sym);
1023 head += print_filter(sym->name);
1028 } else if (sym->name) {
1031 head += QString().sprintf("<a href=\"s%p\">", sym);
1032 head += print_filter(sym->name);
1035 head += "</b></big>";
1040 debug = debug_info(sym);
1042 help = print_filter(_(sym->help));
1043 } else if (menu->prompt) {
1045 head += print_filter(_(menu->prompt->text));
1046 head += "</b></big><br><br>";
1048 if (menu->prompt->visible.expr) {
1049 debug += " dep: ";
1050 expr_print(menu->prompt->visible.expr, expr_print_help, &debug, E_NONE);
1051 debug += "<br><br>";
1056 debug += QString().sprintf("defined at %s:%d<br><br>", menu->file->name, menu->lineno);
1058 setText(head + debug + help);
1061 QString ConfigInfoView::debug_info(struct symbol *sym)
1066 debug += print_filter(sym_type_name(sym->type));
1067 if (sym_is_choice(sym))
1068 debug += " (choice)";
1070 if (sym->rev_dep.expr) {
1071 debug += "reverse dep: ";
1072 expr_print(sym->rev_dep.expr, expr_print_help, &debug, E_NONE);
1075 for (struct property *prop = sym->prop; prop; prop = prop->next) {
1076 switch (prop->type) {
1079 debug += QString().sprintf("prompt: <a href=\"m%p\">", prop->menu);
1080 debug += print_filter(_(prop->text));
1081 debug += "</a><br>";
1084 debug += "default: ";
1085 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1089 if (sym_is_choice(sym)) {
1090 debug += "choice: ";
1091 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1096 debug += "select: ";
1097 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1102 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1106 debug += "unknown property: ";
1107 debug += prop_get_type_name(prop->type);
1110 if (prop->visible.expr) {
1111 debug += " dep: ";
1112 expr_print(prop->visible.expr, expr_print_help, &debug, E_NONE);
1121 QString ConfigInfoView::print_filter(const QString &str)
1123 QRegExp re("[<>&\"\\n]");
1125 for (int i = 0; (i = res.find(re, i)) >= 0;) {
1126 switch (res[i].latin1()) {
1128 res.replace(i, 1, "<");
1132 res.replace(i, 1, ">");
1136 res.replace(i, 1, "&");
1140 res.replace(i, 1, """);
1144 res.replace(i, 1, "<br>");
1152 void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char *str)
1154 QString* text = reinterpret_cast<QString*>(data);
1155 QString str2 = print_filter(str);
1157 if (sym && sym->name && !(sym->flags & SYMBOL_CONST)) {
1158 *text += QString().sprintf("<a href=\"s%p\">", sym);
1165 QPopupMenu* ConfigInfoView::createPopupMenu(const QPoint& pos)
1167 QPopupMenu* popup = Parent::createPopupMenu(pos);
1168 QAction* action = new QAction(NULL,"Show Debug Info", 0, popup);
1169 action->setToggleAction(TRUE);
1170 connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
1171 connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool)));
1172 action->setOn(showDebug());
1173 popup->insertSeparator();
1174 action->addTo(popup);
1178 void ConfigInfoView::contentsContextMenuEvent(QContextMenuEvent *e)
1180 Parent::contentsContextMenuEvent(e);
1183 ConfigSearchWindow::ConfigSearchWindow(QWidget* parent, const char *name)
1184 : Parent(parent, name), result(NULL)
1186 setCaption("Search Config");
1188 QVBoxLayout* layout1 = new QVBoxLayout(this, 11, 6);
1189 QHBoxLayout* layout2 = new QHBoxLayout(0, 0, 6);
1190 layout2->addWidget(new QLabel("Find:", this));
1191 editField = new QLineEdit(this);
1192 connect(editField, SIGNAL(returnPressed()), SLOT(search()));
1193 layout2->addWidget(editField);
1194 searchButton = new QPushButton("Search", this);
1195 searchButton->setAutoDefault(FALSE);
1196 connect(searchButton, SIGNAL(clicked()), SLOT(search()));
1197 layout2->addWidget(searchButton);
1198 layout1->addLayout(layout2);
1200 split = new QSplitter(this);
1201 split->setOrientation(QSplitter::Vertical);
1202 list = new ConfigView(split, name);
1203 list->list->mode = listMode;
1204 info = new ConfigInfoView(split, name);
1205 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1206 info, SLOT(setInfo(struct menu *)));
1207 layout1->addWidget(split);
1210 int x, y, width, height;
1213 configSettings->beginGroup(name);
1214 width = configSettings->readNumEntry("/window width", parent->width() / 2);
1215 height = configSettings->readNumEntry("/window height", parent->height() / 2);
1216 resize(width, height);
1217 x = configSettings->readNumEntry("/window x", 0, &ok);
1219 y = configSettings->readNumEntry("/window y", 0, &ok);
1222 QValueList<int> sizes = configSettings->readSizes("/split", &ok);
1224 split->setSizes(sizes);
1225 configSettings->endGroup();
1226 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
1230 void ConfigSearchWindow::saveSettings(void)
1233 configSettings->beginGroup(name());
1234 configSettings->writeEntry("/window x", pos().x());
1235 configSettings->writeEntry("/window y", pos().y());
1236 configSettings->writeEntry("/window width", size().width());
1237 configSettings->writeEntry("/window height", size().height());
1238 configSettings->writeSizes("/split", split->sizes());
1239 configSettings->endGroup();
1243 void ConfigSearchWindow::search(void)
1246 struct property *prop;
1247 ConfigItem *lastItem = NULL;
1250 list->list->clear();
1253 result = sym_re_search(editField->text().latin1());
1256 for (p = result; *p; p++) {
1257 for_all_prompts((*p), prop)
1258 lastItem = new ConfigItem(list->list, lastItem, prop->menu,
1259 menu_is_visible(prop->menu));
1264 * Construct the complete config widget
1266 ConfigMainWindow::ConfigMainWindow(void)
1271 int x, y, width, height;
1273 QWidget *d = configApp->desktop();
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(QSplitter::Horizontal);
1286 setCentralWidget(split1);
1288 menuView = new ConfigView(split1, "menu");
1289 menuList = menuView->list;
1291 split2 = new QSplitter(split1);
1292 split2->setOrientation(QSplitter::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("Back", QPixmap(xpm_back), "Back", 0, this);
1308 connect(backAction, SIGNAL(activated()), SLOT(goBack()));
1309 backAction->setEnabled(FALSE);
1310 QAction *quitAction = new QAction("Quit", "&Quit", CTRL+Key_Q, this);
1311 connect(quitAction, SIGNAL(activated()), SLOT(close()));
1312 QAction *loadAction = new QAction("Load", QPixmap(xpm_load), "&Load", CTRL+Key_L, this);
1313 connect(loadAction, SIGNAL(activated()), SLOT(loadConfig()));
1314 saveAction = new QAction("Save", QPixmap(xpm_save), "&Save", CTRL+Key_S, this);
1315 connect(saveAction, SIGNAL(activated()), SLOT(saveConfig()));
1316 conf_set_changed_callback(conf_changed);
1317 // Set saveAction's initial state
1319 QAction *saveAsAction = new QAction("Save As...", "Save &As...", 0, this);
1320 connect(saveAsAction, SIGNAL(activated()), SLOT(saveConfigAs()));
1321 QAction *searchAction = new QAction("Find", "&Find", CTRL+Key_F, this);
1322 connect(searchAction, SIGNAL(activated()), SLOT(searchConfig()));
1323 QAction *singleViewAction = new QAction("Single View", QPixmap(xpm_single_view), "Split View", 0, this);
1324 connect(singleViewAction, SIGNAL(activated()), SLOT(showSingleView()));
1325 QAction *splitViewAction = new QAction("Split View", QPixmap(xpm_split_view), "Split View", 0, this);
1326 connect(splitViewAction, SIGNAL(activated()), SLOT(showSplitView()));
1327 QAction *fullViewAction = new QAction("Full View", QPixmap(xpm_tree_view), "Full View", 0, this);
1328 connect(fullViewAction, SIGNAL(activated()), SLOT(showFullView()));
1330 QAction *showNameAction = new QAction(NULL, "Show Name", 0, this);
1331 showNameAction->setToggleAction(TRUE);
1332 connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool)));
1333 connect(configView, SIGNAL(showNameChanged(bool)), showNameAction, SLOT(setOn(bool)));
1334 showNameAction->setOn(configView->showName());
1335 QAction *showRangeAction = new QAction(NULL, "Show Range", 0, this);
1336 showRangeAction->setToggleAction(TRUE);
1337 connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool)));
1338 connect(configView, SIGNAL(showRangeChanged(bool)), showRangeAction, SLOT(setOn(bool)));
1339 showRangeAction->setOn(configList->showRange);
1340 QAction *showDataAction = new QAction(NULL, "Show Data", 0, this);
1341 showDataAction->setToggleAction(TRUE);
1342 connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool)));
1343 connect(configView, SIGNAL(showDataChanged(bool)), showDataAction, SLOT(setOn(bool)));
1344 showDataAction->setOn(configList->showData);
1345 QAction *showAllAction = new QAction(NULL, "Show All Options", 0, this);
1346 showAllAction->setToggleAction(TRUE);
1347 connect(showAllAction, SIGNAL(toggled(bool)), configView, SLOT(setShowAll(bool)));
1348 connect(showAllAction, SIGNAL(toggled(bool)), menuView, SLOT(setShowAll(bool)));
1349 showAllAction->setOn(configList->showAll);
1350 QAction *showDebugAction = new QAction(NULL, "Show Debug Info", 0, this);
1351 showDebugAction->setToggleAction(TRUE);
1352 connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
1353 connect(helpText, SIGNAL(showDebugChanged(bool)), showDebugAction, SLOT(setOn(bool)));
1354 showDebugAction->setOn(helpText->showDebug());
1356 QAction *showIntroAction = new QAction(NULL, "Introduction", 0, this);
1357 connect(showIntroAction, SIGNAL(activated()), SLOT(showIntro()));
1358 QAction *showAboutAction = new QAction(NULL, "About", 0, this);
1359 connect(showAboutAction, SIGNAL(activated()), SLOT(showAbout()));
1362 backAction->addTo(toolBar);
1363 toolBar->addSeparator();
1364 loadAction->addTo(toolBar);
1365 saveAction->addTo(toolBar);
1366 toolBar->addSeparator();
1367 singleViewAction->addTo(toolBar);
1368 splitViewAction->addTo(toolBar);
1369 fullViewAction->addTo(toolBar);
1371 // create config menu
1372 QPopupMenu* config = new QPopupMenu(this);
1373 menu->insertItem("&File", config);
1374 loadAction->addTo(config);
1375 saveAction->addTo(config);
1376 saveAsAction->addTo(config);
1377 config->insertSeparator();
1378 quitAction->addTo(config);
1381 QPopupMenu* editMenu = new QPopupMenu(this);
1382 menu->insertItem("&Edit", editMenu);
1383 searchAction->addTo(editMenu);
1385 // create options menu
1386 QPopupMenu* optionMenu = new QPopupMenu(this);
1387 menu->insertItem("&Option", optionMenu);
1388 showNameAction->addTo(optionMenu);
1389 showRangeAction->addTo(optionMenu);
1390 showDataAction->addTo(optionMenu);
1391 optionMenu->insertSeparator();
1392 showAllAction->addTo(optionMenu);
1393 showDebugAction->addTo(optionMenu);
1396 QPopupMenu* helpMenu = new QPopupMenu(this);
1397 menu->insertSeparator();
1398 menu->insertItem("&Help", helpMenu);
1399 showIntroAction->addTo(helpMenu);
1400 showAboutAction->addTo(helpMenu);
1402 connect(configList, SIGNAL(menuChanged(struct menu *)),
1403 helpText, SLOT(setInfo(struct menu *)));
1404 connect(configList, SIGNAL(menuSelected(struct menu *)),
1405 SLOT(changeMenu(struct menu *)));
1406 connect(configList, SIGNAL(parentSelected()),
1408 connect(menuList, SIGNAL(menuChanged(struct menu *)),
1409 helpText, SLOT(setInfo(struct menu *)));
1410 connect(menuList, SIGNAL(menuSelected(struct menu *)),
1411 SLOT(changeMenu(struct menu *)));
1413 connect(configList, SIGNAL(gotFocus(struct menu *)),
1414 helpText, SLOT(setInfo(struct menu *)));
1415 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1416 helpText, SLOT(setInfo(struct menu *)));
1417 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1418 SLOT(listFocusChanged(void)));
1419 connect(helpText, SIGNAL(menuSelected(struct menu *)),
1420 SLOT(setMenuLink(struct menu *)));
1422 QString listMode = configSettings->readEntry("/listMode", "symbol");
1423 if (listMode == "single")
1425 else if (listMode == "full")
1427 else /*if (listMode == "split")*/
1430 // UI setup done, restore splitter positions
1431 QValueList<int> sizes = configSettings->readSizes("/split1", &ok);
1433 split1->setSizes(sizes);
1435 sizes = configSettings->readSizes("/split2", &ok);
1437 split2->setSizes(sizes);
1440 void ConfigMainWindow::loadConfig(void)
1442 QString s = QFileDialog::getOpenFileName(".config", NULL, this);
1445 if (conf_read(QFile::encodeName(s)))
1446 QMessageBox::information(this, "qconf", "Unable to load configuration!");
1447 ConfigView::updateListAll();
1450 void ConfigMainWindow::saveConfig(void)
1452 if (conf_write(NULL))
1453 QMessageBox::information(this, "qconf", "Unable to save configuration!");
1456 void ConfigMainWindow::saveConfigAs(void)
1458 QString s = QFileDialog::getSaveFileName(".config", NULL, this);
1461 if (conf_write(QFile::encodeName(s)))
1462 QMessageBox::information(this, "qconf", "Unable to save configuration!");
1465 void ConfigMainWindow::searchConfig(void)
1468 searchWindow = new ConfigSearchWindow(this, "search");
1469 searchWindow->show();
1472 void ConfigMainWindow::changeMenu(struct menu *menu)
1474 configList->setRootMenu(menu);
1475 if (configList->rootEntry->parent == &rootmenu)
1476 backAction->setEnabled(FALSE);
1478 backAction->setEnabled(TRUE);
1481 void ConfigMainWindow::setMenuLink(struct menu *menu)
1483 struct menu *parent;
1484 ConfigList* list = NULL;
1487 if (!menu_is_visible(menu) && !configView->showAll())
1490 switch (configList->mode) {
1493 parent = menu_get_parent_menu(menu);
1496 list->setRootMenu(parent);
1499 if (menu->flags & MENU_ROOT) {
1500 configList->setRootMenu(menu);
1501 configList->clearSelection();
1505 parent = menu_get_parent_menu(menu->parent);
1508 item = menuList->findConfigItem(parent);
1510 menuList->setSelected(item, TRUE);
1511 menuList->ensureItemVisible(item);
1513 list->setRootMenu(parent);
1522 item = list->findConfigItem(menu);
1524 list->setSelected(item, TRUE);
1525 list->ensureItemVisible(item);
1531 void ConfigMainWindow::listFocusChanged(void)
1533 if (menuList->mode == menuMode)
1534 configList->clearSelection();
1537 void ConfigMainWindow::goBack(void)
1541 configList->setParentMenu();
1542 if (configList->rootEntry == &rootmenu)
1543 backAction->setEnabled(FALSE);
1544 item = (ConfigItem*)menuList->selectedItem();
1546 if (item->menu == configList->rootEntry) {
1547 menuList->setSelected(item, TRUE);
1550 item = (ConfigItem*)item->parent();
1554 void ConfigMainWindow::showSingleView(void)
1557 menuList->setRootMenu(0);
1558 configList->mode = singleMode;
1559 if (configList->rootEntry == &rootmenu)
1560 configList->updateListAll();
1562 configList->setRootMenu(&rootmenu);
1563 configList->setAllOpen(TRUE);
1564 configList->setFocus();
1567 void ConfigMainWindow::showSplitView(void)
1569 configList->mode = symbolMode;
1570 if (configList->rootEntry == &rootmenu)
1571 configList->updateListAll();
1573 configList->setRootMenu(&rootmenu);
1574 configList->setAllOpen(TRUE);
1575 configApp->processEvents();
1576 menuList->mode = menuMode;
1577 menuList->setRootMenu(&rootmenu);
1578 menuList->setAllOpen(TRUE);
1580 menuList->setFocus();
1583 void ConfigMainWindow::showFullView(void)
1586 menuList->setRootMenu(0);
1587 configList->mode = fullMode;
1588 if (configList->rootEntry == &rootmenu)
1589 configList->updateListAll();
1591 configList->setRootMenu(&rootmenu);
1592 configList->setAllOpen(FALSE);
1593 configList->setFocus();
1597 * ask for saving configuration before quitting
1598 * TODO ask only when something changed
1600 void ConfigMainWindow::closeEvent(QCloseEvent* e)
1602 if (!conf_get_changed()) {
1606 QMessageBox mb("qconf", "Save configuration?", QMessageBox::Warning,
1607 QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape);
1608 mb.setButtonText(QMessageBox::Yes, "&Save Changes");
1609 mb.setButtonText(QMessageBox::No, "&Discard Changes");
1610 mb.setButtonText(QMessageBox::Cancel, "Cancel Exit");
1611 switch (mb.exec()) {
1612 case QMessageBox::Yes:
1614 case QMessageBox::No:
1617 case QMessageBox::Cancel:
1623 void ConfigMainWindow::showIntro(void)
1625 static char str[] = "Welcome to the qconf graphical kernel configuration tool for Linux.\n\n"
1626 "For each option, a blank box indicates the feature is disabled, a check\n"
1627 "indicates it is enabled, and a dot indicates that it is to be compiled\n"
1628 "as a module. Clicking on the box will cycle through the three states.\n\n"
1629 "If you do not see an option (e.g., a device driver) that you believe\n"
1630 "should be present, try turning on Show All Options under the Options menu.\n"
1631 "Although there is no cross reference yet to help you figure out what other\n"
1632 "options must be enabled to support the option you are interested in, you can\n"
1633 "still view the help of a grayed-out option.\n\n"
1634 "Toggling Show Debug Info under the Options menu will show the dependencies,\n"
1635 "which you can then match by examining other options.\n\n";
1637 QMessageBox::information(this, "qconf", str);
1640 void ConfigMainWindow::showAbout(void)
1642 static char str[] = "qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n\n"
1643 "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n";
1645 QMessageBox::information(this, "qconf", str);
1648 void ConfigMainWindow::saveSettings(void)
1650 configSettings->writeEntry("/window x", pos().x());
1651 configSettings->writeEntry("/window y", pos().y());
1652 configSettings->writeEntry("/window width", size().width());
1653 configSettings->writeEntry("/window height", size().height());
1656 switch(configList->mode) {
1669 configSettings->writeEntry("/listMode", entry);
1671 configSettings->writeSizes("/split1", split1->sizes());
1672 configSettings->writeSizes("/split2", split2->sizes());
1675 void ConfigMainWindow::conf_changed(void)
1678 saveAction->setEnabled(conf_get_changed());
1681 void fixup_rootmenu(struct menu *menu)
1684 static int menu_cnt = 0;
1686 menu->flags |= MENU_ROOT;
1687 for (child = menu->list; child; child = child->next) {
1688 if (child->prompt && child->prompt->type == P_MENU) {
1690 fixup_rootmenu(child);
1692 } else if (!menu_cnt)
1693 fixup_rootmenu(child);
1697 static const char *progname;
1699 static void usage(void)
1701 printf("%s <config>\n", progname);
1705 int main(int ac, char** av)
1707 ConfigMainWindow* v;
1710 bindtextdomain(PACKAGE, LOCALEDIR);
1711 textdomain(PACKAGE);
1713 #ifndef LKC_DIRECT_LINK
1718 configApp = new QApplication(ac, av);
1719 if (ac > 1 && av[1][0] == '-') {
1732 fixup_rootmenu(&rootmenu);
1734 //zconfdump(stdout);
1736 configSettings = new ConfigSettings();
1737 configSettings->beginGroup("/kconfig/qconf");
1738 v = new ConfigMainWindow();
1740 //zconfdump(stdout);
1741 configApp->setMainWidget(v);
1742 configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit()));
1743 configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings()));
1747 configSettings->endGroup();
1748 delete configSettings;