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 static inline QString qgettext(const char* str)
43 return QString::fromLocal8Bit(gettext(str));
46 static inline QString qgettext(const QString& str)
48 return QString::fromLocal8Bit(gettext(str.latin1()));
52 * Reads a list of integer values from the application settings.
54 QValueList<int> ConfigSettings::readSizes(const QString& key, bool *ok)
56 QValueList<int> result;
57 QStringList entryList = readListEntry(key, ok);
59 QStringList::Iterator it;
60 for (it = entryList.begin(); it != entryList.end(); ++it)
61 result.push_back((*it).toInt());
68 * Writes a list of integer values to the application settings.
70 bool ConfigSettings::writeSizes(const QString& key, const QValueList<int>& value)
72 QStringList stringList;
73 QValueList<int>::ConstIterator it;
75 for (it = value.begin(); it != value.end(); ++it)
76 stringList.push_back(QString::number(*it));
77 return writeEntry(key, stringList);
84 * TODO check the value
86 void ConfigItem::okRename(int col)
88 Parent::okRename(col);
89 sym_set_string_value(menu->sym, text(dataColIdx).latin1());
94 * update the displayed of a menu entry
96 void ConfigItem::updateMenu(void)
100 struct property *prop;
107 setPixmap(promptColIdx, list->menuBackPix);
114 prompt = QString::fromLocal8Bit(menu_get_prompt(menu));
116 if (prop) switch (prop->type) {
118 if (list->mode == singleMode || list->mode == symbolMode) {
119 /* a menuconfig entry is displayed differently
120 * depending whether it's at the view root or a child.
122 if (sym && list->rootEntry == menu)
124 setPixmap(promptColIdx, list->menuPix);
128 setPixmap(promptColIdx, 0);
132 setPixmap(promptColIdx, 0);
140 setText(nameColIdx, QString::fromLocal8Bit(sym->name));
142 type = sym_get_type(sym);
148 if (!sym_is_changable(sym) && !list->showAll) {
149 setPixmap(promptColIdx, 0);
150 setText(noColIdx, QString::null);
151 setText(modColIdx, QString::null);
152 setText(yesColIdx, QString::null);
155 expr = sym_get_tristate_value(sym);
158 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
159 setPixmap(promptColIdx, list->choiceYesPix);
161 setPixmap(promptColIdx, list->symbolYesPix);
162 setText(yesColIdx, "Y");
166 setPixmap(promptColIdx, list->symbolModPix);
167 setText(modColIdx, "M");
171 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
172 setPixmap(promptColIdx, list->choiceNoPix);
174 setPixmap(promptColIdx, list->symbolNoPix);
175 setText(noColIdx, "N");
180 setText(noColIdx, sym_tristate_within_range(sym, no) ? "_" : 0);
182 setText(modColIdx, sym_tristate_within_range(sym, mod) ? "_" : 0);
184 setText(yesColIdx, sym_tristate_within_range(sym, yes) ? "_" : 0);
186 setText(dataColIdx, QChar(ch));
193 data = sym_get_string_value(sym);
195 #if QT_VERSION >= 300
196 int i = list->mapIdx(dataColIdx);
198 setRenameEnabled(i, TRUE);
200 setText(dataColIdx, data);
201 if (type == S_STRING)
202 prompt = QString("%1: %2").arg(prompt).arg(data);
204 prompt = QString("(%2) %1").arg(prompt).arg(data);
207 if (!sym_has_value(sym) && visible)
210 setText(promptColIdx, prompt);
213 void ConfigItem::testUpdateMenu(bool v)
221 sym_calc_value(menu->sym);
222 if (menu->flags & MENU_CHANGED) {
223 /* the menu entry changed, so update all list items */
224 menu->flags &= ~MENU_CHANGED;
225 for (i = (ConfigItem*)menu->data; i; i = i->nextItem)
227 } else if (listView()->updateAll)
231 void ConfigItem::paintCell(QPainter* p, const QColorGroup& cg, int column, int width, int align)
233 ConfigList* list = listView();
236 if (isSelected() && !list->hasFocus() && list->mode == menuMode)
237 Parent::paintCell(p, list->inactivedColorGroup, column, width, align);
239 Parent::paintCell(p, cg, column, width, align);
241 Parent::paintCell(p, list->disabledColorGroup, column, width, align);
245 * construct a menu entry
247 void ConfigItem::init(void)
250 ConfigList* list = listView();
251 nextItem = (ConfigItem*)menu->data;
254 if (list->mode != fullMode)
256 sym_calc_value(menu->sym);
262 * destruct a menu entry
264 ConfigItem::~ConfigItem(void)
267 ConfigItem** ip = (ConfigItem**)&menu->data;
268 for (; *ip; ip = &(*ip)->nextItem) {
277 ConfigLineEdit::ConfigLineEdit(ConfigView* parent)
280 connect(this, SIGNAL(lostFocus()), SLOT(hide()));
283 void ConfigLineEdit::show(ConfigItem* i)
286 if (sym_get_string_value(item->menu->sym))
287 setText(QString::fromLocal8Bit(sym_get_string_value(item->menu->sym)));
289 setText(QString::null);
294 void ConfigLineEdit::keyPressEvent(QKeyEvent* e)
301 sym_set_string_value(item->menu->sym, text().latin1());
302 parent()->updateList(item);
305 Parent::keyPressEvent(e);
309 parent()->list->setFocus();
313 ConfigList::ConfigList(ConfigView* p, const char *name)
316 symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no),
317 choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no),
318 menuPix(xpm_menu), menuInvPix(xpm_menu_inv), menuBackPix(xpm_menuback), voidPix(xpm_void),
319 showAll(false), showName(false), showRange(false), showData(false),
320 rootEntry(0), headerPopup(0)
325 setRootIsDecorated(TRUE);
326 disabledColorGroup = palette().active();
327 disabledColorGroup.setColor(QColorGroup::Text, palette().disabled().text());
328 inactivedColorGroup = palette().active();
329 inactivedColorGroup.setColor(QColorGroup::Highlight, palette().disabled().highlight());
331 connect(this, SIGNAL(selectionChanged(void)),
332 SLOT(updateSelection(void)));
335 configSettings->beginGroup(name);
336 showAll = configSettings->readBoolEntry("/showAll", false);
337 showName = configSettings->readBoolEntry("/showName", false);
338 showRange = configSettings->readBoolEntry("/showRange", false);
339 showData = configSettings->readBoolEntry("/showData", false);
340 configSettings->endGroup();
341 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
344 for (i = 0; i < colNr; i++)
345 colMap[i] = colRevMap[i] = -1;
346 addColumn(promptColIdx, "Option");
351 void ConfigList::reinit(void)
353 removeColumn(dataColIdx);
354 removeColumn(yesColIdx);
355 removeColumn(modColIdx);
356 removeColumn(noColIdx);
357 removeColumn(nameColIdx);
360 addColumn(nameColIdx, "Name");
362 addColumn(noColIdx, "N");
363 addColumn(modColIdx, "M");
364 addColumn(yesColIdx, "Y");
367 addColumn(dataColIdx, "Value");
372 void ConfigList::saveSettings(void)
375 configSettings->beginGroup(name());
376 configSettings->writeEntry("/showName", showName);
377 configSettings->writeEntry("/showRange", showRange);
378 configSettings->writeEntry("/showData", showData);
379 configSettings->writeEntry("/showAll", showAll);
380 configSettings->endGroup();
384 void ConfigList::updateSelection(void)
389 ConfigItem* item = (ConfigItem*)selectedItem();
394 emit menuChanged(menu);
397 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
398 if (mode == menuMode && type == P_MENU)
399 emit menuSelected(menu);
402 void ConfigList::updateList(ConfigItem* item)
404 ConfigItem* last = 0;
407 if (mode != listMode)
409 QListViewItemIterator it(this);
412 for (; it.current(); ++it) {
413 item = (ConfigItem*)it.current();
416 item->testUpdateMenu(menu_is_visible(item->menu));
421 if (rootEntry != &rootmenu && (mode == singleMode ||
422 (mode == symbolMode && rootEntry->parent != &rootmenu))) {
425 item = new ConfigItem(this, 0, true);
428 if ((mode == singleMode || (mode == symbolMode && !(rootEntry->flags & MENU_ROOT))) &&
429 rootEntry->sym && rootEntry->prompt) {
430 item = last ? last->nextSibling() : firstChild();
432 item = new ConfigItem(this, last, rootEntry, true);
434 item->testUpdateMenu(true);
436 updateMenuList(item, rootEntry);
441 updateMenuList(this, rootEntry);
445 void ConfigList::setValue(ConfigItem* item, tristate val)
451 sym = item->menu ? item->menu->sym : 0;
455 type = sym_get_type(sym);
459 oldval = sym_get_tristate_value(sym);
461 if (!sym_set_tristate_value(sym, val))
463 if (oldval == no && item->menu->list)
465 parent()->updateList(item);
470 void ConfigList::changeValue(ConfigItem* item)
474 int type, oldexpr, newexpr;
481 if (item->menu->list)
482 item->setOpen(!item->isOpen());
486 type = sym_get_type(sym);
490 oldexpr = sym_get_tristate_value(sym);
491 newexpr = sym_toggle_tristate_value(sym);
492 if (item->menu->list) {
493 if (oldexpr == newexpr)
494 item->setOpen(!item->isOpen());
495 else if (oldexpr == no)
498 if (oldexpr != newexpr)
499 parent()->updateList(item);
504 #if QT_VERSION >= 300
505 if (colMap[dataColIdx] >= 0)
506 item->startRename(colMap[dataColIdx]);
509 parent()->lineEdit->show(item);
514 void ConfigList::setRootMenu(struct menu *menu)
518 if (rootEntry == menu)
520 type = menu && menu->prompt ? menu->prompt->type : P_UNKNOWN;
523 updateMenuList(this, 0);
526 setSelected(currentItem(), hasFocus());
529 void ConfigList::setParentMenu(void)
532 struct menu *oldroot;
535 if (rootEntry == &rootmenu)
537 setRootMenu(menu_get_parent_menu(rootEntry->parent));
539 QListViewItemIterator it(this);
540 for (; (item = (ConfigItem*)it.current()); it++) {
541 if (item->menu == oldroot) {
542 setCurrentItem(item);
543 ensureItemVisible(item);
550 * update all the children of a menu entry
551 * removes/adds the entries from the parent widget as necessary
553 * parent: either the menu list widget or a menu entry widget
554 * menu: entry to be updated
557 void ConfigList::updateMenuList(P* parent, struct menu* menu)
566 while ((item = parent->firstChild()))
571 last = parent->firstChild();
572 if (last && !last->goParent)
574 for (child = menu->list; child; child = child->next) {
575 item = last ? last->nextSibling() : parent->firstChild();
576 type = child->prompt ? child->prompt->type : P_UNKNOWN;
580 if (!(child->flags & MENU_ROOT))
584 if (child->flags & MENU_ROOT)
591 visible = menu_is_visible(child);
592 if (showAll || visible) {
593 if (!item || item->menu != child)
594 item = new ConfigItem(parent, last, child, visible);
596 item->testUpdateMenu(visible);
598 if (mode == fullMode || mode == menuMode || type != P_MENU)
599 updateMenuList(item, child);
601 updateMenuList(item, 0);
606 if (item && item->menu == child) {
607 last = parent->firstChild();
610 else while (last->nextSibling() != item)
611 last = last->nextSibling();
617 void ConfigList::keyPressEvent(QKeyEvent* ev)
619 QListViewItem* i = currentItem();
624 if (ev->key() == Key_Escape && mode != fullMode && mode != listMode) {
625 emit parentSelected();
631 Parent::keyPressEvent(ev);
634 item = (ConfigItem*)i;
639 if (item->goParent) {
640 emit parentSelected();
646 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
647 if (type == P_MENU && rootEntry != menu &&
648 mode != fullMode && mode != menuMode) {
649 emit menuSelected(menu);
665 Parent::keyPressEvent(ev);
671 void ConfigList::contentsMousePressEvent(QMouseEvent* e)
673 //QPoint p(contentsToViewport(e->pos()));
674 //printf("contentsMousePressEvent: %d,%d\n", p.x(), p.y());
675 Parent::contentsMousePressEvent(e);
678 void ConfigList::contentsMouseReleaseEvent(QMouseEvent* e)
680 QPoint p(contentsToViewport(e->pos()));
681 ConfigItem* item = (ConfigItem*)itemAt(p);
683 enum prop_type ptype;
691 x = header()->offset() + p.x();
692 idx = colRevMap[header()->sectionAt(x)];
695 pm = item->pixmap(promptColIdx);
697 int off = header()->sectionPos(0) + itemMargin() +
698 treeStepSize() * (item->depth() + (rootIsDecorated() ? 1 : 0));
699 if (x >= off && x < off + pm->width()) {
700 if (item->goParent) {
701 emit parentSelected();
705 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
706 if (ptype == P_MENU && rootEntry != menu &&
707 mode != fullMode && mode != menuMode)
708 emit menuSelected(menu);
729 //printf("contentsMouseReleaseEvent: %d,%d\n", p.x(), p.y());
730 Parent::contentsMouseReleaseEvent(e);
733 void ConfigList::contentsMouseMoveEvent(QMouseEvent* e)
735 //QPoint p(contentsToViewport(e->pos()));
736 //printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y());
737 Parent::contentsMouseMoveEvent(e);
740 void ConfigList::contentsMouseDoubleClickEvent(QMouseEvent* e)
742 QPoint p(contentsToViewport(e->pos()));
743 ConfigItem* item = (ConfigItem*)itemAt(p);
745 enum prop_type ptype;
749 if (item->goParent) {
750 emit parentSelected();
756 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
757 if (ptype == P_MENU && (mode == singleMode || mode == symbolMode))
758 emit menuSelected(menu);
763 //printf("contentsMouseDoubleClickEvent: %d,%d\n", p.x(), p.y());
764 Parent::contentsMouseDoubleClickEvent(e);
767 void ConfigList::focusInEvent(QFocusEvent *e)
769 Parent::focusInEvent(e);
771 QListViewItem* item = currentItem();
775 setSelected(item, TRUE);
779 void ConfigList::contextMenuEvent(QContextMenuEvent *e)
781 if (e->y() <= header()->geometry().bottom()) {
785 headerPopup = new QPopupMenu(this);
786 action = new QAction("Show Name", 0, this);
787 action->setToggleAction(TRUE);
788 connect(action, SIGNAL(toggled(bool)),
789 parent(), SLOT(setShowName(bool)));
790 connect(parent(), SIGNAL(showNameChanged(bool)),
791 action, SLOT(setOn(bool)));
792 action->setOn(showName);
793 action->addTo(headerPopup);
794 action = new QAction("Show Range", 0, this);
795 action->setToggleAction(TRUE);
796 connect(action, SIGNAL(toggled(bool)),
797 parent(), SLOT(setShowRange(bool)));
798 connect(parent(), SIGNAL(showRangeChanged(bool)),
799 action, SLOT(setOn(bool)));
800 action->setOn(showRange);
801 action->addTo(headerPopup);
802 action = new QAction("Show Data", 0, this);
803 action->setToggleAction(TRUE);
804 connect(action, SIGNAL(toggled(bool)),
805 parent(), SLOT(setShowData(bool)));
806 connect(parent(), SIGNAL(showDataChanged(bool)),
807 action, SLOT(setOn(bool)));
808 action->setOn(showData);
809 action->addTo(headerPopup);
811 headerPopup->exec(e->globalPos());
817 ConfigView* ConfigView::viewList;
819 ConfigView::ConfigView(QWidget* parent, const char *name)
820 : Parent(parent, name)
822 list = new ConfigList(this, name);
823 lineEdit = new ConfigLineEdit(this);
826 this->nextView = viewList;
830 ConfigView::~ConfigView(void)
834 for (vp = &viewList; *vp; vp = &(*vp)->nextView) {
842 void ConfigView::setShowAll(bool b)
844 if (list->showAll != b) {
846 list->updateListAll();
847 emit showAllChanged(b);
851 void ConfigView::setShowName(bool b)
853 if (list->showName != b) {
856 emit showNameChanged(b);
860 void ConfigView::setShowRange(bool b)
862 if (list->showRange != b) {
865 emit showRangeChanged(b);
869 void ConfigView::setShowData(bool b)
871 if (list->showData != b) {
874 emit showDataChanged(b);
878 void ConfigList::setAllOpen(bool open)
880 QListViewItemIterator it(this);
882 for (; it.current(); it++)
883 it.current()->setOpen(open);
886 void ConfigView::updateList(ConfigItem* item)
890 for (v = viewList; v; v = v->nextView)
891 v->list->updateList(item);
894 void ConfigView::updateListAll(void)
898 for (v = viewList; v; v = v->nextView)
899 v->list->updateListAll();
902 ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name)
903 : Parent(parent, name), menu(0)
906 configSettings->beginGroup(name);
907 _showDebug = configSettings->readBoolEntry("/showDebug", false);
908 configSettings->endGroup();
909 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
913 void ConfigInfoView::saveSettings(void)
916 configSettings->beginGroup(name());
917 configSettings->writeEntry("/showDebug", showDebug());
918 configSettings->endGroup();
922 void ConfigInfoView::setShowDebug(bool b)
924 if (_showDebug != b) {
928 emit showDebugChanged(b);
932 void ConfigInfoView::setInfo(struct menu *m)
941 void ConfigInfoView::setSource(const QString& name)
943 const char *p = name.latin1();
949 if (sscanf(p, "m%p", &menu) == 1)
955 void ConfigInfoView::menuInfo(void)
958 QString head, debug, help;
964 head += print_filter(_(menu->prompt->text));
965 head += "</b></big>";
968 head += print_filter(sym->name);
971 } else if (sym->name) {
973 head += print_filter(sym->name);
974 head += "</b></big>";
979 debug = debug_info(sym);
981 help = print_filter(_(sym->help));
982 } else if (menu->prompt) {
984 head += print_filter(_(menu->prompt->text));
985 head += "</b></big><br><br>";
987 if (menu->prompt->visible.expr) {
988 debug += " dep: ";
989 expr_print(menu->prompt->visible.expr, expr_print_help, &debug, E_NONE);
995 debug += QString().sprintf("defined at %s:%d<br><br>", menu->file->name, menu->lineno);
997 setText(head + debug + help);
1000 QString ConfigInfoView::debug_info(struct symbol *sym)
1005 debug += print_filter(sym_type_name(sym->type));
1006 if (sym_is_choice(sym))
1007 debug += " (choice)";
1009 if (sym->rev_dep.expr) {
1010 debug += "reverse dep: ";
1011 expr_print(sym->rev_dep.expr, expr_print_help, &debug, E_NONE);
1014 for (struct property *prop = sym->prop; prop; prop = prop->next) {
1015 switch (prop->type) {
1018 debug += "prompt: ";
1019 debug += print_filter(_(prop->text));
1023 debug += "default: ";
1024 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1028 if (sym_is_choice(sym)) {
1029 debug += "choice: ";
1030 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1035 debug += "select: ";
1036 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1041 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1045 debug += "unknown property: ";
1046 debug += prop_get_type_name(prop->type);
1049 if (prop->visible.expr) {
1050 debug += " dep: ";
1051 expr_print(prop->visible.expr, expr_print_help, &debug, E_NONE);
1060 QString ConfigInfoView::print_filter(const QString &str)
1062 QRegExp re("[<>&\"\\n]");
1064 for (int i = 0; (i = res.find(re, i)) >= 0;) {
1065 switch (res[i].latin1()) {
1067 res.replace(i, 1, "<");
1071 res.replace(i, 1, ">");
1075 res.replace(i, 1, "&");
1079 res.replace(i, 1, """);
1083 res.replace(i, 1, "<br>");
1091 void ConfigInfoView::expr_print_help(void *data, const char *str)
1093 reinterpret_cast<QString*>(data)->append(print_filter(str));
1096 QPopupMenu* ConfigInfoView::createPopupMenu(const QPoint& pos)
1098 QPopupMenu* popup = Parent::createPopupMenu(pos);
1099 QAction* action = new QAction("Show Debug Info", 0, popup);
1100 action->setToggleAction(TRUE);
1101 connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
1102 connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool)));
1103 action->setOn(showDebug());
1104 popup->insertSeparator();
1105 action->addTo(popup);
1109 void ConfigInfoView::contentsContextMenuEvent(QContextMenuEvent *e)
1111 Parent::contentsContextMenuEvent(e);
1114 ConfigSearchWindow::ConfigSearchWindow(QWidget* parent, const char *name)
1115 : Parent(parent, name), result(NULL)
1117 setCaption("Search Config");
1119 QVBoxLayout* layout1 = new QVBoxLayout(this, 11, 6);
1120 QHBoxLayout* layout2 = new QHBoxLayout(0, 0, 6);
1121 layout2->addWidget(new QLabel("Find:", this));
1122 editField = new QLineEdit(this);
1123 connect(editField, SIGNAL(returnPressed()), SLOT(search()));
1124 layout2->addWidget(editField);
1125 searchButton = new QPushButton("Search", this);
1126 searchButton->setAutoDefault(FALSE);
1127 connect(searchButton, SIGNAL(clicked()), SLOT(search()));
1128 layout2->addWidget(searchButton);
1129 layout1->addLayout(layout2);
1131 split = new QSplitter(this);
1132 split->setOrientation(QSplitter::Vertical);
1133 list = new ConfigView(split, name);
1134 list->list->mode = listMode;
1135 info = new ConfigInfoView(split, name);
1136 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1137 info, SLOT(setInfo(struct menu *)));
1138 layout1->addWidget(split);
1141 int x, y, width, height;
1144 configSettings->beginGroup(name);
1145 width = configSettings->readNumEntry("/window width", parent->width() / 2);
1146 height = configSettings->readNumEntry("/window height", parent->height() / 2);
1147 resize(width, height);
1148 x = configSettings->readNumEntry("/window x", 0, &ok);
1150 y = configSettings->readNumEntry("/window y", 0, &ok);
1153 QValueList<int> sizes = configSettings->readSizes("/split", &ok);
1155 split->setSizes(sizes);
1156 configSettings->endGroup();
1157 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
1161 void ConfigSearchWindow::saveSettings(void)
1164 configSettings->beginGroup(name());
1165 configSettings->writeEntry("/window x", pos().x());
1166 configSettings->writeEntry("/window y", pos().y());
1167 configSettings->writeEntry("/window width", size().width());
1168 configSettings->writeEntry("/window height", size().height());
1169 configSettings->writeSizes("/split", split->sizes());
1170 configSettings->endGroup();
1174 void ConfigSearchWindow::search(void)
1177 struct property *prop;
1178 ConfigItem *lastItem = NULL;
1181 list->list->clear();
1183 result = sym_re_search(editField->text().latin1());
1186 for (p = result; *p; p++) {
1187 for_all_prompts((*p), prop)
1188 lastItem = new ConfigItem(list->list, lastItem, prop->menu,
1189 menu_is_visible(prop->menu));
1194 * Construct the complete config widget
1196 ConfigMainWindow::ConfigMainWindow(void)
1200 int x, y, width, height;
1202 QWidget *d = configApp->desktop();
1204 width = configSettings->readNumEntry("/window width", d->width() - 64);
1205 height = configSettings->readNumEntry("/window height", d->height() - 64);
1206 resize(width, height);
1207 x = configSettings->readNumEntry("/window x", 0, &ok);
1209 y = configSettings->readNumEntry("/window y", 0, &ok);
1213 split1 = new QSplitter(this);
1214 split1->setOrientation(QSplitter::Horizontal);
1215 setCentralWidget(split1);
1217 menuView = new ConfigView(split1, "menu");
1218 menuList = menuView->list;
1220 split2 = new QSplitter(split1);
1221 split2->setOrientation(QSplitter::Vertical);
1223 // create config tree
1224 configView = new ConfigView(split2, "config");
1225 configList = configView->list;
1227 helpText = new ConfigInfoView(split2, "help");
1228 helpText->setTextFormat(Qt::RichText);
1230 setTabOrder(configList, helpText);
1231 configList->setFocus();
1234 toolBar = new QToolBar("Tools", this);
1236 backAction = new QAction("Back", QPixmap(xpm_back), "Back", 0, this);
1237 connect(backAction, SIGNAL(activated()), SLOT(goBack()));
1238 backAction->setEnabled(FALSE);
1239 QAction *quitAction = new QAction("Quit", "&Quit", CTRL+Key_Q, this);
1240 connect(quitAction, SIGNAL(activated()), SLOT(close()));
1241 QAction *loadAction = new QAction("Load", QPixmap(xpm_load), "&Load", CTRL+Key_L, this);
1242 connect(loadAction, SIGNAL(activated()), SLOT(loadConfig()));
1243 QAction *saveAction = new QAction("Save", QPixmap(xpm_save), "&Save", CTRL+Key_S, this);
1244 connect(saveAction, SIGNAL(activated()), SLOT(saveConfig()));
1245 QAction *saveAsAction = new QAction("Save As...", "Save &As...", 0, this);
1246 connect(saveAsAction, SIGNAL(activated()), SLOT(saveConfigAs()));
1247 QAction *searchAction = new QAction("Search", "&Search", CTRL+Key_F, this);
1248 connect(searchAction, SIGNAL(activated()), SLOT(searchConfig()));
1249 QAction *singleViewAction = new QAction("Single View", QPixmap(xpm_single_view), "Split View", 0, this);
1250 connect(singleViewAction, SIGNAL(activated()), SLOT(showSingleView()));
1251 QAction *splitViewAction = new QAction("Split View", QPixmap(xpm_split_view), "Split View", 0, this);
1252 connect(splitViewAction, SIGNAL(activated()), SLOT(showSplitView()));
1253 QAction *fullViewAction = new QAction("Full View", QPixmap(xpm_tree_view), "Full View", 0, this);
1254 connect(fullViewAction, SIGNAL(activated()), SLOT(showFullView()));
1256 QAction *showNameAction = new QAction(NULL, "Show Name", 0, this);
1257 showNameAction->setToggleAction(TRUE);
1258 connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool)));
1259 connect(configView, SIGNAL(showNameChanged(bool)), showNameAction, SLOT(setOn(bool)));
1260 showNameAction->setOn(configView->showName());
1261 QAction *showRangeAction = new QAction(NULL, "Show Range", 0, this);
1262 showRangeAction->setToggleAction(TRUE);
1263 connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool)));
1264 connect(configView, SIGNAL(showRangeChanged(bool)), showRangeAction, SLOT(setOn(bool)));
1265 showRangeAction->setOn(configList->showRange);
1266 QAction *showDataAction = new QAction(NULL, "Show Data", 0, this);
1267 showDataAction->setToggleAction(TRUE);
1268 connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool)));
1269 connect(configView, SIGNAL(showDataChanged(bool)), showDataAction, SLOT(setOn(bool)));
1270 showDataAction->setOn(configList->showData);
1271 QAction *showAllAction = new QAction(NULL, "Show All Options", 0, this);
1272 showAllAction->setToggleAction(TRUE);
1273 connect(showAllAction, SIGNAL(toggled(bool)), configView, SLOT(setShowAll(bool)));
1274 connect(showAllAction, SIGNAL(toggled(bool)), menuView, SLOT(setShowAll(bool)));
1275 showAllAction->setOn(configList->showAll);
1276 QAction *showDebugAction = new QAction(NULL, "Show Debug Info", 0, this);
1277 showDebugAction->setToggleAction(TRUE);
1278 connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
1279 connect(helpText, SIGNAL(showDebugChanged(bool)), showDebugAction, SLOT(setOn(bool)));
1280 showDebugAction->setOn(helpText->showDebug());
1282 QAction *showIntroAction = new QAction(NULL, "Introduction", 0, this);
1283 connect(showIntroAction, SIGNAL(activated()), SLOT(showIntro()));
1284 QAction *showAboutAction = new QAction(NULL, "About", 0, this);
1285 connect(showAboutAction, SIGNAL(activated()), SLOT(showAbout()));
1288 backAction->addTo(toolBar);
1289 toolBar->addSeparator();
1290 loadAction->addTo(toolBar);
1291 saveAction->addTo(toolBar);
1292 toolBar->addSeparator();
1293 singleViewAction->addTo(toolBar);
1294 splitViewAction->addTo(toolBar);
1295 fullViewAction->addTo(toolBar);
1297 // create config menu
1298 QPopupMenu* config = new QPopupMenu(this);
1299 menu->insertItem("&File", config);
1300 loadAction->addTo(config);
1301 saveAction->addTo(config);
1302 saveAsAction->addTo(config);
1303 config->insertSeparator();
1304 searchAction->addTo(config);
1305 config->insertSeparator();
1306 quitAction->addTo(config);
1308 // create options menu
1309 QPopupMenu* optionMenu = new QPopupMenu(this);
1310 menu->insertItem("&Option", optionMenu);
1311 showNameAction->addTo(optionMenu);
1312 showRangeAction->addTo(optionMenu);
1313 showDataAction->addTo(optionMenu);
1314 optionMenu->insertSeparator();
1315 showAllAction->addTo(optionMenu);
1316 showDebugAction->addTo(optionMenu);
1319 QPopupMenu* helpMenu = new QPopupMenu(this);
1320 menu->insertSeparator();
1321 menu->insertItem("&Help", helpMenu);
1322 showIntroAction->addTo(helpMenu);
1323 showAboutAction->addTo(helpMenu);
1325 connect(configList, SIGNAL(menuChanged(struct menu *)),
1326 helpText, SLOT(setInfo(struct menu *)));
1327 connect(configList, SIGNAL(menuSelected(struct menu *)),
1328 SLOT(changeMenu(struct menu *)));
1329 connect(configList, SIGNAL(parentSelected()),
1331 connect(menuList, SIGNAL(menuChanged(struct menu *)),
1332 helpText, SLOT(setInfo(struct menu *)));
1333 connect(menuList, SIGNAL(menuSelected(struct menu *)),
1334 SLOT(changeMenu(struct menu *)));
1336 connect(configList, SIGNAL(gotFocus(void)),
1337 SLOT(listFocusChanged(void)));
1338 connect(menuList, SIGNAL(gotFocus(void)),
1339 SLOT(listFocusChanged(void)));
1341 QString listMode = configSettings->readEntry("/listMode", "symbol");
1342 if (listMode == "single")
1344 else if (listMode == "full")
1346 else /*if (listMode == "split")*/
1349 // UI setup done, restore splitter positions
1350 QValueList<int> sizes = configSettings->readSizes("/split1", &ok);
1352 split1->setSizes(sizes);
1354 sizes = configSettings->readSizes("/split2", &ok);
1356 split2->setSizes(sizes);
1360 * display a new help entry as soon as a new menu entry is selected
1362 void ConfigMainWindow::setHelp(QListViewItem* item)
1364 struct menu* menu = 0;
1367 menu = ((ConfigItem*)item)->menu;
1368 helpText->setInfo(menu);
1371 void ConfigMainWindow::loadConfig(void)
1373 QString s = QFileDialog::getOpenFileName(".config", NULL, this);
1376 if (conf_read(QFile::encodeName(s)))
1377 QMessageBox::information(this, "qconf", "Unable to load configuration!");
1378 ConfigView::updateListAll();
1381 void ConfigMainWindow::saveConfig(void)
1383 if (conf_write(NULL))
1384 QMessageBox::information(this, "qconf", "Unable to save configuration!");
1387 void ConfigMainWindow::saveConfigAs(void)
1389 QString s = QFileDialog::getSaveFileName(".config", NULL, this);
1392 if (conf_write(QFile::encodeName(s)))
1393 QMessageBox::information(this, "qconf", "Unable to save configuration!");
1396 void ConfigMainWindow::searchConfig(void)
1399 searchWindow = new ConfigSearchWindow(this, "search");
1400 searchWindow->show();
1403 void ConfigMainWindow::changeMenu(struct menu *menu)
1405 configList->setRootMenu(menu);
1406 backAction->setEnabled(TRUE);
1409 void ConfigMainWindow::listFocusChanged(void)
1411 if (menuList->hasFocus()) {
1412 if (menuList->mode == menuMode)
1413 configList->clearSelection();
1414 setHelp(menuList->selectedItem());
1415 } else if (configList->hasFocus()) {
1416 setHelp(configList->selectedItem());
1420 void ConfigMainWindow::goBack(void)
1424 configList->setParentMenu();
1425 if (configList->rootEntry == &rootmenu)
1426 backAction->setEnabled(FALSE);
1427 item = (ConfigItem*)menuList->selectedItem();
1429 if (item->menu == configList->rootEntry) {
1430 menuList->setSelected(item, TRUE);
1433 item = (ConfigItem*)item->parent();
1437 void ConfigMainWindow::showSingleView(void)
1440 menuList->setRootMenu(0);
1441 configList->mode = singleMode;
1442 if (configList->rootEntry == &rootmenu)
1443 configList->updateListAll();
1445 configList->setRootMenu(&rootmenu);
1446 configList->setAllOpen(TRUE);
1447 configList->setFocus();
1450 void ConfigMainWindow::showSplitView(void)
1452 configList->mode = symbolMode;
1453 if (configList->rootEntry == &rootmenu)
1454 configList->updateListAll();
1456 configList->setRootMenu(&rootmenu);
1457 configList->setAllOpen(TRUE);
1458 configApp->processEvents();
1459 menuList->mode = menuMode;
1460 menuList->setRootMenu(&rootmenu);
1461 menuList->setAllOpen(TRUE);
1463 menuList->setFocus();
1466 void ConfigMainWindow::showFullView(void)
1469 menuList->setRootMenu(0);
1470 configList->mode = fullMode;
1471 if (configList->rootEntry == &rootmenu)
1472 configList->updateListAll();
1474 configList->setRootMenu(&rootmenu);
1475 configList->setAllOpen(FALSE);
1476 configList->setFocus();
1480 * ask for saving configuration before quitting
1481 * TODO ask only when something changed
1483 void ConfigMainWindow::closeEvent(QCloseEvent* e)
1485 if (!sym_change_count) {
1489 QMessageBox mb("qconf", "Save configuration?", QMessageBox::Warning,
1490 QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape);
1491 mb.setButtonText(QMessageBox::Yes, "&Save Changes");
1492 mb.setButtonText(QMessageBox::No, "&Discard Changes");
1493 mb.setButtonText(QMessageBox::Cancel, "Cancel Exit");
1494 switch (mb.exec()) {
1495 case QMessageBox::Yes:
1497 case QMessageBox::No:
1500 case QMessageBox::Cancel:
1506 void ConfigMainWindow::showIntro(void)
1508 static char str[] = "Welcome to the qconf graphical kernel configuration tool for Linux.\n\n"
1509 "For each option, a blank box indicates the feature is disabled, a check\n"
1510 "indicates it is enabled, and a dot indicates that it is to be compiled\n"
1511 "as a module. Clicking on the box will cycle through the three states.\n\n"
1512 "If you do not see an option (e.g., a device driver) that you believe\n"
1513 "should be present, try turning on Show All Options under the Options menu.\n"
1514 "Although there is no cross reference yet to help you figure out what other\n"
1515 "options must be enabled to support the option you are interested in, you can\n"
1516 "still view the help of a grayed-out option.\n\n"
1517 "Toggling Show Debug Info under the Options menu will show the dependencies,\n"
1518 "which you can then match by examining other options.\n\n";
1520 QMessageBox::information(this, "qconf", str);
1523 void ConfigMainWindow::showAbout(void)
1525 static char str[] = "qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n\n"
1526 "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n";
1528 QMessageBox::information(this, "qconf", str);
1531 void ConfigMainWindow::saveSettings(void)
1533 configSettings->writeEntry("/window x", pos().x());
1534 configSettings->writeEntry("/window y", pos().y());
1535 configSettings->writeEntry("/window width", size().width());
1536 configSettings->writeEntry("/window height", size().height());
1539 switch(configList->mode) {
1552 configSettings->writeEntry("/listMode", entry);
1554 configSettings->writeSizes("/split1", split1->sizes());
1555 configSettings->writeSizes("/split2", split2->sizes());
1558 void fixup_rootmenu(struct menu *menu)
1561 static int menu_cnt = 0;
1563 menu->flags |= MENU_ROOT;
1564 for (child = menu->list; child; child = child->next) {
1565 if (child->prompt && child->prompt->type == P_MENU) {
1567 fixup_rootmenu(child);
1569 } else if (!menu_cnt)
1570 fixup_rootmenu(child);
1574 static const char *progname;
1576 static void usage(void)
1578 printf("%s <config>\n", progname);
1582 int main(int ac, char** av)
1584 ConfigMainWindow* v;
1587 bindtextdomain(PACKAGE, LOCALEDIR);
1588 textdomain(PACKAGE);
1590 #ifndef LKC_DIRECT_LINK
1595 configApp = new QApplication(ac, av);
1596 if (ac > 1 && av[1][0] == '-') {
1609 fixup_rootmenu(&rootmenu);
1611 //zconfdump(stdout);
1613 configSettings = new ConfigSettings();
1614 configSettings->beginGroup("/kconfig/qconf");
1615 v = new ConfigMainWindow();
1617 //zconfdump(stdout);
1618 configApp->setMainWidget(v);
1619 configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit()));
1620 configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings()));
1624 configSettings->endGroup();
1625 delete configSettings;