2 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
3 * Released under the terms of the GNU GPL v2.0.
6 #include <qapplication.h>
7 #include <qmainwindow.h>
8 #include <qdesktopwidget.h>
12 #include <qsplitter.h>
13 #include <qlistview.h>
14 #include <qtextbrowser.h>
15 #include <qlineedit.h>
17 #include <qpushbutton.h>
19 #include <qmessagebox.h>
22 #include <qfiledialog.h>
23 #include <qdragobject.h>
39 static QApplication *configApp;
40 static ConfigSettings *configSettings;
42 QAction *ConfigMainWindow::saveAction;
44 static inline QString qgettext(const char* str)
46 return QString::fromLocal8Bit(gettext(str));
49 static inline QString qgettext(const QString& str)
51 return QString::fromLocal8Bit(gettext(str.latin1()));
55 * Reads a list of integer values from the application settings.
57 QValueList<int> ConfigSettings::readSizes(const QString& key, bool *ok)
59 QValueList<int> result;
60 QStringList entryList = readListEntry(key, ok);
62 QStringList::Iterator it;
63 for (it = entryList.begin(); it != entryList.end(); ++it)
64 result.push_back((*it).toInt());
71 * Writes a list of integer values to the application settings.
73 bool ConfigSettings::writeSizes(const QString& key, const QValueList<int>& value)
75 QStringList stringList;
76 QValueList<int>::ConstIterator it;
78 for (it = value.begin(); it != value.end(); ++it)
79 stringList.push_back(QString::number(*it));
80 return writeEntry(key, stringList);
87 * TODO check the value
89 void ConfigItem::okRename(int col)
91 Parent::okRename(col);
92 sym_set_string_value(menu->sym, text(dataColIdx).latin1());
93 listView()->updateList(this);
98 * update the displayed of a menu entry
100 void ConfigItem::updateMenu(void)
104 struct property *prop;
111 setPixmap(promptColIdx, list->menuBackPix);
118 prompt = _(menu_get_prompt(menu));
120 if (prop) switch (prop->type) {
122 if (list->mode == singleMode || list->mode == symbolMode) {
123 /* a menuconfig entry is displayed differently
124 * depending whether it's at the view root or a child.
126 if (sym && list->rootEntry == menu)
128 setPixmap(promptColIdx, list->menuPix);
132 setPixmap(promptColIdx, 0);
136 setPixmap(promptColIdx, 0);
144 setText(nameColIdx, QString::fromLocal8Bit(sym->name));
146 type = sym_get_type(sym);
152 if (!sym_is_changable(sym) && !list->showAll) {
153 setPixmap(promptColIdx, 0);
154 setText(noColIdx, QString::null);
155 setText(modColIdx, QString::null);
156 setText(yesColIdx, QString::null);
159 expr = sym_get_tristate_value(sym);
162 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
163 setPixmap(promptColIdx, list->choiceYesPix);
165 setPixmap(promptColIdx, list->symbolYesPix);
166 setText(yesColIdx, "Y");
170 setPixmap(promptColIdx, list->symbolModPix);
171 setText(modColIdx, "M");
175 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
176 setPixmap(promptColIdx, list->choiceNoPix);
178 setPixmap(promptColIdx, list->symbolNoPix);
179 setText(noColIdx, "N");
184 setText(noColIdx, sym_tristate_within_range(sym, no) ? "_" : 0);
186 setText(modColIdx, sym_tristate_within_range(sym, mod) ? "_" : 0);
188 setText(yesColIdx, sym_tristate_within_range(sym, yes) ? "_" : 0);
190 setText(dataColIdx, QChar(ch));
197 data = sym_get_string_value(sym);
199 #if QT_VERSION >= 300
200 int i = list->mapIdx(dataColIdx);
202 setRenameEnabled(i, TRUE);
204 setText(dataColIdx, data);
205 if (type == S_STRING)
206 prompt = QString("%1: %2").arg(prompt).arg(data);
208 prompt = QString("(%2) %1").arg(prompt).arg(data);
211 if (!sym_has_value(sym) && visible)
212 prompt += _(" (NEW)");
214 setText(promptColIdx, prompt);
217 void ConfigItem::testUpdateMenu(bool v)
225 sym_calc_value(menu->sym);
226 if (menu->flags & MENU_CHANGED) {
227 /* the menu entry changed, so update all list items */
228 menu->flags &= ~MENU_CHANGED;
229 for (i = (ConfigItem*)menu->data; i; i = i->nextItem)
231 } else if (listView()->updateAll)
235 void ConfigItem::paintCell(QPainter* p, const QColorGroup& cg, int column, int width, int align)
237 ConfigList* list = listView();
240 if (isSelected() && !list->hasFocus() && list->mode == menuMode)
241 Parent::paintCell(p, list->inactivedColorGroup, column, width, align);
243 Parent::paintCell(p, cg, column, width, align);
245 Parent::paintCell(p, list->disabledColorGroup, column, width, align);
249 * construct a menu entry
251 void ConfigItem::init(void)
254 ConfigList* list = listView();
255 nextItem = (ConfigItem*)menu->data;
258 if (list->mode != fullMode)
260 sym_calc_value(menu->sym);
266 * destruct a menu entry
268 ConfigItem::~ConfigItem(void)
271 ConfigItem** ip = (ConfigItem**)&menu->data;
272 for (; *ip; ip = &(*ip)->nextItem) {
281 ConfigLineEdit::ConfigLineEdit(ConfigView* parent)
284 connect(this, SIGNAL(lostFocus()), SLOT(hide()));
287 void ConfigLineEdit::show(ConfigItem* i)
290 if (sym_get_string_value(item->menu->sym))
291 setText(QString::fromLocal8Bit(sym_get_string_value(item->menu->sym)));
293 setText(QString::null);
298 void ConfigLineEdit::keyPressEvent(QKeyEvent* e)
305 sym_set_string_value(item->menu->sym, text().latin1());
306 parent()->updateList(item);
309 Parent::keyPressEvent(e);
313 parent()->list->setFocus();
317 ConfigList::ConfigList(ConfigView* p, const char *name)
320 symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no),
321 choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no),
322 menuPix(xpm_menu), menuInvPix(xpm_menu_inv), menuBackPix(xpm_menuback), voidPix(xpm_void),
323 showAll(false), showName(false), showRange(false), showData(false),
324 rootEntry(0), headerPopup(0)
329 setRootIsDecorated(TRUE);
330 disabledColorGroup = palette().active();
331 disabledColorGroup.setColor(QColorGroup::Text, palette().disabled().text());
332 inactivedColorGroup = palette().active();
333 inactivedColorGroup.setColor(QColorGroup::Highlight, palette().disabled().highlight());
335 connect(this, SIGNAL(selectionChanged(void)),
336 SLOT(updateSelection(void)));
339 configSettings->beginGroup(name);
340 showAll = configSettings->readBoolEntry("/showAll", false);
341 showName = configSettings->readBoolEntry("/showName", false);
342 showRange = configSettings->readBoolEntry("/showRange", false);
343 showData = configSettings->readBoolEntry("/showData", false);
344 configSettings->endGroup();
345 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
348 for (i = 0; i < colNr; i++)
349 colMap[i] = colRevMap[i] = -1;
350 addColumn(promptColIdx, _("Option"));
355 void ConfigList::reinit(void)
357 removeColumn(dataColIdx);
358 removeColumn(yesColIdx);
359 removeColumn(modColIdx);
360 removeColumn(noColIdx);
361 removeColumn(nameColIdx);
364 addColumn(nameColIdx, _("Name"));
366 addColumn(noColIdx, "N");
367 addColumn(modColIdx, "M");
368 addColumn(yesColIdx, "Y");
371 addColumn(dataColIdx, _("Value"));
376 void ConfigList::saveSettings(void)
379 configSettings->beginGroup(name());
380 configSettings->writeEntry("/showName", showName);
381 configSettings->writeEntry("/showRange", showRange);
382 configSettings->writeEntry("/showData", showData);
383 configSettings->writeEntry("/showAll", showAll);
384 configSettings->endGroup();
388 ConfigItem* ConfigList::findConfigItem(struct menu *menu)
390 ConfigItem* item = (ConfigItem*)menu->data;
392 for (; item; item = item->nextItem) {
393 if (this == item->listView())
400 void ConfigList::updateSelection(void)
405 ConfigItem* item = (ConfigItem*)selectedItem();
410 emit menuChanged(menu);
413 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
414 if (mode == menuMode && type == P_MENU)
415 emit menuSelected(menu);
418 void ConfigList::updateList(ConfigItem* item)
420 ConfigItem* last = 0;
423 if (mode != listMode)
425 QListViewItemIterator it(this);
428 for (; it.current(); ++it) {
429 item = (ConfigItem*)it.current();
432 item->testUpdateMenu(menu_is_visible(item->menu));
437 if (rootEntry != &rootmenu && (mode == singleMode ||
438 (mode == symbolMode && rootEntry->parent != &rootmenu))) {
441 item = new ConfigItem(this, 0, true);
444 if ((mode == singleMode || (mode == symbolMode && !(rootEntry->flags & MENU_ROOT))) &&
445 rootEntry->sym && rootEntry->prompt) {
446 item = last ? last->nextSibling() : firstChild();
448 item = new ConfigItem(this, last, rootEntry, true);
450 item->testUpdateMenu(true);
452 updateMenuList(item, rootEntry);
457 updateMenuList(this, rootEntry);
461 void ConfigList::setValue(ConfigItem* item, tristate val)
467 sym = item->menu ? item->menu->sym : 0;
471 type = sym_get_type(sym);
475 oldval = sym_get_tristate_value(sym);
477 if (!sym_set_tristate_value(sym, val))
479 if (oldval == no && item->menu->list)
481 parent()->updateList(item);
486 void ConfigList::changeValue(ConfigItem* item)
490 int type, oldexpr, newexpr;
497 if (item->menu->list)
498 item->setOpen(!item->isOpen());
502 type = sym_get_type(sym);
506 oldexpr = sym_get_tristate_value(sym);
507 newexpr = sym_toggle_tristate_value(sym);
508 if (item->menu->list) {
509 if (oldexpr == newexpr)
510 item->setOpen(!item->isOpen());
511 else if (oldexpr == no)
514 if (oldexpr != newexpr)
515 parent()->updateList(item);
520 #if QT_VERSION >= 300
521 if (colMap[dataColIdx] >= 0)
522 item->startRename(colMap[dataColIdx]);
525 parent()->lineEdit->show(item);
530 void ConfigList::setRootMenu(struct menu *menu)
534 if (rootEntry == menu)
536 type = menu && menu->prompt ? menu->prompt->type : P_UNKNOWN;
539 updateMenuList(this, 0);
542 setSelected(currentItem(), hasFocus());
543 ensureItemVisible(currentItem());
546 void ConfigList::setParentMenu(void)
549 struct menu *oldroot;
552 if (rootEntry == &rootmenu)
554 setRootMenu(menu_get_parent_menu(rootEntry->parent));
556 QListViewItemIterator it(this);
557 for (; (item = (ConfigItem*)it.current()); it++) {
558 if (item->menu == oldroot) {
559 setCurrentItem(item);
560 ensureItemVisible(item);
567 * update all the children of a menu entry
568 * removes/adds the entries from the parent widget as necessary
570 * parent: either the menu list widget or a menu entry widget
571 * menu: entry to be updated
574 void ConfigList::updateMenuList(P* parent, struct menu* menu)
583 while ((item = parent->firstChild()))
588 last = parent->firstChild();
589 if (last && !last->goParent)
591 for (child = menu->list; child; child = child->next) {
592 item = last ? last->nextSibling() : parent->firstChild();
593 type = child->prompt ? child->prompt->type : P_UNKNOWN;
597 if (!(child->flags & MENU_ROOT))
601 if (child->flags & MENU_ROOT)
608 visible = menu_is_visible(child);
609 if (showAll || visible) {
610 if (!child->sym && !child->list && !child->prompt)
612 if (!item || item->menu != child)
613 item = new ConfigItem(parent, last, child, visible);
615 item->testUpdateMenu(visible);
617 if (mode == fullMode || mode == menuMode || type != P_MENU)
618 updateMenuList(item, child);
620 updateMenuList(item, 0);
625 if (item && item->menu == child) {
626 last = parent->firstChild();
629 else while (last->nextSibling() != item)
630 last = last->nextSibling();
636 void ConfigList::keyPressEvent(QKeyEvent* ev)
638 QListViewItem* i = currentItem();
643 if (ev->key() == Qt::Key_Escape && mode != fullMode && mode != listMode) {
644 emit parentSelected();
650 Parent::keyPressEvent(ev);
653 item = (ConfigItem*)i;
658 if (item->goParent) {
659 emit parentSelected();
665 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
666 if (type == P_MENU && rootEntry != menu &&
667 mode != fullMode && mode != menuMode) {
668 emit menuSelected(menu);
684 Parent::keyPressEvent(ev);
690 void ConfigList::contentsMousePressEvent(QMouseEvent* e)
692 //QPoint p(contentsToViewport(e->pos()));
693 //printf("contentsMousePressEvent: %d,%d\n", p.x(), p.y());
694 Parent::contentsMousePressEvent(e);
697 void ConfigList::contentsMouseReleaseEvent(QMouseEvent* e)
699 QPoint p(contentsToViewport(e->pos()));
700 ConfigItem* item = (ConfigItem*)itemAt(p);
702 enum prop_type ptype;
710 x = header()->offset() + p.x();
711 idx = colRevMap[header()->sectionAt(x)];
714 pm = item->pixmap(promptColIdx);
716 int off = header()->sectionPos(0) + itemMargin() +
717 treeStepSize() * (item->depth() + (rootIsDecorated() ? 1 : 0));
718 if (x >= off && x < off + pm->width()) {
719 if (item->goParent) {
720 emit parentSelected();
724 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
725 if (ptype == P_MENU && rootEntry != menu &&
726 mode != fullMode && mode != menuMode)
727 emit menuSelected(menu);
748 //printf("contentsMouseReleaseEvent: %d,%d\n", p.x(), p.y());
749 Parent::contentsMouseReleaseEvent(e);
752 void ConfigList::contentsMouseMoveEvent(QMouseEvent* e)
754 //QPoint p(contentsToViewport(e->pos()));
755 //printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y());
756 Parent::contentsMouseMoveEvent(e);
759 void ConfigList::contentsMouseDoubleClickEvent(QMouseEvent* e)
761 QPoint p(contentsToViewport(e->pos()));
762 ConfigItem* item = (ConfigItem*)itemAt(p);
764 enum prop_type ptype;
768 if (item->goParent) {
769 emit parentSelected();
775 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
776 if (ptype == P_MENU && (mode == singleMode || mode == symbolMode))
777 emit menuSelected(menu);
782 //printf("contentsMouseDoubleClickEvent: %d,%d\n", p.x(), p.y());
783 Parent::contentsMouseDoubleClickEvent(e);
786 void ConfigList::focusInEvent(QFocusEvent *e)
788 struct menu *menu = NULL;
790 Parent::focusInEvent(e);
792 ConfigItem* item = (ConfigItem *)currentItem();
794 setSelected(item, TRUE);
800 void ConfigList::contextMenuEvent(QContextMenuEvent *e)
802 if (e->y() <= header()->geometry().bottom()) {
806 headerPopup = new QPopupMenu(this);
807 action = new QAction(NULL, _("Show Name"), 0, this);
808 action->setToggleAction(TRUE);
809 connect(action, SIGNAL(toggled(bool)),
810 parent(), SLOT(setShowName(bool)));
811 connect(parent(), SIGNAL(showNameChanged(bool)),
812 action, SLOT(setOn(bool)));
813 action->setOn(showName);
814 action->addTo(headerPopup);
815 action = new QAction(NULL, _("Show Range"), 0, this);
816 action->setToggleAction(TRUE);
817 connect(action, SIGNAL(toggled(bool)),
818 parent(), SLOT(setShowRange(bool)));
819 connect(parent(), SIGNAL(showRangeChanged(bool)),
820 action, SLOT(setOn(bool)));
821 action->setOn(showRange);
822 action->addTo(headerPopup);
823 action = new QAction(NULL, _("Show Data"), 0, this);
824 action->setToggleAction(TRUE);
825 connect(action, SIGNAL(toggled(bool)),
826 parent(), SLOT(setShowData(bool)));
827 connect(parent(), SIGNAL(showDataChanged(bool)),
828 action, SLOT(setOn(bool)));
829 action->setOn(showData);
830 action->addTo(headerPopup);
832 headerPopup->exec(e->globalPos());
838 ConfigView* ConfigView::viewList;
840 ConfigView::ConfigView(QWidget* parent, const char *name)
841 : Parent(parent, name)
843 list = new ConfigList(this, name);
844 lineEdit = new ConfigLineEdit(this);
847 this->nextView = viewList;
851 ConfigView::~ConfigView(void)
855 for (vp = &viewList; *vp; vp = &(*vp)->nextView) {
863 void ConfigView::setShowAll(bool b)
865 if (list->showAll != b) {
867 list->updateListAll();
868 emit showAllChanged(b);
872 void ConfigView::setShowName(bool b)
874 if (list->showName != b) {
877 emit showNameChanged(b);
881 void ConfigView::setShowRange(bool b)
883 if (list->showRange != b) {
886 emit showRangeChanged(b);
890 void ConfigView::setShowData(bool b)
892 if (list->showData != b) {
895 emit showDataChanged(b);
899 void ConfigList::setAllOpen(bool open)
901 QListViewItemIterator it(this);
903 for (; it.current(); it++)
904 it.current()->setOpen(open);
907 void ConfigView::updateList(ConfigItem* item)
911 for (v = viewList; v; v = v->nextView)
912 v->list->updateList(item);
915 void ConfigView::updateListAll(void)
919 for (v = viewList; v; v = v->nextView)
920 v->list->updateListAll();
923 ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name)
924 : Parent(parent, name), sym(0), menu(0)
927 configSettings->beginGroup(name);
928 _showDebug = configSettings->readBoolEntry("/showDebug", false);
929 configSettings->endGroup();
930 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
934 void ConfigInfoView::saveSettings(void)
937 configSettings->beginGroup(name());
938 configSettings->writeEntry("/showDebug", showDebug());
939 configSettings->endGroup();
943 void ConfigInfoView::setShowDebug(bool b)
945 if (_showDebug != b) {
951 emit showDebugChanged(b);
955 void ConfigInfoView::setInfo(struct menu *m)
967 void ConfigInfoView::setSource(const QString& name)
969 const char *p = name.latin1();
978 if (sscanf(p, "m%p", &m) == 1 && menu != m) {
981 emit menuSelected(menu);
987 if (sscanf(p, "s%p", &s) == 1 && sym != s) {
995 void ConfigInfoView::symbolInfo(void)
999 str += "<big>Symbol: <b>";
1000 str += print_filter(sym->name);
1001 str += "</b></big><br><br>value: ";
1002 str += print_filter(sym_get_string_value(sym));
1003 str += "<br>visibility: ";
1004 str += sym->visible == yes ? "y" : sym->visible == mod ? "m" : "n";
1006 str += debug_info(sym);
1011 void ConfigInfoView::menuInfo(void)
1014 QString head, debug, help;
1020 head += print_filter(_(menu->prompt->text));
1021 head += "</b></big>";
1025 head += QString().sprintf("<a href=\"s%p\">", sym);
1026 head += print_filter(sym->name);
1031 } else if (sym->name) {
1034 head += QString().sprintf("<a href=\"s%p\">", sym);
1035 head += print_filter(sym->name);
1038 head += "</b></big>";
1043 debug = debug_info(sym);
1045 help = menu_get_help(menu);
1046 /* Gettextize if the help text not empty */
1048 help = print_filter(menu_get_help(menu));
1050 help = print_filter(_(menu_get_help(menu)));
1051 } else if (menu->prompt) {
1053 head += print_filter(_(menu->prompt->text));
1054 head += "</b></big><br><br>";
1056 if (menu->prompt->visible.expr) {
1057 debug += " dep: ";
1058 expr_print(menu->prompt->visible.expr, expr_print_help, &debug, E_NONE);
1059 debug += "<br><br>";
1064 debug += QString().sprintf("defined at %s:%d<br><br>", menu->file->name, menu->lineno);
1066 setText(head + debug + help);
1069 QString ConfigInfoView::debug_info(struct symbol *sym)
1074 debug += print_filter(sym_type_name(sym->type));
1075 if (sym_is_choice(sym))
1076 debug += " (choice)";
1078 if (sym->rev_dep.expr) {
1079 debug += "reverse dep: ";
1080 expr_print(sym->rev_dep.expr, expr_print_help, &debug, E_NONE);
1083 for (struct property *prop = sym->prop; prop; prop = prop->next) {
1084 switch (prop->type) {
1087 debug += QString().sprintf("prompt: <a href=\"m%p\">", prop->menu);
1088 debug += print_filter(_(prop->text));
1089 debug += "</a><br>";
1095 debug += prop_get_type_name(prop->type);
1097 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1101 if (sym_is_choice(sym)) {
1102 debug += "choice: ";
1103 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1108 debug += "unknown property: ";
1109 debug += prop_get_type_name(prop->type);
1112 if (prop->visible.expr) {
1113 debug += " dep: ";
1114 expr_print(prop->visible.expr, expr_print_help, &debug, E_NONE);
1123 QString ConfigInfoView::print_filter(const QString &str)
1125 QRegExp re("[<>&\"\\n]");
1127 for (int i = 0; (i = res.find(re, i)) >= 0;) {
1128 switch (res[i].latin1()) {
1130 res.replace(i, 1, "<");
1134 res.replace(i, 1, ">");
1138 res.replace(i, 1, "&");
1142 res.replace(i, 1, """);
1146 res.replace(i, 1, "<br>");
1154 void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char *str)
1156 QString* text = reinterpret_cast<QString*>(data);
1157 QString str2 = print_filter(str);
1159 if (sym && sym->name && !(sym->flags & SYMBOL_CONST)) {
1160 *text += QString().sprintf("<a href=\"s%p\">", sym);
1167 QPopupMenu* ConfigInfoView::createPopupMenu(const QPoint& pos)
1169 QPopupMenu* popup = Parent::createPopupMenu(pos);
1170 QAction* action = new QAction(NULL, _("Show Debug Info"), 0, popup);
1171 action->setToggleAction(TRUE);
1172 connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
1173 connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool)));
1174 action->setOn(showDebug());
1175 popup->insertSeparator();
1176 action->addTo(popup);
1180 void ConfigInfoView::contentsContextMenuEvent(QContextMenuEvent *e)
1182 Parent::contentsContextMenuEvent(e);
1185 ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow* parent, const char *name)
1186 : Parent(parent, name), result(NULL)
1188 setCaption("Search Config");
1190 QVBoxLayout* layout1 = new QVBoxLayout(this, 11, 6);
1191 QHBoxLayout* layout2 = new QHBoxLayout(0, 0, 6);
1192 layout2->addWidget(new QLabel(_("Find:"), this));
1193 editField = new QLineEdit(this);
1194 connect(editField, SIGNAL(returnPressed()), SLOT(search()));
1195 layout2->addWidget(editField);
1196 searchButton = new QPushButton(_("Search"), this);
1197 searchButton->setAutoDefault(FALSE);
1198 connect(searchButton, SIGNAL(clicked()), SLOT(search()));
1199 layout2->addWidget(searchButton);
1200 layout1->addLayout(layout2);
1202 split = new QSplitter(this);
1203 split->setOrientation(Qt::Vertical);
1204 list = new ConfigView(split, name);
1205 list->list->mode = listMode;
1206 info = new ConfigInfoView(split, name);
1207 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1208 info, SLOT(setInfo(struct menu *)));
1209 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1210 parent, SLOT(setMenuLink(struct menu *)));
1212 layout1->addWidget(split);
1215 int x, y, width, height;
1218 configSettings->beginGroup(name);
1219 width = configSettings->readNumEntry("/window width", parent->width() / 2);
1220 height = configSettings->readNumEntry("/window height", parent->height() / 2);
1221 resize(width, height);
1222 x = configSettings->readNumEntry("/window x", 0, &ok);
1224 y = configSettings->readNumEntry("/window y", 0, &ok);
1227 QValueList<int> sizes = configSettings->readSizes("/split", &ok);
1229 split->setSizes(sizes);
1230 configSettings->endGroup();
1231 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
1235 void ConfigSearchWindow::saveSettings(void)
1238 configSettings->beginGroup(name());
1239 configSettings->writeEntry("/window x", pos().x());
1240 configSettings->writeEntry("/window y", pos().y());
1241 configSettings->writeEntry("/window width", size().width());
1242 configSettings->writeEntry("/window height", size().height());
1243 configSettings->writeSizes("/split", split->sizes());
1244 configSettings->endGroup();
1248 void ConfigSearchWindow::search(void)
1251 struct property *prop;
1252 ConfigItem *lastItem = NULL;
1255 list->list->clear();
1258 result = sym_re_search(editField->text().latin1());
1261 for (p = result; *p; p++) {
1262 for_all_prompts((*p), prop)
1263 lastItem = new ConfigItem(list->list, lastItem, prop->menu,
1264 menu_is_visible(prop->menu));
1269 * Construct the complete config widget
1271 ConfigMainWindow::ConfigMainWindow(void)
1276 int x, y, width, height;
1279 QDesktopWidget *d = configApp->desktop();
1280 snprintf(title, sizeof(title), _("Linux Kernel v%s Configuration"),
1281 getenv("KERNELVERSION"));
1284 width = configSettings->readNumEntry("/window width", d->width() - 64);
1285 height = configSettings->readNumEntry("/window height", d->height() - 64);
1286 resize(width, height);
1287 x = configSettings->readNumEntry("/window x", 0, &ok);
1289 y = configSettings->readNumEntry("/window y", 0, &ok);
1293 split1 = new QSplitter(this);
1294 split1->setOrientation(Qt::Horizontal);
1295 setCentralWidget(split1);
1297 menuView = new ConfigView(split1, "menu");
1298 menuList = menuView->list;
1300 split2 = new QSplitter(split1);
1301 split2->setOrientation(Qt::Vertical);
1303 // create config tree
1304 configView = new ConfigView(split2, "config");
1305 configList = configView->list;
1307 helpText = new ConfigInfoView(split2, "help");
1308 helpText->setTextFormat(Qt::RichText);
1310 setTabOrder(configList, helpText);
1311 configList->setFocus();
1314 toolBar = new QToolBar("Tools", this);
1316 backAction = new QAction("Back", QPixmap(xpm_back), _("Back"), 0, this);
1317 connect(backAction, SIGNAL(activated()), SLOT(goBack()));
1318 backAction->setEnabled(FALSE);
1319 QAction *quitAction = new QAction("Quit", _("&Quit"), Qt::CTRL + Qt::Key_Q, this);
1320 connect(quitAction, SIGNAL(activated()), SLOT(close()));
1321 QAction *loadAction = new QAction("Load", QPixmap(xpm_load), _("&Load"), Qt::CTRL + Qt::Key_L, this);
1322 connect(loadAction, SIGNAL(activated()), SLOT(loadConfig()));
1323 saveAction = new QAction("Save", QPixmap(xpm_save), _("&Save"), Qt::CTRL + Qt::Key_S, this);
1324 connect(saveAction, SIGNAL(activated()), SLOT(saveConfig()));
1325 conf_set_changed_callback(conf_changed);
1326 // Set saveAction's initial state
1328 QAction *saveAsAction = new QAction("Save As...", _("Save &As..."), 0, this);
1329 connect(saveAsAction, SIGNAL(activated()), SLOT(saveConfigAs()));
1330 QAction *searchAction = new QAction("Find", _("&Find"), Qt::CTRL + Qt::Key_F, this);
1331 connect(searchAction, SIGNAL(activated()), SLOT(searchConfig()));
1332 QAction *singleViewAction = new QAction("Single View", QPixmap(xpm_single_view), _("Single View"), 0, this);
1333 connect(singleViewAction, SIGNAL(activated()), SLOT(showSingleView()));
1334 QAction *splitViewAction = new QAction("Split View", QPixmap(xpm_split_view), _("Split View"), 0, this);
1335 connect(splitViewAction, SIGNAL(activated()), SLOT(showSplitView()));
1336 QAction *fullViewAction = new QAction("Full View", QPixmap(xpm_tree_view), _("Full View"), 0, this);
1337 connect(fullViewAction, SIGNAL(activated()), SLOT(showFullView()));
1339 QAction *showNameAction = new QAction(NULL, _("Show Name"), 0, this);
1340 showNameAction->setToggleAction(TRUE);
1341 connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool)));
1342 connect(configView, SIGNAL(showNameChanged(bool)), showNameAction, SLOT(setOn(bool)));
1343 showNameAction->setOn(configView->showName());
1344 QAction *showRangeAction = new QAction(NULL, _("Show Range"), 0, this);
1345 showRangeAction->setToggleAction(TRUE);
1346 connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool)));
1347 connect(configView, SIGNAL(showRangeChanged(bool)), showRangeAction, SLOT(setOn(bool)));
1348 showRangeAction->setOn(configList->showRange);
1349 QAction *showDataAction = new QAction(NULL, _("Show Data"), 0, this);
1350 showDataAction->setToggleAction(TRUE);
1351 connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool)));
1352 connect(configView, SIGNAL(showDataChanged(bool)), showDataAction, SLOT(setOn(bool)));
1353 showDataAction->setOn(configList->showData);
1354 QAction *showAllAction = new QAction(NULL, _("Show All Options"), 0, this);
1355 showAllAction->setToggleAction(TRUE);
1356 connect(showAllAction, SIGNAL(toggled(bool)), configView, SLOT(setShowAll(bool)));
1357 connect(showAllAction, SIGNAL(toggled(bool)), menuView, SLOT(setShowAll(bool)));
1358 showAllAction->setOn(configList->showAll);
1359 QAction *showDebugAction = new QAction(NULL, _("Show Debug Info"), 0, this);
1360 showDebugAction->setToggleAction(TRUE);
1361 connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
1362 connect(helpText, SIGNAL(showDebugChanged(bool)), showDebugAction, SLOT(setOn(bool)));
1363 showDebugAction->setOn(helpText->showDebug());
1365 QAction *showIntroAction = new QAction(NULL, _("Introduction"), 0, this);
1366 connect(showIntroAction, SIGNAL(activated()), SLOT(showIntro()));
1367 QAction *showAboutAction = new QAction(NULL, _("About"), 0, this);
1368 connect(showAboutAction, SIGNAL(activated()), SLOT(showAbout()));
1371 backAction->addTo(toolBar);
1372 toolBar->addSeparator();
1373 loadAction->addTo(toolBar);
1374 saveAction->addTo(toolBar);
1375 toolBar->addSeparator();
1376 singleViewAction->addTo(toolBar);
1377 splitViewAction->addTo(toolBar);
1378 fullViewAction->addTo(toolBar);
1380 // create config menu
1381 QPopupMenu* config = new QPopupMenu(this);
1382 menu->insertItem(_("&File"), config);
1383 loadAction->addTo(config);
1384 saveAction->addTo(config);
1385 saveAsAction->addTo(config);
1386 config->insertSeparator();
1387 quitAction->addTo(config);
1390 QPopupMenu* editMenu = new QPopupMenu(this);
1391 menu->insertItem(_("&Edit"), editMenu);
1392 searchAction->addTo(editMenu);
1394 // create options menu
1395 QPopupMenu* optionMenu = new QPopupMenu(this);
1396 menu->insertItem(_("&Option"), optionMenu);
1397 showNameAction->addTo(optionMenu);
1398 showRangeAction->addTo(optionMenu);
1399 showDataAction->addTo(optionMenu);
1400 optionMenu->insertSeparator();
1401 showAllAction->addTo(optionMenu);
1402 showDebugAction->addTo(optionMenu);
1405 QPopupMenu* helpMenu = new QPopupMenu(this);
1406 menu->insertSeparator();
1407 menu->insertItem(_("&Help"), helpMenu);
1408 showIntroAction->addTo(helpMenu);
1409 showAboutAction->addTo(helpMenu);
1411 connect(configList, SIGNAL(menuChanged(struct menu *)),
1412 helpText, SLOT(setInfo(struct menu *)));
1413 connect(configList, SIGNAL(menuSelected(struct menu *)),
1414 SLOT(changeMenu(struct menu *)));
1415 connect(configList, SIGNAL(parentSelected()),
1417 connect(menuList, SIGNAL(menuChanged(struct menu *)),
1418 helpText, SLOT(setInfo(struct menu *)));
1419 connect(menuList, SIGNAL(menuSelected(struct menu *)),
1420 SLOT(changeMenu(struct menu *)));
1422 connect(configList, SIGNAL(gotFocus(struct menu *)),
1423 helpText, SLOT(setInfo(struct menu *)));
1424 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1425 helpText, SLOT(setInfo(struct menu *)));
1426 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1427 SLOT(listFocusChanged(void)));
1428 connect(helpText, SIGNAL(menuSelected(struct menu *)),
1429 SLOT(setMenuLink(struct menu *)));
1431 QString listMode = configSettings->readEntry("/listMode", "symbol");
1432 if (listMode == "single")
1434 else if (listMode == "full")
1436 else /*if (listMode == "split")*/
1439 // UI setup done, restore splitter positions
1440 QValueList<int> sizes = configSettings->readSizes("/split1", &ok);
1442 split1->setSizes(sizes);
1444 sizes = configSettings->readSizes("/split2", &ok);
1446 split2->setSizes(sizes);
1449 void ConfigMainWindow::loadConfig(void)
1451 QString s = QFileDialog::getOpenFileName(conf_get_configname(), NULL, this);
1454 if (conf_read(QFile::encodeName(s)))
1455 QMessageBox::information(this, "qconf", _("Unable to load configuration!"));
1456 ConfigView::updateListAll();
1459 void ConfigMainWindow::saveConfig(void)
1461 if (conf_write(NULL))
1462 QMessageBox::information(this, "qconf", _("Unable to save configuration!"));
1465 void ConfigMainWindow::saveConfigAs(void)
1467 QString s = QFileDialog::getSaveFileName(conf_get_configname(), NULL, this);
1470 if (conf_write(QFile::encodeName(s)))
1471 QMessageBox::information(this, "qconf", _("Unable to save configuration!"));
1474 void ConfigMainWindow::searchConfig(void)
1477 searchWindow = new ConfigSearchWindow(this, "search");
1478 searchWindow->show();
1481 void ConfigMainWindow::changeMenu(struct menu *menu)
1483 configList->setRootMenu(menu);
1484 if (configList->rootEntry->parent == &rootmenu)
1485 backAction->setEnabled(FALSE);
1487 backAction->setEnabled(TRUE);
1490 void ConfigMainWindow::setMenuLink(struct menu *menu)
1492 struct menu *parent;
1493 ConfigList* list = NULL;
1496 if (!menu_is_visible(menu) && !configView->showAll())
1499 switch (configList->mode) {
1502 parent = menu_get_parent_menu(menu);
1505 list->setRootMenu(parent);
1508 if (menu->flags & MENU_ROOT) {
1509 configList->setRootMenu(menu);
1510 configList->clearSelection();
1514 parent = menu_get_parent_menu(menu->parent);
1517 item = menuList->findConfigItem(parent);
1519 menuList->setSelected(item, TRUE);
1520 menuList->ensureItemVisible(item);
1522 list->setRootMenu(parent);
1533 item = list->findConfigItem(menu);
1535 list->setSelected(item, TRUE);
1536 list->ensureItemVisible(item);
1542 void ConfigMainWindow::listFocusChanged(void)
1544 if (menuList->mode == menuMode)
1545 configList->clearSelection();
1548 void ConfigMainWindow::goBack(void)
1552 configList->setParentMenu();
1553 if (configList->rootEntry == &rootmenu)
1554 backAction->setEnabled(FALSE);
1555 item = (ConfigItem*)menuList->selectedItem();
1557 if (item->menu == configList->rootEntry) {
1558 menuList->setSelected(item, TRUE);
1561 item = (ConfigItem*)item->parent();
1565 void ConfigMainWindow::showSingleView(void)
1568 menuList->setRootMenu(0);
1569 configList->mode = singleMode;
1570 if (configList->rootEntry == &rootmenu)
1571 configList->updateListAll();
1573 configList->setRootMenu(&rootmenu);
1574 configList->setAllOpen(TRUE);
1575 configList->setFocus();
1578 void ConfigMainWindow::showSplitView(void)
1580 configList->mode = symbolMode;
1581 if (configList->rootEntry == &rootmenu)
1582 configList->updateListAll();
1584 configList->setRootMenu(&rootmenu);
1585 configList->setAllOpen(TRUE);
1586 configApp->processEvents();
1587 menuList->mode = menuMode;
1588 menuList->setRootMenu(&rootmenu);
1589 menuList->setAllOpen(TRUE);
1591 menuList->setFocus();
1594 void ConfigMainWindow::showFullView(void)
1597 menuList->setRootMenu(0);
1598 configList->mode = fullMode;
1599 if (configList->rootEntry == &rootmenu)
1600 configList->updateListAll();
1602 configList->setRootMenu(&rootmenu);
1603 configList->setAllOpen(FALSE);
1604 configList->setFocus();
1608 * ask for saving configuration before quitting
1609 * TODO ask only when something changed
1611 void ConfigMainWindow::closeEvent(QCloseEvent* e)
1613 if (!conf_get_changed()) {
1617 QMessageBox mb("qconf", _("Save configuration?"), QMessageBox::Warning,
1618 QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape);
1619 mb.setButtonText(QMessageBox::Yes, _("&Save Changes"));
1620 mb.setButtonText(QMessageBox::No, _("&Discard Changes"));
1621 mb.setButtonText(QMessageBox::Cancel, _("Cancel Exit"));
1622 switch (mb.exec()) {
1623 case QMessageBox::Yes:
1625 case QMessageBox::No:
1628 case QMessageBox::Cancel:
1634 void ConfigMainWindow::showIntro(void)
1636 static const QString str = _("Welcome to the qconf graphical kernel configuration tool for Linux.\n\n"
1637 "For each option, a blank box indicates the feature is disabled, a check\n"
1638 "indicates it is enabled, and a dot indicates that it is to be compiled\n"
1639 "as a module. Clicking on the box will cycle through the three states.\n\n"
1640 "If you do not see an option (e.g., a device driver) that you believe\n"
1641 "should be present, try turning on Show All Options under the Options menu.\n"
1642 "Although there is no cross reference yet to help you figure out what other\n"
1643 "options must be enabled to support the option you are interested in, you can\n"
1644 "still view the help of a grayed-out option.\n\n"
1645 "Toggling Show Debug Info under the Options menu will show the dependencies,\n"
1646 "which you can then match by examining other options.\n\n");
1648 QMessageBox::information(this, "qconf", str);
1651 void ConfigMainWindow::showAbout(void)
1653 static const QString str = _("qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n\n"
1654 "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n");
1656 QMessageBox::information(this, "qconf", str);
1659 void ConfigMainWindow::saveSettings(void)
1661 configSettings->writeEntry("/window x", pos().x());
1662 configSettings->writeEntry("/window y", pos().y());
1663 configSettings->writeEntry("/window width", size().width());
1664 configSettings->writeEntry("/window height", size().height());
1667 switch(configList->mode) {
1683 configSettings->writeEntry("/listMode", entry);
1685 configSettings->writeSizes("/split1", split1->sizes());
1686 configSettings->writeSizes("/split2", split2->sizes());
1689 void ConfigMainWindow::conf_changed(void)
1692 saveAction->setEnabled(conf_get_changed());
1695 void fixup_rootmenu(struct menu *menu)
1698 static int menu_cnt = 0;
1700 menu->flags |= MENU_ROOT;
1701 for (child = menu->list; child; child = child->next) {
1702 if (child->prompt && child->prompt->type == P_MENU) {
1704 fixup_rootmenu(child);
1706 } else if (!menu_cnt)
1707 fixup_rootmenu(child);
1711 static const char *progname;
1713 static void usage(void)
1715 printf(_("%s <config>\n"), progname);
1719 int main(int ac, char** av)
1721 ConfigMainWindow* v;
1724 bindtextdomain(PACKAGE, LOCALEDIR);
1725 textdomain(PACKAGE);
1727 #ifndef LKC_DIRECT_LINK
1732 configApp = new QApplication(ac, av);
1733 if (ac > 1 && av[1][0] == '-') {
1746 fixup_rootmenu(&rootmenu);
1748 //zconfdump(stdout);
1750 configSettings = new ConfigSettings();
1751 configSettings->beginGroup("/kconfig/qconf");
1752 v = new ConfigMainWindow();
1754 //zconfdump(stdout);
1755 configApp->setMainWidget(v);
1756 configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit()));
1757 configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings()));
1761 configSettings->endGroup();
1762 delete configSettings;