2 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
3 * Released under the terms of the GNU GPL v2.0.
6 #include <qapplication.h>
7 #include <qmainwindow.h>
11 #include <qsplitter.h>
12 #include <qlistview.h>
13 #include <qtextbrowser.h>
14 #include <qlineedit.h>
16 #include <qpushbutton.h>
18 #include <qmessagebox.h>
21 #include <qfiledialog.h>
22 #include <qdragobject.h>
38 static QApplication *configApp;
39 static ConfigSettings *configSettings;
41 QAction *ConfigMainWindow::saveAction;
43 static inline QString qgettext(const char* str)
45 return QString::fromLocal8Bit(gettext(str));
48 static inline QString qgettext(const QString& str)
50 return QString::fromLocal8Bit(gettext(str.latin1()));
54 * Reads a list of integer values from the application settings.
56 QValueList<int> ConfigSettings::readSizes(const QString& key, bool *ok)
58 QValueList<int> result;
59 QStringList entryList = readListEntry(key, ok);
61 QStringList::Iterator it;
62 for (it = entryList.begin(); it != entryList.end(); ++it)
63 result.push_back((*it).toInt());
70 * Writes a list of integer values to the application settings.
72 bool ConfigSettings::writeSizes(const QString& key, const QValueList<int>& value)
74 QStringList stringList;
75 QValueList<int>::ConstIterator it;
77 for (it = value.begin(); it != value.end(); ++it)
78 stringList.push_back(QString::number(*it));
79 return writeEntry(key, stringList);
86 * TODO check the value
88 void ConfigItem::okRename(int col)
90 Parent::okRename(col);
91 sym_set_string_value(menu->sym, text(dataColIdx).latin1());
96 * update the displayed of a menu entry
98 void ConfigItem::updateMenu(void)
102 struct property *prop;
109 setPixmap(promptColIdx, list->menuBackPix);
116 prompt = QString::fromLocal8Bit(menu_get_prompt(menu));
118 if (prop) switch (prop->type) {
120 if (list->mode == singleMode || list->mode == symbolMode) {
121 /* a menuconfig entry is displayed differently
122 * depending whether it's at the view root or a child.
124 if (sym && list->rootEntry == menu)
126 setPixmap(promptColIdx, list->menuPix);
130 setPixmap(promptColIdx, 0);
134 setPixmap(promptColIdx, 0);
142 setText(nameColIdx, QString::fromLocal8Bit(sym->name));
144 type = sym_get_type(sym);
150 if (!sym_is_changable(sym) && !list->showAll) {
151 setPixmap(promptColIdx, 0);
152 setText(noColIdx, QString::null);
153 setText(modColIdx, QString::null);
154 setText(yesColIdx, QString::null);
157 expr = sym_get_tristate_value(sym);
160 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
161 setPixmap(promptColIdx, list->choiceYesPix);
163 setPixmap(promptColIdx, list->symbolYesPix);
164 setText(yesColIdx, "Y");
168 setPixmap(promptColIdx, list->symbolModPix);
169 setText(modColIdx, "M");
173 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
174 setPixmap(promptColIdx, list->choiceNoPix);
176 setPixmap(promptColIdx, list->symbolNoPix);
177 setText(noColIdx, "N");
182 setText(noColIdx, sym_tristate_within_range(sym, no) ? "_" : 0);
184 setText(modColIdx, sym_tristate_within_range(sym, mod) ? "_" : 0);
186 setText(yesColIdx, sym_tristate_within_range(sym, yes) ? "_" : 0);
188 setText(dataColIdx, QChar(ch));
195 data = sym_get_string_value(sym);
197 #if QT_VERSION >= 300
198 int i = list->mapIdx(dataColIdx);
200 setRenameEnabled(i, TRUE);
202 setText(dataColIdx, data);
203 if (type == S_STRING)
204 prompt = QString("%1: %2").arg(prompt).arg(data);
206 prompt = QString("(%2) %1").arg(prompt).arg(data);
209 if (!sym_has_value(sym) && visible)
212 setText(promptColIdx, prompt);
215 void ConfigItem::testUpdateMenu(bool v)
223 sym_calc_value(menu->sym);
224 if (menu->flags & MENU_CHANGED) {
225 /* the menu entry changed, so update all list items */
226 menu->flags &= ~MENU_CHANGED;
227 for (i = (ConfigItem*)menu->data; i; i = i->nextItem)
229 } else if (listView()->updateAll)
233 void ConfigItem::paintCell(QPainter* p, const QColorGroup& cg, int column, int width, int align)
235 ConfigList* list = listView();
238 if (isSelected() && !list->hasFocus() && list->mode == menuMode)
239 Parent::paintCell(p, list->inactivedColorGroup, column, width, align);
241 Parent::paintCell(p, cg, column, width, align);
243 Parent::paintCell(p, list->disabledColorGroup, column, width, align);
247 * construct a menu entry
249 void ConfigItem::init(void)
252 ConfigList* list = listView();
253 nextItem = (ConfigItem*)menu->data;
256 if (list->mode != fullMode)
258 sym_calc_value(menu->sym);
264 * destruct a menu entry
266 ConfigItem::~ConfigItem(void)
269 ConfigItem** ip = (ConfigItem**)&menu->data;
270 for (; *ip; ip = &(*ip)->nextItem) {
279 ConfigLineEdit::ConfigLineEdit(ConfigView* parent)
282 connect(this, SIGNAL(lostFocus()), SLOT(hide()));
285 void ConfigLineEdit::show(ConfigItem* i)
288 if (sym_get_string_value(item->menu->sym))
289 setText(QString::fromLocal8Bit(sym_get_string_value(item->menu->sym)));
291 setText(QString::null);
296 void ConfigLineEdit::keyPressEvent(QKeyEvent* e)
303 sym_set_string_value(item->menu->sym, text().latin1());
304 parent()->updateList(item);
307 Parent::keyPressEvent(e);
311 parent()->list->setFocus();
315 ConfigList::ConfigList(ConfigView* p, const char *name)
318 symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no),
319 choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no),
320 menuPix(xpm_menu), menuInvPix(xpm_menu_inv), menuBackPix(xpm_menuback), voidPix(xpm_void),
321 showAll(false), showName(false), showRange(false), showData(false),
322 rootEntry(0), headerPopup(0)
327 setRootIsDecorated(TRUE);
328 disabledColorGroup = palette().active();
329 disabledColorGroup.setColor(QColorGroup::Text, palette().disabled().text());
330 inactivedColorGroup = palette().active();
331 inactivedColorGroup.setColor(QColorGroup::Highlight, palette().disabled().highlight());
333 connect(this, SIGNAL(selectionChanged(void)),
334 SLOT(updateSelection(void)));
337 configSettings->beginGroup(name);
338 showAll = configSettings->readBoolEntry("/showAll", false);
339 showName = configSettings->readBoolEntry("/showName", false);
340 showRange = configSettings->readBoolEntry("/showRange", false);
341 showData = configSettings->readBoolEntry("/showData", false);
342 configSettings->endGroup();
343 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
346 for (i = 0; i < colNr; i++)
347 colMap[i] = colRevMap[i] = -1;
348 addColumn(promptColIdx, "Option");
353 void ConfigList::reinit(void)
355 removeColumn(dataColIdx);
356 removeColumn(yesColIdx);
357 removeColumn(modColIdx);
358 removeColumn(noColIdx);
359 removeColumn(nameColIdx);
362 addColumn(nameColIdx, "Name");
364 addColumn(noColIdx, "N");
365 addColumn(modColIdx, "M");
366 addColumn(yesColIdx, "Y");
369 addColumn(dataColIdx, "Value");
374 void ConfigList::saveSettings(void)
377 configSettings->beginGroup(name());
378 configSettings->writeEntry("/showName", showName);
379 configSettings->writeEntry("/showRange", showRange);
380 configSettings->writeEntry("/showData", showData);
381 configSettings->writeEntry("/showAll", showAll);
382 configSettings->endGroup();
386 ConfigItem* ConfigList::findConfigItem(struct menu *menu)
388 ConfigItem* item = (ConfigItem*)menu->data;
390 for (; item; item = item->nextItem) {
391 if (this == item->listView())
398 void ConfigList::updateSelection(void)
403 ConfigItem* item = (ConfigItem*)selectedItem();
408 emit menuChanged(menu);
411 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
412 if (mode == menuMode && type == P_MENU)
413 emit menuSelected(menu);
416 void ConfigList::updateList(ConfigItem* item)
418 ConfigItem* last = 0;
421 if (mode != listMode)
423 QListViewItemIterator it(this);
426 for (; it.current(); ++it) {
427 item = (ConfigItem*)it.current();
430 item->testUpdateMenu(menu_is_visible(item->menu));
435 if (rootEntry != &rootmenu && (mode == singleMode ||
436 (mode == symbolMode && rootEntry->parent != &rootmenu))) {
439 item = new ConfigItem(this, 0, true);
442 if ((mode == singleMode || (mode == symbolMode && !(rootEntry->flags & MENU_ROOT))) &&
443 rootEntry->sym && rootEntry->prompt) {
444 item = last ? last->nextSibling() : firstChild();
446 item = new ConfigItem(this, last, rootEntry, true);
448 item->testUpdateMenu(true);
450 updateMenuList(item, rootEntry);
455 updateMenuList(this, rootEntry);
459 void ConfigList::setValue(ConfigItem* item, tristate val)
465 sym = item->menu ? item->menu->sym : 0;
469 type = sym_get_type(sym);
473 oldval = sym_get_tristate_value(sym);
475 if (!sym_set_tristate_value(sym, val))
477 if (oldval == no && item->menu->list)
479 parent()->updateList(item);
484 void ConfigList::changeValue(ConfigItem* item)
488 int type, oldexpr, newexpr;
495 if (item->menu->list)
496 item->setOpen(!item->isOpen());
500 type = sym_get_type(sym);
504 oldexpr = sym_get_tristate_value(sym);
505 newexpr = sym_toggle_tristate_value(sym);
506 if (item->menu->list) {
507 if (oldexpr == newexpr)
508 item->setOpen(!item->isOpen());
509 else if (oldexpr == no)
512 if (oldexpr != newexpr)
513 parent()->updateList(item);
518 #if QT_VERSION >= 300
519 if (colMap[dataColIdx] >= 0)
520 item->startRename(colMap[dataColIdx]);
523 parent()->lineEdit->show(item);
528 void ConfigList::setRootMenu(struct menu *menu)
532 if (rootEntry == menu)
534 type = menu && menu->prompt ? menu->prompt->type : P_UNKNOWN;
537 updateMenuList(this, 0);
540 setSelected(currentItem(), hasFocus());
541 ensureItemVisible(currentItem());
544 void ConfigList::setParentMenu(void)
547 struct menu *oldroot;
550 if (rootEntry == &rootmenu)
552 setRootMenu(menu_get_parent_menu(rootEntry->parent));
554 QListViewItemIterator it(this);
555 for (; (item = (ConfigItem*)it.current()); it++) {
556 if (item->menu == oldroot) {
557 setCurrentItem(item);
558 ensureItemVisible(item);
565 * update all the children of a menu entry
566 * removes/adds the entries from the parent widget as necessary
568 * parent: either the menu list widget or a menu entry widget
569 * menu: entry to be updated
572 void ConfigList::updateMenuList(P* parent, struct menu* menu)
581 while ((item = parent->firstChild()))
586 last = parent->firstChild();
587 if (last && !last->goParent)
589 for (child = menu->list; child; child = child->next) {
590 item = last ? last->nextSibling() : parent->firstChild();
591 type = child->prompt ? child->prompt->type : P_UNKNOWN;
595 if (!(child->flags & MENU_ROOT))
599 if (child->flags & MENU_ROOT)
606 visible = menu_is_visible(child);
607 if (showAll || visible) {
608 if (!item || item->menu != child)
609 item = new ConfigItem(parent, last, child, visible);
611 item->testUpdateMenu(visible);
613 if (mode == fullMode || mode == menuMode || type != P_MENU)
614 updateMenuList(item, child);
616 updateMenuList(item, 0);
621 if (item && item->menu == child) {
622 last = parent->firstChild();
625 else while (last->nextSibling() != item)
626 last = last->nextSibling();
632 void ConfigList::keyPressEvent(QKeyEvent* ev)
634 QListViewItem* i = currentItem();
639 if (ev->key() == Key_Escape && mode != fullMode && mode != listMode) {
640 emit parentSelected();
646 Parent::keyPressEvent(ev);
649 item = (ConfigItem*)i;
654 if (item->goParent) {
655 emit parentSelected();
661 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
662 if (type == P_MENU && rootEntry != menu &&
663 mode != fullMode && mode != menuMode) {
664 emit menuSelected(menu);
680 Parent::keyPressEvent(ev);
686 void ConfigList::contentsMousePressEvent(QMouseEvent* e)
688 //QPoint p(contentsToViewport(e->pos()));
689 //printf("contentsMousePressEvent: %d,%d\n", p.x(), p.y());
690 Parent::contentsMousePressEvent(e);
693 void ConfigList::contentsMouseReleaseEvent(QMouseEvent* e)
695 QPoint p(contentsToViewport(e->pos()));
696 ConfigItem* item = (ConfigItem*)itemAt(p);
698 enum prop_type ptype;
706 x = header()->offset() + p.x();
707 idx = colRevMap[header()->sectionAt(x)];
710 pm = item->pixmap(promptColIdx);
712 int off = header()->sectionPos(0) + itemMargin() +
713 treeStepSize() * (item->depth() + (rootIsDecorated() ? 1 : 0));
714 if (x >= off && x < off + pm->width()) {
715 if (item->goParent) {
716 emit parentSelected();
720 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
721 if (ptype == P_MENU && rootEntry != menu &&
722 mode != fullMode && mode != menuMode)
723 emit menuSelected(menu);
744 //printf("contentsMouseReleaseEvent: %d,%d\n", p.x(), p.y());
745 Parent::contentsMouseReleaseEvent(e);
748 void ConfigList::contentsMouseMoveEvent(QMouseEvent* e)
750 //QPoint p(contentsToViewport(e->pos()));
751 //printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y());
752 Parent::contentsMouseMoveEvent(e);
755 void ConfigList::contentsMouseDoubleClickEvent(QMouseEvent* e)
757 QPoint p(contentsToViewport(e->pos()));
758 ConfigItem* item = (ConfigItem*)itemAt(p);
760 enum prop_type ptype;
764 if (item->goParent) {
765 emit parentSelected();
771 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
772 if (ptype == P_MENU && (mode == singleMode || mode == symbolMode))
773 emit menuSelected(menu);
778 //printf("contentsMouseDoubleClickEvent: %d,%d\n", p.x(), p.y());
779 Parent::contentsMouseDoubleClickEvent(e);
782 void ConfigList::focusInEvent(QFocusEvent *e)
784 struct menu *menu = NULL;
786 Parent::focusInEvent(e);
788 ConfigItem* item = (ConfigItem *)currentItem();
790 setSelected(item, TRUE);
796 void ConfigList::contextMenuEvent(QContextMenuEvent *e)
798 if (e->y() <= header()->geometry().bottom()) {
802 headerPopup = new QPopupMenu(this);
803 action = new QAction(NULL, "Show Name", 0, this);
804 action->setToggleAction(TRUE);
805 connect(action, SIGNAL(toggled(bool)),
806 parent(), SLOT(setShowName(bool)));
807 connect(parent(), SIGNAL(showNameChanged(bool)),
808 action, SLOT(setOn(bool)));
809 action->setOn(showName);
810 action->addTo(headerPopup);
811 action = new QAction(NULL, "Show Range", 0, this);
812 action->setToggleAction(TRUE);
813 connect(action, SIGNAL(toggled(bool)),
814 parent(), SLOT(setShowRange(bool)));
815 connect(parent(), SIGNAL(showRangeChanged(bool)),
816 action, SLOT(setOn(bool)));
817 action->setOn(showRange);
818 action->addTo(headerPopup);
819 action = new QAction(NULL, "Show Data", 0, this);
820 action->setToggleAction(TRUE);
821 connect(action, SIGNAL(toggled(bool)),
822 parent(), SLOT(setShowData(bool)));
823 connect(parent(), SIGNAL(showDataChanged(bool)),
824 action, SLOT(setOn(bool)));
825 action->setOn(showData);
826 action->addTo(headerPopup);
828 headerPopup->exec(e->globalPos());
834 ConfigView* ConfigView::viewList;
836 ConfigView::ConfigView(QWidget* parent, const char *name)
837 : Parent(parent, name)
839 list = new ConfigList(this, name);
840 lineEdit = new ConfigLineEdit(this);
843 this->nextView = viewList;
847 ConfigView::~ConfigView(void)
851 for (vp = &viewList; *vp; vp = &(*vp)->nextView) {
859 void ConfigView::setShowAll(bool b)
861 if (list->showAll != b) {
863 list->updateListAll();
864 emit showAllChanged(b);
868 void ConfigView::setShowName(bool b)
870 if (list->showName != b) {
873 emit showNameChanged(b);
877 void ConfigView::setShowRange(bool b)
879 if (list->showRange != b) {
882 emit showRangeChanged(b);
886 void ConfigView::setShowData(bool b)
888 if (list->showData != b) {
891 emit showDataChanged(b);
895 void ConfigList::setAllOpen(bool open)
897 QListViewItemIterator it(this);
899 for (; it.current(); it++)
900 it.current()->setOpen(open);
903 void ConfigView::updateList(ConfigItem* item)
907 for (v = viewList; v; v = v->nextView)
908 v->list->updateList(item);
911 void ConfigView::updateListAll(void)
915 for (v = viewList; v; v = v->nextView)
916 v->list->updateListAll();
919 ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name)
920 : Parent(parent, name), menu(0)
923 configSettings->beginGroup(name);
924 _showDebug = configSettings->readBoolEntry("/showDebug", false);
925 configSettings->endGroup();
926 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
932 void ConfigInfoView::saveSettings(void)
935 configSettings->beginGroup(name());
936 configSettings->writeEntry("/showDebug", showDebug());
937 configSettings->endGroup();
941 void ConfigInfoView::setShowDebug(bool b)
943 if (_showDebug != b) {
949 emit showDebugChanged(b);
953 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)
1002 str += "<big>Symbol: <b>";
1003 str += print_filter(sym->name);
1004 str += "</b></big><br><br>value: ";
1005 str += print_filter(sym_get_string_value(sym));
1006 str += "<br>visibility: ";
1007 str += sym->visible == yes ? "y" : sym->visible == mod ? "m" : "n";
1009 str += debug_info(sym);
1014 void ConfigInfoView::menuInfo(void)
1017 QString head, debug, help;
1023 head += print_filter(_(menu->prompt->text));
1024 head += "</b></big>";
1028 head += QString().sprintf("<a href=\"s%p\">", sym);
1029 head += print_filter(sym->name);
1034 } else if (sym->name) {
1037 head += QString().sprintf("<a href=\"s%p\">", sym);
1038 head += print_filter(sym->name);
1041 head += "</b></big>";
1046 debug = debug_info(sym);
1048 help = print_filter(_(sym->help));
1049 } else if (menu->prompt) {
1051 head += print_filter(_(menu->prompt->text));
1052 head += "</b></big><br><br>";
1054 if (menu->prompt->visible.expr) {
1055 debug += " dep: ";
1056 expr_print(menu->prompt->visible.expr, expr_print_help, &debug, E_NONE);
1057 debug += "<br><br>";
1062 debug += QString().sprintf("defined at %s:%d<br><br>", menu->file->name, menu->lineno);
1064 setText(head + debug + help);
1067 QString ConfigInfoView::debug_info(struct symbol *sym)
1072 debug += print_filter(sym_type_name(sym->type));
1073 if (sym_is_choice(sym))
1074 debug += " (choice)";
1076 if (sym->rev_dep.expr) {
1077 debug += "reverse dep: ";
1078 expr_print(sym->rev_dep.expr, expr_print_help, &debug, E_NONE);
1081 for (struct property *prop = sym->prop; prop; prop = prop->next) {
1082 switch (prop->type) {
1085 debug += QString().sprintf("prompt: <a href=\"m%p\">", prop->menu);
1086 debug += print_filter(_(prop->text));
1087 debug += "</a><br>";
1090 debug += "default: ";
1091 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1095 if (sym_is_choice(sym)) {
1096 debug += "choice: ";
1097 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1102 debug += "select: ";
1103 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1108 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1112 debug += "unknown property: ";
1113 debug += prop_get_type_name(prop->type);
1116 if (prop->visible.expr) {
1117 debug += " dep: ";
1118 expr_print(prop->visible.expr, expr_print_help, &debug, E_NONE);
1127 QString ConfigInfoView::print_filter(const QString &str)
1129 QRegExp re("[<>&\"\\n]");
1131 for (int i = 0; (i = res.find(re, i)) >= 0;) {
1132 switch (res[i].latin1()) {
1134 res.replace(i, 1, "<");
1138 res.replace(i, 1, ">");
1142 res.replace(i, 1, "&");
1146 res.replace(i, 1, """);
1150 res.replace(i, 1, "<br>");
1158 void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char *str)
1160 QString* text = reinterpret_cast<QString*>(data);
1161 QString str2 = print_filter(str);
1163 if (sym && sym->name && !(sym->flags & SYMBOL_CONST)) {
1164 *text += QString().sprintf("<a href=\"s%p\">", sym);
1171 QPopupMenu* ConfigInfoView::createPopupMenu(const QPoint& pos)
1173 QPopupMenu* popup = Parent::createPopupMenu(pos);
1174 QAction* action = new QAction(NULL,"Show Debug Info", 0, popup);
1175 action->setToggleAction(TRUE);
1176 connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
1177 connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool)));
1178 action->setOn(showDebug());
1179 popup->insertSeparator();
1180 action->addTo(popup);
1184 void ConfigInfoView::contentsContextMenuEvent(QContextMenuEvent *e)
1186 Parent::contentsContextMenuEvent(e);
1189 ConfigSearchWindow::ConfigSearchWindow(QWidget* parent, const char *name)
1190 : Parent(parent, name), result(NULL)
1192 setCaption("Search Config");
1194 QVBoxLayout* layout1 = new QVBoxLayout(this, 11, 6);
1195 QHBoxLayout* layout2 = new QHBoxLayout(0, 0, 6);
1196 layout2->addWidget(new QLabel("Find:", this));
1197 editField = new QLineEdit(this);
1198 connect(editField, SIGNAL(returnPressed()), SLOT(search()));
1199 layout2->addWidget(editField);
1200 searchButton = new QPushButton("Search", this);
1201 searchButton->setAutoDefault(FALSE);
1202 connect(searchButton, SIGNAL(clicked()), SLOT(search()));
1203 layout2->addWidget(searchButton);
1204 layout1->addLayout(layout2);
1206 split = new QSplitter(this);
1207 split->setOrientation(QSplitter::Vertical);
1208 list = new ConfigView(split, name);
1209 list->list->mode = listMode;
1210 info = new ConfigInfoView(split, name);
1211 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1212 info, SLOT(setInfo(struct menu *)));
1213 layout1->addWidget(split);
1216 int x, y, width, height;
1219 configSettings->beginGroup(name);
1220 width = configSettings->readNumEntry("/window width", parent->width() / 2);
1221 height = configSettings->readNumEntry("/window height", parent->height() / 2);
1222 resize(width, height);
1223 x = configSettings->readNumEntry("/window x", 0, &ok);
1225 y = configSettings->readNumEntry("/window y", 0, &ok);
1228 QValueList<int> sizes = configSettings->readSizes("/split", &ok);
1230 split->setSizes(sizes);
1231 configSettings->endGroup();
1232 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
1236 void ConfigSearchWindow::saveSettings(void)
1239 configSettings->beginGroup(name());
1240 configSettings->writeEntry("/window x", pos().x());
1241 configSettings->writeEntry("/window y", pos().y());
1242 configSettings->writeEntry("/window width", size().width());
1243 configSettings->writeEntry("/window height", size().height());
1244 configSettings->writeSizes("/split", split->sizes());
1245 configSettings->endGroup();
1249 void ConfigSearchWindow::search(void)
1252 struct property *prop;
1253 ConfigItem *lastItem = NULL;
1256 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;
1278 QWidget *d = configApp->desktop();
1280 width = configSettings->readNumEntry("/window width", d->width() - 64);
1281 height = configSettings->readNumEntry("/window height", d->height() - 64);
1282 resize(width, height);
1283 x = configSettings->readNumEntry("/window x", 0, &ok);
1285 y = configSettings->readNumEntry("/window y", 0, &ok);
1289 split1 = new QSplitter(this);
1290 split1->setOrientation(QSplitter::Horizontal);
1291 setCentralWidget(split1);
1293 menuView = new ConfigView(split1, "menu");
1294 menuList = menuView->list;
1296 split2 = new QSplitter(split1);
1297 split2->setOrientation(QSplitter::Vertical);
1299 // create config tree
1300 configView = new ConfigView(split2, "config");
1301 configList = configView->list;
1303 helpText = new ConfigInfoView(split2, "help");
1304 helpText->setTextFormat(Qt::RichText);
1306 setTabOrder(configList, helpText);
1307 configList->setFocus();
1310 toolBar = new QToolBar("Tools", this);
1312 backAction = new QAction("Back", QPixmap(xpm_back), "Back", 0, this);
1313 connect(backAction, SIGNAL(activated()), SLOT(goBack()));
1314 backAction->setEnabled(FALSE);
1315 QAction *quitAction = new QAction("Quit", "&Quit", CTRL+Key_Q, this);
1316 connect(quitAction, SIGNAL(activated()), SLOT(close()));
1317 QAction *loadAction = new QAction("Load", QPixmap(xpm_load), "&Load", CTRL+Key_L, this);
1318 connect(loadAction, SIGNAL(activated()), SLOT(loadConfig()));
1319 saveAction = new QAction("Save", QPixmap(xpm_save), "&Save", CTRL+Key_S, this);
1320 connect(saveAction, SIGNAL(activated()), SLOT(saveConfig()));
1321 conf_set_changed_callback(conf_changed);
1322 // Set saveAction's initial state
1324 QAction *saveAsAction = new QAction("Save As...", "Save &As...", 0, this);
1325 connect(saveAsAction, SIGNAL(activated()), SLOT(saveConfigAs()));
1326 QAction *searchAction = new QAction("Search", "&Search", CTRL+Key_F, this);
1327 connect(searchAction, SIGNAL(activated()), SLOT(searchConfig()));
1328 QAction *singleViewAction = new QAction("Single View", QPixmap(xpm_single_view), "Split View", 0, this);
1329 connect(singleViewAction, SIGNAL(activated()), SLOT(showSingleView()));
1330 QAction *splitViewAction = new QAction("Split View", QPixmap(xpm_split_view), "Split View", 0, this);
1331 connect(splitViewAction, SIGNAL(activated()), SLOT(showSplitView()));
1332 QAction *fullViewAction = new QAction("Full View", QPixmap(xpm_tree_view), "Full View", 0, this);
1333 connect(fullViewAction, SIGNAL(activated()), SLOT(showFullView()));
1335 QAction *showNameAction = new QAction(NULL, "Show Name", 0, 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(NULL, "Show Range", 0, 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(NULL, "Show Data", 0, 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);
1350 QAction *showAllAction = new QAction(NULL, "Show All Options", 0, this);
1351 showAllAction->setToggleAction(TRUE);
1352 connect(showAllAction, SIGNAL(toggled(bool)), configView, SLOT(setShowAll(bool)));
1353 connect(showAllAction, SIGNAL(toggled(bool)), menuView, SLOT(setShowAll(bool)));
1354 showAllAction->setOn(configList->showAll);
1355 QAction *showDebugAction = new QAction(NULL, "Show Debug Info", 0, this);
1356 showDebugAction->setToggleAction(TRUE);
1357 connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
1358 connect(helpText, SIGNAL(showDebugChanged(bool)), showDebugAction, SLOT(setOn(bool)));
1359 showDebugAction->setOn(helpText->showDebug());
1361 QAction *showIntroAction = new QAction(NULL, "Introduction", 0, this);
1362 connect(showIntroAction, SIGNAL(activated()), SLOT(showIntro()));
1363 QAction *showAboutAction = new QAction(NULL, "About", 0, this);
1364 connect(showAboutAction, SIGNAL(activated()), SLOT(showAbout()));
1367 backAction->addTo(toolBar);
1368 toolBar->addSeparator();
1369 loadAction->addTo(toolBar);
1370 saveAction->addTo(toolBar);
1371 toolBar->addSeparator();
1372 singleViewAction->addTo(toolBar);
1373 splitViewAction->addTo(toolBar);
1374 fullViewAction->addTo(toolBar);
1376 // create config menu
1377 QPopupMenu* config = new QPopupMenu(this);
1378 menu->insertItem("&File", config);
1379 loadAction->addTo(config);
1380 saveAction->addTo(config);
1381 saveAsAction->addTo(config);
1382 config->insertSeparator();
1383 searchAction->addTo(config);
1384 config->insertSeparator();
1385 quitAction->addTo(config);
1387 // create options menu
1388 QPopupMenu* optionMenu = new QPopupMenu(this);
1389 menu->insertItem("&Option", optionMenu);
1390 showNameAction->addTo(optionMenu);
1391 showRangeAction->addTo(optionMenu);
1392 showDataAction->addTo(optionMenu);
1393 optionMenu->insertSeparator();
1394 showAllAction->addTo(optionMenu);
1395 showDebugAction->addTo(optionMenu);
1398 QPopupMenu* helpMenu = new QPopupMenu(this);
1399 menu->insertSeparator();
1400 menu->insertItem("&Help", helpMenu);
1401 showIntroAction->addTo(helpMenu);
1402 showAboutAction->addTo(helpMenu);
1404 connect(configList, SIGNAL(menuChanged(struct menu *)),
1405 helpText, SLOT(setInfo(struct menu *)));
1406 connect(configList, SIGNAL(menuSelected(struct menu *)),
1407 SLOT(changeMenu(struct menu *)));
1408 connect(configList, SIGNAL(parentSelected()),
1410 connect(menuList, SIGNAL(menuChanged(struct menu *)),
1411 helpText, SLOT(setInfo(struct menu *)));
1412 connect(menuList, SIGNAL(menuSelected(struct menu *)),
1413 SLOT(changeMenu(struct menu *)));
1415 connect(configList, SIGNAL(gotFocus(struct menu *)),
1416 helpText, SLOT(setInfo(struct menu *)));
1417 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1418 helpText, SLOT(setInfo(struct menu *)));
1419 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1420 SLOT(listFocusChanged(void)));
1421 connect(helpText, SIGNAL(menuSelected(struct menu *)),
1422 SLOT(setMenuLink(struct menu *)));
1424 QString listMode = configSettings->readEntry("/listMode", "symbol");
1425 if (listMode == "single")
1427 else if (listMode == "full")
1429 else /*if (listMode == "split")*/
1432 // UI setup done, restore splitter positions
1433 QValueList<int> sizes = configSettings->readSizes("/split1", &ok);
1435 split1->setSizes(sizes);
1437 sizes = configSettings->readSizes("/split2", &ok);
1439 split2->setSizes(sizes);
1442 void ConfigMainWindow::loadConfig(void)
1444 QString s = QFileDialog::getOpenFileName(".config", NULL, this);
1447 if (conf_read(QFile::encodeName(s)))
1448 QMessageBox::information(this, "qconf", "Unable to load configuration!");
1449 ConfigView::updateListAll();
1452 void ConfigMainWindow::saveConfig(void)
1454 if (conf_write(NULL))
1455 QMessageBox::information(this, "qconf", "Unable to save configuration!");
1458 void ConfigMainWindow::saveConfigAs(void)
1460 QString s = QFileDialog::getSaveFileName(".config", NULL, this);
1463 if (conf_write(QFile::encodeName(s)))
1464 QMessageBox::information(this, "qconf", "Unable to save configuration!");
1467 void ConfigMainWindow::searchConfig(void)
1470 searchWindow = new ConfigSearchWindow(this, "search");
1471 searchWindow->show();
1474 void ConfigMainWindow::changeMenu(struct menu *menu)
1476 configList->setRootMenu(menu);
1477 backAction->setEnabled(TRUE);
1480 void ConfigMainWindow::setMenuLink(struct menu *menu)
1482 struct menu *parent;
1483 ConfigList* list = NULL;
1486 if (!menu_is_visible(menu) && !configView->showAll())
1489 switch (configList->mode) {
1492 parent = menu_get_parent_menu(menu);
1495 list->setRootMenu(parent);
1498 if (menu->flags & MENU_ROOT) {
1499 configList->setRootMenu(menu);
1500 configList->clearSelection();
1504 parent = menu_get_parent_menu(menu->parent);
1507 item = menuList->findConfigItem(parent);
1509 menuList->setSelected(item, TRUE);
1510 menuList->ensureItemVisible(item);
1512 list->setRootMenu(parent);
1521 item = list->findConfigItem(menu);
1523 list->setSelected(item, TRUE);
1524 list->ensureItemVisible(item);
1530 void ConfigMainWindow::listFocusChanged(void)
1532 if (menuList->mode == menuMode)
1533 configList->clearSelection();
1536 void ConfigMainWindow::goBack(void)
1540 configList->setParentMenu();
1541 if (configList->rootEntry == &rootmenu)
1542 backAction->setEnabled(FALSE);
1543 item = (ConfigItem*)menuList->selectedItem();
1545 if (item->menu == configList->rootEntry) {
1546 menuList->setSelected(item, TRUE);
1549 item = (ConfigItem*)item->parent();
1553 void ConfigMainWindow::showSingleView(void)
1556 menuList->setRootMenu(0);
1557 configList->mode = singleMode;
1558 if (configList->rootEntry == &rootmenu)
1559 configList->updateListAll();
1561 configList->setRootMenu(&rootmenu);
1562 configList->setAllOpen(TRUE);
1563 configList->setFocus();
1566 void ConfigMainWindow::showSplitView(void)
1568 configList->mode = symbolMode;
1569 if (configList->rootEntry == &rootmenu)
1570 configList->updateListAll();
1572 configList->setRootMenu(&rootmenu);
1573 configList->setAllOpen(TRUE);
1574 configApp->processEvents();
1575 menuList->mode = menuMode;
1576 menuList->setRootMenu(&rootmenu);
1577 menuList->setAllOpen(TRUE);
1579 menuList->setFocus();
1582 void ConfigMainWindow::showFullView(void)
1585 menuList->setRootMenu(0);
1586 configList->mode = fullMode;
1587 if (configList->rootEntry == &rootmenu)
1588 configList->updateListAll();
1590 configList->setRootMenu(&rootmenu);
1591 configList->setAllOpen(FALSE);
1592 configList->setFocus();
1596 * ask for saving configuration before quitting
1597 * TODO ask only when something changed
1599 void ConfigMainWindow::closeEvent(QCloseEvent* e)
1601 if (!conf_get_changed()) {
1605 QMessageBox mb("qconf", "Save configuration?", QMessageBox::Warning,
1606 QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape);
1607 mb.setButtonText(QMessageBox::Yes, "&Save Changes");
1608 mb.setButtonText(QMessageBox::No, "&Discard Changes");
1609 mb.setButtonText(QMessageBox::Cancel, "Cancel Exit");
1610 switch (mb.exec()) {
1611 case QMessageBox::Yes:
1613 case QMessageBox::No:
1616 case QMessageBox::Cancel:
1622 void ConfigMainWindow::showIntro(void)
1624 static char str[] = "Welcome to the qconf graphical kernel configuration tool for Linux.\n\n"
1625 "For each option, a blank box indicates the feature is disabled, a check\n"
1626 "indicates it is enabled, and a dot indicates that it is to be compiled\n"
1627 "as a module. Clicking on the box will cycle through the three states.\n\n"
1628 "If you do not see an option (e.g., a device driver) that you believe\n"
1629 "should be present, try turning on Show All Options under the Options menu.\n"
1630 "Although there is no cross reference yet to help you figure out what other\n"
1631 "options must be enabled to support the option you are interested in, you can\n"
1632 "still view the help of a grayed-out option.\n\n"
1633 "Toggling Show Debug Info under the Options menu will show the dependencies,\n"
1634 "which you can then match by examining other options.\n\n";
1636 QMessageBox::information(this, "qconf", str);
1639 void ConfigMainWindow::showAbout(void)
1641 static char str[] = "qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n\n"
1642 "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n";
1644 QMessageBox::information(this, "qconf", str);
1647 void ConfigMainWindow::saveSettings(void)
1649 configSettings->writeEntry("/window x", pos().x());
1650 configSettings->writeEntry("/window y", pos().y());
1651 configSettings->writeEntry("/window width", size().width());
1652 configSettings->writeEntry("/window height", size().height());
1655 switch(configList->mode) {
1668 configSettings->writeEntry("/listMode", entry);
1670 configSettings->writeSizes("/split1", split1->sizes());
1671 configSettings->writeSizes("/split2", split2->sizes());
1674 void ConfigMainWindow::conf_changed(void)
1677 saveAction->setEnabled(conf_get_changed());
1680 void fixup_rootmenu(struct menu *menu)
1683 static int menu_cnt = 0;
1685 menu->flags |= MENU_ROOT;
1686 for (child = menu->list; child; child = child->next) {
1687 if (child->prompt && child->prompt->type == P_MENU) {
1689 fixup_rootmenu(child);
1691 } else if (!menu_cnt)
1692 fixup_rootmenu(child);
1696 static const char *progname;
1698 static void usage(void)
1700 printf("%s <config>\n", progname);
1704 int main(int ac, char** av)
1706 ConfigMainWindow* v;
1709 bindtextdomain(PACKAGE, LOCALEDIR);
1710 textdomain(PACKAGE);
1712 #ifndef LKC_DIRECT_LINK
1717 configApp = new QApplication(ac, av);
1718 if (ac > 1 && av[1][0] == '-') {
1731 fixup_rootmenu(&rootmenu);
1733 //zconfdump(stdout);
1735 configSettings = new ConfigSettings();
1736 configSettings->beginGroup("/kconfig/qconf");
1737 v = new ConfigMainWindow();
1739 //zconfdump(stdout);
1740 configApp->setMainWidget(v);
1741 configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit()));
1742 configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings()));
1746 configSettings->endGroup();
1747 delete configSettings;