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), sym(0)
923 configSettings->beginGroup(name);
924 _showDebug = configSettings->readBoolEntry("/showDebug", false);
925 configSettings->endGroup();
926 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
930 void ConfigInfoView::saveSettings(void)
933 configSettings->beginGroup(name());
934 configSettings->writeEntry("/showDebug", showDebug());
935 configSettings->endGroup();
939 void ConfigInfoView::setShowDebug(bool b)
941 if (_showDebug != b) {
947 emit showDebugChanged(b);
951 void ConfigInfoView::setInfo(struct menu *m)
963 void ConfigInfoView::setSource(const QString& name)
965 const char *p = name.latin1();
974 if (sscanf(p, "m%p", &m) == 1 && menu != m) {
977 emit menuSelected(menu);
983 if (sscanf(p, "s%p", &s) == 1 && sym != s) {
991 void ConfigInfoView::symbolInfo(void)
995 str += "<big>Symbol: <b>";
996 str += print_filter(sym->name);
997 str += "</b></big><br><br>value: ";
998 str += print_filter(sym_get_string_value(sym));
999 str += "<br>visibility: ";
1000 str += sym->visible == yes ? "y" : sym->visible == mod ? "m" : "n";
1002 str += debug_info(sym);
1007 void ConfigInfoView::menuInfo(void)
1010 QString head, debug, help;
1016 head += print_filter(_(menu->prompt->text));
1017 head += "</b></big>";
1021 head += QString().sprintf("<a href=\"s%p\">", sym);
1022 head += print_filter(sym->name);
1027 } else if (sym->name) {
1030 head += QString().sprintf("<a href=\"s%p\">", sym);
1031 head += print_filter(sym->name);
1034 head += "</b></big>";
1039 debug = debug_info(sym);
1041 help = print_filter(_(sym->help));
1042 } else if (menu->prompt) {
1044 head += print_filter(_(menu->prompt->text));
1045 head += "</b></big><br><br>";
1047 if (menu->prompt->visible.expr) {
1048 debug += " dep: ";
1049 expr_print(menu->prompt->visible.expr, expr_print_help, &debug, E_NONE);
1050 debug += "<br><br>";
1055 debug += QString().sprintf("defined at %s:%d<br><br>", menu->file->name, menu->lineno);
1057 setText(head + debug + help);
1060 QString ConfigInfoView::debug_info(struct symbol *sym)
1065 debug += print_filter(sym_type_name(sym->type));
1066 if (sym_is_choice(sym))
1067 debug += " (choice)";
1069 if (sym->rev_dep.expr) {
1070 debug += "reverse dep: ";
1071 expr_print(sym->rev_dep.expr, expr_print_help, &debug, E_NONE);
1074 for (struct property *prop = sym->prop; prop; prop = prop->next) {
1075 switch (prop->type) {
1078 debug += QString().sprintf("prompt: <a href=\"m%p\">", prop->menu);
1079 debug += print_filter(_(prop->text));
1080 debug += "</a><br>";
1083 debug += "default: ";
1084 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1088 if (sym_is_choice(sym)) {
1089 debug += "choice: ";
1090 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1095 debug += "select: ";
1096 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1101 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1105 debug += "unknown property: ";
1106 debug += prop_get_type_name(prop->type);
1109 if (prop->visible.expr) {
1110 debug += " dep: ";
1111 expr_print(prop->visible.expr, expr_print_help, &debug, E_NONE);
1120 QString ConfigInfoView::print_filter(const QString &str)
1122 QRegExp re("[<>&\"\\n]");
1124 for (int i = 0; (i = res.find(re, i)) >= 0;) {
1125 switch (res[i].latin1()) {
1127 res.replace(i, 1, "<");
1131 res.replace(i, 1, ">");
1135 res.replace(i, 1, "&");
1139 res.replace(i, 1, """);
1143 res.replace(i, 1, "<br>");
1151 void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char *str)
1153 QString* text = reinterpret_cast<QString*>(data);
1154 QString str2 = print_filter(str);
1156 if (sym && sym->name && !(sym->flags & SYMBOL_CONST)) {
1157 *text += QString().sprintf("<a href=\"s%p\">", sym);
1164 QPopupMenu* ConfigInfoView::createPopupMenu(const QPoint& pos)
1166 QPopupMenu* popup = Parent::createPopupMenu(pos);
1167 QAction* action = new QAction(NULL,"Show Debug Info", 0, popup);
1168 action->setToggleAction(TRUE);
1169 connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
1170 connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool)));
1171 action->setOn(showDebug());
1172 popup->insertSeparator();
1173 action->addTo(popup);
1177 void ConfigInfoView::contentsContextMenuEvent(QContextMenuEvent *e)
1179 Parent::contentsContextMenuEvent(e);
1182 ConfigSearchWindow::ConfigSearchWindow(QWidget* parent, const char *name)
1183 : Parent(parent, name), result(NULL)
1185 setCaption("Search Config");
1187 QVBoxLayout* layout1 = new QVBoxLayout(this, 11, 6);
1188 QHBoxLayout* layout2 = new QHBoxLayout(0, 0, 6);
1189 layout2->addWidget(new QLabel("Find:", this));
1190 editField = new QLineEdit(this);
1191 connect(editField, SIGNAL(returnPressed()), SLOT(search()));
1192 layout2->addWidget(editField);
1193 searchButton = new QPushButton("Search", this);
1194 searchButton->setAutoDefault(FALSE);
1195 connect(searchButton, SIGNAL(clicked()), SLOT(search()));
1196 layout2->addWidget(searchButton);
1197 layout1->addLayout(layout2);
1199 split = new QSplitter(this);
1200 split->setOrientation(QSplitter::Vertical);
1201 list = new ConfigView(split, name);
1202 list->list->mode = listMode;
1203 info = new ConfigInfoView(split, name);
1204 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1205 info, SLOT(setInfo(struct menu *)));
1206 layout1->addWidget(split);
1209 int x, y, width, height;
1212 configSettings->beginGroup(name);
1213 width = configSettings->readNumEntry("/window width", parent->width() / 2);
1214 height = configSettings->readNumEntry("/window height", parent->height() / 2);
1215 resize(width, height);
1216 x = configSettings->readNumEntry("/window x", 0, &ok);
1218 y = configSettings->readNumEntry("/window y", 0, &ok);
1221 QValueList<int> sizes = configSettings->readSizes("/split", &ok);
1223 split->setSizes(sizes);
1224 configSettings->endGroup();
1225 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
1229 void ConfigSearchWindow::saveSettings(void)
1232 configSettings->beginGroup(name());
1233 configSettings->writeEntry("/window x", pos().x());
1234 configSettings->writeEntry("/window y", pos().y());
1235 configSettings->writeEntry("/window width", size().width());
1236 configSettings->writeEntry("/window height", size().height());
1237 configSettings->writeSizes("/split", split->sizes());
1238 configSettings->endGroup();
1242 void ConfigSearchWindow::search(void)
1245 struct property *prop;
1246 ConfigItem *lastItem = NULL;
1249 list->list->clear();
1251 result = sym_re_search(editField->text().latin1());
1254 for (p = result; *p; p++) {
1255 for_all_prompts((*p), prop)
1256 lastItem = new ConfigItem(list->list, lastItem, prop->menu,
1257 menu_is_visible(prop->menu));
1262 * Construct the complete config widget
1264 ConfigMainWindow::ConfigMainWindow(void)
1269 int x, y, width, height;
1271 QWidget *d = configApp->desktop();
1273 width = configSettings->readNumEntry("/window width", d->width() - 64);
1274 height = configSettings->readNumEntry("/window height", d->height() - 64);
1275 resize(width, height);
1276 x = configSettings->readNumEntry("/window x", 0, &ok);
1278 y = configSettings->readNumEntry("/window y", 0, &ok);
1282 split1 = new QSplitter(this);
1283 split1->setOrientation(QSplitter::Horizontal);
1284 setCentralWidget(split1);
1286 menuView = new ConfigView(split1, "menu");
1287 menuList = menuView->list;
1289 split2 = new QSplitter(split1);
1290 split2->setOrientation(QSplitter::Vertical);
1292 // create config tree
1293 configView = new ConfigView(split2, "config");
1294 configList = configView->list;
1296 helpText = new ConfigInfoView(split2, "help");
1297 helpText->setTextFormat(Qt::RichText);
1299 setTabOrder(configList, helpText);
1300 configList->setFocus();
1303 toolBar = new QToolBar("Tools", this);
1305 backAction = new QAction("Back", QPixmap(xpm_back), "Back", 0, this);
1306 connect(backAction, SIGNAL(activated()), SLOT(goBack()));
1307 backAction->setEnabled(FALSE);
1308 QAction *quitAction = new QAction("Quit", "&Quit", CTRL+Key_Q, this);
1309 connect(quitAction, SIGNAL(activated()), SLOT(close()));
1310 QAction *loadAction = new QAction("Load", QPixmap(xpm_load), "&Load", CTRL+Key_L, this);
1311 connect(loadAction, SIGNAL(activated()), SLOT(loadConfig()));
1312 saveAction = new QAction("Save", QPixmap(xpm_save), "&Save", CTRL+Key_S, this);
1313 connect(saveAction, SIGNAL(activated()), SLOT(saveConfig()));
1314 conf_set_changed_callback(conf_changed);
1315 // Set saveAction's initial state
1317 QAction *saveAsAction = new QAction("Save As...", "Save &As...", 0, this);
1318 connect(saveAsAction, SIGNAL(activated()), SLOT(saveConfigAs()));
1319 QAction *searchAction = new QAction("Search", "&Search", CTRL+Key_F, this);
1320 connect(searchAction, SIGNAL(activated()), SLOT(searchConfig()));
1321 QAction *singleViewAction = new QAction("Single View", QPixmap(xpm_single_view), "Split View", 0, this);
1322 connect(singleViewAction, SIGNAL(activated()), SLOT(showSingleView()));
1323 QAction *splitViewAction = new QAction("Split View", QPixmap(xpm_split_view), "Split View", 0, this);
1324 connect(splitViewAction, SIGNAL(activated()), SLOT(showSplitView()));
1325 QAction *fullViewAction = new QAction("Full View", QPixmap(xpm_tree_view), "Full View", 0, this);
1326 connect(fullViewAction, SIGNAL(activated()), SLOT(showFullView()));
1328 QAction *showNameAction = new QAction(NULL, "Show Name", 0, this);
1329 showNameAction->setToggleAction(TRUE);
1330 connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool)));
1331 connect(configView, SIGNAL(showNameChanged(bool)), showNameAction, SLOT(setOn(bool)));
1332 showNameAction->setOn(configView->showName());
1333 QAction *showRangeAction = new QAction(NULL, "Show Range", 0, this);
1334 showRangeAction->setToggleAction(TRUE);
1335 connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool)));
1336 connect(configView, SIGNAL(showRangeChanged(bool)), showRangeAction, SLOT(setOn(bool)));
1337 showRangeAction->setOn(configList->showRange);
1338 QAction *showDataAction = new QAction(NULL, "Show Data", 0, this);
1339 showDataAction->setToggleAction(TRUE);
1340 connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool)));
1341 connect(configView, SIGNAL(showDataChanged(bool)), showDataAction, SLOT(setOn(bool)));
1342 showDataAction->setOn(configList->showData);
1343 QAction *showAllAction = new QAction(NULL, "Show All Options", 0, this);
1344 showAllAction->setToggleAction(TRUE);
1345 connect(showAllAction, SIGNAL(toggled(bool)), configView, SLOT(setShowAll(bool)));
1346 connect(showAllAction, SIGNAL(toggled(bool)), menuView, SLOT(setShowAll(bool)));
1347 showAllAction->setOn(configList->showAll);
1348 QAction *showDebugAction = new QAction(NULL, "Show Debug Info", 0, this);
1349 showDebugAction->setToggleAction(TRUE);
1350 connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
1351 connect(helpText, SIGNAL(showDebugChanged(bool)), showDebugAction, SLOT(setOn(bool)));
1352 showDebugAction->setOn(helpText->showDebug());
1354 QAction *showIntroAction = new QAction(NULL, "Introduction", 0, this);
1355 connect(showIntroAction, SIGNAL(activated()), SLOT(showIntro()));
1356 QAction *showAboutAction = new QAction(NULL, "About", 0, this);
1357 connect(showAboutAction, SIGNAL(activated()), SLOT(showAbout()));
1360 backAction->addTo(toolBar);
1361 toolBar->addSeparator();
1362 loadAction->addTo(toolBar);
1363 saveAction->addTo(toolBar);
1364 toolBar->addSeparator();
1365 singleViewAction->addTo(toolBar);
1366 splitViewAction->addTo(toolBar);
1367 fullViewAction->addTo(toolBar);
1369 // create config menu
1370 QPopupMenu* config = new QPopupMenu(this);
1371 menu->insertItem("&File", config);
1372 loadAction->addTo(config);
1373 saveAction->addTo(config);
1374 saveAsAction->addTo(config);
1375 config->insertSeparator();
1376 searchAction->addTo(config);
1377 config->insertSeparator();
1378 quitAction->addTo(config);
1380 // create options menu
1381 QPopupMenu* optionMenu = new QPopupMenu(this);
1382 menu->insertItem("&Option", optionMenu);
1383 showNameAction->addTo(optionMenu);
1384 showRangeAction->addTo(optionMenu);
1385 showDataAction->addTo(optionMenu);
1386 optionMenu->insertSeparator();
1387 showAllAction->addTo(optionMenu);
1388 showDebugAction->addTo(optionMenu);
1391 QPopupMenu* helpMenu = new QPopupMenu(this);
1392 menu->insertSeparator();
1393 menu->insertItem("&Help", helpMenu);
1394 showIntroAction->addTo(helpMenu);
1395 showAboutAction->addTo(helpMenu);
1397 connect(configList, SIGNAL(menuChanged(struct menu *)),
1398 helpText, SLOT(setInfo(struct menu *)));
1399 connect(configList, SIGNAL(menuSelected(struct menu *)),
1400 SLOT(changeMenu(struct menu *)));
1401 connect(configList, SIGNAL(parentSelected()),
1403 connect(menuList, SIGNAL(menuChanged(struct menu *)),
1404 helpText, SLOT(setInfo(struct menu *)));
1405 connect(menuList, SIGNAL(menuSelected(struct menu *)),
1406 SLOT(changeMenu(struct menu *)));
1408 connect(configList, SIGNAL(gotFocus(struct menu *)),
1409 helpText, SLOT(setInfo(struct menu *)));
1410 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1411 helpText, SLOT(setInfo(struct menu *)));
1412 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1413 SLOT(listFocusChanged(void)));
1414 connect(helpText, SIGNAL(menuSelected(struct menu *)),
1415 SLOT(setMenuLink(struct menu *)));
1417 QString listMode = configSettings->readEntry("/listMode", "symbol");
1418 if (listMode == "single")
1420 else if (listMode == "full")
1422 else /*if (listMode == "split")*/
1425 // UI setup done, restore splitter positions
1426 QValueList<int> sizes = configSettings->readSizes("/split1", &ok);
1428 split1->setSizes(sizes);
1430 sizes = configSettings->readSizes("/split2", &ok);
1432 split2->setSizes(sizes);
1435 void ConfigMainWindow::loadConfig(void)
1437 QString s = QFileDialog::getOpenFileName(".config", NULL, this);
1440 if (conf_read(QFile::encodeName(s)))
1441 QMessageBox::information(this, "qconf", "Unable to load configuration!");
1442 ConfigView::updateListAll();
1445 void ConfigMainWindow::saveConfig(void)
1447 if (conf_write(NULL))
1448 QMessageBox::information(this, "qconf", "Unable to save configuration!");
1451 void ConfigMainWindow::saveConfigAs(void)
1453 QString s = QFileDialog::getSaveFileName(".config", NULL, this);
1456 if (conf_write(QFile::encodeName(s)))
1457 QMessageBox::information(this, "qconf", "Unable to save configuration!");
1460 void ConfigMainWindow::searchConfig(void)
1463 searchWindow = new ConfigSearchWindow(this, "search");
1464 searchWindow->show();
1467 void ConfigMainWindow::changeMenu(struct menu *menu)
1469 configList->setRootMenu(menu);
1470 backAction->setEnabled(TRUE);
1473 void ConfigMainWindow::setMenuLink(struct menu *menu)
1475 struct menu *parent;
1476 ConfigList* list = NULL;
1479 if (!menu_is_visible(menu) && !configView->showAll())
1482 switch (configList->mode) {
1485 parent = menu_get_parent_menu(menu);
1488 list->setRootMenu(parent);
1491 if (menu->flags & MENU_ROOT) {
1492 configList->setRootMenu(menu);
1493 configList->clearSelection();
1497 parent = menu_get_parent_menu(menu->parent);
1500 item = menuList->findConfigItem(parent);
1502 menuList->setSelected(item, TRUE);
1503 menuList->ensureItemVisible(item);
1505 list->setRootMenu(parent);
1514 item = list->findConfigItem(menu);
1516 list->setSelected(item, TRUE);
1517 list->ensureItemVisible(item);
1523 void ConfigMainWindow::listFocusChanged(void)
1525 if (menuList->mode == menuMode)
1526 configList->clearSelection();
1529 void ConfigMainWindow::goBack(void)
1533 configList->setParentMenu();
1534 if (configList->rootEntry == &rootmenu)
1535 backAction->setEnabled(FALSE);
1536 item = (ConfigItem*)menuList->selectedItem();
1538 if (item->menu == configList->rootEntry) {
1539 menuList->setSelected(item, TRUE);
1542 item = (ConfigItem*)item->parent();
1546 void ConfigMainWindow::showSingleView(void)
1549 menuList->setRootMenu(0);
1550 configList->mode = singleMode;
1551 if (configList->rootEntry == &rootmenu)
1552 configList->updateListAll();
1554 configList->setRootMenu(&rootmenu);
1555 configList->setAllOpen(TRUE);
1556 configList->setFocus();
1559 void ConfigMainWindow::showSplitView(void)
1561 configList->mode = symbolMode;
1562 if (configList->rootEntry == &rootmenu)
1563 configList->updateListAll();
1565 configList->setRootMenu(&rootmenu);
1566 configList->setAllOpen(TRUE);
1567 configApp->processEvents();
1568 menuList->mode = menuMode;
1569 menuList->setRootMenu(&rootmenu);
1570 menuList->setAllOpen(TRUE);
1572 menuList->setFocus();
1575 void ConfigMainWindow::showFullView(void)
1578 menuList->setRootMenu(0);
1579 configList->mode = fullMode;
1580 if (configList->rootEntry == &rootmenu)
1581 configList->updateListAll();
1583 configList->setRootMenu(&rootmenu);
1584 configList->setAllOpen(FALSE);
1585 configList->setFocus();
1589 * ask for saving configuration before quitting
1590 * TODO ask only when something changed
1592 void ConfigMainWindow::closeEvent(QCloseEvent* e)
1594 if (!conf_get_changed()) {
1598 QMessageBox mb("qconf", "Save configuration?", QMessageBox::Warning,
1599 QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape);
1600 mb.setButtonText(QMessageBox::Yes, "&Save Changes");
1601 mb.setButtonText(QMessageBox::No, "&Discard Changes");
1602 mb.setButtonText(QMessageBox::Cancel, "Cancel Exit");
1603 switch (mb.exec()) {
1604 case QMessageBox::Yes:
1606 case QMessageBox::No:
1609 case QMessageBox::Cancel:
1615 void ConfigMainWindow::showIntro(void)
1617 static char str[] = "Welcome to the qconf graphical kernel configuration tool for Linux.\n\n"
1618 "For each option, a blank box indicates the feature is disabled, a check\n"
1619 "indicates it is enabled, and a dot indicates that it is to be compiled\n"
1620 "as a module. Clicking on the box will cycle through the three states.\n\n"
1621 "If you do not see an option (e.g., a device driver) that you believe\n"
1622 "should be present, try turning on Show All Options under the Options menu.\n"
1623 "Although there is no cross reference yet to help you figure out what other\n"
1624 "options must be enabled to support the option you are interested in, you can\n"
1625 "still view the help of a grayed-out option.\n\n"
1626 "Toggling Show Debug Info under the Options menu will show the dependencies,\n"
1627 "which you can then match by examining other options.\n\n";
1629 QMessageBox::information(this, "qconf", str);
1632 void ConfigMainWindow::showAbout(void)
1634 static char str[] = "qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n\n"
1635 "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n";
1637 QMessageBox::information(this, "qconf", str);
1640 void ConfigMainWindow::saveSettings(void)
1642 configSettings->writeEntry("/window x", pos().x());
1643 configSettings->writeEntry("/window y", pos().y());
1644 configSettings->writeEntry("/window width", size().width());
1645 configSettings->writeEntry("/window height", size().height());
1648 switch(configList->mode) {
1661 configSettings->writeEntry("/listMode", entry);
1663 configSettings->writeSizes("/split1", split1->sizes());
1664 configSettings->writeSizes("/split2", split2->sizes());
1667 void ConfigMainWindow::conf_changed(void)
1670 saveAction->setEnabled(conf_get_changed());
1673 void fixup_rootmenu(struct menu *menu)
1676 static int menu_cnt = 0;
1678 menu->flags |= MENU_ROOT;
1679 for (child = menu->list; child; child = child->next) {
1680 if (child->prompt && child->prompt->type == P_MENU) {
1682 fixup_rootmenu(child);
1684 } else if (!menu_cnt)
1685 fixup_rootmenu(child);
1689 static const char *progname;
1691 static void usage(void)
1693 printf("%s <config>\n", progname);
1697 int main(int ac, char** av)
1699 ConfigMainWindow* v;
1702 bindtextdomain(PACKAGE, LOCALEDIR);
1703 textdomain(PACKAGE);
1705 #ifndef LKC_DIRECT_LINK
1710 configApp = new QApplication(ac, av);
1711 if (ac > 1 && av[1][0] == '-') {
1724 fixup_rootmenu(&rootmenu);
1726 //zconfdump(stdout);
1728 configSettings = new ConfigSettings();
1729 configSettings->beginGroup("/kconfig/qconf");
1730 v = new ConfigMainWindow();
1732 //zconfdump(stdout);
1733 configApp->setMainWidget(v);
1734 configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit()));
1735 configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings()));
1739 configSettings->endGroup();
1740 delete configSettings;