2 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
3 * Released under the terms of the GNU GPL v2.0.
8 #if QT_VERSION < 0x040000
9 #include <qmainwindow.h>
11 #include <qvaluelist.h>
12 #include <qtextbrowser.h>
15 #include <qfiledialog.h>
16 #include <qdragobject.h>
17 #include <qpopupmenu.h>
19 #include <q3mainwindow.h>
21 #include <q3valuelist.h>
22 #include <q3textbrowser.h>
25 #include <q3filedialog.h>
26 #include <q3dragobject.h>
27 #include <q3popupmenu.h>
30 #include <qapplication.h>
31 #include <qdesktopwidget.h>
34 #include <qsplitter.h>
35 #include <qlineedit.h>
37 #include <qpushbutton.h>
39 #include <qmessagebox.h>
56 static QApplication *configApp;
57 static ConfigSettings *configSettings;
59 Q3Action *ConfigMainWindow::saveAction;
61 static inline QString qgettext(const char* str)
63 return QString::fromLocal8Bit(gettext(str));
66 static inline QString qgettext(const QString& str)
68 return QString::fromLocal8Bit(gettext(str.latin1()));
72 * Reads a list of integer values from the application settings.
74 Q3ValueList<int> ConfigSettings::readSizes(const QString& key, bool *ok)
76 Q3ValueList<int> result;
77 QStringList entryList = readListEntry(key, ok);
78 QStringList::Iterator it;
80 for (it = entryList.begin(); it != entryList.end(); ++it)
81 result.push_back((*it).toInt());
87 * Writes a list of integer values to the application settings.
89 bool ConfigSettings::writeSizes(const QString& key, const Q3ValueList<int>& value)
91 QStringList stringList;
92 Q3ValueList<int>::ConstIterator it;
94 for (it = value.begin(); it != value.end(); ++it)
95 stringList.push_back(QString::number(*it));
96 return writeEntry(key, stringList);
102 * TODO check the value
104 void ConfigItem::okRename(int col)
106 Parent::okRename(col);
107 sym_set_string_value(menu->sym, text(dataColIdx).latin1());
108 listView()->updateList(this);
112 * update the displayed of a menu entry
114 void ConfigItem::updateMenu(void)
118 struct property *prop;
125 setPixmap(promptColIdx, list->menuBackPix);
132 prompt = _(menu_get_prompt(menu));
134 if (prop) switch (prop->type) {
136 if (list->mode == singleMode || list->mode == symbolMode) {
137 /* a menuconfig entry is displayed differently
138 * depending whether it's at the view root or a child.
140 if (sym && list->rootEntry == menu)
142 setPixmap(promptColIdx, list->menuPix);
146 setPixmap(promptColIdx, 0);
150 setPixmap(promptColIdx, 0);
158 setText(nameColIdx, QString::fromLocal8Bit(sym->name));
160 type = sym_get_type(sym);
166 if (!sym_is_changable(sym) && list->optMode == normalOpt) {
167 setPixmap(promptColIdx, 0);
168 setText(noColIdx, QString::null);
169 setText(modColIdx, QString::null);
170 setText(yesColIdx, QString::null);
173 expr = sym_get_tristate_value(sym);
176 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
177 setPixmap(promptColIdx, list->choiceYesPix);
179 setPixmap(promptColIdx, list->symbolYesPix);
180 setText(yesColIdx, "Y");
184 setPixmap(promptColIdx, list->symbolModPix);
185 setText(modColIdx, "M");
189 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
190 setPixmap(promptColIdx, list->choiceNoPix);
192 setPixmap(promptColIdx, list->symbolNoPix);
193 setText(noColIdx, "N");
198 setText(noColIdx, sym_tristate_within_range(sym, no) ? "_" : 0);
200 setText(modColIdx, sym_tristate_within_range(sym, mod) ? "_" : 0);
202 setText(yesColIdx, sym_tristate_within_range(sym, yes) ? "_" : 0);
204 setText(dataColIdx, QChar(ch));
211 data = sym_get_string_value(sym);
213 int i = list->mapIdx(dataColIdx);
215 setRenameEnabled(i, TRUE);
216 setText(dataColIdx, data);
217 if (type == S_STRING)
218 prompt = QString("%1: %2").arg(prompt).arg(data);
220 prompt = QString("(%2) %1").arg(prompt).arg(data);
223 if (!sym_has_value(sym) && visible)
224 prompt += _(" (NEW)");
226 setText(promptColIdx, prompt);
229 void ConfigItem::testUpdateMenu(bool v)
237 sym_calc_value(menu->sym);
238 if (menu->flags & MENU_CHANGED) {
239 /* the menu entry changed, so update all list items */
240 menu->flags &= ~MENU_CHANGED;
241 for (i = (ConfigItem*)menu->data; i; i = i->nextItem)
243 } else if (listView()->updateAll)
247 void ConfigItem::paintCell(QPainter* p, const QColorGroup& cg, int column, int width, int align)
249 ConfigList* list = listView();
252 if (isSelected() && !list->hasFocus() && list->mode == menuMode)
253 Parent::paintCell(p, list->inactivedColorGroup, column, width, align);
255 Parent::paintCell(p, cg, column, width, align);
257 Parent::paintCell(p, list->disabledColorGroup, column, width, align);
261 * construct a menu entry
263 void ConfigItem::init(void)
266 ConfigList* list = listView();
267 nextItem = (ConfigItem*)menu->data;
270 if (list->mode != fullMode)
272 sym_calc_value(menu->sym);
278 * destruct a menu entry
280 ConfigItem::~ConfigItem(void)
283 ConfigItem** ip = (ConfigItem**)&menu->data;
284 for (; *ip; ip = &(*ip)->nextItem) {
293 ConfigLineEdit::ConfigLineEdit(ConfigView* parent)
296 connect(this, SIGNAL(lostFocus()), SLOT(hide()));
299 void ConfigLineEdit::show(ConfigItem* i)
302 if (sym_get_string_value(item->menu->sym))
303 setText(QString::fromLocal8Bit(sym_get_string_value(item->menu->sym)));
305 setText(QString::null);
310 void ConfigLineEdit::keyPressEvent(QKeyEvent* e)
317 sym_set_string_value(item->menu->sym, text().latin1());
318 parent()->updateList(item);
321 Parent::keyPressEvent(e);
325 parent()->list->setFocus();
329 ConfigList::ConfigList(ConfigView* p, const char *name)
332 symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no),
333 choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no),
334 menuPix(xpm_menu), menuInvPix(xpm_menu_inv), menuBackPix(xpm_menuback), voidPix(xpm_void),
335 showName(false), showRange(false), showData(false), optMode(normalOpt),
336 rootEntry(0), headerPopup(0)
341 setRootIsDecorated(TRUE);
342 disabledColorGroup = palette().active();
343 disabledColorGroup.setColor(QColorGroup::Text, palette().disabled().text());
344 inactivedColorGroup = palette().active();
345 inactivedColorGroup.setColor(QColorGroup::Highlight, palette().disabled().highlight());
347 connect(this, SIGNAL(selectionChanged(void)),
348 SLOT(updateSelection(void)));
351 configSettings->beginGroup(name);
352 showName = configSettings->readBoolEntry("/showName", false);
353 showRange = configSettings->readBoolEntry("/showRange", false);
354 showData = configSettings->readBoolEntry("/showData", false);
355 optMode = (enum optionMode)configSettings->readNumEntry("/optionMode", false);
356 configSettings->endGroup();
357 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
360 for (i = 0; i < colNr; i++)
361 colMap[i] = colRevMap[i] = -1;
362 addColumn(promptColIdx, _("Option"));
367 bool ConfigList::menuSkip(struct menu *menu)
369 if (optMode == normalOpt && menu_is_visible(menu))
371 if (optMode == promptOpt && menu_has_prompt(menu))
373 if (optMode == allOpt)
378 void ConfigList::reinit(void)
380 removeColumn(dataColIdx);
381 removeColumn(yesColIdx);
382 removeColumn(modColIdx);
383 removeColumn(noColIdx);
384 removeColumn(nameColIdx);
387 addColumn(nameColIdx, _("Name"));
389 addColumn(noColIdx, "N");
390 addColumn(modColIdx, "M");
391 addColumn(yesColIdx, "Y");
394 addColumn(dataColIdx, _("Value"));
399 void ConfigList::saveSettings(void)
402 configSettings->beginGroup(name());
403 configSettings->writeEntry("/showName", showName);
404 configSettings->writeEntry("/showRange", showRange);
405 configSettings->writeEntry("/showData", showData);
406 configSettings->writeEntry("/optionMode", (int)optMode);
407 configSettings->endGroup();
411 ConfigItem* ConfigList::findConfigItem(struct menu *menu)
413 ConfigItem* item = (ConfigItem*)menu->data;
415 for (; item; item = item->nextItem) {
416 if (this == item->listView())
423 void ConfigList::updateSelection(void)
428 ConfigItem* item = (ConfigItem*)selectedItem();
433 emit menuChanged(menu);
436 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
437 if (mode == menuMode && type == P_MENU)
438 emit menuSelected(menu);
441 void ConfigList::updateList(ConfigItem* item)
443 ConfigItem* last = 0;
446 if (mode != listMode)
448 Q3ListViewItemIterator it(this);
451 for (; it.current(); ++it) {
452 item = (ConfigItem*)it.current();
455 item->testUpdateMenu(menu_is_visible(item->menu));
460 if (rootEntry != &rootmenu && (mode == singleMode ||
461 (mode == symbolMode && rootEntry->parent != &rootmenu))) {
464 item = new ConfigItem(this, 0, true);
467 if ((mode == singleMode || (mode == symbolMode && !(rootEntry->flags & MENU_ROOT))) &&
468 rootEntry->sym && rootEntry->prompt) {
469 item = last ? last->nextSibling() : firstChild();
471 item = new ConfigItem(this, last, rootEntry, true);
473 item->testUpdateMenu(true);
475 updateMenuList(item, rootEntry);
480 updateMenuList(this, rootEntry);
484 void ConfigList::setValue(ConfigItem* item, tristate val)
490 sym = item->menu ? item->menu->sym : 0;
494 type = sym_get_type(sym);
498 oldval = sym_get_tristate_value(sym);
500 if (!sym_set_tristate_value(sym, val))
502 if (oldval == no && item->menu->list)
504 parent()->updateList(item);
509 void ConfigList::changeValue(ConfigItem* item)
513 int type, oldexpr, newexpr;
520 if (item->menu->list)
521 item->setOpen(!item->isOpen());
525 type = sym_get_type(sym);
529 oldexpr = sym_get_tristate_value(sym);
530 newexpr = sym_toggle_tristate_value(sym);
531 if (item->menu->list) {
532 if (oldexpr == newexpr)
533 item->setOpen(!item->isOpen());
534 else if (oldexpr == no)
537 if (oldexpr != newexpr)
538 parent()->updateList(item);
543 if (colMap[dataColIdx] >= 0)
544 item->startRename(colMap[dataColIdx]);
546 parent()->lineEdit->show(item);
551 void ConfigList::setRootMenu(struct menu *menu)
555 if (rootEntry == menu)
557 type = menu && menu->prompt ? menu->prompt->type : P_UNKNOWN;
560 updateMenuList(this, 0);
563 setSelected(currentItem(), hasFocus());
564 ensureItemVisible(currentItem());
567 void ConfigList::setParentMenu(void)
570 struct menu *oldroot;
573 if (rootEntry == &rootmenu)
575 setRootMenu(menu_get_parent_menu(rootEntry->parent));
577 Q3ListViewItemIterator it(this);
578 for (; (item = (ConfigItem*)it.current()); it++) {
579 if (item->menu == oldroot) {
580 setCurrentItem(item);
581 ensureItemVisible(item);
588 * update all the children of a menu entry
589 * removes/adds the entries from the parent widget as necessary
591 * parent: either the menu list widget or a menu entry widget
592 * menu: entry to be updated
595 void ConfigList::updateMenuList(P* parent, struct menu* menu)
604 while ((item = parent->firstChild()))
609 last = parent->firstChild();
610 if (last && !last->goParent)
612 for (child = menu->list; child; child = child->next) {
613 item = last ? last->nextSibling() : parent->firstChild();
614 type = child->prompt ? child->prompt->type : P_UNKNOWN;
618 if (!(child->flags & MENU_ROOT))
622 if (child->flags & MENU_ROOT)
629 visible = menu_is_visible(child);
630 if (!menuSkip(child)) {
631 if (!child->sym && !child->list && !child->prompt)
633 if (!item || item->menu != child)
634 item = new ConfigItem(parent, last, child, visible);
636 item->testUpdateMenu(visible);
638 if (mode == fullMode || mode == menuMode || type != P_MENU)
639 updateMenuList(item, child);
641 updateMenuList(item, 0);
646 if (item && item->menu == child) {
647 last = parent->firstChild();
650 else while (last->nextSibling() != item)
651 last = last->nextSibling();
657 void ConfigList::keyPressEvent(QKeyEvent* ev)
659 Q3ListViewItem* i = currentItem();
664 if (ev->key() == Qt::Key_Escape && mode != fullMode && mode != listMode) {
665 emit parentSelected();
671 Parent::keyPressEvent(ev);
674 item = (ConfigItem*)i;
679 if (item->goParent) {
680 emit parentSelected();
686 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
687 if (type == P_MENU && rootEntry != menu &&
688 mode != fullMode && mode != menuMode) {
689 emit menuSelected(menu);
705 Parent::keyPressEvent(ev);
711 void ConfigList::contentsMousePressEvent(QMouseEvent* e)
713 //QPoint p(contentsToViewport(e->pos()));
714 //printf("contentsMousePressEvent: %d,%d\n", p.x(), p.y());
715 Parent::contentsMousePressEvent(e);
718 void ConfigList::contentsMouseReleaseEvent(QMouseEvent* e)
720 QPoint p(contentsToViewport(e->pos()));
721 ConfigItem* item = (ConfigItem*)itemAt(p);
723 enum prop_type ptype;
731 x = header()->offset() + p.x();
732 idx = colRevMap[header()->sectionAt(x)];
735 pm = item->pixmap(promptColIdx);
737 int off = header()->sectionPos(0) + itemMargin() +
738 treeStepSize() * (item->depth() + (rootIsDecorated() ? 1 : 0));
739 if (x >= off && x < off + pm->width()) {
740 if (item->goParent) {
741 emit parentSelected();
745 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
746 if (ptype == P_MENU && rootEntry != menu &&
747 mode != fullMode && mode != menuMode)
748 emit menuSelected(menu);
769 //printf("contentsMouseReleaseEvent: %d,%d\n", p.x(), p.y());
770 Parent::contentsMouseReleaseEvent(e);
773 void ConfigList::contentsMouseMoveEvent(QMouseEvent* e)
775 //QPoint p(contentsToViewport(e->pos()));
776 //printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y());
777 Parent::contentsMouseMoveEvent(e);
780 void ConfigList::contentsMouseDoubleClickEvent(QMouseEvent* e)
782 QPoint p(contentsToViewport(e->pos()));
783 ConfigItem* item = (ConfigItem*)itemAt(p);
785 enum prop_type ptype;
789 if (item->goParent) {
790 emit parentSelected();
796 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
797 if (ptype == P_MENU && (mode == singleMode || mode == symbolMode))
798 emit menuSelected(menu);
803 //printf("contentsMouseDoubleClickEvent: %d,%d\n", p.x(), p.y());
804 Parent::contentsMouseDoubleClickEvent(e);
807 void ConfigList::focusInEvent(QFocusEvent *e)
809 struct menu *menu = NULL;
811 Parent::focusInEvent(e);
813 ConfigItem* item = (ConfigItem *)currentItem();
815 setSelected(item, TRUE);
821 void ConfigList::contextMenuEvent(QContextMenuEvent *e)
823 if (e->y() <= header()->geometry().bottom()) {
827 headerPopup = new Q3PopupMenu(this);
828 action = new Q3Action(NULL, _("Show Name"), 0, this);
829 action->setToggleAction(TRUE);
830 connect(action, SIGNAL(toggled(bool)),
831 parent(), SLOT(setShowName(bool)));
832 connect(parent(), SIGNAL(showNameChanged(bool)),
833 action, SLOT(setOn(bool)));
834 action->setOn(showName);
835 action->addTo(headerPopup);
836 action = new Q3Action(NULL, _("Show Range"), 0, this);
837 action->setToggleAction(TRUE);
838 connect(action, SIGNAL(toggled(bool)),
839 parent(), SLOT(setShowRange(bool)));
840 connect(parent(), SIGNAL(showRangeChanged(bool)),
841 action, SLOT(setOn(bool)));
842 action->setOn(showRange);
843 action->addTo(headerPopup);
844 action = new Q3Action(NULL, _("Show Data"), 0, this);
845 action->setToggleAction(TRUE);
846 connect(action, SIGNAL(toggled(bool)),
847 parent(), SLOT(setShowData(bool)));
848 connect(parent(), SIGNAL(showDataChanged(bool)),
849 action, SLOT(setOn(bool)));
850 action->setOn(showData);
851 action->addTo(headerPopup);
853 headerPopup->exec(e->globalPos());
859 ConfigView*ConfigView::viewList;
860 QAction *ConfigView::showNormalAction;
861 QAction *ConfigView::showAllAction;
862 QAction *ConfigView::showPromptAction;
864 ConfigView::ConfigView(QWidget* parent, const char *name)
865 : Parent(parent, name)
867 list = new ConfigList(this, name);
868 lineEdit = new ConfigLineEdit(this);
871 this->nextView = viewList;
875 ConfigView::~ConfigView(void)
879 for (vp = &viewList; *vp; vp = &(*vp)->nextView) {
887 void ConfigView::setOptionMode(QAction *act)
889 if (act == showNormalAction)
890 list->optMode = normalOpt;
891 else if (act == showAllAction)
892 list->optMode = allOpt;
894 list->optMode = promptOpt;
896 list->updateListAll();
899 void ConfigView::setShowName(bool b)
901 if (list->showName != b) {
904 emit showNameChanged(b);
908 void ConfigView::setShowRange(bool b)
910 if (list->showRange != b) {
913 emit showRangeChanged(b);
917 void ConfigView::setShowData(bool b)
919 if (list->showData != b) {
922 emit showDataChanged(b);
926 void ConfigList::setAllOpen(bool open)
928 Q3ListViewItemIterator it(this);
930 for (; it.current(); it++)
931 it.current()->setOpen(open);
934 void ConfigView::updateList(ConfigItem* item)
938 for (v = viewList; v; v = v->nextView)
939 v->list->updateList(item);
942 void ConfigView::updateListAll(void)
946 for (v = viewList; v; v = v->nextView)
947 v->list->updateListAll();
950 ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name)
951 : Parent(parent, name), sym(0), _menu(0)
954 configSettings->beginGroup(name);
955 _showDebug = configSettings->readBoolEntry("/showDebug", false);
956 configSettings->endGroup();
957 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
961 void ConfigInfoView::saveSettings(void)
964 configSettings->beginGroup(name());
965 configSettings->writeEntry("/showDebug", showDebug());
966 configSettings->endGroup();
970 void ConfigInfoView::setShowDebug(bool b)
972 if (_showDebug != b) {
978 emit showDebugChanged(b);
982 void ConfigInfoView::setInfo(struct menu *m)
994 void ConfigInfoView::symbolInfo(void)
998 str += "<big>Symbol: <b>";
999 str += print_filter(sym->name);
1000 str += "</b></big><br><br>value: ";
1001 str += print_filter(sym_get_string_value(sym));
1002 str += "<br>visibility: ";
1003 str += sym->visible == yes ? "y" : sym->visible == mod ? "m" : "n";
1005 str += debug_info(sym);
1010 void ConfigInfoView::menuInfo(void)
1013 QString head, debug, help;
1017 if (_menu->prompt) {
1019 head += print_filter(_(_menu->prompt->text));
1020 head += "</b></big>";
1024 head += QString().sprintf("<a href=\"s%p\">", sym);
1025 head += print_filter(sym->name);
1030 } else if (sym->name) {
1033 head += QString().sprintf("<a href=\"s%p\">", sym);
1034 head += print_filter(sym->name);
1037 head += "</b></big>";
1042 debug = debug_info(sym);
1044 struct gstr help_gstr = str_new();
1045 menu_get_ext_help(_menu, &help_gstr);
1046 help = print_filter(str_get(&help_gstr));
1047 str_free(&help_gstr);
1048 } else if (_menu->prompt) {
1050 head += print_filter(_(_menu->prompt->text));
1051 head += "</b></big><br><br>";
1053 if (_menu->prompt->visible.expr) {
1054 debug += " dep: ";
1055 expr_print(_menu->prompt->visible.expr, expr_print_help, &debug, E_NONE);
1056 debug += "<br><br>";
1061 debug += QString().sprintf("defined at %s:%d<br><br>", _menu->file->name, _menu->lineno);
1063 setText(head + debug + help);
1066 QString ConfigInfoView::debug_info(struct symbol *sym)
1071 debug += print_filter(sym_type_name(sym->type));
1072 if (sym_is_choice(sym))
1073 debug += " (choice)";
1075 if (sym->rev_dep.expr) {
1076 debug += "reverse dep: ";
1077 expr_print(sym->rev_dep.expr, expr_print_help, &debug, E_NONE);
1080 for (struct property *prop = sym->prop; prop; prop = prop->next) {
1081 switch (prop->type) {
1084 debug += QString().sprintf("prompt: <a href=\"m%p\">", prop->menu);
1085 debug += print_filter(_(prop->text));
1086 debug += "</a><br>";
1092 debug += prop_get_type_name(prop->type);
1094 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1098 if (sym_is_choice(sym)) {
1099 debug += "choice: ";
1100 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 Q3PopupMenu* ConfigInfoView::createPopupMenu(const QPoint& pos)
1166 Q3PopupMenu* popup = Parent::createPopupMenu(pos);
1167 Q3Action* action = new Q3Action(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(ConfigMainWindow* 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(Qt::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 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1207 parent, SLOT(setMenuLink(struct menu *)));
1209 layout1->addWidget(split);
1212 int x, y, width, height;
1215 configSettings->beginGroup(name);
1216 width = configSettings->readNumEntry("/window width", parent->width() / 2);
1217 height = configSettings->readNumEntry("/window height", parent->height() / 2);
1218 resize(width, height);
1219 x = configSettings->readNumEntry("/window x", 0, &ok);
1221 y = configSettings->readNumEntry("/window y", 0, &ok);
1224 Q3ValueList<int> sizes = configSettings->readSizes("/split", &ok);
1226 split->setSizes(sizes);
1227 configSettings->endGroup();
1228 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
1232 void ConfigSearchWindow::saveSettings(void)
1235 configSettings->beginGroup(name());
1236 configSettings->writeEntry("/window x", pos().x());
1237 configSettings->writeEntry("/window y", pos().y());
1238 configSettings->writeEntry("/window width", size().width());
1239 configSettings->writeEntry("/window height", size().height());
1240 configSettings->writeSizes("/split", split->sizes());
1241 configSettings->endGroup();
1245 void ConfigSearchWindow::search(void)
1248 struct property *prop;
1249 ConfigItem *lastItem = NULL;
1252 list->list->clear();
1255 result = sym_re_search(editField->text().latin1());
1258 for (p = result; *p; p++) {
1259 for_all_prompts((*p), prop)
1260 lastItem = new ConfigItem(list->list, lastItem, prop->menu,
1261 menu_is_visible(prop->menu));
1266 * Construct the complete config widget
1268 ConfigMainWindow::ConfigMainWindow(void)
1273 int x, y, width, height;
1276 QDesktopWidget *d = configApp->desktop();
1277 snprintf(title, sizeof(title), "%s%s",
1278 rootmenu.prompt->text,
1279 #if QT_VERSION < 0x040000
1287 width = configSettings->readNumEntry("/window width", d->width() - 64);
1288 height = configSettings->readNumEntry("/window height", d->height() - 64);
1289 resize(width, height);
1290 x = configSettings->readNumEntry("/window x", 0, &ok);
1292 y = configSettings->readNumEntry("/window y", 0, &ok);
1296 split1 = new QSplitter(this);
1297 split1->setOrientation(Qt::Horizontal);
1298 setCentralWidget(split1);
1300 menuView = new ConfigView(split1, "menu");
1301 menuList = menuView->list;
1303 split2 = new QSplitter(split1);
1304 split2->setOrientation(Qt::Vertical);
1306 // create config tree
1307 configView = new ConfigView(split2, "config");
1308 configList = configView->list;
1310 helpText = new ConfigInfoView(split2, "help");
1311 helpText->setTextFormat(Qt::RichText);
1313 setTabOrder(configList, helpText);
1314 configList->setFocus();
1317 toolBar = new Q3ToolBar("Tools", this);
1319 backAction = new Q3Action("Back", QPixmap(xpm_back), _("Back"), 0, this);
1320 connect(backAction, SIGNAL(activated()), SLOT(goBack()));
1321 backAction->setEnabled(FALSE);
1322 Q3Action *quitAction = new Q3Action("Quit", _("&Quit"), Qt::CTRL + Qt::Key_Q, this);
1323 connect(quitAction, SIGNAL(activated()), SLOT(close()));
1324 Q3Action *loadAction = new Q3Action("Load", QPixmap(xpm_load), _("&Load"), Qt::CTRL + Qt::Key_L, this);
1325 connect(loadAction, SIGNAL(activated()), SLOT(loadConfig()));
1326 saveAction = new Q3Action("Save", QPixmap(xpm_save), _("&Save"), Qt::CTRL + Qt::Key_S, this);
1327 connect(saveAction, SIGNAL(activated()), SLOT(saveConfig()));
1328 conf_set_changed_callback(conf_changed);
1329 // Set saveAction's initial state
1331 Q3Action *saveAsAction = new Q3Action("Save As...", _("Save &As..."), 0, this);
1332 connect(saveAsAction, SIGNAL(activated()), SLOT(saveConfigAs()));
1333 Q3Action *searchAction = new Q3Action("Find", _("&Find"), Qt::CTRL + Qt::Key_F, this);
1334 connect(searchAction, SIGNAL(activated()), SLOT(searchConfig()));
1335 Q3Action *singleViewAction = new Q3Action("Single View", QPixmap(xpm_single_view), _("Single View"), 0, this);
1336 connect(singleViewAction, SIGNAL(activated()), SLOT(showSingleView()));
1337 Q3Action *splitViewAction = new Q3Action("Split View", QPixmap(xpm_split_view), _("Split View"), 0, this);
1338 connect(splitViewAction, SIGNAL(activated()), SLOT(showSplitView()));
1339 Q3Action *fullViewAction = new Q3Action("Full View", QPixmap(xpm_tree_view), _("Full View"), 0, this);
1340 connect(fullViewAction, SIGNAL(activated()), SLOT(showFullView()));
1342 Q3Action *showNameAction = new Q3Action(NULL, _("Show Name"), 0, this);
1343 showNameAction->setToggleAction(TRUE);
1344 connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool)));
1345 connect(configView, SIGNAL(showNameChanged(bool)), showNameAction, SLOT(setOn(bool)));
1346 showNameAction->setOn(configView->showName());
1347 Q3Action *showRangeAction = new Q3Action(NULL, _("Show Range"), 0, this);
1348 showRangeAction->setToggleAction(TRUE);
1349 connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool)));
1350 connect(configView, SIGNAL(showRangeChanged(bool)), showRangeAction, SLOT(setOn(bool)));
1351 showRangeAction->setOn(configList->showRange);
1352 Q3Action *showDataAction = new Q3Action(NULL, _("Show Data"), 0, this);
1353 showDataAction->setToggleAction(TRUE);
1354 connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool)));
1355 connect(configView, SIGNAL(showDataChanged(bool)), showDataAction, SLOT(setOn(bool)));
1356 showDataAction->setOn(configList->showData);
1358 QActionGroup *optGroup = new QActionGroup(this);
1359 optGroup->setExclusive(TRUE);
1360 connect(optGroup, SIGNAL(selected(QAction *)), configView,
1361 SLOT(setOptionMode(QAction *)));
1362 connect(optGroup, SIGNAL(selected(QAction *)), menuView,
1363 SLOT(setOptionMode(QAction *)));
1365 #if QT_VERSION >= 0x040000
1366 configView->showNormalAction = new QAction(_("Show Normal Options"), optGroup);
1367 configView->showAllAction = new QAction(_("Show All Options"), optGroup);
1368 configView->showPromptAction = new QAction(_("Show Prompt Options"), optGroup);
1370 configView->showNormalAction = new QAction(_("Show Normal Options"), 0, optGroup);
1371 configView->showAllAction = new QAction(_("Show All Options"), 0, optGroup);
1372 configView->showPromptAction = new QAction(_("Show Prompt Options"), 0, optGroup);
1374 configView->showNormalAction->setToggleAction(TRUE);
1375 configView->showNormalAction->setOn(configList->optMode == normalOpt);
1376 configView->showAllAction->setToggleAction(TRUE);
1377 configView->showAllAction->setOn(configList->optMode == allOpt);
1378 configView->showPromptAction->setToggleAction(TRUE);
1379 configView->showPromptAction->setOn(configList->optMode == promptOpt);
1381 Q3Action *showDebugAction = new Q3Action(NULL, _("Show Debug Info"), 0, this);
1382 showDebugAction->setToggleAction(TRUE);
1383 connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
1384 connect(helpText, SIGNAL(showDebugChanged(bool)), showDebugAction, SLOT(setOn(bool)));
1385 showDebugAction->setOn(helpText->showDebug());
1387 Q3Action *showIntroAction = new Q3Action(NULL, _("Introduction"), 0, this);
1388 connect(showIntroAction, SIGNAL(activated()), SLOT(showIntro()));
1389 Q3Action *showAboutAction = new Q3Action(NULL, _("About"), 0, this);
1390 connect(showAboutAction, SIGNAL(activated()), SLOT(showAbout()));
1393 backAction->addTo(toolBar);
1394 toolBar->addSeparator();
1395 loadAction->addTo(toolBar);
1396 saveAction->addTo(toolBar);
1397 toolBar->addSeparator();
1398 singleViewAction->addTo(toolBar);
1399 splitViewAction->addTo(toolBar);
1400 fullViewAction->addTo(toolBar);
1402 // create config menu
1403 Q3PopupMenu* config = new Q3PopupMenu(this);
1404 menu->insertItem(_("&File"), config);
1405 loadAction->addTo(config);
1406 saveAction->addTo(config);
1407 saveAsAction->addTo(config);
1408 config->insertSeparator();
1409 quitAction->addTo(config);
1412 Q3PopupMenu* editMenu = new Q3PopupMenu(this);
1413 menu->insertItem(_("&Edit"), editMenu);
1414 searchAction->addTo(editMenu);
1416 // create options menu
1417 Q3PopupMenu* optionMenu = new Q3PopupMenu(this);
1418 menu->insertItem(_("&Option"), optionMenu);
1419 showNameAction->addTo(optionMenu);
1420 showRangeAction->addTo(optionMenu);
1421 showDataAction->addTo(optionMenu);
1422 optionMenu->insertSeparator();
1423 optGroup->addTo(optionMenu);
1424 optionMenu->insertSeparator();
1427 Q3PopupMenu* helpMenu = new Q3PopupMenu(this);
1428 menu->insertSeparator();
1429 menu->insertItem(_("&Help"), helpMenu);
1430 showIntroAction->addTo(helpMenu);
1431 showAboutAction->addTo(helpMenu);
1433 connect(configList, SIGNAL(menuChanged(struct menu *)),
1434 helpText, SLOT(setInfo(struct menu *)));
1435 connect(configList, SIGNAL(menuSelected(struct menu *)),
1436 SLOT(changeMenu(struct menu *)));
1437 connect(configList, SIGNAL(parentSelected()),
1439 connect(menuList, SIGNAL(menuChanged(struct menu *)),
1440 helpText, SLOT(setInfo(struct menu *)));
1441 connect(menuList, SIGNAL(menuSelected(struct menu *)),
1442 SLOT(changeMenu(struct menu *)));
1444 connect(configList, SIGNAL(gotFocus(struct menu *)),
1445 helpText, SLOT(setInfo(struct menu *)));
1446 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1447 helpText, SLOT(setInfo(struct menu *)));
1448 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1449 SLOT(listFocusChanged(void)));
1450 connect(helpText, SIGNAL(menuSelected(struct menu *)),
1451 SLOT(setMenuLink(struct menu *)));
1453 QString listMode = configSettings->readEntry("/listMode", "symbol");
1454 if (listMode == "single")
1456 else if (listMode == "full")
1458 else /*if (listMode == "split")*/
1461 // UI setup done, restore splitter positions
1462 Q3ValueList<int> sizes = configSettings->readSizes("/split1", &ok);
1464 split1->setSizes(sizes);
1466 sizes = configSettings->readSizes("/split2", &ok);
1468 split2->setSizes(sizes);
1471 void ConfigMainWindow::loadConfig(void)
1473 QString s = Q3FileDialog::getOpenFileName(conf_get_configname(), NULL, this);
1476 if (conf_read(QFile::encodeName(s)))
1477 QMessageBox::information(this, "qconf", _("Unable to load configuration!"));
1478 ConfigView::updateListAll();
1481 void ConfigMainWindow::saveConfig(void)
1483 if (conf_write(NULL))
1484 QMessageBox::information(this, "qconf", _("Unable to save configuration!"));
1487 void ConfigMainWindow::saveConfigAs(void)
1489 QString s = Q3FileDialog::getSaveFileName(conf_get_configname(), NULL, this);
1495 void ConfigMainWindow::searchConfig(void)
1498 searchWindow = new ConfigSearchWindow(this, "search");
1499 searchWindow->show();
1502 void ConfigMainWindow::changeMenu(struct menu *menu)
1504 configList->setRootMenu(menu);
1505 if (configList->rootEntry->parent == &rootmenu)
1506 backAction->setEnabled(FALSE);
1508 backAction->setEnabled(TRUE);
1511 void ConfigMainWindow::setMenuLink(struct menu *menu)
1513 struct menu *parent;
1514 ConfigList* list = NULL;
1517 if (configList->menuSkip(menu))
1520 switch (configList->mode) {
1523 parent = menu_get_parent_menu(menu);
1526 list->setRootMenu(parent);
1529 if (menu->flags & MENU_ROOT) {
1530 configList->setRootMenu(menu);
1531 configList->clearSelection();
1535 parent = menu_get_parent_menu(menu->parent);
1538 item = menuList->findConfigItem(parent);
1540 menuList->setSelected(item, TRUE);
1541 menuList->ensureItemVisible(item);
1543 list->setRootMenu(parent);
1554 item = list->findConfigItem(menu);
1556 list->setSelected(item, TRUE);
1557 list->ensureItemVisible(item);
1563 void ConfigMainWindow::listFocusChanged(void)
1565 if (menuList->mode == menuMode)
1566 configList->clearSelection();
1569 void ConfigMainWindow::goBack(void)
1573 configList->setParentMenu();
1574 if (configList->rootEntry == &rootmenu)
1575 backAction->setEnabled(FALSE);
1576 item = (ConfigItem*)menuList->selectedItem();
1578 if (item->menu == configList->rootEntry) {
1579 menuList->setSelected(item, TRUE);
1582 item = (ConfigItem*)item->parent();
1586 void ConfigMainWindow::showSingleView(void)
1589 menuList->setRootMenu(0);
1590 configList->mode = singleMode;
1591 if (configList->rootEntry == &rootmenu)
1592 configList->updateListAll();
1594 configList->setRootMenu(&rootmenu);
1595 configList->setAllOpen(TRUE);
1596 configList->setFocus();
1599 void ConfigMainWindow::showSplitView(void)
1601 configList->mode = symbolMode;
1602 if (configList->rootEntry == &rootmenu)
1603 configList->updateListAll();
1605 configList->setRootMenu(&rootmenu);
1606 configList->setAllOpen(TRUE);
1607 configApp->processEvents();
1608 menuList->mode = menuMode;
1609 menuList->setRootMenu(&rootmenu);
1610 menuList->setAllOpen(TRUE);
1612 menuList->setFocus();
1615 void ConfigMainWindow::showFullView(void)
1618 menuList->setRootMenu(0);
1619 configList->mode = fullMode;
1620 if (configList->rootEntry == &rootmenu)
1621 configList->updateListAll();
1623 configList->setRootMenu(&rootmenu);
1624 configList->setAllOpen(FALSE);
1625 configList->setFocus();
1629 * ask for saving configuration before quitting
1630 * TODO ask only when something changed
1632 void ConfigMainWindow::closeEvent(QCloseEvent* e)
1634 if (!conf_get_changed()) {
1638 QMessageBox mb("qconf", _("Save configuration?"), QMessageBox::Warning,
1639 QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape);
1640 mb.setButtonText(QMessageBox::Yes, _("&Save Changes"));
1641 mb.setButtonText(QMessageBox::No, _("&Discard Changes"));
1642 mb.setButtonText(QMessageBox::Cancel, _("Cancel Exit"));
1643 switch (mb.exec()) {
1644 case QMessageBox::Yes:
1646 case QMessageBox::No:
1649 case QMessageBox::Cancel:
1655 void ConfigMainWindow::showIntro(void)
1657 static const QString str = _("Welcome to the qconf graphical configuration tool.\n\n"
1658 "For each option, a blank box indicates the feature is disabled, a check\n"
1659 "indicates it is enabled, and a dot indicates that it is to be compiled\n"
1660 "as a module. Clicking on the box will cycle through the three states.\n\n"
1661 "If you do not see an option (e.g., a device driver) that you believe\n"
1662 "should be present, try turning on Show All Options under the Options menu.\n"
1663 "Although there is no cross reference yet to help you figure out what other\n"
1664 "options must be enabled to support the option you are interested in, you can\n"
1665 "still view the help of a grayed-out option.\n\n"
1666 "Toggling Show Debug Info under the Options menu will show the dependencies,\n"
1667 "which you can then match by examining other options.\n\n");
1669 QMessageBox::information(this, "qconf", str);
1672 void ConfigMainWindow::showAbout(void)
1674 static const QString str = _("qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n\n"
1675 "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n");
1677 QMessageBox::information(this, "qconf", str);
1680 void ConfigMainWindow::saveSettings(void)
1682 configSettings->writeEntry("/window x", pos().x());
1683 configSettings->writeEntry("/window y", pos().y());
1684 configSettings->writeEntry("/window width", size().width());
1685 configSettings->writeEntry("/window height", size().height());
1688 switch(configList->mode) {
1704 configSettings->writeEntry("/listMode", entry);
1706 configSettings->writeSizes("/split1", split1->sizes());
1707 configSettings->writeSizes("/split2", split2->sizes());
1710 void ConfigMainWindow::conf_changed(void)
1713 saveAction->setEnabled(conf_get_changed());
1716 void fixup_rootmenu(struct menu *menu)
1719 static int menu_cnt = 0;
1721 menu->flags |= MENU_ROOT;
1722 for (child = menu->list; child; child = child->next) {
1723 if (child->prompt && child->prompt->type == P_MENU) {
1725 fixup_rootmenu(child);
1727 } else if (!menu_cnt)
1728 fixup_rootmenu(child);
1732 static const char *progname;
1734 static void usage(void)
1736 printf(_("%s <config>\n"), progname);
1740 int main(int ac, char** av)
1742 ConfigMainWindow* v;
1745 bindtextdomain(PACKAGE, LOCALEDIR);
1746 textdomain(PACKAGE);
1749 configApp = new QApplication(ac, av);
1750 if (ac > 1 && av[1][0] == '-') {
1763 fixup_rootmenu(&rootmenu);
1765 //zconfdump(stdout);
1767 configSettings = new ConfigSettings();
1768 configSettings->beginGroup("/kconfig/qconf");
1769 v = new ConfigMainWindow();
1771 //zconfdump(stdout);
1772 configApp->setMainWidget(v);
1773 configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit()));
1774 configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings()));
1778 configSettings->endGroup();
1779 delete configSettings;