2 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
3 * Released under the terms of the GNU GPL v2.0.
11 #include <qtextbrowser.h>
14 #include <QFileDialog>
15 #include <q3dragobject.h>
18 #include <qapplication.h>
19 #include <qdesktopwidget.h>
22 #include <qsplitter.h>
23 #include <qlineedit.h>
25 #include <qpushbutton.h>
27 #include <qmessagebox.h>
44 static QApplication *configApp;
45 static ConfigSettings *configSettings;
47 QAction *ConfigMainWindow::saveAction;
49 static inline QString qgettext(const char* str)
51 return QString::fromLocal8Bit(gettext(str));
54 static inline QString qgettext(const QString& str)
56 return QString::fromLocal8Bit(gettext(str.latin1()));
59 ConfigSettings::ConfigSettings()
60 : QSettings("kernel.org", "qconf")
65 * Reads a list of integer values from the application settings.
67 QList<int> ConfigSettings::readSizes(const QString& key, bool *ok)
70 QStringList entryList = readListEntry(key, ok);
71 QStringList::Iterator it;
73 for (it = entryList.begin(); it != entryList.end(); ++it)
74 result.push_back((*it).toInt());
80 * Writes a list of integer values to the application settings.
82 bool ConfigSettings::writeSizes(const QString& key, const QList<int>& value)
84 QStringList stringList;
85 QList<int>::ConstIterator it;
87 for (it = value.begin(); it != value.end(); ++it)
88 stringList.push_back(QString::number(*it));
89 return writeEntry(key, stringList);
95 * TODO check the value
97 void ConfigItem::okRename(int col)
99 Parent::okRename(col);
100 sym_set_string_value(menu->sym, text(dataColIdx).latin1());
101 listView()->updateList(this);
105 * update the displayed of a menu entry
107 void ConfigItem::updateMenu(void)
111 struct property *prop;
118 setPixmap(promptColIdx, list->menuBackPix);
125 prompt = _(menu_get_prompt(menu));
127 if (prop) switch (prop->type) {
129 if (list->mode == singleMode || list->mode == symbolMode) {
130 /* a menuconfig entry is displayed differently
131 * depending whether it's at the view root or a child.
133 if (sym && list->rootEntry == menu)
135 setPixmap(promptColIdx, list->menuPix);
139 setPixmap(promptColIdx, 0);
143 setPixmap(promptColIdx, 0);
151 setText(nameColIdx, QString::fromLocal8Bit(sym->name));
153 type = sym_get_type(sym);
159 if (!sym_is_changable(sym) && list->optMode == normalOpt) {
160 setPixmap(promptColIdx, 0);
161 setText(noColIdx, QString::null);
162 setText(modColIdx, QString::null);
163 setText(yesColIdx, QString::null);
166 expr = sym_get_tristate_value(sym);
169 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
170 setPixmap(promptColIdx, list->choiceYesPix);
172 setPixmap(promptColIdx, list->symbolYesPix);
173 setText(yesColIdx, "Y");
177 setPixmap(promptColIdx, list->symbolModPix);
178 setText(modColIdx, "M");
182 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
183 setPixmap(promptColIdx, list->choiceNoPix);
185 setPixmap(promptColIdx, list->symbolNoPix);
186 setText(noColIdx, "N");
191 setText(noColIdx, sym_tristate_within_range(sym, no) ? "_" : 0);
193 setText(modColIdx, sym_tristate_within_range(sym, mod) ? "_" : 0);
195 setText(yesColIdx, sym_tristate_within_range(sym, yes) ? "_" : 0);
197 setText(dataColIdx, QChar(ch));
204 data = sym_get_string_value(sym);
206 int i = list->mapIdx(dataColIdx);
208 setRenameEnabled(i, TRUE);
209 setText(dataColIdx, data);
210 if (type == S_STRING)
211 prompt = QString("%1: %2").arg(prompt).arg(data);
213 prompt = QString("(%2) %1").arg(prompt).arg(data);
216 if (!sym_has_value(sym) && visible)
217 prompt += _(" (NEW)");
219 setText(promptColIdx, prompt);
222 void ConfigItem::testUpdateMenu(bool v)
230 sym_calc_value(menu->sym);
231 if (menu->flags & MENU_CHANGED) {
232 /* the menu entry changed, so update all list items */
233 menu->flags &= ~MENU_CHANGED;
234 for (i = (ConfigItem*)menu->data; i; i = i->nextItem)
236 } else if (listView()->updateAll)
240 void ConfigItem::paintCell(QPainter* p, const QColorGroup& cg, int column, int width, int align)
242 ConfigList* list = listView();
245 if (isSelected() && !list->hasFocus() && list->mode == menuMode)
246 Parent::paintCell(p, list->inactivedColorGroup, column, width, align);
248 Parent::paintCell(p, cg, column, width, align);
250 Parent::paintCell(p, list->disabledColorGroup, column, width, align);
254 * construct a menu entry
256 void ConfigItem::init(void)
259 ConfigList* list = listView();
260 nextItem = (ConfigItem*)menu->data;
263 if (list->mode != fullMode)
265 sym_calc_value(menu->sym);
271 * destruct a menu entry
273 ConfigItem::~ConfigItem(void)
276 ConfigItem** ip = (ConfigItem**)&menu->data;
277 for (; *ip; ip = &(*ip)->nextItem) {
286 ConfigLineEdit::ConfigLineEdit(ConfigView* parent)
289 connect(this, SIGNAL(lostFocus()), SLOT(hide()));
292 void ConfigLineEdit::show(ConfigItem* i)
295 if (sym_get_string_value(item->menu->sym))
296 setText(QString::fromLocal8Bit(sym_get_string_value(item->menu->sym)));
298 setText(QString::null);
303 void ConfigLineEdit::keyPressEvent(QKeyEvent* e)
310 sym_set_string_value(item->menu->sym, text().latin1());
311 parent()->updateList(item);
314 Parent::keyPressEvent(e);
318 parent()->list->setFocus();
322 ConfigList::ConfigList(ConfigView* p, const char *name)
325 symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no),
326 choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no),
327 menuPix(xpm_menu), menuInvPix(xpm_menu_inv), menuBackPix(xpm_menuback), voidPix(xpm_void),
328 showName(false), showRange(false), showData(false), optMode(normalOpt),
329 rootEntry(0), headerPopup(0)
334 setRootIsDecorated(TRUE);
335 disabledColorGroup = palette().active();
336 disabledColorGroup.setColor(QColorGroup::Text, palette().disabled().text());
337 inactivedColorGroup = palette().active();
338 inactivedColorGroup.setColor(QColorGroup::Highlight, palette().disabled().highlight());
340 connect(this, SIGNAL(selectionChanged(void)),
341 SLOT(updateSelection(void)));
344 configSettings->beginGroup(name);
345 showName = configSettings->readBoolEntry("/showName", false);
346 showRange = configSettings->readBoolEntry("/showRange", false);
347 showData = configSettings->readBoolEntry("/showData", false);
348 optMode = (enum optionMode)configSettings->readNumEntry("/optionMode", false);
349 configSettings->endGroup();
350 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
353 for (i = 0; i < colNr; i++)
354 colMap[i] = colRevMap[i] = -1;
355 addColumn(promptColIdx, _("Option"));
360 bool ConfigList::menuSkip(struct menu *menu)
362 if (optMode == normalOpt && menu_is_visible(menu))
364 if (optMode == promptOpt && menu_has_prompt(menu))
366 if (optMode == allOpt)
371 void ConfigList::reinit(void)
373 removeColumn(dataColIdx);
374 removeColumn(yesColIdx);
375 removeColumn(modColIdx);
376 removeColumn(noColIdx);
377 removeColumn(nameColIdx);
380 addColumn(nameColIdx, _("Name"));
382 addColumn(noColIdx, "N");
383 addColumn(modColIdx, "M");
384 addColumn(yesColIdx, "Y");
387 addColumn(dataColIdx, _("Value"));
392 void ConfigList::saveSettings(void)
395 configSettings->beginGroup(name());
396 configSettings->writeEntry("/showName", showName);
397 configSettings->writeEntry("/showRange", showRange);
398 configSettings->writeEntry("/showData", showData);
399 configSettings->writeEntry("/optionMode", (int)optMode);
400 configSettings->endGroup();
404 ConfigItem* ConfigList::findConfigItem(struct menu *menu)
406 ConfigItem* item = (ConfigItem*)menu->data;
408 for (; item; item = item->nextItem) {
409 if (this == item->listView())
416 void ConfigList::updateSelection(void)
421 ConfigItem* item = (ConfigItem*)selectedItem();
426 emit menuChanged(menu);
429 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
430 if (mode == menuMode && type == P_MENU)
431 emit menuSelected(menu);
434 void ConfigList::updateList(ConfigItem* item)
436 ConfigItem* last = 0;
439 if (mode != listMode)
441 Q3ListViewItemIterator it(this);
444 for (; it.current(); ++it) {
445 item = (ConfigItem*)it.current();
448 item->testUpdateMenu(menu_is_visible(item->menu));
453 if (rootEntry != &rootmenu && (mode == singleMode ||
454 (mode == symbolMode && rootEntry->parent != &rootmenu))) {
457 item = new ConfigItem(this, 0, true);
460 if ((mode == singleMode || (mode == symbolMode && !(rootEntry->flags & MENU_ROOT))) &&
461 rootEntry->sym && rootEntry->prompt) {
462 item = last ? last->nextSibling() : firstChild();
464 item = new ConfigItem(this, last, rootEntry, true);
466 item->testUpdateMenu(true);
468 updateMenuList(item, rootEntry);
473 updateMenuList(this, rootEntry);
477 void ConfigList::setValue(ConfigItem* item, tristate val)
483 sym = item->menu ? item->menu->sym : 0;
487 type = sym_get_type(sym);
491 oldval = sym_get_tristate_value(sym);
493 if (!sym_set_tristate_value(sym, val))
495 if (oldval == no && item->menu->list)
497 parent()->updateList(item);
502 void ConfigList::changeValue(ConfigItem* item)
506 int type, oldexpr, newexpr;
513 if (item->menu->list)
514 item->setOpen(!item->isOpen());
518 type = sym_get_type(sym);
522 oldexpr = sym_get_tristate_value(sym);
523 newexpr = sym_toggle_tristate_value(sym);
524 if (item->menu->list) {
525 if (oldexpr == newexpr)
526 item->setOpen(!item->isOpen());
527 else if (oldexpr == no)
530 if (oldexpr != newexpr)
531 parent()->updateList(item);
536 if (colMap[dataColIdx] >= 0)
537 item->startRename(colMap[dataColIdx]);
539 parent()->lineEdit->show(item);
544 void ConfigList::setRootMenu(struct menu *menu)
548 if (rootEntry == menu)
550 type = menu && menu->prompt ? menu->prompt->type : P_UNKNOWN;
553 updateMenuList(this, 0);
556 setSelected(currentItem(), hasFocus());
557 ensureItemVisible(currentItem());
560 void ConfigList::setParentMenu(void)
563 struct menu *oldroot;
566 if (rootEntry == &rootmenu)
568 setRootMenu(menu_get_parent_menu(rootEntry->parent));
570 Q3ListViewItemIterator it(this);
571 for (; (item = (ConfigItem*)it.current()); it++) {
572 if (item->menu == oldroot) {
573 setCurrentItem(item);
574 ensureItemVisible(item);
581 * update all the children of a menu entry
582 * removes/adds the entries from the parent widget as necessary
584 * parent: either the menu list widget or a menu entry widget
585 * menu: entry to be updated
588 void ConfigList::updateMenuList(P* parent, struct menu* menu)
597 while ((item = parent->firstChild()))
602 last = parent->firstChild();
603 if (last && !last->goParent)
605 for (child = menu->list; child; child = child->next) {
606 item = last ? last->nextSibling() : parent->firstChild();
607 type = child->prompt ? child->prompt->type : P_UNKNOWN;
611 if (!(child->flags & MENU_ROOT))
615 if (child->flags & MENU_ROOT)
622 visible = menu_is_visible(child);
623 if (!menuSkip(child)) {
624 if (!child->sym && !child->list && !child->prompt)
626 if (!item || item->menu != child)
627 item = new ConfigItem(parent, last, child, visible);
629 item->testUpdateMenu(visible);
631 if (mode == fullMode || mode == menuMode || type != P_MENU)
632 updateMenuList(item, child);
634 updateMenuList(item, 0);
639 if (item && item->menu == child) {
640 last = parent->firstChild();
643 else while (last->nextSibling() != item)
644 last = last->nextSibling();
650 void ConfigList::keyPressEvent(QKeyEvent* ev)
652 Q3ListViewItem* i = currentItem();
657 if (ev->key() == Qt::Key_Escape && mode != fullMode && mode != listMode) {
658 emit parentSelected();
664 Parent::keyPressEvent(ev);
667 item = (ConfigItem*)i;
672 if (item->goParent) {
673 emit parentSelected();
679 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
680 if (type == P_MENU && rootEntry != menu &&
681 mode != fullMode && mode != menuMode) {
682 emit menuSelected(menu);
698 Parent::keyPressEvent(ev);
704 void ConfigList::contentsMousePressEvent(QMouseEvent* e)
706 //QPoint p(contentsToViewport(e->pos()));
707 //printf("contentsMousePressEvent: %d,%d\n", p.x(), p.y());
708 Parent::contentsMousePressEvent(e);
711 void ConfigList::contentsMouseReleaseEvent(QMouseEvent* e)
713 QPoint p(contentsToViewport(e->pos()));
714 ConfigItem* item = (ConfigItem*)itemAt(p);
716 enum prop_type ptype;
724 x = header()->offset() + p.x();
725 idx = colRevMap[header()->sectionAt(x)];
728 pm = item->pixmap(promptColIdx);
730 int off = header()->sectionPos(0) + itemMargin() +
731 treeStepSize() * (item->depth() + (rootIsDecorated() ? 1 : 0));
732 if (x >= off && x < off + pm->width()) {
733 if (item->goParent) {
734 emit parentSelected();
738 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
739 if (ptype == P_MENU && rootEntry != menu &&
740 mode != fullMode && mode != menuMode)
741 emit menuSelected(menu);
762 //printf("contentsMouseReleaseEvent: %d,%d\n", p.x(), p.y());
763 Parent::contentsMouseReleaseEvent(e);
766 void ConfigList::contentsMouseMoveEvent(QMouseEvent* e)
768 //QPoint p(contentsToViewport(e->pos()));
769 //printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y());
770 Parent::contentsMouseMoveEvent(e);
773 void ConfigList::contentsMouseDoubleClickEvent(QMouseEvent* e)
775 QPoint p(contentsToViewport(e->pos()));
776 ConfigItem* item = (ConfigItem*)itemAt(p);
778 enum prop_type ptype;
782 if (item->goParent) {
783 emit parentSelected();
789 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
790 if (ptype == P_MENU && (mode == singleMode || mode == symbolMode))
791 emit menuSelected(menu);
796 //printf("contentsMouseDoubleClickEvent: %d,%d\n", p.x(), p.y());
797 Parent::contentsMouseDoubleClickEvent(e);
800 void ConfigList::focusInEvent(QFocusEvent *e)
802 struct menu *menu = NULL;
804 Parent::focusInEvent(e);
806 ConfigItem* item = (ConfigItem *)currentItem();
808 setSelected(item, TRUE);
814 void ConfigList::contextMenuEvent(QContextMenuEvent *e)
816 if (e->y() <= header()->geometry().bottom()) {
820 headerPopup = new QMenu(this);
821 action = new QAction(_("Show Name"), this);
822 action->setToggleAction(TRUE);
823 connect(action, SIGNAL(toggled(bool)),
824 parent(), SLOT(setShowName(bool)));
825 connect(parent(), SIGNAL(showNameChanged(bool)),
826 action, SLOT(setOn(bool)));
827 action->setOn(showName);
828 action->addTo(headerPopup);
829 action = new QAction(_("Show Range"), this);
830 action->setToggleAction(TRUE);
831 connect(action, SIGNAL(toggled(bool)),
832 parent(), SLOT(setShowRange(bool)));
833 connect(parent(), SIGNAL(showRangeChanged(bool)),
834 action, SLOT(setOn(bool)));
835 action->setOn(showRange);
836 action->addTo(headerPopup);
837 action = new QAction( _("Show Data"), this);
838 action->setToggleAction(TRUE);
839 connect(action, SIGNAL(toggled(bool)),
840 parent(), SLOT(setShowData(bool)));
841 connect(parent(), SIGNAL(showDataChanged(bool)),
842 action, SLOT(setOn(bool)));
843 action->setOn(showData);
844 action->addTo(headerPopup);
846 headerPopup->exec(e->globalPos());
852 ConfigView*ConfigView::viewList;
853 QAction *ConfigView::showNormalAction;
854 QAction *ConfigView::showAllAction;
855 QAction *ConfigView::showPromptAction;
857 ConfigView::ConfigView(QWidget* parent, const char *name)
858 : Parent(parent, name)
860 list = new ConfigList(this, name);
861 lineEdit = new ConfigLineEdit(this);
864 this->nextView = viewList;
868 ConfigView::~ConfigView(void)
872 for (vp = &viewList; *vp; vp = &(*vp)->nextView) {
880 void ConfigView::setOptionMode(QAction *act)
882 if (act == showNormalAction)
883 list->optMode = normalOpt;
884 else if (act == showAllAction)
885 list->optMode = allOpt;
887 list->optMode = promptOpt;
889 list->updateListAll();
892 void ConfigView::setShowName(bool b)
894 if (list->showName != b) {
897 emit showNameChanged(b);
901 void ConfigView::setShowRange(bool b)
903 if (list->showRange != b) {
906 emit showRangeChanged(b);
910 void ConfigView::setShowData(bool b)
912 if (list->showData != b) {
915 emit showDataChanged(b);
919 void ConfigList::setAllOpen(bool open)
921 Q3ListViewItemIterator it(this);
923 for (; it.current(); it++)
924 it.current()->setOpen(open);
927 void ConfigView::updateList(ConfigItem* item)
931 for (v = viewList; v; v = v->nextView)
932 v->list->updateList(item);
935 void ConfigView::updateListAll(void)
939 for (v = viewList; v; v = v->nextView)
940 v->list->updateListAll();
943 ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name)
944 : Parent(parent, name), sym(0), _menu(0)
947 configSettings->beginGroup(name);
948 _showDebug = configSettings->readBoolEntry("/showDebug", false);
949 configSettings->endGroup();
950 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
954 void ConfigInfoView::saveSettings(void)
957 configSettings->beginGroup(name());
958 configSettings->writeEntry("/showDebug", showDebug());
959 configSettings->endGroup();
963 void ConfigInfoView::setShowDebug(bool b)
965 if (_showDebug != b) {
971 emit showDebugChanged(b);
975 void ConfigInfoView::setInfo(struct menu *m)
987 void ConfigInfoView::symbolInfo(void)
991 str += "<big>Symbol: <b>";
992 str += print_filter(sym->name);
993 str += "</b></big><br><br>value: ";
994 str += print_filter(sym_get_string_value(sym));
995 str += "<br>visibility: ";
996 str += sym->visible == yes ? "y" : sym->visible == mod ? "m" : "n";
998 str += debug_info(sym);
1003 void ConfigInfoView::menuInfo(void)
1006 QString head, debug, help;
1010 if (_menu->prompt) {
1012 head += print_filter(_(_menu->prompt->text));
1013 head += "</b></big>";
1017 head += QString().sprintf("<a href=\"s%p\">", sym);
1018 head += print_filter(sym->name);
1023 } else if (sym->name) {
1026 head += QString().sprintf("<a href=\"s%p\">", sym);
1027 head += print_filter(sym->name);
1030 head += "</b></big>";
1035 debug = debug_info(sym);
1037 struct gstr help_gstr = str_new();
1038 menu_get_ext_help(_menu, &help_gstr);
1039 help = print_filter(str_get(&help_gstr));
1040 str_free(&help_gstr);
1041 } else if (_menu->prompt) {
1043 head += print_filter(_(_menu->prompt->text));
1044 head += "</b></big><br><br>";
1046 if (_menu->prompt->visible.expr) {
1047 debug += " dep: ";
1048 expr_print(_menu->prompt->visible.expr, expr_print_help, &debug, E_NONE);
1049 debug += "<br><br>";
1054 debug += QString().sprintf("defined at %s:%d<br><br>", _menu->file->name, _menu->lineno);
1056 setText(head + debug + help);
1059 QString ConfigInfoView::debug_info(struct symbol *sym)
1064 debug += print_filter(sym_type_name(sym->type));
1065 if (sym_is_choice(sym))
1066 debug += " (choice)";
1068 if (sym->rev_dep.expr) {
1069 debug += "reverse dep: ";
1070 expr_print(sym->rev_dep.expr, expr_print_help, &debug, E_NONE);
1073 for (struct property *prop = sym->prop; prop; prop = prop->next) {
1074 switch (prop->type) {
1077 debug += QString().sprintf("prompt: <a href=\"m%p\">", prop->menu);
1078 debug += print_filter(_(prop->text));
1079 debug += "</a><br>";
1085 debug += prop_get_type_name(prop->type);
1087 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1091 if (sym_is_choice(sym)) {
1092 debug += "choice: ";
1093 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1098 debug += "unknown property: ";
1099 debug += prop_get_type_name(prop->type);
1102 if (prop->visible.expr) {
1103 debug += " dep: ";
1104 expr_print(prop->visible.expr, expr_print_help, &debug, E_NONE);
1113 QString ConfigInfoView::print_filter(const QString &str)
1115 QRegExp re("[<>&\"\\n]");
1117 for (int i = 0; (i = res.find(re, i)) >= 0;) {
1118 switch (res[i].latin1()) {
1120 res.replace(i, 1, "<");
1124 res.replace(i, 1, ">");
1128 res.replace(i, 1, "&");
1132 res.replace(i, 1, """);
1136 res.replace(i, 1, "<br>");
1144 void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char *str)
1146 QString* text = reinterpret_cast<QString*>(data);
1147 QString str2 = print_filter(str);
1149 if (sym && sym->name && !(sym->flags & SYMBOL_CONST)) {
1150 *text += QString().sprintf("<a href=\"s%p\">", sym);
1157 QMenu* ConfigInfoView::createStandardContextMenu(const QPoint & pos)
1159 QMenu* popup = Parent::createStandardContextMenu(pos);
1160 QAction* action = new QAction(_("Show Debug Info"), popup);
1161 action->setToggleAction(TRUE);
1162 connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
1163 connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool)));
1164 action->setOn(showDebug());
1165 popup->addSeparator();
1166 action->addTo(popup);
1170 void ConfigInfoView::contextMenuEvent(QContextMenuEvent *e)
1172 Parent::contextMenuEvent(e);
1175 ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow* parent, const char *name)
1176 : Parent(parent, name), result(NULL)
1178 setCaption("Search Config");
1180 QVBoxLayout* layout1 = new QVBoxLayout(this, 11, 6);
1181 QHBoxLayout* layout2 = new QHBoxLayout(0, 0, 6);
1182 layout2->addWidget(new QLabel(_("Find:"), this));
1183 editField = new QLineEdit(this);
1184 connect(editField, SIGNAL(returnPressed()), SLOT(search()));
1185 layout2->addWidget(editField);
1186 searchButton = new QPushButton(_("Search"), this);
1187 searchButton->setAutoDefault(FALSE);
1188 connect(searchButton, SIGNAL(clicked()), SLOT(search()));
1189 layout2->addWidget(searchButton);
1190 layout1->addLayout(layout2);
1192 split = new QSplitter(this);
1193 split->setOrientation(Qt::Vertical);
1194 list = new ConfigView(split, name);
1195 list->list->mode = listMode;
1196 info = new ConfigInfoView(split, name);
1197 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1198 info, SLOT(setInfo(struct menu *)));
1199 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1200 parent, SLOT(setMenuLink(struct menu *)));
1202 layout1->addWidget(split);
1205 int x, y, width, height;
1208 configSettings->beginGroup(name);
1209 width = configSettings->readNumEntry("/window width", parent->width() / 2);
1210 height = configSettings->readNumEntry("/window height", parent->height() / 2);
1211 resize(width, height);
1212 x = configSettings->readNumEntry("/window x", 0, &ok);
1214 y = configSettings->readNumEntry("/window y", 0, &ok);
1217 QList<int> sizes = configSettings->readSizes("/split", &ok);
1219 split->setSizes(sizes);
1220 configSettings->endGroup();
1221 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
1225 void ConfigSearchWindow::saveSettings(void)
1228 configSettings->beginGroup(name());
1229 configSettings->writeEntry("/window x", pos().x());
1230 configSettings->writeEntry("/window y", pos().y());
1231 configSettings->writeEntry("/window width", size().width());
1232 configSettings->writeEntry("/window height", size().height());
1233 configSettings->writeSizes("/split", split->sizes());
1234 configSettings->endGroup();
1238 void ConfigSearchWindow::search(void)
1241 struct property *prop;
1242 ConfigItem *lastItem = NULL;
1245 list->list->clear();
1248 result = sym_re_search(editField->text().latin1());
1251 for (p = result; *p; p++) {
1252 for_all_prompts((*p), prop)
1253 lastItem = new ConfigItem(list->list, lastItem, prop->menu,
1254 menu_is_visible(prop->menu));
1259 * Construct the complete config widget
1261 ConfigMainWindow::ConfigMainWindow(void)
1266 int x, y, width, height;
1269 QDesktopWidget *d = configApp->desktop();
1270 snprintf(title, sizeof(title), "%s%s",
1271 rootmenu.prompt->text,
1276 width = configSettings->readNumEntry("/window width", d->width() - 64);
1277 height = configSettings->readNumEntry("/window height", d->height() - 64);
1278 resize(width, height);
1279 x = configSettings->readNumEntry("/window x", 0, &ok);
1281 y = configSettings->readNumEntry("/window y", 0, &ok);
1285 split1 = new QSplitter(this);
1286 split1->setOrientation(Qt::Horizontal);
1287 setCentralWidget(split1);
1289 menuView = new ConfigView(split1, "menu");
1290 menuList = menuView->list;
1292 split2 = new QSplitter(split1);
1293 split2->setOrientation(Qt::Vertical);
1295 // create config tree
1296 configView = new ConfigView(split2, "config");
1297 configList = configView->list;
1299 helpText = new ConfigInfoView(split2, "help");
1300 helpText->setTextFormat(Qt::RichText);
1302 setTabOrder(configList, helpText);
1303 configList->setFocus();
1306 toolBar = new QToolBar("Tools", this);
1308 backAction = new QAction(QPixmap(xpm_back), _("Back"), this);
1309 connect(backAction, SIGNAL(activated()), SLOT(goBack()));
1310 backAction->setEnabled(FALSE);
1311 QAction *quitAction = new QAction(_("&Quit"), this);
1312 quitAction->setShortcut(Qt::CTRL + Qt::Key_Q);
1313 connect(quitAction, SIGNAL(activated()), SLOT(close()));
1314 QAction *loadAction = new QAction(QPixmap(xpm_load), _("&Load"), this);
1315 loadAction->setShortcut(Qt::CTRL + Qt::Key_L);
1316 connect(loadAction, SIGNAL(activated()), SLOT(loadConfig()));
1317 saveAction = new QAction(QPixmap(xpm_save), _("&Save"), this);
1318 saveAction->setShortcut(Qt::CTRL + Qt::Key_S);
1319 connect(saveAction, SIGNAL(activated()), SLOT(saveConfig()));
1320 conf_set_changed_callback(conf_changed);
1321 // Set saveAction's initial state
1323 QAction *saveAsAction = new QAction(_("Save &As..."), this);
1324 connect(saveAsAction, SIGNAL(activated()), SLOT(saveConfigAs()));
1325 QAction *searchAction = new QAction(_("&Find"), this);
1326 searchAction->setShortcut(Qt::CTRL + Qt::Key_F);
1327 connect(searchAction, SIGNAL(activated()), SLOT(searchConfig()));
1328 QAction *singleViewAction = new QAction(QPixmap(xpm_single_view), _("Single View"), this);
1329 connect(singleViewAction, SIGNAL(activated()), SLOT(showSingleView()));
1330 QAction *splitViewAction = new QAction(QPixmap(xpm_split_view), _("Split View"), this);
1331 connect(splitViewAction, SIGNAL(activated()), SLOT(showSplitView()));
1332 QAction *fullViewAction = new QAction(QPixmap(xpm_tree_view), _("Full View"), this);
1333 connect(fullViewAction, SIGNAL(activated()), SLOT(showFullView()));
1335 QAction *showNameAction = new QAction(_("Show Name"), this);
1336 showNameAction->setToggleAction(TRUE);
1337 connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool)));
1338 connect(configView, SIGNAL(showNameChanged(bool)), showNameAction, SLOT(setOn(bool)));
1339 showNameAction->setOn(configView->showName());
1340 QAction *showRangeAction = new QAction(_("Show Range"), this);
1341 showRangeAction->setToggleAction(TRUE);
1342 connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool)));
1343 connect(configView, SIGNAL(showRangeChanged(bool)), showRangeAction, SLOT(setOn(bool)));
1344 showRangeAction->setOn(configList->showRange);
1345 QAction *showDataAction = new QAction(_("Show Data"), this);
1346 showDataAction->setToggleAction(TRUE);
1347 connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool)));
1348 connect(configView, SIGNAL(showDataChanged(bool)), showDataAction, SLOT(setOn(bool)));
1349 showDataAction->setOn(configList->showData);
1351 QActionGroup *optGroup = new QActionGroup(this);
1352 optGroup->setExclusive(TRUE);
1353 connect(optGroup, SIGNAL(selected(QAction *)), configView,
1354 SLOT(setOptionMode(QAction *)));
1355 connect(optGroup, SIGNAL(selected(QAction *)), menuView,
1356 SLOT(setOptionMode(QAction *)));
1358 configView->showNormalAction = new QAction(_("Show Normal Options"), optGroup);
1359 configView->showAllAction = new QAction(_("Show All Options"), optGroup);
1360 configView->showPromptAction = new QAction(_("Show Prompt Options"), optGroup);
1361 configView->showNormalAction->setToggleAction(TRUE);
1362 configView->showNormalAction->setOn(configList->optMode == normalOpt);
1363 configView->showAllAction->setToggleAction(TRUE);
1364 configView->showAllAction->setOn(configList->optMode == allOpt);
1365 configView->showPromptAction->setToggleAction(TRUE);
1366 configView->showPromptAction->setOn(configList->optMode == promptOpt);
1368 QAction *showDebugAction = new QAction( _("Show Debug Info"), this);
1369 showDebugAction->setToggleAction(TRUE);
1370 connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
1371 connect(helpText, SIGNAL(showDebugChanged(bool)), showDebugAction, SLOT(setOn(bool)));
1372 showDebugAction->setOn(helpText->showDebug());
1374 QAction *showIntroAction = new QAction( _("Introduction"), this);
1375 connect(showIntroAction, SIGNAL(activated()), SLOT(showIntro()));
1376 QAction *showAboutAction = new QAction( _("About"), this);
1377 connect(showAboutAction, SIGNAL(activated()), SLOT(showAbout()));
1380 backAction->addTo(toolBar);
1381 toolBar->addSeparator();
1382 loadAction->addTo(toolBar);
1383 saveAction->addTo(toolBar);
1384 toolBar->addSeparator();
1385 singleViewAction->addTo(toolBar);
1386 splitViewAction->addTo(toolBar);
1387 fullViewAction->addTo(toolBar);
1389 // create config menu
1390 QMenu* config = new QMenu(this);
1391 menu->insertItem(_("&File"), config);
1392 loadAction->addTo(config);
1393 saveAction->addTo(config);
1394 saveAsAction->addTo(config);
1395 config->addSeparator();
1396 quitAction->addTo(config);
1399 QMenu* editMenu = new QMenu(this);
1400 menu->insertItem(_("&Edit"), editMenu);
1401 searchAction->addTo(editMenu);
1403 // create options menu
1404 QMenu* optionMenu = new QMenu(this);
1405 menu->insertItem(_("&Option"), optionMenu);
1406 showNameAction->addTo(optionMenu);
1407 showRangeAction->addTo(optionMenu);
1408 showDataAction->addTo(optionMenu);
1409 optionMenu->addSeparator();
1410 optGroup->addTo(optionMenu);
1411 optionMenu->addSeparator();
1414 QMenu* helpMenu = new QMenu(this);
1415 menu->addSeparator();
1416 menu->insertItem(_("&Help"), helpMenu);
1417 showIntroAction->addTo(helpMenu);
1418 showAboutAction->addTo(helpMenu);
1420 connect(configList, SIGNAL(menuChanged(struct menu *)),
1421 helpText, SLOT(setInfo(struct menu *)));
1422 connect(configList, SIGNAL(menuSelected(struct menu *)),
1423 SLOT(changeMenu(struct menu *)));
1424 connect(configList, SIGNAL(parentSelected()),
1426 connect(menuList, SIGNAL(menuChanged(struct menu *)),
1427 helpText, SLOT(setInfo(struct menu *)));
1428 connect(menuList, SIGNAL(menuSelected(struct menu *)),
1429 SLOT(changeMenu(struct menu *)));
1431 connect(configList, SIGNAL(gotFocus(struct menu *)),
1432 helpText, SLOT(setInfo(struct menu *)));
1433 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1434 helpText, SLOT(setInfo(struct menu *)));
1435 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1436 SLOT(listFocusChanged(void)));
1437 connect(helpText, SIGNAL(menuSelected(struct menu *)),
1438 SLOT(setMenuLink(struct menu *)));
1440 QString listMode = configSettings->readEntry("/listMode", "symbol");
1441 if (listMode == "single")
1443 else if (listMode == "full")
1445 else /*if (listMode == "split")*/
1448 // UI setup done, restore splitter positions
1449 QList<int> sizes = configSettings->readSizes("/split1", &ok);
1451 split1->setSizes(sizes);
1453 sizes = configSettings->readSizes("/split2", &ok);
1455 split2->setSizes(sizes);
1458 void ConfigMainWindow::loadConfig(void)
1460 QString s = QFileDialog::getOpenFileName(conf_get_configname(), NULL, this);
1463 if (conf_read(QFile::encodeName(s)))
1464 QMessageBox::information(this, "qconf", _("Unable to load configuration!"));
1465 ConfigView::updateListAll();
1468 bool ConfigMainWindow::saveConfig(void)
1470 if (conf_write(NULL)) {
1471 QMessageBox::information(this, "qconf", _("Unable to save configuration!"));
1477 void ConfigMainWindow::saveConfigAs(void)
1479 QString s = QFileDialog::getSaveFileName(conf_get_configname(), NULL, this);
1485 void ConfigMainWindow::searchConfig(void)
1488 searchWindow = new ConfigSearchWindow(this, "search");
1489 searchWindow->show();
1492 void ConfigMainWindow::changeMenu(struct menu *menu)
1494 configList->setRootMenu(menu);
1495 if (configList->rootEntry->parent == &rootmenu)
1496 backAction->setEnabled(FALSE);
1498 backAction->setEnabled(TRUE);
1501 void ConfigMainWindow::setMenuLink(struct menu *menu)
1503 struct menu *parent;
1504 ConfigList* list = NULL;
1507 if (configList->menuSkip(menu))
1510 switch (configList->mode) {
1513 parent = menu_get_parent_menu(menu);
1516 list->setRootMenu(parent);
1519 if (menu->flags & MENU_ROOT) {
1520 configList->setRootMenu(menu);
1521 configList->clearSelection();
1525 parent = menu_get_parent_menu(menu->parent);
1528 item = menuList->findConfigItem(parent);
1530 menuList->setSelected(item, TRUE);
1531 menuList->ensureItemVisible(item);
1533 list->setRootMenu(parent);
1544 item = list->findConfigItem(menu);
1546 list->setSelected(item, TRUE);
1547 list->ensureItemVisible(item);
1553 void ConfigMainWindow::listFocusChanged(void)
1555 if (menuList->mode == menuMode)
1556 configList->clearSelection();
1559 void ConfigMainWindow::goBack(void)
1563 configList->setParentMenu();
1564 if (configList->rootEntry == &rootmenu)
1565 backAction->setEnabled(FALSE);
1566 item = (ConfigItem*)menuList->selectedItem();
1568 if (item->menu == configList->rootEntry) {
1569 menuList->setSelected(item, TRUE);
1572 item = (ConfigItem*)item->parent();
1576 void ConfigMainWindow::showSingleView(void)
1579 menuList->setRootMenu(0);
1580 configList->mode = singleMode;
1581 if (configList->rootEntry == &rootmenu)
1582 configList->updateListAll();
1584 configList->setRootMenu(&rootmenu);
1585 configList->setAllOpen(TRUE);
1586 configList->setFocus();
1589 void ConfigMainWindow::showSplitView(void)
1591 configList->mode = symbolMode;
1592 if (configList->rootEntry == &rootmenu)
1593 configList->updateListAll();
1595 configList->setRootMenu(&rootmenu);
1596 configList->setAllOpen(TRUE);
1597 configApp->processEvents();
1598 menuList->mode = menuMode;
1599 menuList->setRootMenu(&rootmenu);
1600 menuList->setAllOpen(TRUE);
1602 menuList->setFocus();
1605 void ConfigMainWindow::showFullView(void)
1608 menuList->setRootMenu(0);
1609 configList->mode = fullMode;
1610 if (configList->rootEntry == &rootmenu)
1611 configList->updateListAll();
1613 configList->setRootMenu(&rootmenu);
1614 configList->setAllOpen(FALSE);
1615 configList->setFocus();
1619 * ask for saving configuration before quitting
1620 * TODO ask only when something changed
1622 void ConfigMainWindow::closeEvent(QCloseEvent* e)
1624 if (!conf_get_changed()) {
1628 QMessageBox mb("qconf", _("Save configuration?"), QMessageBox::Warning,
1629 QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape);
1630 mb.setButtonText(QMessageBox::Yes, _("&Save Changes"));
1631 mb.setButtonText(QMessageBox::No, _("&Discard Changes"));
1632 mb.setButtonText(QMessageBox::Cancel, _("Cancel Exit"));
1633 switch (mb.exec()) {
1634 case QMessageBox::Yes:
1640 case QMessageBox::No:
1643 case QMessageBox::Cancel:
1649 void ConfigMainWindow::showIntro(void)
1651 static const QString str = _("Welcome to the qconf graphical configuration tool.\n\n"
1652 "For each option, a blank box indicates the feature is disabled, a check\n"
1653 "indicates it is enabled, and a dot indicates that it is to be compiled\n"
1654 "as a module. Clicking on the box will cycle through the three states.\n\n"
1655 "If you do not see an option (e.g., a device driver) that you believe\n"
1656 "should be present, try turning on Show All Options under the Options menu.\n"
1657 "Although there is no cross reference yet to help you figure out what other\n"
1658 "options must be enabled to support the option you are interested in, you can\n"
1659 "still view the help of a grayed-out option.\n\n"
1660 "Toggling Show Debug Info under the Options menu will show the dependencies,\n"
1661 "which you can then match by examining other options.\n\n");
1663 QMessageBox::information(this, "qconf", str);
1666 void ConfigMainWindow::showAbout(void)
1668 static const QString str = _("qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n\n"
1669 "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n");
1671 QMessageBox::information(this, "qconf", str);
1674 void ConfigMainWindow::saveSettings(void)
1676 configSettings->writeEntry("/window x", pos().x());
1677 configSettings->writeEntry("/window y", pos().y());
1678 configSettings->writeEntry("/window width", size().width());
1679 configSettings->writeEntry("/window height", size().height());
1682 switch(configList->mode) {
1698 configSettings->writeEntry("/listMode", entry);
1700 configSettings->writeSizes("/split1", split1->sizes());
1701 configSettings->writeSizes("/split2", split2->sizes());
1704 void ConfigMainWindow::conf_changed(void)
1707 saveAction->setEnabled(conf_get_changed());
1710 void fixup_rootmenu(struct menu *menu)
1713 static int menu_cnt = 0;
1715 menu->flags |= MENU_ROOT;
1716 for (child = menu->list; child; child = child->next) {
1717 if (child->prompt && child->prompt->type == P_MENU) {
1719 fixup_rootmenu(child);
1721 } else if (!menu_cnt)
1722 fixup_rootmenu(child);
1726 static const char *progname;
1728 static void usage(void)
1730 printf(_("%s [-s] <config>\n"), progname);
1734 int main(int ac, char** av)
1736 ConfigMainWindow* v;
1739 bindtextdomain(PACKAGE, LOCALEDIR);
1740 textdomain(PACKAGE);
1743 configApp = new QApplication(ac, av);
1744 if (ac > 1 && av[1][0] == '-') {
1747 conf_set_message_callback(NULL);
1760 fixup_rootmenu(&rootmenu);
1762 //zconfdump(stdout);
1764 configSettings = new ConfigSettings();
1765 configSettings->beginGroup("/kconfig/qconf");
1766 v = new ConfigMainWindow();
1768 //zconfdump(stdout);
1769 configApp->setMainWidget(v);
1770 configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit()));
1771 configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings()));
1775 configSettings->endGroup();
1776 delete configSettings;