2 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
3 * Released under the terms of the GNU GPL v2.0.
10 #include <qtextbrowser.h>
12 #include <QFileDialog>
15 #include <qapplication.h>
16 #include <qdesktopwidget.h>
19 #include <qsplitter.h>
20 #include <qlineedit.h>
22 #include <qpushbutton.h>
24 #include <qmessagebox.h>
41 static QApplication *configApp;
42 static ConfigSettings *configSettings;
44 QAction *ConfigMainWindow::saveAction;
46 static inline QString qgettext(const char* str)
48 return QString::fromLocal8Bit(gettext(str));
51 static inline QString qgettext(const QString& str)
53 return QString::fromLocal8Bit(gettext(str.toLatin1()));
56 ConfigSettings::ConfigSettings()
57 : QSettings("kernel.org", "qconf")
62 * Reads a list of integer values from the application settings.
64 QList<int> ConfigSettings::readSizes(const QString& key, bool *ok)
67 QStringList entryList = value(key).toStringList();
68 QStringList::Iterator it;
70 for (it = entryList.begin(); it != entryList.end(); ++it)
71 result.push_back((*it).toInt());
77 * Writes a list of integer values to the application settings.
79 bool ConfigSettings::writeSizes(const QString& key, const QList<int>& value)
81 QStringList stringList;
82 QList<int>::ConstIterator it;
84 for (it = value.begin(); it != value.end(); ++it)
85 stringList.push_back(QString::number(*it));
86 setValue(key, stringList);
94 * TODO check the value
96 void ConfigItem::okRename(int col)
101 * update the displayed of a menu entry
103 void ConfigItem::updateMenu(void)
107 struct property *prop;
114 setPixmap(promptColIdx, list->menuBackPix);
121 prompt = _(menu_get_prompt(menu));
123 if (prop) switch (prop->type) {
125 if (list->mode == singleMode || list->mode == symbolMode) {
126 /* a menuconfig entry is displayed differently
127 * depending whether it's at the view root or a child.
129 if (sym && list->rootEntry == menu)
131 setPixmap(promptColIdx, list->menuPix);
135 setPixmap(promptColIdx, QIcon());
139 setPixmap(promptColIdx, QIcon());
147 setText(nameColIdx, QString::fromLocal8Bit(sym->name));
149 type = sym_get_type(sym);
155 if (!sym_is_changable(sym) && list->optMode == normalOpt) {
156 setPixmap(promptColIdx, QIcon());
157 setText(noColIdx, QString::null);
158 setText(modColIdx, QString::null);
159 setText(yesColIdx, QString::null);
162 expr = sym_get_tristate_value(sym);
165 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
166 setPixmap(promptColIdx, list->choiceYesPix);
168 setPixmap(promptColIdx, list->symbolYesPix);
169 setText(yesColIdx, "Y");
173 setPixmap(promptColIdx, list->symbolModPix);
174 setText(modColIdx, "M");
178 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
179 setPixmap(promptColIdx, list->choiceNoPix);
181 setPixmap(promptColIdx, list->symbolNoPix);
182 setText(noColIdx, "N");
187 setText(noColIdx, sym_tristate_within_range(sym, no) ? "_" : 0);
189 setText(modColIdx, sym_tristate_within_range(sym, mod) ? "_" : 0);
191 setText(yesColIdx, sym_tristate_within_range(sym, yes) ? "_" : 0);
193 setText(dataColIdx, QChar(ch));
200 data = sym_get_string_value(sym);
202 //int i = list->mapIdx(dataColIdx);
204 // setRenameEnabled(i, true);
205 setText(dataColIdx, data);
206 if (type == S_STRING)
207 prompt = QString("%1: %2").arg(prompt).arg(data);
209 prompt = QString("(%2) %1").arg(prompt).arg(data);
212 if (!sym_has_value(sym) && visible)
213 prompt += _(" (NEW)");
215 setText(promptColIdx, prompt);
218 void ConfigItem::testUpdateMenu(bool v)
226 sym_calc_value(menu->sym);
227 if (menu->flags & MENU_CHANGED) {
228 /* the menu entry changed, so update all list items */
229 menu->flags &= ~MENU_CHANGED;
230 for (i = (ConfigItem*)menu->data; i; i = i->nextItem)
232 } else if (listView()->updateAll)
238 * construct a menu entry
240 void ConfigItem::init(void)
243 ConfigList* list = listView();
244 nextItem = (ConfigItem*)menu->data;
247 if (list->mode != fullMode)
249 sym_calc_value(menu->sym);
255 * destruct a menu entry
257 ConfigItem::~ConfigItem(void)
260 ConfigItem** ip = (ConfigItem**)&menu->data;
261 for (; *ip; ip = &(*ip)->nextItem) {
270 ConfigLineEdit::ConfigLineEdit(ConfigView* parent)
273 connect(this, SIGNAL(editingFinished()), SLOT(hide()));
276 void ConfigLineEdit::show(ConfigItem* i)
279 if (sym_get_string_value(item->menu->sym))
280 setText(QString::fromLocal8Bit(sym_get_string_value(item->menu->sym)));
282 setText(QString::null);
287 void ConfigLineEdit::keyPressEvent(QKeyEvent* e)
294 sym_set_string_value(item->menu->sym, text().toLatin1());
295 parent()->updateList(item);
298 Parent::keyPressEvent(e);
302 parent()->list->setFocus();
306 ConfigList::ConfigList(ConfigView* p, const char *name)
309 symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no),
310 choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no),
311 menuPix(xpm_menu), menuInvPix(xpm_menu_inv), menuBackPix(xpm_menuback), voidPix(xpm_void),
312 showName(false), showRange(false), showData(false), optMode(normalOpt),
313 rootEntry(0), headerPopup(0)
318 setSortingEnabled(-1);
319 setRootIsDecorated(true);
321 connect(this, SIGNAL(itemSelectionChanged(void)),
322 SLOT(updateSelection(void)));
325 configSettings->beginGroup(name);
326 showName = configSettings->value("/showName", false).toBool();
327 showRange = configSettings->value("/showRange", false).toBool();
328 showData = configSettings->value("/showData", false).toBool();
329 optMode = (enum optionMode)configSettings->value("/optionMode", 0).toInt();
330 configSettings->endGroup();
331 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
334 addColumn(promptColIdx);
339 bool ConfigList::menuSkip(struct menu *menu)
341 if (optMode == normalOpt && menu_is_visible(menu))
343 if (optMode == promptOpt && menu_has_prompt(menu))
345 if (optMode == allOpt)
350 void ConfigList::reinit(void)
352 removeColumn(dataColIdx);
353 removeColumn(yesColIdx);
354 removeColumn(modColIdx);
355 removeColumn(noColIdx);
356 removeColumn(nameColIdx);
359 addColumn(nameColIdx);
362 addColumn(modColIdx);
363 addColumn(yesColIdx);
366 addColumn(dataColIdx);
371 void ConfigList::saveSettings(void)
373 if (!objectName().isEmpty()) {
374 configSettings->beginGroup(objectName());
375 configSettings->setValue("/showName", showName);
376 configSettings->setValue("/showRange", showRange);
377 configSettings->setValue("/showData", showData);
378 configSettings->setValue("/optionMode", (int)optMode);
379 configSettings->endGroup();
383 ConfigItem* ConfigList::findConfigItem(struct menu *menu)
385 ConfigItem* item = (ConfigItem*)menu->data;
387 for (; item; item = item->nextItem) {
388 if (this == item->listView())
395 void ConfigList::updateSelection(void)
400 ConfigItem* item = (ConfigItem*)selectedItems().first();
405 emit menuChanged(menu);
408 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
409 if (mode == menuMode && type == P_MENU)
410 emit menuSelected(menu);
413 void ConfigList::updateList(ConfigItem* item)
415 ConfigItem* last = 0;
418 if (mode != listMode)
420 QTreeWidgetItemIterator it(this);
424 item = (ConfigItem*)(*it);
427 item->testUpdateMenu(menu_is_visible(item->menu));
434 if (rootEntry != &rootmenu && (mode == singleMode ||
435 (mode == symbolMode && rootEntry->parent != &rootmenu))) {
438 item = new ConfigItem(this, 0, true);
441 if ((mode == singleMode || (mode == symbolMode && !(rootEntry->flags & MENU_ROOT))) &&
442 rootEntry->sym && rootEntry->prompt) {
443 item = last ? last->nextSibling() : firstChild();
445 item = new ConfigItem(this, last, rootEntry, true);
447 item->testUpdateMenu(true);
449 updateMenuList(item, rootEntry);
454 updateMenuList(this, rootEntry);
458 void ConfigList::setValue(ConfigItem* item, tristate val)
464 sym = item->menu ? item->menu->sym : 0;
468 type = sym_get_type(sym);
472 oldval = sym_get_tristate_value(sym);
474 if (!sym_set_tristate_value(sym, val))
476 if (oldval == no && item->menu->list)
477 item->setExpanded(true);
478 parent()->updateList(item);
483 void ConfigList::changeValue(ConfigItem* item)
487 int type, oldexpr, newexpr;
494 if (item->menu->list)
495 item->setExpanded(!item->isExpanded());
499 type = sym_get_type(sym);
503 oldexpr = sym_get_tristate_value(sym);
504 newexpr = sym_toggle_tristate_value(sym);
505 if (item->menu->list) {
506 if (oldexpr == newexpr)
507 item->setExpanded(!item->isExpanded());
508 else if (oldexpr == no)
509 item->setExpanded(true);
511 if (oldexpr != newexpr)
512 parent()->updateList(item);
521 void ConfigList::setRootMenu(struct menu *menu)
525 if (rootEntry == menu)
527 type = menu && menu->prompt ? menu->prompt->type : P_UNKNOWN;
530 updateMenuList(this, 0);
534 currentItem()->setSelected(hasFocus());
535 scrollToItem(currentItem());
539 void ConfigList::setParentMenu(void)
542 struct menu *oldroot;
545 if (rootEntry == &rootmenu)
547 setRootMenu(menu_get_parent_menu(rootEntry->parent));
549 QTreeWidgetItemIterator it(this);
551 item = (ConfigItem *)(*it);
552 if (item->menu == oldroot) {
553 setCurrentItem(item);
563 * update all the children of a menu entry
564 * removes/adds the entries from the parent widget as necessary
566 * parent: either the menu list widget or a menu entry widget
567 * menu: entry to be updated
570 void ConfigList::updateMenuList(P* parent, struct menu* menu)
582 last = parent->firstChild();
583 if (last && !last->goParent)
585 for (child = menu->list; child; child = child->next) {
586 item = last ? last->nextSibling() : parent->firstChild();
587 type = child->prompt ? child->prompt->type : P_UNKNOWN;
591 if (!(child->flags & MENU_ROOT))
595 if (child->flags & MENU_ROOT)
602 visible = menu_is_visible(child);
603 if (!menuSkip(child)) {
604 if (!child->sym && !child->list && !child->prompt)
606 if (!item || item->menu != child)
607 item = new ConfigItem(parent, last, child, visible);
609 item->testUpdateMenu(visible);
611 if (mode == fullMode || mode == menuMode || type != P_MENU)
612 updateMenuList(item, child);
614 updateMenuList(item, 0);
619 if (item && item->menu == child) {
620 last = parent->firstChild();
623 else while (last->nextSibling() != item)
624 last = last->nextSibling();
630 void ConfigList::keyPressEvent(QKeyEvent* ev)
632 QTreeWidgetItem* i = currentItem();
637 if (ev->key() == Qt::Key_Escape && mode != fullMode && mode != listMode) {
638 emit parentSelected();
644 Parent::keyPressEvent(ev);
647 item = (ConfigItem*)i;
652 if (item->goParent) {
653 emit parentSelected();
659 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
660 if (type == P_MENU && rootEntry != menu &&
661 mode != fullMode && mode != menuMode) {
662 emit menuSelected(menu);
678 Parent::keyPressEvent(ev);
684 void ConfigList::mousePressEvent(QMouseEvent* e)
686 //QPoint p(contentsToViewport(e->pos()));
687 //printf("contentsMousePressEvent: %d,%d\n", p.x(), p.y());
688 Parent::mousePressEvent(e);
691 void ConfigList::mouseReleaseEvent(QMouseEvent* e)
694 ConfigItem* item = (ConfigItem*)itemAt(p);
696 enum prop_type ptype;
704 x = header()->offset() + p.x();
705 idx = header()->sectionPosition(x);
708 icon = item->pixmap(promptColIdx);
725 //printf("contentsMouseReleaseEvent: %d,%d\n", p.x(), p.y());
726 Parent::mouseReleaseEvent(e);
729 void ConfigList::mouseMoveEvent(QMouseEvent* e)
731 //QPoint p(contentsToViewport(e->pos()));
732 //printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y());
733 Parent::mouseMoveEvent(e);
736 void ConfigList::mouseDoubleClickEvent(QMouseEvent* e)
738 QPoint p = e->pos(); // TODO: Check if this works(was contentsToViewport).
739 ConfigItem* item = (ConfigItem*)itemAt(p);
741 enum prop_type ptype;
745 if (item->goParent) {
746 emit parentSelected();
752 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
753 if (ptype == P_MENU && (mode == singleMode || mode == symbolMode))
754 emit menuSelected(menu);
759 //printf("contentsMouseDoubleClickEvent: %d,%d\n", p.x(), p.y());
760 Parent::mouseDoubleClickEvent(e);
763 void ConfigList::focusInEvent(QFocusEvent *e)
765 struct menu *menu = NULL;
767 Parent::focusInEvent(e);
769 ConfigItem* item = (ConfigItem *)currentItem();
771 item->setSelected(true);
777 void ConfigList::contextMenuEvent(QContextMenuEvent *e)
779 if (e->y() <= header()->geometry().bottom()) {
783 headerPopup = new QMenu(this);
784 action = new QAction(_("Show Name"), this);
785 action->setCheckable(true);
786 connect(action, SIGNAL(toggled(bool)),
787 parent(), SLOT(setShowName(bool)));
788 connect(parent(), SIGNAL(showNameChanged(bool)),
789 action, SLOT(setOn(bool)));
790 action->setChecked(showName);
791 headerPopup->addAction(action);
792 action = new QAction(_("Show Range"), this);
793 action->setCheckable(true);
794 connect(action, SIGNAL(toggled(bool)),
795 parent(), SLOT(setShowRange(bool)));
796 connect(parent(), SIGNAL(showRangeChanged(bool)),
797 action, SLOT(setOn(bool)));
798 action->setChecked(showRange);
799 headerPopup->addAction(action);
800 action = new QAction(_("Show Data"), this);
801 action->setCheckable(true);
802 connect(action, SIGNAL(toggled(bool)),
803 parent(), SLOT(setShowData(bool)));
804 connect(parent(), SIGNAL(showDataChanged(bool)),
805 action, SLOT(setOn(bool)));
806 action->setChecked(showData);
807 headerPopup->addAction(action);
809 headerPopup->exec(e->globalPos());
815 ConfigView*ConfigView::viewList;
816 QAction *ConfigView::showNormalAction;
817 QAction *ConfigView::showAllAction;
818 QAction *ConfigView::showPromptAction;
820 ConfigView::ConfigView(QWidget* parent, const char *name)
824 QVBoxLayout *verticalLayout = new QVBoxLayout(this);
825 verticalLayout->setContentsMargins(0, 0, 0, 0);
827 list = new ConfigList(this);
828 verticalLayout->addWidget(list);
829 lineEdit = new ConfigLineEdit(this);
831 verticalLayout->addWidget(lineEdit);
833 this->nextView = viewList;
837 ConfigView::~ConfigView(void)
841 for (vp = &viewList; *vp; vp = &(*vp)->nextView) {
849 void ConfigView::setOptionMode(QAction *act)
851 if (act == showNormalAction)
852 list->optMode = normalOpt;
853 else if (act == showAllAction)
854 list->optMode = allOpt;
856 list->optMode = promptOpt;
858 list->updateListAll();
861 void ConfigView::setShowName(bool b)
863 if (list->showName != b) {
866 emit showNameChanged(b);
870 void ConfigView::setShowRange(bool b)
872 if (list->showRange != b) {
875 emit showRangeChanged(b);
879 void ConfigView::setShowData(bool b)
881 if (list->showData != b) {
884 emit showDataChanged(b);
888 void ConfigList::setAllOpen(bool open)
890 QTreeWidgetItemIterator it(this);
893 (*it)->setExpanded(open);
899 void ConfigView::updateList(ConfigItem* item)
903 for (v = viewList; v; v = v->nextView)
904 v->list->updateList(item);
907 void ConfigView::updateListAll(void)
911 for (v = viewList; v; v = v->nextView)
912 v->list->updateListAll();
915 ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name)
916 : Parent(parent), sym(0), _menu(0)
921 if (!objectName().isEmpty()) {
922 configSettings->beginGroup(objectName());
923 _showDebug = configSettings->value("/showDebug", false).toBool();
924 configSettings->endGroup();
925 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
929 void ConfigInfoView::saveSettings(void)
931 if (!objectName().isEmpty()) {
932 configSettings->beginGroup(objectName());
933 configSettings->setValue("/showDebug", showDebug());
934 configSettings->endGroup();
938 void ConfigInfoView::setShowDebug(bool b)
940 if (_showDebug != b) {
946 emit showDebugChanged(b);
950 void ConfigInfoView::setInfo(struct menu *m)
962 void ConfigInfoView::symbolInfo(void)
966 str += "<big>Symbol: <b>";
967 str += print_filter(sym->name);
968 str += "</b></big><br><br>value: ";
969 str += print_filter(sym_get_string_value(sym));
970 str += "<br>visibility: ";
971 str += sym->visible == yes ? "y" : sym->visible == mod ? "m" : "n";
973 str += debug_info(sym);
978 void ConfigInfoView::menuInfo(void)
981 QString head, debug, help;
987 head += print_filter(_(_menu->prompt->text));
988 head += "</b></big>";
992 head += QString().sprintf("<a href=\"s%p\">", sym);
993 head += print_filter(sym->name);
998 } else if (sym->name) {
1001 head += QString().sprintf("<a href=\"s%p\">", sym);
1002 head += print_filter(sym->name);
1005 head += "</b></big>";
1010 debug = debug_info(sym);
1012 struct gstr help_gstr = str_new();
1013 menu_get_ext_help(_menu, &help_gstr);
1014 help = print_filter(str_get(&help_gstr));
1015 str_free(&help_gstr);
1016 } else if (_menu->prompt) {
1018 head += print_filter(_(_menu->prompt->text));
1019 head += "</b></big><br><br>";
1021 if (_menu->prompt->visible.expr) {
1022 debug += " dep: ";
1023 expr_print(_menu->prompt->visible.expr, expr_print_help, &debug, E_NONE);
1024 debug += "<br><br>";
1029 debug += QString().sprintf("defined at %s:%d<br><br>", _menu->file->name, _menu->lineno);
1031 setText(head + debug + help);
1034 QString ConfigInfoView::debug_info(struct symbol *sym)
1039 debug += print_filter(sym_type_name(sym->type));
1040 if (sym_is_choice(sym))
1041 debug += " (choice)";
1043 if (sym->rev_dep.expr) {
1044 debug += "reverse dep: ";
1045 expr_print(sym->rev_dep.expr, expr_print_help, &debug, E_NONE);
1048 for (struct property *prop = sym->prop; prop; prop = prop->next) {
1049 switch (prop->type) {
1052 debug += QString().sprintf("prompt: <a href=\"m%p\">", prop->menu);
1053 debug += print_filter(_(prop->text));
1054 debug += "</a><br>";
1060 debug += prop_get_type_name(prop->type);
1062 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1066 if (sym_is_choice(sym)) {
1067 debug += "choice: ";
1068 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1073 debug += "unknown property: ";
1074 debug += prop_get_type_name(prop->type);
1077 if (prop->visible.expr) {
1078 debug += " dep: ";
1079 expr_print(prop->visible.expr, expr_print_help, &debug, E_NONE);
1088 QString ConfigInfoView::print_filter(const QString &str)
1090 QRegExp re("[<>&\"\\n]");
1092 for (int i = 0; (i = res.indexOf(re, i)) >= 0;) {
1093 switch (res[i].toLatin1()) {
1095 res.replace(i, 1, "<");
1099 res.replace(i, 1, ">");
1103 res.replace(i, 1, "&");
1107 res.replace(i, 1, """);
1111 res.replace(i, 1, "<br>");
1119 void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char *str)
1121 QString* text = reinterpret_cast<QString*>(data);
1122 QString str2 = print_filter(str);
1124 if (sym && sym->name && !(sym->flags & SYMBOL_CONST)) {
1125 *text += QString().sprintf("<a href=\"s%p\">", sym);
1132 QMenu* ConfigInfoView::createStandardContextMenu(const QPoint & pos)
1134 QMenu* popup = Parent::createStandardContextMenu(pos);
1135 QAction* action = new QAction(_("Show Debug Info"), popup);
1136 action->setCheckable(true);
1137 connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
1138 connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool)));
1139 action->setChecked(showDebug());
1140 popup->addSeparator();
1141 popup->addAction(action);
1145 void ConfigInfoView::contextMenuEvent(QContextMenuEvent *e)
1147 Parent::contextMenuEvent(e);
1150 ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow* parent, const char *name)
1151 : Parent(parent), result(NULL)
1153 setObjectName(name);
1154 setWindowTitle("Search Config");
1156 QVBoxLayout* layout1 = new QVBoxLayout(this);
1157 layout1->setContentsMargins(11, 11, 11, 11);
1158 layout1->setSpacing(6);
1159 QHBoxLayout* layout2 = new QHBoxLayout(0);
1160 layout2->setContentsMargins(0, 0, 0, 0);
1161 layout2->setSpacing(6);
1162 layout2->addWidget(new QLabel(_("Find:"), this));
1163 editField = new QLineEdit(this);
1164 connect(editField, SIGNAL(returnPressed()), SLOT(search()));
1165 layout2->addWidget(editField);
1166 searchButton = new QPushButton(_("Search"), this);
1167 searchButton->setAutoDefault(false);
1168 connect(searchButton, SIGNAL(clicked()), SLOT(search()));
1169 layout2->addWidget(searchButton);
1170 layout1->addLayout(layout2);
1172 split = new QSplitter(this);
1173 split->setOrientation(Qt::Vertical);
1174 list = new ConfigView(split, name);
1175 list->list->mode = listMode;
1176 info = new ConfigInfoView(split, name);
1177 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1178 info, SLOT(setInfo(struct menu *)));
1179 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1180 parent, SLOT(setMenuLink(struct menu *)));
1182 layout1->addWidget(split);
1189 configSettings->beginGroup(name);
1190 width = configSettings->value("/window width", parent->width() / 2).toInt();
1191 height = configSettings->value("/window height", parent->height() / 2).toInt();
1192 resize(width, height);
1193 x = configSettings->value("/window x");
1194 y = configSettings->value("/window y");
1195 if ((x.isValid())&&(y.isValid()))
1196 move(x.toInt(), y.toInt());
1197 QList<int> sizes = configSettings->readSizes("/split", &ok);
1199 split->setSizes(sizes);
1200 configSettings->endGroup();
1201 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
1205 void ConfigSearchWindow::saveSettings(void)
1207 if (!objectName().isEmpty()) {
1208 configSettings->beginGroup(objectName());
1209 configSettings->setValue("/window x", pos().x());
1210 configSettings->setValue("/window y", pos().y());
1211 configSettings->setValue("/window width", size().width());
1212 configSettings->setValue("/window height", size().height());
1213 configSettings->writeSizes("/split", split->sizes());
1214 configSettings->endGroup();
1218 void ConfigSearchWindow::search(void)
1221 struct property *prop;
1222 ConfigItem *lastItem = NULL;
1225 list->list->clear();
1228 result = sym_re_search(editField->text().toLatin1());
1231 for (p = result; *p; p++) {
1232 for_all_prompts((*p), prop)
1233 lastItem = new ConfigItem(list->list, lastItem, prop->menu,
1234 menu_is_visible(prop->menu));
1239 * Construct the complete config widget
1241 ConfigMainWindow::ConfigMainWindow(void)
1250 QDesktopWidget *d = configApp->desktop();
1251 snprintf(title, sizeof(title), "%s%s",
1252 rootmenu.prompt->text,
1255 setWindowTitle(title);
1257 width = configSettings->value("/window width", d->width() - 64).toInt();
1258 height = configSettings->value("/window height", d->height() - 64).toInt();
1259 resize(width, height);
1260 x = configSettings->value("/window x");
1261 y = configSettings->value("/window y");
1262 if ((x.isValid())&&(y.isValid()))
1263 move(x.toInt(), y.toInt());
1265 split1 = new QSplitter(this);
1266 split1->setOrientation(Qt::Horizontal);
1267 setCentralWidget(split1);
1269 menuView = new ConfigView(split1, "menu");
1270 menuList = menuView->list;
1272 split2 = new QSplitter(split1);
1273 split2->setOrientation(Qt::Vertical);
1275 // create config tree
1276 configView = new ConfigView(split2, "config");
1277 configList = configView->list;
1279 helpText = new ConfigInfoView(split2, "help");
1280 //helpText->setTextFormat(Qt::RichText);
1282 setTabOrder(configList, helpText);
1283 configList->setFocus();
1286 toolBar = new QToolBar("Tools", this);
1287 addToolBar(toolBar);
1289 backAction = new QAction(QPixmap(xpm_back), _("Back"), this);
1290 connect(backAction, SIGNAL(triggered(bool)), SLOT(goBack()));
1291 backAction->setEnabled(false);
1292 QAction *quitAction = new QAction(_("&Quit"), this);
1293 quitAction->setShortcut(Qt::CTRL + Qt::Key_Q);
1294 connect(quitAction, SIGNAL(triggered(bool)), SLOT(close()));
1295 QAction *loadAction = new QAction(QPixmap(xpm_load), _("&Load"), this);
1296 loadAction->setShortcut(Qt::CTRL + Qt::Key_L);
1297 connect(loadAction, SIGNAL(triggered(bool)), SLOT(loadConfig()));
1298 saveAction = new QAction(QPixmap(xpm_save), _("&Save"), this);
1299 saveAction->setShortcut(Qt::CTRL + Qt::Key_S);
1300 connect(saveAction, SIGNAL(triggered(bool)), SLOT(saveConfig()));
1301 conf_set_changed_callback(conf_changed);
1302 // Set saveAction's initial state
1304 QAction *saveAsAction = new QAction(_("Save &As..."), this);
1305 connect(saveAsAction, SIGNAL(triggered(bool)), SLOT(saveConfigAs()));
1306 QAction *searchAction = new QAction(_("&Find"), this);
1307 searchAction->setShortcut(Qt::CTRL + Qt::Key_F);
1308 connect(searchAction, SIGNAL(triggered(bool)), SLOT(searchConfig()));
1309 singleViewAction = new QAction(QPixmap(xpm_single_view), _("Single View"), this);
1310 singleViewAction->setCheckable(true);
1311 connect(singleViewAction, SIGNAL(triggered(bool)), SLOT(showSingleView()));
1312 splitViewAction = new QAction(QPixmap(xpm_split_view), _("Split View"), this);
1313 splitViewAction->setCheckable(true);
1314 connect(splitViewAction, SIGNAL(triggered(bool)), SLOT(showSplitView()));
1315 fullViewAction = new QAction(QPixmap(xpm_tree_view), _("Full View"), this);
1316 fullViewAction->setCheckable(true);
1317 connect(fullViewAction, SIGNAL(triggered(bool)), SLOT(showFullView()));
1319 QAction *showNameAction = new QAction(_("Show Name"), this);
1320 showNameAction->setCheckable(true);
1321 connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool)));
1322 showNameAction->setChecked(configView->showName());
1323 QAction *showRangeAction = new QAction(_("Show Range"), this);
1324 showRangeAction->setCheckable(true);
1325 connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool)));
1326 QAction *showDataAction = new QAction(_("Show Data"), this);
1327 showDataAction->setCheckable(true);
1328 connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool)));
1330 QActionGroup *optGroup = new QActionGroup(this);
1331 optGroup->setExclusive(true);
1332 connect(optGroup, SIGNAL(triggered(QAction*)), configView,
1333 SLOT(setOptionMode(QAction *)));
1334 connect(optGroup, SIGNAL(triggered(QAction *)), menuView,
1335 SLOT(setOptionMode(QAction *)));
1337 configView->showNormalAction = new QAction(_("Show Normal Options"), optGroup);
1338 configView->showAllAction = new QAction(_("Show All Options"), optGroup);
1339 configView->showPromptAction = new QAction(_("Show Prompt Options"), optGroup);
1340 configView->showNormalAction->setCheckable(true);
1341 configView->showAllAction->setCheckable(true);
1342 configView->showPromptAction->setCheckable(true);
1344 QAction *showDebugAction = new QAction( _("Show Debug Info"), this);
1345 showDebugAction->setCheckable(true);
1346 connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
1347 showDebugAction->setChecked(helpText->showDebug());
1349 QAction *showIntroAction = new QAction( _("Introduction"), this);
1350 connect(showIntroAction, SIGNAL(triggered(bool)), SLOT(showIntro()));
1351 QAction *showAboutAction = new QAction( _("About"), this);
1352 connect(showAboutAction, SIGNAL(triggered(bool)), SLOT(showAbout()));
1355 toolBar->addAction(backAction);
1356 toolBar->addSeparator();
1357 toolBar->addAction(loadAction);
1358 toolBar->addAction(saveAction);
1359 toolBar->addSeparator();
1360 toolBar->addAction(singleViewAction);
1361 toolBar->addAction(splitViewAction);
1362 toolBar->addAction(fullViewAction);
1364 // create config menu
1365 QMenu* config = menu->addMenu(_("&File"));
1366 config->addAction(loadAction);
1367 config->addAction(saveAction);
1368 config->addAction(saveAsAction);
1369 config->addSeparator();
1370 config->addAction(quitAction);
1373 QMenu* editMenu = menu->addMenu(_("&Edit"));
1374 editMenu->addAction(searchAction);
1376 // create options menu
1377 QMenu* optionMenu = menu->addMenu(_("&Option"));
1378 optionMenu->addAction(showNameAction);
1379 optionMenu->addAction(showRangeAction);
1380 optionMenu->addAction(showDataAction);
1381 optionMenu->addSeparator();
1382 optionMenu->addActions(optGroup->actions());
1383 optionMenu->addSeparator();
1386 menu->addSeparator();
1387 QMenu* helpMenu = menu->addMenu(_("&Help"));
1388 helpMenu->addAction(showIntroAction);
1389 helpMenu->addAction(showAboutAction);
1391 connect(configList, SIGNAL(menuChanged(struct menu *)),
1392 helpText, SLOT(setInfo(struct menu *)));
1393 connect(configList, SIGNAL(menuSelected(struct menu *)),
1394 SLOT(changeMenu(struct menu *)));
1395 connect(configList, SIGNAL(parentSelected()),
1397 connect(menuList, SIGNAL(menuChanged(struct menu *)),
1398 helpText, SLOT(setInfo(struct menu *)));
1399 connect(menuList, SIGNAL(menuSelected(struct menu *)),
1400 SLOT(changeMenu(struct menu *)));
1402 connect(configList, SIGNAL(gotFocus(struct menu *)),
1403 helpText, SLOT(setInfo(struct menu *)));
1404 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1405 helpText, SLOT(setInfo(struct menu *)));
1406 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1407 SLOT(listFocusChanged(void)));
1408 connect(helpText, SIGNAL(menuSelected(struct menu *)),
1409 SLOT(setMenuLink(struct menu *)));
1411 QString listMode = configSettings->value("/listMode", "symbol").toString();
1412 if (listMode == "single")
1414 else if (listMode == "full")
1416 else /*if (listMode == "split")*/
1419 // UI setup done, restore splitter positions
1420 QList<int> sizes = configSettings->readSizes("/split1", &ok);
1422 split1->setSizes(sizes);
1424 sizes = configSettings->readSizes("/split2", &ok);
1426 split2->setSizes(sizes);
1429 void ConfigMainWindow::loadConfig(void)
1431 QString s = QFileDialog::getOpenFileName(this, "", conf_get_configname());
1434 if (conf_read(QFile::encodeName(s)))
1435 QMessageBox::information(this, "qconf", _("Unable to load configuration!"));
1436 ConfigView::updateListAll();
1439 bool ConfigMainWindow::saveConfig(void)
1441 if (conf_write(NULL)) {
1442 QMessageBox::information(this, "qconf", _("Unable to save configuration!"));
1448 void ConfigMainWindow::saveConfigAs(void)
1450 QString s = QFileDialog::getSaveFileName(this, "", conf_get_configname());
1456 void ConfigMainWindow::searchConfig(void)
1459 searchWindow = new ConfigSearchWindow(this, "search");
1460 searchWindow->show();
1463 void ConfigMainWindow::changeMenu(struct menu *menu)
1465 configList->setRootMenu(menu);
1466 if (configList->rootEntry->parent == &rootmenu)
1467 backAction->setEnabled(false);
1469 backAction->setEnabled(true);
1472 void ConfigMainWindow::setMenuLink(struct menu *menu)
1474 struct menu *parent;
1475 ConfigList* list = NULL;
1478 if (configList->menuSkip(menu))
1481 switch (configList->mode) {
1484 parent = menu_get_parent_menu(menu);
1487 list->setRootMenu(parent);
1490 if (menu->flags & MENU_ROOT) {
1491 configList->setRootMenu(menu);
1492 configList->clearSelection();
1496 parent = menu_get_parent_menu(menu->parent);
1499 item = menuList->findConfigItem(parent);
1501 item->setSelected(true);
1502 menuList->scrollToItem(item);
1504 list->setRootMenu(parent);
1515 item = list->findConfigItem(menu);
1517 item->setSelected(true);
1518 list->scrollToItem(item);
1524 void ConfigMainWindow::listFocusChanged(void)
1526 if (menuList->mode == menuMode)
1527 configList->clearSelection();
1530 void ConfigMainWindow::goBack(void)
1534 configList->setParentMenu();
1535 if (configList->rootEntry == &rootmenu)
1536 backAction->setEnabled(false);
1537 item = (ConfigItem*)menuList->selectedItems().first();
1539 if (item->menu == configList->rootEntry) {
1540 item->setSelected(true);
1543 item = (ConfigItem*)item->parent();
1547 void ConfigMainWindow::showSingleView(void)
1549 singleViewAction->setEnabled(false);
1550 singleViewAction->setChecked(true);
1551 splitViewAction->setEnabled(true);
1552 splitViewAction->setChecked(false);
1553 fullViewAction->setEnabled(true);
1554 fullViewAction->setChecked(false);
1557 menuList->setRootMenu(0);
1558 configList->mode = singleMode;
1559 if (configList->rootEntry == &rootmenu)
1560 configList->updateListAll();
1562 configList->setRootMenu(&rootmenu);
1563 configList->setFocus();
1566 void ConfigMainWindow::showSplitView(void)
1568 singleViewAction->setEnabled(true);
1569 singleViewAction->setChecked(false);
1570 splitViewAction->setEnabled(false);
1571 splitViewAction->setChecked(true);
1572 fullViewAction->setEnabled(true);
1573 fullViewAction->setChecked(false);
1575 configList->mode = symbolMode;
1576 if (configList->rootEntry == &rootmenu)
1577 configList->updateListAll();
1579 configList->setRootMenu(&rootmenu);
1580 configList->setAllOpen(true);
1581 configApp->processEvents();
1582 menuList->mode = menuMode;
1583 menuList->setRootMenu(&rootmenu);
1584 menuList->setAllOpen(true);
1586 menuList->setFocus();
1589 void ConfigMainWindow::showFullView(void)
1591 singleViewAction->setEnabled(true);
1592 singleViewAction->setChecked(false);
1593 splitViewAction->setEnabled(true);
1594 splitViewAction->setChecked(false);
1595 fullViewAction->setEnabled(false);
1596 fullViewAction->setChecked(true);
1599 menuList->setRootMenu(0);
1600 configList->mode = fullMode;
1601 if (configList->rootEntry == &rootmenu)
1602 configList->updateListAll();
1604 configList->setRootMenu(&rootmenu);
1605 configList->setFocus();
1609 * ask for saving configuration before quitting
1610 * TODO ask only when something changed
1612 void ConfigMainWindow::closeEvent(QCloseEvent* e)
1614 if (!conf_get_changed()) {
1618 QMessageBox mb("qconf", _("Save configuration?"), QMessageBox::Warning,
1619 QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape);
1620 mb.setButtonText(QMessageBox::Yes, _("&Save Changes"));
1621 mb.setButtonText(QMessageBox::No, _("&Discard Changes"));
1622 mb.setButtonText(QMessageBox::Cancel, _("Cancel Exit"));
1623 switch (mb.exec()) {
1624 case QMessageBox::Yes:
1630 case QMessageBox::No:
1633 case QMessageBox::Cancel:
1639 void ConfigMainWindow::showIntro(void)
1641 static const QString str = _("Welcome to the qconf graphical configuration tool.\n\n"
1642 "For each option, a blank box indicates the feature is disabled, a check\n"
1643 "indicates it is enabled, and a dot indicates that it is to be compiled\n"
1644 "as a module. Clicking on the box will cycle through the three states.\n\n"
1645 "If you do not see an option (e.g., a device driver) that you believe\n"
1646 "should be present, try turning on Show All Options under the Options menu.\n"
1647 "Although there is no cross reference yet to help you figure out what other\n"
1648 "options must be enabled to support the option you are interested in, you can\n"
1649 "still view the help of a grayed-out option.\n\n"
1650 "Toggling Show Debug Info under the Options menu will show the dependencies,\n"
1651 "which you can then match by examining other options.\n\n");
1653 QMessageBox::information(this, "qconf", str);
1656 void ConfigMainWindow::showAbout(void)
1658 static const QString str = _("qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n\n"
1659 "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n");
1661 QMessageBox::information(this, "qconf", str);
1664 void ConfigMainWindow::saveSettings(void)
1666 configSettings->setValue("/window x", pos().x());
1667 configSettings->setValue("/window y", pos().y());
1668 configSettings->setValue("/window width", size().width());
1669 configSettings->setValue("/window height", size().height());
1672 switch(configList->mode) {
1688 configSettings->setValue("/listMode", entry);
1690 configSettings->writeSizes("/split1", split1->sizes());
1691 configSettings->writeSizes("/split2", split2->sizes());
1694 void ConfigMainWindow::conf_changed(void)
1697 saveAction->setEnabled(conf_get_changed());
1700 void fixup_rootmenu(struct menu *menu)
1703 static int menu_cnt = 0;
1705 menu->flags |= MENU_ROOT;
1706 for (child = menu->list; child; child = child->next) {
1707 if (child->prompt && child->prompt->type == P_MENU) {
1709 fixup_rootmenu(child);
1711 } else if (!menu_cnt)
1712 fixup_rootmenu(child);
1716 static const char *progname;
1718 static void usage(void)
1720 printf(_("%s [-s] <config>\n").toLatin1().constData(), progname);
1724 int main(int ac, char** av)
1726 ConfigMainWindow* v;
1729 bindtextdomain(PACKAGE, LOCALEDIR);
1730 textdomain(PACKAGE);
1733 configApp = new QApplication(ac, av);
1734 if (ac > 1 && av[1][0] == '-') {
1737 conf_set_message_callback(NULL);
1750 fixup_rootmenu(&rootmenu);
1752 //zconfdump(stdout);
1754 configSettings = new ConfigSettings();
1755 configSettings->beginGroup("/kconfig/qconf");
1756 v = new ConfigMainWindow();
1758 //zconfdump(stdout);
1759 configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit()));
1760 configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings()));
1764 configSettings->endGroup();
1765 delete configSettings;