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;
40 static inline QString qgettext(const char* str)
42 return QString::fromLocal8Bit(gettext(str));
45 static inline QString qgettext(const QString& str)
47 return QString::fromLocal8Bit(gettext(str.latin1()));
50 ConfigSettings::ConfigSettings()
51 : showAll(false), showName(false), showRange(false), showData(false)
57 * Reads the list column settings from the application settings.
59 void ConfigSettings::readListSettings()
61 showAll = readBoolEntry("/kconfig/qconf/showAll", false);
62 showName = readBoolEntry("/kconfig/qconf/showName", false);
63 showRange = readBoolEntry("/kconfig/qconf/showRange", false);
64 showData = readBoolEntry("/kconfig/qconf/showData", false);
68 * Reads a list of integer values from the application settings.
70 QValueList<int> ConfigSettings::readSizes(const QString& key, bool *ok)
72 QValueList<int> result;
73 QStringList entryList = readListEntry(key, ok);
75 QStringList::Iterator it;
76 for (it = entryList.begin(); it != entryList.end(); ++it)
77 result.push_back((*it).toInt());
84 * Writes a list of integer values to the application settings.
86 bool ConfigSettings::writeSizes(const QString& key, const QValueList<int>& value)
88 QStringList stringList;
89 QValueList<int>::ConstIterator it;
91 for (it = value.begin(); it != value.end(); ++it)
92 stringList.push_back(QString::number(*it));
93 return writeEntry(key, stringList);
99 * update all the children of a menu entry
100 * removes/adds the entries from the parent widget as necessary
102 * parent: either the menu list widget or a menu entry widget
103 * menu: entry to be updated
106 void ConfigList::updateMenuList(P* parent, struct menu* menu)
115 while ((item = parent->firstChild()))
120 last = parent->firstChild();
121 if (last && !last->goParent)
123 for (child = menu->list; child; child = child->next) {
124 item = last ? last->nextSibling() : parent->firstChild();
125 type = child->prompt ? child->prompt->type : P_UNKNOWN;
129 if (!(child->flags & MENU_ROOT))
133 if (child->flags & MENU_ROOT)
140 visible = menu_is_visible(child);
141 if (showAll || visible) {
142 if (!item || item->menu != child)
143 item = new ConfigItem(parent, last, child, visible);
145 item->testUpdateMenu(visible);
147 if (mode == fullMode || mode == menuMode || type != P_MENU)
148 updateMenuList(item, child);
150 updateMenuList(item, 0);
155 if (item && item->menu == child) {
156 last = parent->firstChild();
159 else while (last->nextSibling() != item)
160 last = last->nextSibling();
166 #if QT_VERSION >= 300
169 * TODO check the value
171 void ConfigItem::okRename(int col)
173 Parent::okRename(col);
174 sym_set_string_value(menu->sym, text(dataColIdx).latin1());
179 * update the displayed of a menu entry
181 void ConfigItem::updateMenu(void)
185 struct property *prop;
192 setPixmap(promptColIdx, list->menuBackPix);
199 prompt = QString::fromLocal8Bit(menu_get_prompt(menu));
201 if (prop) switch (prop->type) {
203 if (list->mode == singleMode || list->mode == symbolMode) {
204 /* a menuconfig entry is displayed differently
205 * depending whether it's at the view root or a child.
207 if (sym && list->rootEntry == menu)
209 setPixmap(promptColIdx, list->menuPix);
213 setPixmap(promptColIdx, 0);
217 setPixmap(promptColIdx, 0);
225 setText(nameColIdx, QString::fromLocal8Bit(sym->name));
227 type = sym_get_type(sym);
233 if (!sym_is_changable(sym) && !list->showAll) {
234 setPixmap(promptColIdx, 0);
235 setText(noColIdx, QString::null);
236 setText(modColIdx, QString::null);
237 setText(yesColIdx, QString::null);
240 expr = sym_get_tristate_value(sym);
243 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
244 setPixmap(promptColIdx, list->choiceYesPix);
246 setPixmap(promptColIdx, list->symbolYesPix);
247 setText(yesColIdx, "Y");
251 setPixmap(promptColIdx, list->symbolModPix);
252 setText(modColIdx, "M");
256 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
257 setPixmap(promptColIdx, list->choiceNoPix);
259 setPixmap(promptColIdx, list->symbolNoPix);
260 setText(noColIdx, "N");
265 setText(noColIdx, sym_tristate_within_range(sym, no) ? "_" : 0);
267 setText(modColIdx, sym_tristate_within_range(sym, mod) ? "_" : 0);
269 setText(yesColIdx, sym_tristate_within_range(sym, yes) ? "_" : 0);
271 setText(dataColIdx, QChar(ch));
278 data = sym_get_string_value(sym);
280 #if QT_VERSION >= 300
281 int i = list->mapIdx(dataColIdx);
283 setRenameEnabled(i, TRUE);
285 setText(dataColIdx, data);
286 if (type == S_STRING)
287 prompt = QString("%1: %2").arg(prompt).arg(data);
289 prompt = QString("(%2) %1").arg(prompt).arg(data);
292 if (!sym_has_value(sym) && visible)
295 setText(promptColIdx, prompt);
298 void ConfigItem::testUpdateMenu(bool v)
306 sym_calc_value(menu->sym);
307 if (menu->flags & MENU_CHANGED) {
308 /* the menu entry changed, so update all list items */
309 menu->flags &= ~MENU_CHANGED;
310 for (i = (ConfigItem*)menu->data; i; i = i->nextItem)
312 } else if (listView()->updateAll)
316 void ConfigItem::paintCell(QPainter* p, const QColorGroup& cg, int column, int width, int align)
318 ConfigList* list = listView();
321 if (isSelected() && !list->hasFocus() && list->mode == menuMode)
322 Parent::paintCell(p, list->inactivedColorGroup, column, width, align);
324 Parent::paintCell(p, cg, column, width, align);
326 Parent::paintCell(p, list->disabledColorGroup, column, width, align);
330 * construct a menu entry
332 void ConfigItem::init(void)
335 ConfigList* list = listView();
336 nextItem = (ConfigItem*)menu->data;
339 if (list->mode != fullMode)
341 sym_calc_value(menu->sym);
347 * destruct a menu entry
349 ConfigItem::~ConfigItem(void)
352 ConfigItem** ip = (ConfigItem**)&menu->data;
353 for (; *ip; ip = &(*ip)->nextItem) {
362 ConfigLineEdit::ConfigLineEdit(ConfigView* parent)
365 connect(this, SIGNAL(lostFocus()), SLOT(hide()));
368 void ConfigLineEdit::show(ConfigItem* i)
371 if (sym_get_string_value(item->menu->sym))
372 setText(QString::fromLocal8Bit(sym_get_string_value(item->menu->sym)));
374 setText(QString::null);
379 void ConfigLineEdit::keyPressEvent(QKeyEvent* e)
386 sym_set_string_value(item->menu->sym, text().latin1());
387 parent()->updateList(item);
390 Parent::keyPressEvent(e);
394 parent()->list->setFocus();
398 ConfigList::ConfigList(ConfigView* p, ConfigSettings* configSettings)
401 symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no),
402 choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no),
403 menuPix(xpm_menu), menuInvPix(xpm_menu_inv), menuBackPix(xpm_menuback), voidPix(xpm_void),
404 showAll(false), showName(false), showRange(false), showData(false),
410 setRootIsDecorated(TRUE);
411 disabledColorGroup = palette().active();
412 disabledColorGroup.setColor(QColorGroup::Text, palette().disabled().text());
413 inactivedColorGroup = palette().active();
414 inactivedColorGroup.setColor(QColorGroup::Highlight, palette().disabled().highlight());
416 connect(this, SIGNAL(selectionChanged(void)),
417 SLOT(updateSelection(void)));
419 if (configSettings) {
420 showAll = configSettings->showAll;
421 showName = configSettings->showName;
422 showRange = configSettings->showRange;
423 showData = configSettings->showData;
426 for (i = 0; i < colNr; i++)
427 colMap[i] = colRevMap[i] = -1;
428 addColumn(promptColIdx, "Option");
433 void ConfigList::reinit(void)
435 removeColumn(dataColIdx);
436 removeColumn(yesColIdx);
437 removeColumn(modColIdx);
438 removeColumn(noColIdx);
439 removeColumn(nameColIdx);
442 addColumn(nameColIdx, "Name");
444 addColumn(noColIdx, "N");
445 addColumn(modColIdx, "M");
446 addColumn(yesColIdx, "Y");
449 addColumn(dataColIdx, "Value");
454 void ConfigList::updateSelection(void)
459 ConfigItem* item = (ConfigItem*)selectedItem();
464 emit menuChanged(menu);
467 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
468 if (mode == menuMode && type == P_MENU)
469 emit menuSelected(menu);
472 void ConfigList::updateList(ConfigItem* item)
474 ConfigItem* last = 0;
477 if (mode != listMode)
479 QListViewItemIterator it(this);
482 for (; it.current(); ++it) {
483 item = (ConfigItem*)it.current();
486 item->testUpdateMenu(menu_is_visible(item->menu));
491 if (rootEntry != &rootmenu && (mode == singleMode ||
492 (mode == symbolMode && rootEntry->parent != &rootmenu))) {
495 item = new ConfigItem(this, 0, true);
498 if ((mode == singleMode || (mode == symbolMode && !(rootEntry->flags & MENU_ROOT))) &&
499 rootEntry->sym && rootEntry->prompt) {
500 item = last ? last->nextSibling() : firstChild();
502 item = new ConfigItem(this, last, rootEntry, true);
504 item->testUpdateMenu(true);
506 updateMenuList(item, rootEntry);
511 updateMenuList(this, rootEntry);
515 void ConfigList::setAllOpen(bool open)
517 QListViewItemIterator it(this);
519 for (; it.current(); it++)
520 it.current()->setOpen(open);
523 void ConfigList::setValue(ConfigItem* item, tristate val)
529 sym = item->menu ? item->menu->sym : 0;
533 type = sym_get_type(sym);
537 oldval = sym_get_tristate_value(sym);
539 if (!sym_set_tristate_value(sym, val))
541 if (oldval == no && item->menu->list)
543 parent()->updateList(item);
548 void ConfigList::changeValue(ConfigItem* item)
552 int type, oldexpr, newexpr;
559 if (item->menu->list)
560 item->setOpen(!item->isOpen());
564 type = sym_get_type(sym);
568 oldexpr = sym_get_tristate_value(sym);
569 newexpr = sym_toggle_tristate_value(sym);
570 if (item->menu->list) {
571 if (oldexpr == newexpr)
572 item->setOpen(!item->isOpen());
573 else if (oldexpr == no)
576 if (oldexpr != newexpr)
577 parent()->updateList(item);
582 #if QT_VERSION >= 300
583 if (colMap[dataColIdx] >= 0)
584 item->startRename(colMap[dataColIdx]);
587 parent()->lineEdit->show(item);
592 void ConfigList::setRootMenu(struct menu *menu)
596 if (rootEntry == menu)
598 type = menu && menu->prompt ? menu->prompt->type : P_UNKNOWN;
601 updateMenuList(this, 0);
604 setSelected(currentItem(), hasFocus());
607 void ConfigList::setParentMenu(void)
610 struct menu *oldroot;
613 if (rootEntry == &rootmenu)
615 setRootMenu(menu_get_parent_menu(rootEntry->parent));
617 QListViewItemIterator it(this);
618 for (; (item = (ConfigItem*)it.current()); it++) {
619 if (item->menu == oldroot) {
620 setCurrentItem(item);
621 ensureItemVisible(item);
627 void ConfigList::keyPressEvent(QKeyEvent* ev)
629 QListViewItem* i = currentItem();
634 if (ev->key() == Key_Escape && mode != fullMode && mode != listMode) {
635 emit parentSelected();
641 Parent::keyPressEvent(ev);
644 item = (ConfigItem*)i;
649 if (item->goParent) {
650 emit parentSelected();
656 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
657 if (type == P_MENU && rootEntry != menu &&
658 mode != fullMode && mode != menuMode) {
659 emit menuSelected(menu);
675 Parent::keyPressEvent(ev);
681 void ConfigList::contentsMousePressEvent(QMouseEvent* e)
683 //QPoint p(contentsToViewport(e->pos()));
684 //printf("contentsMousePressEvent: %d,%d\n", p.x(), p.y());
685 Parent::contentsMousePressEvent(e);
688 void ConfigList::contentsMouseReleaseEvent(QMouseEvent* e)
690 QPoint p(contentsToViewport(e->pos()));
691 ConfigItem* item = (ConfigItem*)itemAt(p);
693 enum prop_type ptype;
701 x = header()->offset() + p.x();
702 idx = colRevMap[header()->sectionAt(x)];
705 pm = item->pixmap(promptColIdx);
707 int off = header()->sectionPos(0) + itemMargin() +
708 treeStepSize() * (item->depth() + (rootIsDecorated() ? 1 : 0));
709 if (x >= off && x < off + pm->width()) {
710 if (item->goParent) {
711 emit parentSelected();
715 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
716 if (ptype == P_MENU && rootEntry != menu &&
717 mode != fullMode && mode != menuMode)
718 emit menuSelected(menu);
739 //printf("contentsMouseReleaseEvent: %d,%d\n", p.x(), p.y());
740 Parent::contentsMouseReleaseEvent(e);
743 void ConfigList::contentsMouseMoveEvent(QMouseEvent* e)
745 //QPoint p(contentsToViewport(e->pos()));
746 //printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y());
747 Parent::contentsMouseMoveEvent(e);
750 void ConfigList::contentsMouseDoubleClickEvent(QMouseEvent* e)
752 QPoint p(contentsToViewport(e->pos()));
753 ConfigItem* item = (ConfigItem*)itemAt(p);
755 enum prop_type ptype;
759 if (item->goParent) {
760 emit parentSelected();
766 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
767 if (ptype == P_MENU && (mode == singleMode || mode == symbolMode))
768 emit menuSelected(menu);
773 //printf("contentsMouseDoubleClickEvent: %d,%d\n", p.x(), p.y());
774 Parent::contentsMouseDoubleClickEvent(e);
777 void ConfigList::focusInEvent(QFocusEvent *e)
779 Parent::focusInEvent(e);
781 QListViewItem* item = currentItem();
785 setSelected(item, TRUE);
789 ConfigView* ConfigView::viewList;
791 ConfigView::ConfigView(QWidget* parent, ConfigSettings *configSettings)
794 list = new ConfigList(this, configSettings);
795 lineEdit = new ConfigLineEdit(this);
798 this->nextView = viewList;
802 ConfigView::~ConfigView(void)
806 for (vp = &viewList; *vp; vp = &(*vp)->nextView) {
814 void ConfigView::updateList(ConfigItem* item)
818 for (v = viewList; v; v = v->nextView)
819 v->list->updateList(item);
822 void ConfigView::updateListAll(void)
826 for (v = viewList; v; v = v->nextView)
827 v->list->updateListAll();
830 ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name)
831 : Parent(parent, name), menu(0)
835 void ConfigInfoView::setShowDebug(bool b)
837 if (_showDebug != b) {
841 emit showDebugChanged(b);
845 void ConfigInfoView::setInfo(struct menu *m)
854 void ConfigInfoView::setSource(const QString& name)
856 const char *p = name.latin1();
862 if (sscanf(p, "m%p", &menu) == 1)
868 void ConfigInfoView::menuInfo(void)
871 QString head, debug, help;
877 head += print_filter(_(menu->prompt->text));
878 head += "</b></big>";
881 head += print_filter(sym->name);
884 } else if (sym->name) {
886 head += print_filter(sym->name);
887 head += "</b></big>";
892 debug = debug_info(sym);
894 help = print_filter(_(sym->help));
895 } else if (menu->prompt) {
897 head += print_filter(_(menu->prompt->text));
898 head += "</b></big><br><br>";
900 if (menu->prompt->visible.expr) {
901 debug += " dep: ";
902 expr_print(menu->prompt->visible.expr, expr_print_help, &debug, E_NONE);
908 debug += QString().sprintf("defined at %s:%d<br><br>", menu->file->name, menu->lineno);
910 setText(head + debug + help);
913 QString ConfigInfoView::debug_info(struct symbol *sym)
918 debug += print_filter(sym_type_name(sym->type));
919 if (sym_is_choice(sym))
920 debug += " (choice)";
922 if (sym->rev_dep.expr) {
923 debug += "reverse dep: ";
924 expr_print(sym->rev_dep.expr, expr_print_help, &debug, E_NONE);
927 for (struct property *prop = sym->prop; prop; prop = prop->next) {
928 switch (prop->type) {
932 debug += print_filter(_(prop->text));
936 debug += "default: ";
937 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
941 if (sym_is_choice(sym)) {
943 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
949 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
954 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
958 debug += "unknown property: ";
959 debug += prop_get_type_name(prop->type);
962 if (prop->visible.expr) {
963 debug += " dep: ";
964 expr_print(prop->visible.expr, expr_print_help, &debug, E_NONE);
973 QString ConfigInfoView::print_filter(const QString &str)
975 QRegExp re("[<>&\"\\n]");
977 for (int i = 0; (i = res.find(re, i)) >= 0;) {
978 switch (res[i].latin1()) {
980 res.replace(i, 1, "<");
984 res.replace(i, 1, ">");
988 res.replace(i, 1, "&");
992 res.replace(i, 1, """);
996 res.replace(i, 1, "<br>");
1004 void ConfigInfoView::expr_print_help(void *data, const char *str)
1006 reinterpret_cast<QString*>(data)->append(print_filter(str));
1009 ConfigSearchWindow::ConfigSearchWindow(QWidget* parent)
1010 : Parent(parent), result(NULL)
1012 setCaption("Search Config");
1014 QVBoxLayout* layout1 = new QVBoxLayout(this, 11, 6);
1015 QHBoxLayout* layout2 = new QHBoxLayout(0, 0, 6);
1016 layout2->addWidget(new QLabel("Find:", this));
1017 editField = new QLineEdit(this);
1018 connect(editField, SIGNAL(returnPressed()), SLOT(search()));
1019 layout2->addWidget(editField);
1020 searchButton = new QPushButton("Search", this);
1021 searchButton->setAutoDefault(FALSE);
1022 connect(searchButton, SIGNAL(clicked()), SLOT(search()));
1023 layout2->addWidget(searchButton);
1024 layout1->addLayout(layout2);
1026 QSplitter* split = new QSplitter(this);
1027 split->setOrientation(QSplitter::Vertical);
1028 list = new ConfigView(split, NULL);
1029 list->list->mode = listMode;
1030 info = new ConfigInfoView(split);
1031 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1032 info, SLOT(setInfo(struct menu *)));
1033 layout1->addWidget(split);
1036 void ConfigSearchWindow::search(void)
1039 struct property *prop;
1040 ConfigItem *lastItem = NULL;
1043 list->list->clear();
1045 result = sym_re_search(editField->text().latin1());
1048 for (p = result; *p; p++) {
1049 for_all_prompts((*p), prop)
1050 lastItem = new ConfigItem(list->list, lastItem, prop->menu,
1051 menu_is_visible(prop->menu));
1056 * Construct the complete config widget
1058 ConfigMainWindow::ConfigMainWindow(void)
1062 int x, y, width, height;
1064 QWidget *d = configApp->desktop();
1066 ConfigSettings* configSettings = new ConfigSettings();
1067 #if QT_VERSION >= 300
1068 width = configSettings->readNumEntry("/kconfig/qconf/window width", d->width() - 64);
1069 height = configSettings->readNumEntry("/kconfig/qconf/window height", d->height() - 64);
1070 resize(width, height);
1071 x = configSettings->readNumEntry("/kconfig/qconf/window x", 0, &ok);
1073 y = configSettings->readNumEntry("/kconfig/qconf/window y", 0, &ok);
1076 showDebug = configSettings->readBoolEntry("/kconfig/qconf/showDebug", false);
1078 // read list settings into configSettings, will be used later for ConfigList setup
1079 configSettings->readListSettings();
1081 width = d->width() - 64;
1082 height = d->height() - 64;
1083 resize(width, height);
1087 split1 = new QSplitter(this);
1088 split1->setOrientation(QSplitter::Horizontal);
1089 setCentralWidget(split1);
1091 menuView = new ConfigView(split1, configSettings);
1092 menuList = menuView->list;
1094 split2 = new QSplitter(split1);
1095 split2->setOrientation(QSplitter::Vertical);
1097 // create config tree
1098 configView = new ConfigView(split2, configSettings);
1099 configList = configView->list;
1101 helpText = new ConfigInfoView(split2);
1102 helpText->setTextFormat(Qt::RichText);
1103 helpText->setShowDebug(showDebug);
1105 setTabOrder(configList, helpText);
1106 configList->setFocus();
1109 toolBar = new QToolBar("Tools", this);
1111 backAction = new QAction("Back", QPixmap(xpm_back), "Back", 0, this);
1112 connect(backAction, SIGNAL(activated()), SLOT(goBack()));
1113 backAction->setEnabled(FALSE);
1114 QAction *quitAction = new QAction("Quit", "&Quit", CTRL+Key_Q, this);
1115 connect(quitAction, SIGNAL(activated()), SLOT(close()));
1116 QAction *loadAction = new QAction("Load", QPixmap(xpm_load), "&Load", CTRL+Key_L, this);
1117 connect(loadAction, SIGNAL(activated()), SLOT(loadConfig()));
1118 QAction *saveAction = new QAction("Save", QPixmap(xpm_save), "&Save", CTRL+Key_S, this);
1119 connect(saveAction, SIGNAL(activated()), SLOT(saveConfig()));
1120 QAction *saveAsAction = new QAction("Save As...", "Save &As...", 0, this);
1121 connect(saveAsAction, SIGNAL(activated()), SLOT(saveConfigAs()));
1122 QAction *searchAction = new QAction("Search", "&Search", CTRL+Key_F, this);
1123 connect(searchAction, SIGNAL(activated()), SLOT(searchConfig()));
1124 QAction *singleViewAction = new QAction("Single View", QPixmap(xpm_single_view), "Split View", 0, this);
1125 connect(singleViewAction, SIGNAL(activated()), SLOT(showSingleView()));
1126 QAction *splitViewAction = new QAction("Split View", QPixmap(xpm_split_view), "Split View", 0, this);
1127 connect(splitViewAction, SIGNAL(activated()), SLOT(showSplitView()));
1128 QAction *fullViewAction = new QAction("Full View", QPixmap(xpm_tree_view), "Full View", 0, this);
1129 connect(fullViewAction, SIGNAL(activated()), SLOT(showFullView()));
1131 QAction *showNameAction = new QAction(NULL, "Show Name", 0, this);
1132 showNameAction->setToggleAction(TRUE);
1133 showNameAction->setOn(configList->showName);
1134 connect(showNameAction, SIGNAL(toggled(bool)), SLOT(setShowName(bool)));
1135 QAction *showRangeAction = new QAction(NULL, "Show Range", 0, this);
1136 showRangeAction->setToggleAction(TRUE);
1137 showRangeAction->setOn(configList->showRange);
1138 connect(showRangeAction, SIGNAL(toggled(bool)), SLOT(setShowRange(bool)));
1139 QAction *showDataAction = new QAction(NULL, "Show Data", 0, this);
1140 showDataAction->setToggleAction(TRUE);
1141 showDataAction->setOn(configList->showData);
1142 connect(showDataAction, SIGNAL(toggled(bool)), SLOT(setShowData(bool)));
1143 QAction *showAllAction = new QAction(NULL, "Show All Options", 0, this);
1144 showAllAction->setToggleAction(TRUE);
1145 showAllAction->setOn(configList->showAll);
1146 connect(showAllAction, SIGNAL(toggled(bool)), SLOT(setShowAll(bool)));
1147 QAction *showDebugAction = new QAction(NULL, "Show Debug Info", 0, this);
1148 showDebugAction->setToggleAction(TRUE);
1149 showDebugAction->setOn(showDebug);
1150 connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
1151 connect(helpText, SIGNAL(showDebugChanged(bool)), showDebugAction, SLOT(setOn(bool)));
1153 QAction *showIntroAction = new QAction(NULL, "Introduction", 0, this);
1154 connect(showIntroAction, SIGNAL(activated()), SLOT(showIntro()));
1155 QAction *showAboutAction = new QAction(NULL, "About", 0, this);
1156 connect(showAboutAction, SIGNAL(activated()), SLOT(showAbout()));
1159 backAction->addTo(toolBar);
1160 toolBar->addSeparator();
1161 loadAction->addTo(toolBar);
1162 saveAction->addTo(toolBar);
1163 toolBar->addSeparator();
1164 singleViewAction->addTo(toolBar);
1165 splitViewAction->addTo(toolBar);
1166 fullViewAction->addTo(toolBar);
1168 // create config menu
1169 QPopupMenu* config = new QPopupMenu(this);
1170 menu->insertItem("&File", config);
1171 loadAction->addTo(config);
1172 saveAction->addTo(config);
1173 saveAsAction->addTo(config);
1174 config->insertSeparator();
1175 searchAction->addTo(config);
1176 config->insertSeparator();
1177 quitAction->addTo(config);
1179 // create options menu
1180 QPopupMenu* optionMenu = new QPopupMenu(this);
1181 menu->insertItem("&Option", optionMenu);
1182 showNameAction->addTo(optionMenu);
1183 showRangeAction->addTo(optionMenu);
1184 showDataAction->addTo(optionMenu);
1185 optionMenu->insertSeparator();
1186 showAllAction->addTo(optionMenu);
1187 showDebugAction->addTo(optionMenu);
1190 QPopupMenu* helpMenu = new QPopupMenu(this);
1191 menu->insertSeparator();
1192 menu->insertItem("&Help", helpMenu);
1193 showIntroAction->addTo(helpMenu);
1194 showAboutAction->addTo(helpMenu);
1196 connect(configList, SIGNAL(menuChanged(struct menu *)),
1197 helpText, SLOT(setInfo(struct menu *)));
1198 connect(configList, SIGNAL(menuSelected(struct menu *)),
1199 SLOT(changeMenu(struct menu *)));
1200 connect(configList, SIGNAL(parentSelected()),
1202 connect(menuList, SIGNAL(menuChanged(struct menu *)),
1203 helpText, SLOT(setInfo(struct menu *)));
1204 connect(menuList, SIGNAL(menuSelected(struct menu *)),
1205 SLOT(changeMenu(struct menu *)));
1207 connect(configList, SIGNAL(gotFocus(void)),
1208 SLOT(listFocusChanged(void)));
1209 connect(menuList, SIGNAL(gotFocus(void)),
1210 SLOT(listFocusChanged(void)));
1212 #if QT_VERSION >= 300
1213 QString listMode = configSettings->readEntry("/kconfig/qconf/listMode", "symbol");
1214 if (listMode == "single")
1216 else if (listMode == "full")
1218 else /*if (listMode == "split")*/
1221 // UI setup done, restore splitter positions
1222 QValueList<int> sizes = configSettings->readSizes("/kconfig/qconf/split1", &ok);
1224 split1->setSizes(sizes);
1226 sizes = configSettings->readSizes("/kconfig/qconf/split2", &ok);
1228 split2->setSizes(sizes);
1232 delete configSettings;
1236 * display a new help entry as soon as a new menu entry is selected
1238 void ConfigMainWindow::setHelp(QListViewItem* item)
1241 struct menu* menu = 0;
1244 menu = ((ConfigItem*)item)->menu;
1245 helpText->setInfo(menu);
1248 void ConfigMainWindow::loadConfig(void)
1250 QString s = QFileDialog::getOpenFileName(".config", NULL, this);
1253 if (conf_read(QFile::encodeName(s)))
1254 QMessageBox::information(this, "qconf", "Unable to load configuration!");
1255 ConfigView::updateListAll();
1258 void ConfigMainWindow::saveConfig(void)
1260 if (conf_write(NULL))
1261 QMessageBox::information(this, "qconf", "Unable to save configuration!");
1264 void ConfigMainWindow::saveConfigAs(void)
1266 QString s = QFileDialog::getSaveFileName(".config", NULL, this);
1269 if (conf_write(QFile::encodeName(s)))
1270 QMessageBox::information(this, "qconf", "Unable to save configuration!");
1273 void ConfigMainWindow::searchConfig(void)
1276 searchWindow = new ConfigSearchWindow(this);
1277 searchWindow->show();
1280 void ConfigMainWindow::changeMenu(struct menu *menu)
1282 configList->setRootMenu(menu);
1283 backAction->setEnabled(TRUE);
1286 void ConfigMainWindow::listFocusChanged(void)
1288 if (menuList->hasFocus()) {
1289 if (menuList->mode == menuMode)
1290 configList->clearSelection();
1291 setHelp(menuList->selectedItem());
1292 } else if (configList->hasFocus()) {
1293 setHelp(configList->selectedItem());
1297 void ConfigMainWindow::goBack(void)
1301 configList->setParentMenu();
1302 if (configList->rootEntry == &rootmenu)
1303 backAction->setEnabled(FALSE);
1304 item = (ConfigItem*)menuList->selectedItem();
1306 if (item->menu == configList->rootEntry) {
1307 menuList->setSelected(item, TRUE);
1310 item = (ConfigItem*)item->parent();
1314 void ConfigMainWindow::showSingleView(void)
1317 menuList->setRootMenu(0);
1318 configList->mode = singleMode;
1319 if (configList->rootEntry == &rootmenu)
1320 configList->updateListAll();
1322 configList->setRootMenu(&rootmenu);
1323 configList->setAllOpen(TRUE);
1324 configList->setFocus();
1327 void ConfigMainWindow::showSplitView(void)
1329 configList->mode = symbolMode;
1330 if (configList->rootEntry == &rootmenu)
1331 configList->updateListAll();
1333 configList->setRootMenu(&rootmenu);
1334 configList->setAllOpen(TRUE);
1335 configApp->processEvents();
1336 menuList->mode = menuMode;
1337 menuList->setRootMenu(&rootmenu);
1338 menuList->setAllOpen(TRUE);
1340 menuList->setFocus();
1343 void ConfigMainWindow::showFullView(void)
1346 menuList->setRootMenu(0);
1347 configList->mode = fullMode;
1348 if (configList->rootEntry == &rootmenu)
1349 configList->updateListAll();
1351 configList->setRootMenu(&rootmenu);
1352 configList->setAllOpen(FALSE);
1353 configList->setFocus();
1356 void ConfigMainWindow::setShowAll(bool b)
1358 if (configList->showAll == b)
1360 configList->showAll = b;
1361 configList->updateListAll();
1362 menuList->showAll = b;
1363 menuList->updateListAll();
1366 void ConfigMainWindow::setShowName(bool b)
1368 if (configList->showName == b)
1370 configList->showName = b;
1371 configList->reinit();
1372 menuList->showName = b;
1376 void ConfigMainWindow::setShowRange(bool b)
1378 if (configList->showRange == b)
1380 configList->showRange = b;
1381 configList->reinit();
1382 menuList->showRange = b;
1386 void ConfigMainWindow::setShowData(bool b)
1388 if (configList->showData == b)
1390 configList->showData = b;
1391 configList->reinit();
1392 menuList->showData = b;
1397 * ask for saving configuration before quitting
1398 * TODO ask only when something changed
1400 void ConfigMainWindow::closeEvent(QCloseEvent* e)
1402 if (!sym_change_count) {
1406 QMessageBox mb("qconf", "Save configuration?", QMessageBox::Warning,
1407 QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape);
1408 mb.setButtonText(QMessageBox::Yes, "&Save Changes");
1409 mb.setButtonText(QMessageBox::No, "&Discard Changes");
1410 mb.setButtonText(QMessageBox::Cancel, "Cancel Exit");
1411 switch (mb.exec()) {
1412 case QMessageBox::Yes:
1414 case QMessageBox::No:
1417 case QMessageBox::Cancel:
1423 void ConfigMainWindow::showIntro(void)
1425 static char str[] = "Welcome to the qconf graphical kernel configuration tool for Linux.\n\n"
1426 "For each option, a blank box indicates the feature is disabled, a check\n"
1427 "indicates it is enabled, and a dot indicates that it is to be compiled\n"
1428 "as a module. Clicking on the box will cycle through the three states.\n\n"
1429 "If you do not see an option (e.g., a device driver) that you believe\n"
1430 "should be present, try turning on Show All Options under the Options menu.\n"
1431 "Although there is no cross reference yet to help you figure out what other\n"
1432 "options must be enabled to support the option you are interested in, you can\n"
1433 "still view the help of a grayed-out option.\n\n"
1434 "Toggling Show Debug Info under the Options menu will show the dependencies,\n"
1435 "which you can then match by examining other options.\n\n";
1437 QMessageBox::information(this, "qconf", str);
1440 void ConfigMainWindow::showAbout(void)
1442 static char str[] = "qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n\n"
1443 "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n";
1445 QMessageBox::information(this, "qconf", str);
1448 void ConfigMainWindow::saveSettings(void)
1450 #if QT_VERSION >= 300
1451 ConfigSettings *configSettings = new ConfigSettings;
1452 configSettings->writeEntry("/kconfig/qconf/window x", pos().x());
1453 configSettings->writeEntry("/kconfig/qconf/window y", pos().y());
1454 configSettings->writeEntry("/kconfig/qconf/window width", size().width());
1455 configSettings->writeEntry("/kconfig/qconf/window height", size().height());
1456 configSettings->writeEntry("/kconfig/qconf/showName", configList->showName);
1457 configSettings->writeEntry("/kconfig/qconf/showRange", configList->showRange);
1458 configSettings->writeEntry("/kconfig/qconf/showData", configList->showData);
1459 configSettings->writeEntry("/kconfig/qconf/showAll", configList->showAll);
1460 configSettings->writeEntry("/kconfig/qconf/showDebug", helpText->showDebug());
1463 switch(configList->mode) {
1476 configSettings->writeEntry("/kconfig/qconf/listMode", entry);
1478 configSettings->writeSizes("/kconfig/qconf/split1", split1->sizes());
1479 configSettings->writeSizes("/kconfig/qconf/split2", split2->sizes());
1481 delete configSettings;
1485 void fixup_rootmenu(struct menu *menu)
1488 static int menu_cnt = 0;
1490 menu->flags |= MENU_ROOT;
1491 for (child = menu->list; child; child = child->next) {
1492 if (child->prompt && child->prompt->type == P_MENU) {
1494 fixup_rootmenu(child);
1496 } else if (!menu_cnt)
1497 fixup_rootmenu(child);
1501 static const char *progname;
1503 static void usage(void)
1505 printf("%s <config>\n", progname);
1509 int main(int ac, char** av)
1511 ConfigMainWindow* v;
1514 bindtextdomain(PACKAGE, LOCALEDIR);
1515 textdomain(PACKAGE);
1517 #ifndef LKC_DIRECT_LINK
1522 configApp = new QApplication(ac, av);
1523 if (ac > 1 && av[1][0] == '-') {
1536 fixup_rootmenu(&rootmenu);
1538 //zconfdump(stdout);
1540 v = new ConfigMainWindow();
1542 //zconfdump(stdout);
1543 configApp->setMainWidget(v);
1544 configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit()));
1545 configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings()));