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
10 #include <qmainwindow.h>
12 #include <qvaluelist.h>
13 #include <qtextbrowser.h>
16 #include <qfiledialog.h>
17 #include <qdragobject.h>
18 #include <qpopupmenu.h>
20 #include <q3mainwindow.h>
22 #include <q3valuelist.h>
23 #include <q3textbrowser.h>
26 #include <q3filedialog.h>
27 #include <q3dragobject.h>
28 #include <q3popupmenu.h>
31 #include <qapplication.h>
32 #include <qdesktopwidget.h>
35 #include <qsplitter.h>
36 #include <qlineedit.h>
38 #include <qpushbutton.h>
40 #include <qmessagebox.h>
57 static QApplication *configApp;
58 static ConfigSettings *configSettings;
60 Q3Action *ConfigMainWindow::saveAction;
62 static inline QString qgettext(const char* str)
64 return QString::fromLocal8Bit(gettext(str));
67 static inline QString qgettext(const QString& str)
69 return QString::fromLocal8Bit(gettext(str.latin1()));
73 * Reads a list of integer values from the application settings.
75 Q3ValueList<int> ConfigSettings::readSizes(const QString& key, bool *ok)
77 Q3ValueList<int> result;
78 QStringList entryList = readListEntry(key, ok);
79 QStringList::Iterator it;
81 for (it = entryList.begin(); it != entryList.end(); ++it)
82 result.push_back((*it).toInt());
88 * Writes a list of integer values to the application settings.
90 bool ConfigSettings::writeSizes(const QString& key, const Q3ValueList<int>& value)
92 QStringList stringList;
93 Q3ValueList<int>::ConstIterator it;
95 for (it = value.begin(); it != value.end(); ++it)
96 stringList.push_back(QString::number(*it));
97 return writeEntry(key, stringList);
103 * TODO check the value
105 void ConfigItem::okRename(int col)
107 Parent::okRename(col);
108 sym_set_string_value(menu->sym, text(dataColIdx).latin1());
109 listView()->updateList(this);
113 * update the displayed of a menu entry
115 void ConfigItem::updateMenu(void)
119 struct property *prop;
126 setPixmap(promptColIdx, list->menuBackPix);
133 prompt = _(menu_get_prompt(menu));
135 if (prop) switch (prop->type) {
137 if (list->mode == singleMode || list->mode == symbolMode) {
138 /* a menuconfig entry is displayed differently
139 * depending whether it's at the view root or a child.
141 if (sym && list->rootEntry == menu)
143 setPixmap(promptColIdx, list->menuPix);
147 setPixmap(promptColIdx, 0);
151 setPixmap(promptColIdx, 0);
159 setText(nameColIdx, QString::fromLocal8Bit(sym->name));
161 type = sym_get_type(sym);
167 if (!sym_is_changable(sym) && list->optMode == normalOpt) {
168 setPixmap(promptColIdx, 0);
169 setText(noColIdx, QString::null);
170 setText(modColIdx, QString::null);
171 setText(yesColIdx, QString::null);
174 expr = sym_get_tristate_value(sym);
177 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
178 setPixmap(promptColIdx, list->choiceYesPix);
180 setPixmap(promptColIdx, list->symbolYesPix);
181 setText(yesColIdx, "Y");
185 setPixmap(promptColIdx, list->symbolModPix);
186 setText(modColIdx, "M");
190 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
191 setPixmap(promptColIdx, list->choiceNoPix);
193 setPixmap(promptColIdx, list->symbolNoPix);
194 setText(noColIdx, "N");
199 setText(noColIdx, sym_tristate_within_range(sym, no) ? "_" : 0);
201 setText(modColIdx, sym_tristate_within_range(sym, mod) ? "_" : 0);
203 setText(yesColIdx, sym_tristate_within_range(sym, yes) ? "_" : 0);
205 setText(dataColIdx, QChar(ch));
212 data = sym_get_string_value(sym);
214 int i = list->mapIdx(dataColIdx);
216 setRenameEnabled(i, TRUE);
217 setText(dataColIdx, data);
218 if (type == S_STRING)
219 prompt = QString("%1: %2").arg(prompt).arg(data);
221 prompt = QString("(%2) %1").arg(prompt).arg(data);
224 if (!sym_has_value(sym) && visible)
225 prompt += _(" (NEW)");
227 setText(promptColIdx, prompt);
230 void ConfigItem::testUpdateMenu(bool v)
238 sym_calc_value(menu->sym);
239 if (menu->flags & MENU_CHANGED) {
240 /* the menu entry changed, so update all list items */
241 menu->flags &= ~MENU_CHANGED;
242 for (i = (ConfigItem*)menu->data; i; i = i->nextItem)
244 } else if (listView()->updateAll)
248 void ConfigItem::paintCell(QPainter* p, const QColorGroup& cg, int column, int width, int align)
250 ConfigList* list = listView();
253 if (isSelected() && !list->hasFocus() && list->mode == menuMode)
254 Parent::paintCell(p, list->inactivedColorGroup, column, width, align);
256 Parent::paintCell(p, cg, column, width, align);
258 Parent::paintCell(p, list->disabledColorGroup, column, width, align);
262 * construct a menu entry
264 void ConfigItem::init(void)
267 ConfigList* list = listView();
268 nextItem = (ConfigItem*)menu->data;
271 if (list->mode != fullMode)
273 sym_calc_value(menu->sym);
279 * destruct a menu entry
281 ConfigItem::~ConfigItem(void)
284 ConfigItem** ip = (ConfigItem**)&menu->data;
285 for (; *ip; ip = &(*ip)->nextItem) {
294 ConfigLineEdit::ConfigLineEdit(ConfigView* parent)
297 connect(this, SIGNAL(lostFocus()), SLOT(hide()));
300 void ConfigLineEdit::show(ConfigItem* i)
303 if (sym_get_string_value(item->menu->sym))
304 setText(QString::fromLocal8Bit(sym_get_string_value(item->menu->sym)));
306 setText(QString::null);
311 void ConfigLineEdit::keyPressEvent(QKeyEvent* e)
318 sym_set_string_value(item->menu->sym, text().latin1());
319 parent()->updateList(item);
322 Parent::keyPressEvent(e);
326 parent()->list->setFocus();
330 ConfigList::ConfigList(ConfigView* p, const char *name)
333 symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no),
334 choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no),
335 menuPix(xpm_menu), menuInvPix(xpm_menu_inv), menuBackPix(xpm_menuback), voidPix(xpm_void),
336 showName(false), showRange(false), showData(false), optMode(normalOpt),
337 rootEntry(0), headerPopup(0)
342 setRootIsDecorated(TRUE);
343 disabledColorGroup = palette().active();
344 disabledColorGroup.setColor(QColorGroup::Text, palette().disabled().text());
345 inactivedColorGroup = palette().active();
346 inactivedColorGroup.setColor(QColorGroup::Highlight, palette().disabled().highlight());
348 connect(this, SIGNAL(selectionChanged(void)),
349 SLOT(updateSelection(void)));
352 configSettings->beginGroup(name);
353 showName = configSettings->readBoolEntry("/showName", false);
354 showRange = configSettings->readBoolEntry("/showRange", false);
355 showData = configSettings->readBoolEntry("/showData", false);
356 optMode = (enum optionMode)configSettings->readNumEntry("/optionMode", false);
357 configSettings->endGroup();
358 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
361 for (i = 0; i < colNr; i++)
362 colMap[i] = colRevMap[i] = -1;
363 addColumn(promptColIdx, _("Option"));
368 bool ConfigList::menuSkip(struct menu *menu)
370 if (optMode == normalOpt && menu_is_visible(menu))
372 if (optMode == promptOpt && menu_has_prompt(menu))
374 if (optMode == allOpt)
379 void ConfigList::reinit(void)
381 removeColumn(dataColIdx);
382 removeColumn(yesColIdx);
383 removeColumn(modColIdx);
384 removeColumn(noColIdx);
385 removeColumn(nameColIdx);
388 addColumn(nameColIdx, _("Name"));
390 addColumn(noColIdx, "N");
391 addColumn(modColIdx, "M");
392 addColumn(yesColIdx, "Y");
395 addColumn(dataColIdx, _("Value"));
400 void ConfigList::saveSettings(void)
403 configSettings->beginGroup(name());
404 configSettings->writeEntry("/showName", showName);
405 configSettings->writeEntry("/showRange", showRange);
406 configSettings->writeEntry("/showData", showData);
407 configSettings->writeEntry("/optionMode", (int)optMode);
408 configSettings->endGroup();
412 ConfigItem* ConfigList::findConfigItem(struct menu *menu)
414 ConfigItem* item = (ConfigItem*)menu->data;
416 for (; item; item = item->nextItem) {
417 if (this == item->listView())
424 void ConfigList::updateSelection(void)
429 ConfigItem* item = (ConfigItem*)selectedItem();
434 emit menuChanged(menu);
437 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
438 if (mode == menuMode && type == P_MENU)
439 emit menuSelected(menu);
442 void ConfigList::updateList(ConfigItem* item)
444 ConfigItem* last = 0;
447 if (mode != listMode)
449 Q3ListViewItemIterator it(this);
452 for (; it.current(); ++it) {
453 item = (ConfigItem*)it.current();
456 item->testUpdateMenu(menu_is_visible(item->menu));
461 if (rootEntry != &rootmenu && (mode == singleMode ||
462 (mode == symbolMode && rootEntry->parent != &rootmenu))) {
465 item = new ConfigItem(this, 0, true);
468 if ((mode == singleMode || (mode == symbolMode && !(rootEntry->flags & MENU_ROOT))) &&
469 rootEntry->sym && rootEntry->prompt) {
470 item = last ? last->nextSibling() : firstChild();
472 item = new ConfigItem(this, last, rootEntry, true);
474 item->testUpdateMenu(true);
476 updateMenuList(item, rootEntry);
481 updateMenuList(this, rootEntry);
485 void ConfigList::setValue(ConfigItem* item, tristate val)
491 sym = item->menu ? item->menu->sym : 0;
495 type = sym_get_type(sym);
499 oldval = sym_get_tristate_value(sym);
501 if (!sym_set_tristate_value(sym, val))
503 if (oldval == no && item->menu->list)
505 parent()->updateList(item);
510 void ConfigList::changeValue(ConfigItem* item)
514 int type, oldexpr, newexpr;
521 if (item->menu->list)
522 item->setOpen(!item->isOpen());
526 type = sym_get_type(sym);
530 oldexpr = sym_get_tristate_value(sym);
531 newexpr = sym_toggle_tristate_value(sym);
532 if (item->menu->list) {
533 if (oldexpr == newexpr)
534 item->setOpen(!item->isOpen());
535 else if (oldexpr == no)
538 if (oldexpr != newexpr)
539 parent()->updateList(item);
544 if (colMap[dataColIdx] >= 0)
545 item->startRename(colMap[dataColIdx]);
547 parent()->lineEdit->show(item);
552 void ConfigList::setRootMenu(struct menu *menu)
556 if (rootEntry == menu)
558 type = menu && menu->prompt ? menu->prompt->type : P_UNKNOWN;
561 updateMenuList(this, 0);
564 setSelected(currentItem(), hasFocus());
565 ensureItemVisible(currentItem());
568 void ConfigList::setParentMenu(void)
571 struct menu *oldroot;
574 if (rootEntry == &rootmenu)
576 setRootMenu(menu_get_parent_menu(rootEntry->parent));
578 Q3ListViewItemIterator it(this);
579 for (; (item = (ConfigItem*)it.current()); it++) {
580 if (item->menu == oldroot) {
581 setCurrentItem(item);
582 ensureItemVisible(item);
589 * update all the children of a menu entry
590 * removes/adds the entries from the parent widget as necessary
592 * parent: either the menu list widget or a menu entry widget
593 * menu: entry to be updated
596 void ConfigList::updateMenuList(P* parent, struct menu* menu)
605 while ((item = parent->firstChild()))
610 last = parent->firstChild();
611 if (last && !last->goParent)
613 for (child = menu->list; child; child = child->next) {
614 item = last ? last->nextSibling() : parent->firstChild();
615 type = child->prompt ? child->prompt->type : P_UNKNOWN;
619 if (!(child->flags & MENU_ROOT))
623 if (child->flags & MENU_ROOT)
630 visible = menu_is_visible(child);
631 if (!menuSkip(child)) {
632 if (!child->sym && !child->list && !child->prompt)
634 if (!item || item->menu != child)
635 item = new ConfigItem(parent, last, child, visible);
637 item->testUpdateMenu(visible);
639 if (mode == fullMode || mode == menuMode || type != P_MENU)
640 updateMenuList(item, child);
642 updateMenuList(item, 0);
647 if (item && item->menu == child) {
648 last = parent->firstChild();
651 else while (last->nextSibling() != item)
652 last = last->nextSibling();
658 void ConfigList::keyPressEvent(QKeyEvent* ev)
660 Q3ListViewItem* i = currentItem();
665 if (ev->key() == Qt::Key_Escape && mode != fullMode && mode != listMode) {
666 emit parentSelected();
672 Parent::keyPressEvent(ev);
675 item = (ConfigItem*)i;
680 if (item->goParent) {
681 emit parentSelected();
687 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
688 if (type == P_MENU && rootEntry != menu &&
689 mode != fullMode && mode != menuMode) {
690 emit menuSelected(menu);
706 Parent::keyPressEvent(ev);
712 void ConfigList::contentsMousePressEvent(QMouseEvent* e)
714 //QPoint p(contentsToViewport(e->pos()));
715 //printf("contentsMousePressEvent: %d,%d\n", p.x(), p.y());
716 Parent::contentsMousePressEvent(e);
719 void ConfigList::contentsMouseReleaseEvent(QMouseEvent* e)
721 QPoint p(contentsToViewport(e->pos()));
722 ConfigItem* item = (ConfigItem*)itemAt(p);
724 enum prop_type ptype;
732 x = header()->offset() + p.x();
733 idx = colRevMap[header()->sectionAt(x)];
736 pm = item->pixmap(promptColIdx);
738 int off = header()->sectionPos(0) + itemMargin() +
739 treeStepSize() * (item->depth() + (rootIsDecorated() ? 1 : 0));
740 if (x >= off && x < off + pm->width()) {
741 if (item->goParent) {
742 emit parentSelected();
746 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
747 if (ptype == P_MENU && rootEntry != menu &&
748 mode != fullMode && mode != menuMode)
749 emit menuSelected(menu);
770 //printf("contentsMouseReleaseEvent: %d,%d\n", p.x(), p.y());
771 Parent::contentsMouseReleaseEvent(e);
774 void ConfigList::contentsMouseMoveEvent(QMouseEvent* e)
776 //QPoint p(contentsToViewport(e->pos()));
777 //printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y());
778 Parent::contentsMouseMoveEvent(e);
781 void ConfigList::contentsMouseDoubleClickEvent(QMouseEvent* e)
783 QPoint p(contentsToViewport(e->pos()));
784 ConfigItem* item = (ConfigItem*)itemAt(p);
786 enum prop_type ptype;
790 if (item->goParent) {
791 emit parentSelected();
797 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
798 if (ptype == P_MENU && (mode == singleMode || mode == symbolMode))
799 emit menuSelected(menu);
804 //printf("contentsMouseDoubleClickEvent: %d,%d\n", p.x(), p.y());
805 Parent::contentsMouseDoubleClickEvent(e);
808 void ConfigList::focusInEvent(QFocusEvent *e)
810 struct menu *menu = NULL;
812 Parent::focusInEvent(e);
814 ConfigItem* item = (ConfigItem *)currentItem();
816 setSelected(item, TRUE);
822 void ConfigList::contextMenuEvent(QContextMenuEvent *e)
824 if (e->y() <= header()->geometry().bottom()) {
828 headerPopup = new Q3PopupMenu(this);
829 action = new Q3Action(NULL, _("Show Name"), 0, this);
830 action->setToggleAction(TRUE);
831 connect(action, SIGNAL(toggled(bool)),
832 parent(), SLOT(setShowName(bool)));
833 connect(parent(), SIGNAL(showNameChanged(bool)),
834 action, SLOT(setOn(bool)));
835 action->setOn(showName);
836 action->addTo(headerPopup);
837 action = new Q3Action(NULL, _("Show Range"), 0, this);
838 action->setToggleAction(TRUE);
839 connect(action, SIGNAL(toggled(bool)),
840 parent(), SLOT(setShowRange(bool)));
841 connect(parent(), SIGNAL(showRangeChanged(bool)),
842 action, SLOT(setOn(bool)));
843 action->setOn(showRange);
844 action->addTo(headerPopup);
845 action = new Q3Action(NULL, _("Show Data"), 0, this);
846 action->setToggleAction(TRUE);
847 connect(action, SIGNAL(toggled(bool)),
848 parent(), SLOT(setShowData(bool)));
849 connect(parent(), SIGNAL(showDataChanged(bool)),
850 action, SLOT(setOn(bool)));
851 action->setOn(showData);
852 action->addTo(headerPopup);
854 headerPopup->exec(e->globalPos());
860 ConfigView*ConfigView::viewList;
861 QAction *ConfigView::showNormalAction;
862 QAction *ConfigView::showAllAction;
863 QAction *ConfigView::showPromptAction;
865 ConfigView::ConfigView(QWidget* parent, const char *name)
866 : Parent(parent, name)
868 list = new ConfigList(this, name);
869 lineEdit = new ConfigLineEdit(this);
872 this->nextView = viewList;
876 ConfigView::~ConfigView(void)
880 for (vp = &viewList; *vp; vp = &(*vp)->nextView) {
888 void ConfigView::setOptionMode(QAction *act)
890 if (act == showNormalAction)
891 list->optMode = normalOpt;
892 else if (act == showAllAction)
893 list->optMode = allOpt;
895 list->optMode = promptOpt;
897 list->updateListAll();
900 void ConfigView::setShowName(bool b)
902 if (list->showName != b) {
905 emit showNameChanged(b);
909 void ConfigView::setShowRange(bool b)
911 if (list->showRange != b) {
914 emit showRangeChanged(b);
918 void ConfigView::setShowData(bool b)
920 if (list->showData != b) {
923 emit showDataChanged(b);
927 void ConfigList::setAllOpen(bool open)
929 Q3ListViewItemIterator it(this);
931 for (; it.current(); it++)
932 it.current()->setOpen(open);
935 void ConfigView::updateList(ConfigItem* item)
939 for (v = viewList; v; v = v->nextView)
940 v->list->updateList(item);
943 void ConfigView::updateListAll(void)
947 for (v = viewList; v; v = v->nextView)
948 v->list->updateListAll();
951 ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name)
952 : Parent(parent, name), sym(0), _menu(0)
955 configSettings->beginGroup(name);
956 _showDebug = configSettings->readBoolEntry("/showDebug", false);
957 configSettings->endGroup();
958 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
962 void ConfigInfoView::saveSettings(void)
965 configSettings->beginGroup(name());
966 configSettings->writeEntry("/showDebug", showDebug());
967 configSettings->endGroup();
971 void ConfigInfoView::setShowDebug(bool b)
973 if (_showDebug != b) {
979 emit showDebugChanged(b);
983 void ConfigInfoView::setInfo(struct menu *m)
995 void ConfigInfoView::symbolInfo(void)
999 str += "<big>Symbol: <b>";
1000 str += print_filter(sym->name);
1001 str += "</b></big><br><br>value: ";
1002 str += print_filter(sym_get_string_value(sym));
1003 str += "<br>visibility: ";
1004 str += sym->visible == yes ? "y" : sym->visible == mod ? "m" : "n";
1006 str += debug_info(sym);
1011 void ConfigInfoView::menuInfo(void)
1014 QString head, debug, help;
1018 if (_menu->prompt) {
1020 head += print_filter(_(_menu->prompt->text));
1021 head += "</b></big>";
1025 head += QString().sprintf("<a href=\"s%p\">", sym);
1026 head += print_filter(sym->name);
1031 } else if (sym->name) {
1034 head += QString().sprintf("<a href=\"s%p\">", sym);
1035 head += print_filter(sym->name);
1038 head += "</b></big>";
1043 debug = debug_info(sym);
1045 struct gstr help_gstr = str_new();
1046 menu_get_ext_help(_menu, &help_gstr);
1047 help = print_filter(str_get(&help_gstr));
1048 str_free(&help_gstr);
1049 } else if (_menu->prompt) {
1051 head += print_filter(_(_menu->prompt->text));
1052 head += "</b></big><br><br>";
1054 if (_menu->prompt->visible.expr) {
1055 debug += " dep: ";
1056 expr_print(_menu->prompt->visible.expr, expr_print_help, &debug, E_NONE);
1057 debug += "<br><br>";
1062 debug += QString().sprintf("defined at %s:%d<br><br>", _menu->file->name, _menu->lineno);
1064 setText(head + debug + help);
1067 QString ConfigInfoView::debug_info(struct symbol *sym)
1072 debug += print_filter(sym_type_name(sym->type));
1073 if (sym_is_choice(sym))
1074 debug += " (choice)";
1076 if (sym->rev_dep.expr) {
1077 debug += "reverse dep: ";
1078 expr_print(sym->rev_dep.expr, expr_print_help, &debug, E_NONE);
1081 for (struct property *prop = sym->prop; prop; prop = prop->next) {
1082 switch (prop->type) {
1085 debug += QString().sprintf("prompt: <a href=\"m%p\">", prop->menu);
1086 debug += print_filter(_(prop->text));
1087 debug += "</a><br>";
1093 debug += prop_get_type_name(prop->type);
1095 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1099 if (sym_is_choice(sym)) {
1100 debug += "choice: ";
1101 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1106 debug += "unknown property: ";
1107 debug += prop_get_type_name(prop->type);
1110 if (prop->visible.expr) {
1111 debug += " dep: ";
1112 expr_print(prop->visible.expr, expr_print_help, &debug, E_NONE);
1121 QString ConfigInfoView::print_filter(const QString &str)
1123 QRegExp re("[<>&\"\\n]");
1125 for (int i = 0; (i = res.find(re, i)) >= 0;) {
1126 switch (res[i].latin1()) {
1128 res.replace(i, 1, "<");
1132 res.replace(i, 1, ">");
1136 res.replace(i, 1, "&");
1140 res.replace(i, 1, """);
1144 res.replace(i, 1, "<br>");
1152 void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char *str)
1154 QString* text = reinterpret_cast<QString*>(data);
1155 QString str2 = print_filter(str);
1157 if (sym && sym->name && !(sym->flags & SYMBOL_CONST)) {
1158 *text += QString().sprintf("<a href=\"s%p\">", sym);
1165 Q3PopupMenu* ConfigInfoView::createPopupMenu(const QPoint& pos)
1167 Q3PopupMenu* popup = Parent::createPopupMenu(pos);
1168 Q3Action* action = new Q3Action(NULL, _("Show Debug Info"), 0, popup);
1169 action->setToggleAction(TRUE);
1170 connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
1171 connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool)));
1172 action->setOn(showDebug());
1173 popup->insertSeparator();
1174 action->addTo(popup);
1178 void ConfigInfoView::contentsContextMenuEvent(QContextMenuEvent *e)
1180 Parent::contentsContextMenuEvent(e);
1183 ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow* parent, const char *name)
1184 : Parent(parent, name), result(NULL)
1186 setCaption("Search Config");
1188 QVBoxLayout* layout1 = new QVBoxLayout(this, 11, 6);
1189 QHBoxLayout* layout2 = new QHBoxLayout(0, 0, 6);
1190 layout2->addWidget(new QLabel(_("Find:"), this));
1191 editField = new QLineEdit(this);
1192 connect(editField, SIGNAL(returnPressed()), SLOT(search()));
1193 layout2->addWidget(editField);
1194 searchButton = new QPushButton(_("Search"), this);
1195 searchButton->setAutoDefault(FALSE);
1196 connect(searchButton, SIGNAL(clicked()), SLOT(search()));
1197 layout2->addWidget(searchButton);
1198 layout1->addLayout(layout2);
1200 split = new QSplitter(this);
1201 split->setOrientation(Qt::Vertical);
1202 list = new ConfigView(split, name);
1203 list->list->mode = listMode;
1204 info = new ConfigInfoView(split, name);
1205 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1206 info, SLOT(setInfo(struct menu *)));
1207 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1208 parent, SLOT(setMenuLink(struct menu *)));
1210 layout1->addWidget(split);
1213 int x, y, width, height;
1216 configSettings->beginGroup(name);
1217 width = configSettings->readNumEntry("/window width", parent->width() / 2);
1218 height = configSettings->readNumEntry("/window height", parent->height() / 2);
1219 resize(width, height);
1220 x = configSettings->readNumEntry("/window x", 0, &ok);
1222 y = configSettings->readNumEntry("/window y", 0, &ok);
1225 Q3ValueList<int> sizes = configSettings->readSizes("/split", &ok);
1227 split->setSizes(sizes);
1228 configSettings->endGroup();
1229 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
1233 void ConfigSearchWindow::saveSettings(void)
1236 configSettings->beginGroup(name());
1237 configSettings->writeEntry("/window x", pos().x());
1238 configSettings->writeEntry("/window y", pos().y());
1239 configSettings->writeEntry("/window width", size().width());
1240 configSettings->writeEntry("/window height", size().height());
1241 configSettings->writeSizes("/split", split->sizes());
1242 configSettings->endGroup();
1246 void ConfigSearchWindow::search(void)
1249 struct property *prop;
1250 ConfigItem *lastItem = NULL;
1253 list->list->clear();
1256 result = sym_re_search(editField->text().latin1());
1259 for (p = result; *p; p++) {
1260 for_all_prompts((*p), prop)
1261 lastItem = new ConfigItem(list->list, lastItem, prop->menu,
1262 menu_is_visible(prop->menu));
1267 * Construct the complete config widget
1269 ConfigMainWindow::ConfigMainWindow(void)
1274 int x, y, width, height;
1277 QDesktopWidget *d = configApp->desktop();
1278 snprintf(title, sizeof(title), "%s%s",
1279 rootmenu.prompt->text,
1280 #if QT_VERSION < 0x040000
1288 width = configSettings->readNumEntry("/window width", d->width() - 64);
1289 height = configSettings->readNumEntry("/window height", d->height() - 64);
1290 resize(width, height);
1291 x = configSettings->readNumEntry("/window x", 0, &ok);
1293 y = configSettings->readNumEntry("/window y", 0, &ok);
1297 split1 = new QSplitter(this);
1298 split1->setOrientation(Qt::Horizontal);
1299 setCentralWidget(split1);
1301 menuView = new ConfigView(split1, "menu");
1302 menuList = menuView->list;
1304 split2 = new QSplitter(split1);
1305 split2->setOrientation(Qt::Vertical);
1307 // create config tree
1308 configView = new ConfigView(split2, "config");
1309 configList = configView->list;
1311 helpText = new ConfigInfoView(split2, "help");
1312 helpText->setTextFormat(Qt::RichText);
1314 setTabOrder(configList, helpText);
1315 configList->setFocus();
1318 toolBar = new Q3ToolBar("Tools", this);
1320 backAction = new Q3Action("Back", QPixmap(xpm_back), _("Back"), 0, this);
1321 connect(backAction, SIGNAL(activated()), SLOT(goBack()));
1322 backAction->setEnabled(FALSE);
1323 Q3Action *quitAction = new Q3Action("Quit", _("&Quit"), Qt::CTRL + Qt::Key_Q, this);
1324 connect(quitAction, SIGNAL(activated()), SLOT(close()));
1325 Q3Action *loadAction = new Q3Action("Load", QPixmap(xpm_load), _("&Load"), Qt::CTRL + Qt::Key_L, this);
1326 connect(loadAction, SIGNAL(activated()), SLOT(loadConfig()));
1327 saveAction = new Q3Action("Save", QPixmap(xpm_save), _("&Save"), Qt::CTRL + Qt::Key_S, this);
1328 connect(saveAction, SIGNAL(activated()), SLOT(saveConfig()));
1329 conf_set_changed_callback(conf_changed);
1330 // Set saveAction's initial state
1332 Q3Action *saveAsAction = new Q3Action("Save As...", _("Save &As..."), 0, this);
1333 connect(saveAsAction, SIGNAL(activated()), SLOT(saveConfigAs()));
1334 Q3Action *searchAction = new Q3Action("Find", _("&Find"), Qt::CTRL + Qt::Key_F, this);
1335 connect(searchAction, SIGNAL(activated()), SLOT(searchConfig()));
1336 Q3Action *singleViewAction = new Q3Action("Single View", QPixmap(xpm_single_view), _("Single View"), 0, this);
1337 connect(singleViewAction, SIGNAL(activated()), SLOT(showSingleView()));
1338 Q3Action *splitViewAction = new Q3Action("Split View", QPixmap(xpm_split_view), _("Split View"), 0, this);
1339 connect(splitViewAction, SIGNAL(activated()), SLOT(showSplitView()));
1340 Q3Action *fullViewAction = new Q3Action("Full View", QPixmap(xpm_tree_view), _("Full View"), 0, this);
1341 connect(fullViewAction, SIGNAL(activated()), SLOT(showFullView()));
1343 Q3Action *showNameAction = new Q3Action(NULL, _("Show Name"), 0, this);
1344 showNameAction->setToggleAction(TRUE);
1345 connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool)));
1346 connect(configView, SIGNAL(showNameChanged(bool)), showNameAction, SLOT(setOn(bool)));
1347 showNameAction->setOn(configView->showName());
1348 Q3Action *showRangeAction = new Q3Action(NULL, _("Show Range"), 0, this);
1349 showRangeAction->setToggleAction(TRUE);
1350 connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool)));
1351 connect(configView, SIGNAL(showRangeChanged(bool)), showRangeAction, SLOT(setOn(bool)));
1352 showRangeAction->setOn(configList->showRange);
1353 Q3Action *showDataAction = new Q3Action(NULL, _("Show Data"), 0, this);
1354 showDataAction->setToggleAction(TRUE);
1355 connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool)));
1356 connect(configView, SIGNAL(showDataChanged(bool)), showDataAction, SLOT(setOn(bool)));
1357 showDataAction->setOn(configList->showData);
1359 QActionGroup *optGroup = new QActionGroup(this);
1360 optGroup->setExclusive(TRUE);
1361 connect(optGroup, SIGNAL(selected(QAction *)), configView,
1362 SLOT(setOptionMode(QAction *)));
1363 connect(optGroup, SIGNAL(selected(QAction *)), menuView,
1364 SLOT(setOptionMode(QAction *)));
1366 #if QT_VERSION >= 0x040000
1367 configView->showNormalAction = new QAction(_("Show Normal Options"), optGroup);
1368 configView->showAllAction = new QAction(_("Show All Options"), optGroup);
1369 configView->showPromptAction = new QAction(_("Show Prompt Options"), optGroup);
1371 configView->showNormalAction = new QAction(_("Show Normal Options"), 0, optGroup);
1372 configView->showAllAction = new QAction(_("Show All Options"), 0, optGroup);
1373 configView->showPromptAction = new QAction(_("Show Prompt Options"), 0, optGroup);
1375 configView->showNormalAction->setToggleAction(TRUE);
1376 configView->showNormalAction->setOn(configList->optMode == normalOpt);
1377 configView->showAllAction->setToggleAction(TRUE);
1378 configView->showAllAction->setOn(configList->optMode == allOpt);
1379 configView->showPromptAction->setToggleAction(TRUE);
1380 configView->showPromptAction->setOn(configList->optMode == promptOpt);
1382 Q3Action *showDebugAction = new Q3Action(NULL, _("Show Debug Info"), 0, this);
1383 showDebugAction->setToggleAction(TRUE);
1384 connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
1385 connect(helpText, SIGNAL(showDebugChanged(bool)), showDebugAction, SLOT(setOn(bool)));
1386 showDebugAction->setOn(helpText->showDebug());
1388 Q3Action *showIntroAction = new Q3Action(NULL, _("Introduction"), 0, this);
1389 connect(showIntroAction, SIGNAL(activated()), SLOT(showIntro()));
1390 Q3Action *showAboutAction = new Q3Action(NULL, _("About"), 0, this);
1391 connect(showAboutAction, SIGNAL(activated()), SLOT(showAbout()));
1394 backAction->addTo(toolBar);
1395 toolBar->addSeparator();
1396 loadAction->addTo(toolBar);
1397 saveAction->addTo(toolBar);
1398 toolBar->addSeparator();
1399 singleViewAction->addTo(toolBar);
1400 splitViewAction->addTo(toolBar);
1401 fullViewAction->addTo(toolBar);
1403 // create config menu
1404 Q3PopupMenu* config = new Q3PopupMenu(this);
1405 menu->insertItem(_("&File"), config);
1406 loadAction->addTo(config);
1407 saveAction->addTo(config);
1408 saveAsAction->addTo(config);
1409 config->insertSeparator();
1410 quitAction->addTo(config);
1413 Q3PopupMenu* editMenu = new Q3PopupMenu(this);
1414 menu->insertItem(_("&Edit"), editMenu);
1415 searchAction->addTo(editMenu);
1417 // create options menu
1418 Q3PopupMenu* optionMenu = new Q3PopupMenu(this);
1419 menu->insertItem(_("&Option"), optionMenu);
1420 showNameAction->addTo(optionMenu);
1421 showRangeAction->addTo(optionMenu);
1422 showDataAction->addTo(optionMenu);
1423 optionMenu->insertSeparator();
1424 optGroup->addTo(optionMenu);
1425 optionMenu->insertSeparator();
1428 Q3PopupMenu* helpMenu = new Q3PopupMenu(this);
1429 menu->insertSeparator();
1430 menu->insertItem(_("&Help"), helpMenu);
1431 showIntroAction->addTo(helpMenu);
1432 showAboutAction->addTo(helpMenu);
1434 connect(configList, SIGNAL(menuChanged(struct menu *)),
1435 helpText, SLOT(setInfo(struct menu *)));
1436 connect(configList, SIGNAL(menuSelected(struct menu *)),
1437 SLOT(changeMenu(struct menu *)));
1438 connect(configList, SIGNAL(parentSelected()),
1440 connect(menuList, SIGNAL(menuChanged(struct menu *)),
1441 helpText, SLOT(setInfo(struct menu *)));
1442 connect(menuList, SIGNAL(menuSelected(struct menu *)),
1443 SLOT(changeMenu(struct menu *)));
1445 connect(configList, SIGNAL(gotFocus(struct menu *)),
1446 helpText, SLOT(setInfo(struct menu *)));
1447 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1448 helpText, SLOT(setInfo(struct menu *)));
1449 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1450 SLOT(listFocusChanged(void)));
1451 connect(helpText, SIGNAL(menuSelected(struct menu *)),
1452 SLOT(setMenuLink(struct menu *)));
1454 QString listMode = configSettings->readEntry("/listMode", "symbol");
1455 if (listMode == "single")
1457 else if (listMode == "full")
1459 else /*if (listMode == "split")*/
1462 // UI setup done, restore splitter positions
1463 Q3ValueList<int> sizes = configSettings->readSizes("/split1", &ok);
1465 split1->setSizes(sizes);
1467 sizes = configSettings->readSizes("/split2", &ok);
1469 split2->setSizes(sizes);
1472 void ConfigMainWindow::loadConfig(void)
1474 QString s = Q3FileDialog::getOpenFileName(conf_get_configname(), NULL, this);
1477 if (conf_read(QFile::encodeName(s)))
1478 QMessageBox::information(this, "qconf", _("Unable to load configuration!"));
1479 ConfigView::updateListAll();
1482 bool ConfigMainWindow::saveConfig(void)
1484 if (conf_write(NULL)) {
1485 QMessageBox::information(this, "qconf", _("Unable to save configuration!"));
1491 void ConfigMainWindow::saveConfigAs(void)
1493 QString s = Q3FileDialog::getSaveFileName(conf_get_configname(), NULL, this);
1499 void ConfigMainWindow::searchConfig(void)
1502 searchWindow = new ConfigSearchWindow(this, "search");
1503 searchWindow->show();
1506 void ConfigMainWindow::changeMenu(struct menu *menu)
1508 configList->setRootMenu(menu);
1509 if (configList->rootEntry->parent == &rootmenu)
1510 backAction->setEnabled(FALSE);
1512 backAction->setEnabled(TRUE);
1515 void ConfigMainWindow::setMenuLink(struct menu *menu)
1517 struct menu *parent;
1518 ConfigList* list = NULL;
1521 if (configList->menuSkip(menu))
1524 switch (configList->mode) {
1527 parent = menu_get_parent_menu(menu);
1530 list->setRootMenu(parent);
1533 if (menu->flags & MENU_ROOT) {
1534 configList->setRootMenu(menu);
1535 configList->clearSelection();
1539 parent = menu_get_parent_menu(menu->parent);
1542 item = menuList->findConfigItem(parent);
1544 menuList->setSelected(item, TRUE);
1545 menuList->ensureItemVisible(item);
1547 list->setRootMenu(parent);
1558 item = list->findConfigItem(menu);
1560 list->setSelected(item, TRUE);
1561 list->ensureItemVisible(item);
1567 void ConfigMainWindow::listFocusChanged(void)
1569 if (menuList->mode == menuMode)
1570 configList->clearSelection();
1573 void ConfigMainWindow::goBack(void)
1577 configList->setParentMenu();
1578 if (configList->rootEntry == &rootmenu)
1579 backAction->setEnabled(FALSE);
1580 item = (ConfigItem*)menuList->selectedItem();
1582 if (item->menu == configList->rootEntry) {
1583 menuList->setSelected(item, TRUE);
1586 item = (ConfigItem*)item->parent();
1590 void ConfigMainWindow::showSingleView(void)
1593 menuList->setRootMenu(0);
1594 configList->mode = singleMode;
1595 if (configList->rootEntry == &rootmenu)
1596 configList->updateListAll();
1598 configList->setRootMenu(&rootmenu);
1599 configList->setAllOpen(TRUE);
1600 configList->setFocus();
1603 void ConfigMainWindow::showSplitView(void)
1605 configList->mode = symbolMode;
1606 if (configList->rootEntry == &rootmenu)
1607 configList->updateListAll();
1609 configList->setRootMenu(&rootmenu);
1610 configList->setAllOpen(TRUE);
1611 configApp->processEvents();
1612 menuList->mode = menuMode;
1613 menuList->setRootMenu(&rootmenu);
1614 menuList->setAllOpen(TRUE);
1616 menuList->setFocus();
1619 void ConfigMainWindow::showFullView(void)
1622 menuList->setRootMenu(0);
1623 configList->mode = fullMode;
1624 if (configList->rootEntry == &rootmenu)
1625 configList->updateListAll();
1627 configList->setRootMenu(&rootmenu);
1628 configList->setAllOpen(FALSE);
1629 configList->setFocus();
1633 * ask for saving configuration before quitting
1634 * TODO ask only when something changed
1636 void ConfigMainWindow::closeEvent(QCloseEvent* e)
1638 if (!conf_get_changed()) {
1642 QMessageBox mb("qconf", _("Save configuration?"), QMessageBox::Warning,
1643 QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape);
1644 mb.setButtonText(QMessageBox::Yes, _("&Save Changes"));
1645 mb.setButtonText(QMessageBox::No, _("&Discard Changes"));
1646 mb.setButtonText(QMessageBox::Cancel, _("Cancel Exit"));
1647 switch (mb.exec()) {
1648 case QMessageBox::Yes:
1654 case QMessageBox::No:
1657 case QMessageBox::Cancel:
1663 void ConfigMainWindow::showIntro(void)
1665 static const QString str = _("Welcome to the qconf graphical configuration tool.\n\n"
1666 "For each option, a blank box indicates the feature is disabled, a check\n"
1667 "indicates it is enabled, and a dot indicates that it is to be compiled\n"
1668 "as a module. Clicking on the box will cycle through the three states.\n\n"
1669 "If you do not see an option (e.g., a device driver) that you believe\n"
1670 "should be present, try turning on Show All Options under the Options menu.\n"
1671 "Although there is no cross reference yet to help you figure out what other\n"
1672 "options must be enabled to support the option you are interested in, you can\n"
1673 "still view the help of a grayed-out option.\n\n"
1674 "Toggling Show Debug Info under the Options menu will show the dependencies,\n"
1675 "which you can then match by examining other options.\n\n");
1677 QMessageBox::information(this, "qconf", str);
1680 void ConfigMainWindow::showAbout(void)
1682 static const QString str = _("qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n\n"
1683 "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n");
1685 QMessageBox::information(this, "qconf", str);
1688 void ConfigMainWindow::saveSettings(void)
1690 configSettings->writeEntry("/window x", pos().x());
1691 configSettings->writeEntry("/window y", pos().y());
1692 configSettings->writeEntry("/window width", size().width());
1693 configSettings->writeEntry("/window height", size().height());
1696 switch(configList->mode) {
1712 configSettings->writeEntry("/listMode", entry);
1714 configSettings->writeSizes("/split1", split1->sizes());
1715 configSettings->writeSizes("/split2", split2->sizes());
1718 void ConfigMainWindow::conf_changed(void)
1721 saveAction->setEnabled(conf_get_changed());
1724 void fixup_rootmenu(struct menu *menu)
1727 static int menu_cnt = 0;
1729 menu->flags |= MENU_ROOT;
1730 for (child = menu->list; child; child = child->next) {
1731 if (child->prompt && child->prompt->type == P_MENU) {
1733 fixup_rootmenu(child);
1735 } else if (!menu_cnt)
1736 fixup_rootmenu(child);
1740 static const char *progname;
1742 static void usage(void)
1744 printf(_("%s <config>\n"), progname);
1748 int main(int ac, char** av)
1750 ConfigMainWindow* v;
1753 bindtextdomain(PACKAGE, LOCALEDIR);
1754 textdomain(PACKAGE);
1757 configApp = new QApplication(ac, av);
1758 if (ac > 1 && av[1][0] == '-') {
1771 fixup_rootmenu(&rootmenu);
1773 //zconfdump(stdout);
1775 configSettings = new ConfigSettings();
1776 configSettings->beginGroup("/kconfig/qconf");
1777 v = new ConfigMainWindow();
1779 //zconfdump(stdout);
1780 configApp->setMainWidget(v);
1781 configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit()));
1782 configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings()));
1786 configSettings->endGroup();
1787 delete configSettings;